Skip to main content
Glama
CocoaBeans
by CocoaBeans
README.md
# worldmodel-mcp

An external **world model** for LLM agents: a validated state database that lives
outside the context window, exposed as an MCP server and a standalone `wm` CLI.

## Why

Apple's [*The Illusion of Thinking*](https://machinelearning.apple.com/research/illusion-of-thinking)
shows reasoning models collapsing on compositional tasks (Tower of Hanoi fails
around 8 disks) — even when handed the explicit algorithm. The failure pattern
points at **execution fidelity, not insight**: a transformer cannot reliably
maintain exact state across hundreds of steps of its own token stream, and one
silent tracking error compounds forever.

This tool changes the model's job. Instead of being the state-keeper, the
executor, and the policy all at once, the model keeps only the part it's good
at (judgment, decomposition, interpretation) and delegates the rest:

| Paper failure mode | Tool answer |
|---|---|
| State drift over long horizons | State lives in SQLite tables; the model queries only the working set it needs per step (`query`) |
| Silent, compounding errors | Every mutation is a transaction checked against declared **invariants**; illegal transitions are rejected with the broken rule named (`apply_action`, `define_invariant`) |
| Can't execute known algorithms | Register the algorithm once and let the tool run it — a thousand exact, validated steps for zero tokens (`define_procedure`, `run_procedure`) |
| Can't backtrack cleanly | Snapshots and branches; abandoning a branch truly forgets it (`snapshot`, `branch`, `checkout`, `restore_snapshot`) |
| Work lost to context limits | The world outlives the window; `describe_world` + `history` re-orient a fresh context in one call |

**What it does not fix:** choosing the right next action is still the model.
This moves the collapse threshold out substantially; it does not remove it.

## Acceptance test

Straight from the paper: 12-disk Tower of Hanoi (unaided models collapse ~8).
Through the world model: schema + 2 invariants + a 12-line recursive procedure →
**4095 moves, every one invariant-checked, in 0.26 s**, final state verified by
query. See `src/core.test.ts` ("Tower of Hanoi") for the runnable version.

## Documentation

- **[AGENTS.md](AGENTS.md) — the agent operating manual.** If you are an LLM
  agent (or configuring one), start there: when to reach for a world, the five
  habits, recipes, the procedure contract, how to write good invariants, gotchas.
- Over MCP the same manual is available without reading files: call the
  **`guide`** tool (`topic`: `all` | `quickstart` | `recipes` | `procedures`),
  or read the **`worldmodel://guide`** / **`worldmodel://readme`** resources.
  The server also sends a summary as MCP *instructions* at connection time, so
  a client model knows what this is before calling anything.
- `wm help` documents every CLI command.

## Install

```bash
npm install
npm run build
npm test
```

Optionally `npm link` to get `wm` and `worldmodel-mcp` on your PATH.

### Register as an MCP server (Claude Code)

```bash
claude mcp add worldmodel -- node /path/to/worldmodel-mcp/dist/server.js
```

Worlds are stored under `~/.worldmodel/` (override with `WORLDMODEL_DIR`).

## Model of operation

A **world** = one problem domain (a puzzle, an investigation, a migration plan).
Each world has:

- **Tables** — ordinary SQLite tables you define; one fact per row.
- **Invariants** — named SELECTs that return *violating* rows (empty = healthy).
  Checked inside every action's transaction; violations roll the action back.
- **Actions** — named, logged, transactional mutations (`apply_action`, or the
  `assert_facts` / `retract_facts` conveniences).
- **Procedures** — deterministic JS function bodies `(query, act, log, args, lib)`
  run in a `node:vm` sandbox with step/time budgets; each `act()` is a full
  validated transition, and a pre-run snapshot makes any run one `restore` from
  undone. (The sandbox is an isolation convenience, not a security boundary —
  procedures run with local trust, same as the agent's shell access.)
- **`lib.search`** — generic BFS/DFS over in-memory states:
  `lib.search({start, moves, goal, key?, mode?, maxNodes?})` returns
  `{found, path, finalState, nodesExpanded}`. The intended pattern is
  **plan in memory, execute validated**: search over lightweight state objects
  (no DB copies per node), then replay the winning path via `act()` so every
  real step is still invariant-checked. See the river-crossing test — the
  paper's other benchmark family — solved this way in `src/core.test.ts`.
- **Templates** — `create_world` with `template: "facts"` scaffolds an evidence
  ledger for investigations: `facts(entity, attribute, value, source,
  confidence, status, superseded_by, ...)` plus invariants that force
  contradictions to be resolved explicitly (supersede or mark `disputed`)
  instead of letting incompatible beliefs silently coexist.
- **Branches & snapshots** — cheap file-level copies (`VACUUM INTO`) for
  exploration and undo.
- **Event log** — every schema change, action, and procedure run, queryable
  via `history`.

## CLI quickstart

```bash
wm create hanoi "Tower of Hanoi"
wm schema hanoi "CREATE TABLE disks (disk INTEGER PRIMARY KEY, peg TEXT NOT NULL, height INTEGER NOT NULL, UNIQUE (peg, height))"
wm invariant hanoi no-disk-on-smaller "No disk on a smaller disk" \
  "SELECT u.disk, l.disk FROM disks u JOIN disks l ON u.peg = l.peg AND u.height = l.height + 1 WHERE u.disk > l.disk"
wm assert hanoi disks '[{"disk":1,"peg":"A","height":3},{"disk":2,"peg":"A","height":2},{"disk":3,"peg":"A","height":1}]'
wm act hanoi move "UPDATE disks SET peg=@dst, height=COALESCE((SELECT MAX(height) FROM disks WHERE peg=@dst),0)+1 WHERE disk=(SELECT disk FROM disks WHERE peg=@src ORDER BY height DESC LIMIT 1)" '{"src":"A","dst":"B"}'
wm query hanoi "SELECT * FROM disks ORDER BY peg, height"
wm check hanoi
```

`wm help` lists everything; long SQL/code args accept `-` for stdin;
`wm serve` runs the MCP server.

## MCP tools

`list_worlds` · `create_world` · `describe_world` · `define_schema` ·
`define_invariant` · `drop_invariant` · `apply_action` · `assert_facts` ·
`retract_facts` · `query` · `check_invariants` · `snapshot` ·
`restore_snapshot` · `branch` · `checkout` · `history` ·
`define_procedure` · `run_procedure`

## Agent usage discipline

The tool only helps if state is routed through it. The intended habit, for any
task with evolving state plus rules:

1. `create_world`, `define_schema`, and encode the domain rules as invariants
   *first* — rules in the database, not in your head.
2. Mutate only via actions; treat a rejection as information, not failure.
3. Query the working set per step; never re-derive state from the transcript.
4. The moment you know the algorithm, write a procedure instead of narrating steps.
5. Snapshot before anything exploratory; branch to compare alternatives.

Maintenance

ActivitySlowing
ResponsivenessNo issues