Structured Wiki
A TypeScript, event-sourced, LLM-first structured wiki. Pages aren't free text — they're typed
documents (a "feature brief", an "implementation plan") that change only through named, typed
mutations gated by a finite-state machine. A workspace is a graph of pages backed by a single
append-only Durable Stream; history is the source of truth, and
every page renders deterministically to Markdown. Agents reach it over MCP.
- Only legal actions. A mutation is accepted only where the page's FSM allows it; illegal calls
return a structured error naming the legal set, so an agent self-corrects.
- Atomic within a workspace. Structural changes (reparent, link, cross-page item moves) are
all-or-nothing — one workspace is one event stream.
- Read-your-writes. Writes return a consistency token; the MCP layer threads it so an agent always
reads its own prior writes.
- Schema is pluggable and hot-reloadable. Page types live in
wiki-models and load into a running
server by reference — the engine ships none baked in.
- Renders back to disk (optional, per project). A project registers a Markdown mirror at runtime over MCP —
configureEmitter({ emitterId, workspaceId, root }) — and the wiki mirrors that workspace's Markdown into that
absolute root, kept current off the same projection tail, content-hashed so the git diff stays honest. The
emitter set is event-sourced on its own durable stream (replayed on boot, tailed live → no restart). The wiki
stays the source of truth; each repo gets a faithful, always-current rendered copy.
The packages
| Package | Role |
|---|
wiki | The engine. Transport-free TypeScript API; event sourcing, FSM, CQRS, Markdown render. Ships no page types. |
wiki-models | The schema layer — the only home for concrete page types (e.g. the feature bundle). Loaded at runtime. |
wiki-mcp | Long-lived host: embeds the engine, maintains a SQL read model (PGlite/pg), exposes MCP tools + resources. |
wiki-server | Thin process that runs the durable stream host and hosts wiki-mcp in one process. |
wiki-ui | Standalone Next.js browser for a running server — embeds the engine client-side, tails the stream live, drives FSM transitions. Not a workspace member (own install/build). |
Architecture, boundaries, and conventions live in CLAUDE.md; per-package design intent,
the content model, ADRs, and feature specs live in the wiki's own rendered mirror under
docs/hotseat-wiki/.
Quickstart: using the wiki
The wiki is driven over MCP. Boot the server (which loads your page-type schema), point an MCP client
at it, and create content with the wiki tools.
1. Start the server with a schema loaded
The server loads no page types by default — pass the feature bundle so feature-brief and friends
become creatable:
npm install # first time only
npm run start -w wiki-server -- --models wiki-models/feature
This boots three local listeners: the stream host (:4437), a control API (:4438), and the
MCP endpoint (:4439/mcp). Data persists under ./.wiki-data. Confirm it's healthy and the schema
loaded:
curl localhost:4438/_server/health # {"status":"ok"}
curl localhost:4438/_server/models # bundle "feature" with its page types
2. Connect an MCP client
This repo already ships .mcp.json pointing the wiki MCP server at
http://127.0.0.1:4439/mcp — so in Claude Code, the wiki tools light up as soon as the server is
running (with a model loaded). Any other MCP client can connect to the same URL.
3. Build a feature with /build-feature
The bundled Claude Code skill drives a feature through the feature bundle's FSM end-to-end:
/build-feature <workspaceId> "<one-line intent>"
/build-feature <workspaceId> feature-brief:<id> # drive an existing brief
(No workspace yet? One MCP call — createWorkspace → { name: "My project" } — returns the workspaceId.)
It seeds (or picks up) a feature-brief, grounds the implementation plan in the real repo, writes the
code, and verifies with real typecheck/tests plus a /code-review pass before flipping any FSM gate —
stopping at the human sign-off gates (submitForReview / ship). It delegates what's next to the
wiki's own nextActions rather than hardcoding the lifecycle, and it's branch/worktree-agnostic, so
several can run in parallel worktrees against the one shared wiki. Design and caveats:
.claude/skills/build-feature/README.md.