{"slug": "show-hn-seahaven-open-source-framework-for-building-rl-environments", "title": "Show HN: Seahaven – Open-source framework for building RL environments", "summary": "Kiln-AI released Seahaven, an open-source Python framework for building synthetic RL and evaluation environments in which each agent run gets its own isolated, stateful SQLite-backed world. Seahaven serves hundreds of world instances per process at thousands of requests per second, logs every row an agent changes for state-based grading, and reproduces runs from the same fixture, clock and random seed; it exposes environments via OpenEnv and MCP and is installed with the command `uvx seahaven new crm_world`.", "body_md": "[**Quick Start**](#quickstart) •\n  [**Docs**](https://github.com/Kiln-AI/Seahaven/blob/main/src/seahaven/docs/index.md) •\n  **Examples**\n\nEvals and RL need thousands of agent runs, each isolated, starting from a known state, and graded on what the agent changed. Production systems can't do that. Seahaven is a Python framework for building synthetic worlds that can: working copies of your agent's tools, realistic enough that the agent can't tell the difference.\n\nSeahaven handles the hard parts: parallel instances, reproducibility, serving, and change logs. You only write what's specific to your world: its tables and its tools.\n\nNamed after the town in *The Truman Show*: an entire world built so that one inhabitant believes\nit is real.\n\n- **[Recreate Any Environment](https://github.com/Kiln-AI/Seahaven/blob/main/src/seahaven/docs/authoring.md#writing-a-tool):** Mock AI tool\ncalls, REST APIs, sandboxed SQL, search, or any custom format.\n- **[Stateful](https://github.com/Kiln-AI/Seahaven/blob/main/src/seahaven/docs/concepts.md#instance):** Each instance of a world has its own independent\nSQLite database.\n- **[Composable](#composing-worlds):** Compose, reuse and share worlds. Example: MyCoWorld\ncan include[StripeAPIWorld](https://github.com/Kiln-AI/stripe_world) and ShopifyAPIWorld.\n\n- **[Fixtures](https://github.com/Kiln-AI/Seahaven/blob/main/src/seahaven/docs/db_schema_and_fixtures.md):** Freeze known starting states like`small_startup` ,`agency` or`big_co` , and reuse them across runs.\n- **[Concurrent Instances](https://github.com/Kiln-AI/Seahaven/blob/main/src/seahaven/docs/serving_and_openenv.md):** Serve hundreds of world\ninstances per process, at thousands of requests per second.\n- **[Evaluate World State](https://github.com/Kiln-AI/Seahaven/blob/main/src/seahaven/docs/state.md):** Grade on state, not on transcripts.\nEvery row the agent changed is logged.\n- **[Reproducible](https://github.com/Kiln-AI/Seahaven/blob/main/src/seahaven/docs/concepts.md#reproducibility):** Same initial state (fixture),\nsame clock/time, same random seed: the same run, every time.\n\n- **[OpenEnv](#serve-with-openenv):**`seahaven serve` is an OpenEnv environment. Drive it with any\nOpenEnv client, in any language, or publish it to Hugging Face.\n- **[Web Console](https://github.com/Kiln-AI/Seahaven/blob/main/src/seahaven/docs/serving_and_openenv.md#the-web-console):**`seahaven serve` includes a web UI: open instances, call tools, and inspect state in your browser.\n- **[MCP](#use-with-mcp-clients):**`seahaven mcp` serves one world to an MCP client, so you can\nwork against it by hand from an editor or chat app.\n\n- **[Built for Coding Agents](#build-worlds-with-your-coding-agent):** Docs optimized for agents\nauthoring worlds.`seahaven check` tells an agent the exact fix for every mistake.\n- **[Just Python](https://github.com/Kiln-AI/Seahaven/blob/main/src/seahaven/docs/authoring.md#writing-a-tool):** Tools are just functions.\nTests use pytest. Your agent already knows how to write and test Seahaven worlds.\n\n|  | Seahaven | Production or staging | Hand-written mocks | \n|---|---|---|---|\n| Realistic tools and data | ✅ | ✅ | ❌ | \n| Stateful across arbitrary tool calls | ✅ | ✅ | ❌ | \n| A private instance for every run | ✅ | ❌ | ✅ | \n| Hundreds of parallel instances | ✅ | ❌ | ✅ | \n| Every run starts from a known state | ✅ | ❌ | ✅ | \n| Reproducible | ✅ | ❌ | ✅ | \n| Every change logged for grading | ✅ | ❌ | ❌ | \n| Safe for the agent to break things | ✅ | ❌ | ✅ | \n\n**Create a world.** This writes a complete project: schema, tools, tests, a fixture generator, and\nan `AGENTS.md` that points your coding agent at the docs.\n\n```\nuvx seahaven new crm_world # your world name\ncd crm_world && uv sync\n```\n\n**Write your world.** A world is a schema and a set of tools. Here is a small CRM:\n\n``` python\nimport seahaven\n\nworld = seahaven.World(\n    name=\"crm\",\n    version=\"1.0.0\",\n    schema=\"\"\"\n    CREATE TABLE contacts (\n        id TEXT PRIMARY KEY,\n        email TEXT NOT NULL,\n        stage TEXT NOT NULL,\n        updated_at TEXT NOT NULL\n    ) STRICT;\n    \"\"\",\n    state_format=\"seahaven.state/1\",\n)\n\n@world.tool\ndef create_lead(ctx: seahaven.Ctx, email: str) -> dict[str, str]:\n    \"\"\"Add a contact to the pipeline as a new lead.\"\"\"\n    lead = {\"id\": ctx.ids.uuid(), \"email\": email, \"stage\": \"lead\", \"updated_at\": ctx.clock.iso()}\n    ctx.db.execute(\"INSERT INTO contacts VALUES (?, ?, ?, ?)\", *lead.values())\n    return lead\n\n@world.tool\ndef list_stale_leads(ctx: seahaven.Ctx) -> list[dict[str, object]]:\n    \"\"\"List leads nobody has touched in 30 days.\"\"\"\n    return ctx.db.rows(\n        \"SELECT * FROM contacts WHERE stage = 'lead' \"\n        \"AND updated_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-30 days')\"\n    )\n```\n\n**Freeze a starting state.** A fixture is a frozen database that every run starts from:\n\n```\nwith world.instance(now=\"2026-06-01T09:00:00.000Z\", clock_mode=\"fixed\") as inst:\n    for n in range(500):\n        inst.call(\"create_lead\", email=f\"lead{n}@example.com\")\n    inst.freeze(\"big_co\", \"A pipeline of 500 new leads.\")\n```\n\n**Run your agent.** Each run gets a private copy of the fixture in milliseconds. The same seed\nreplays the same run, and what the agent changed is a document you grade:\n\n```\nfor rollout in range(100):\n    with world.instance(\"big_co\", seed=rollout) as inst:\n        run_agent(inst)  # your agent, your harness\n        reward = grade(inst.state())  # every row the agent changed\n```\n\n**Serve it.** `seahaven serve` hosts an OpenEnv endpoint where every connection gets its own\ninstance. Open `http://127.0.0.1:8000/console` to drive it by hand.\n\n```\nuv run --extra serve seahaven serve\npython\nfrom seahaven.openenv import SeahavenClient\n\nwith SeahavenClient(base_url=\"http://127.0.0.1:8000\") as env:\n    env.reset(fixture=\"big_co\", seed=42)\n    env.call(\"create_lead\", email=\"ada@example.com\")\n    final_state = env.state()  # the document the eval grades\n```\n\n- **[ProjectTracker](https://github.com/Kiln-AI/Seahaven/blob/main/worlds/projecttracker)** : the reference world, a fictional issue tracker\nshaped like Linear or Jira. Nine tables, 25 tools, full-text search, and fixtures from an empty\nworkspace to a twelve-person agency with six months of history. Start here to learn the patterns\n([walkthrough](https://github.com/Kiln-AI/Seahaven/blob/main/src/seahaven/docs/projecttracker.md) ).\n- **[Stripe World](https://github.com/Kiln-AI/stripe_world)** : a mock of Stripe's Billing and\nPayments core, with 24 tables and 155 API operations behind the same tools as Stripe's own MCP\nserver. It also serves Stripe's REST API, so the Stripe SDKs work against it unchanged.\n\nBuild a world once and reuse it everywhere. A company world can add a payments world, such as\n[Stripe World](https://github.com/Kiln-AI/stripe_world), and a chat world, plus its own tables and\ntools. The agent sees one tool list, and an eval grades what changed in every world from one state\ndocument. See the [composition docs](https://github.com/Kiln-AI/Seahaven/blob/main/src/seahaven/docs/composition.md).\n\n```\ncompany.add_world(payments_world.world, name=\"payments\", tool_prefix=\"pay_\")\ncompany.add_world(chat_world.world, name=\"chat\", tool_prefix=\"chat_\")\n\n@company.tool\ndef refund_order(ctx: seahaven.Ctx, charge_id: str, channel: str) -> dict[str, object]:\n    \"\"\"Refund a charge and tell the support channel it is done.\"\"\"\n    refund = ctx.worlds.payments.call(\"create_refund\", charge_id=charge_id)\n    ctx.worlds.chat.call(\"post_message\", channel=channel, text=f\"refunded {refund['amount']}\")\n    return refund\n```\n\n`seahaven serve` hosts your world as an [OpenEnv](https://github.com/huggingface/OpenEnv)\nenvironment, the open standard for RL environments. Every connection gets its own private instance.\nEach process can host hundreds of parallel instances. Drive it from Python, from\n[Kiln](https://kiln.tech), or from any OpenEnv client, such as OpenEnv's own generic client:\n\n``` python\nfrom openenv import GenericEnvClient\nfrom openenv.core.env_server.mcp_types import CallToolAction\n\nwith GenericEnvClient(base_url=\"http://127.0.0.1:8000\") as env:\n    env.reset(fixture=\"big_co\", seed=7)\n    create = CallToolAction(tool_name=\"create_lead\", arguments={\"email\": \"ada@example.com\"})\n    env.step(create.model_dump())\n    final_state = env.state()\n```\n\nSee the [serving docs](https://github.com/Kiln-AI/Seahaven/blob/main/src/seahaven/docs/serving_and_openenv.md) for the client, the wire protocol\nand running in production.\n\n`seahaven mcp` connects a world to Claude, Cursor, or any MCP client. Explore a world by hand, debug\nyour tools, or try a task yourself before you give it to an agent.\n\n```\nuv run --extra mcp seahaven mcp --fixture big_co\n```\n\nSeahaven is designed to be built by coding agents. `seahaven new` writes an `AGENTS.md` that points\nyour agent at the docs for the version you have installed, not stale ones from the web.\n`seahaven check` catches the mistakes that are easy to make and hard to notice, and names the fix.\n\nSee [CONTRIBUTING.md](https://github.com/Kiln-AI/Seahaven/blob/main/.github/CONTRIBUTING.md) for setup and the checks CI runs.\n\n[MIT](https://github.com/Kiln-AI/Seahaven/blob/main/LICENSE).\n\nSeahaven is built by the team behind [Kiln](https://kiln.tech), a free app and open-source library\nfor building better AI products. Kiln connects to any Seahaven world: write scenarios against a\nfixture, [evaluate](https://kiln.tech/features/evals) your agent on the state it leaves behind, then\n[auto-optimize](https://kiln.tech/features/auto-optimize) prompts and models against those evals.", "url": "https://wpnews.pro/news/show-hn-seahaven-open-source-framework-for-building-rl-environments", "canonical_source": "https://github.com/Kiln-AI/Seahaven", "published_at": "2026-10-08 16:35:25+00:00", "updated_at": "2026-10-08 16:47:23.328334+00:00", "lang": "en", "topics": ["ai-agents", "ai-research", "developer-tools", "agent-protocols", "artificial-intelligence"], "entities": ["Kiln-AI", "Seahaven", "OpenEnv", "Hugging Face", "MCP", "StripeAPIWorld", "ShopifyAPIWorld", "SQLite"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-seahaven-open-source-framework-for-building-rl-environments", "markdown": "https://wpnews.pro/news/show-hn-seahaven-open-source-framework-for-building-rl-environments.md", "text": "https://wpnews.pro/news/show-hn-seahaven-open-source-framework-for-building-rl-environments.txt", "jsonld": "https://wpnews.pro/news/show-hn-seahaven-open-source-framework-for-building-rl-environments.jsonld"}}