The control plane's architecture, for both kinds of reader. Humans read this page;
agents read ARCHITECTURE.md
in the repo or ask the running worker at /api/surface.
All three render the same registry the server registers its tools from, the tables below are
fetched from it live, and CI refuses any commit where the committed copies drift.
┌──────────────────────────────────────────────┐
humans ────────────▶│ static pages · /d/<key> ruling links │
browser, phone │ /authorize — invite code → identity │
│ │──▶ D1 — per-tenant:
agents ────────────▶│ /mcp — McpAgent on a Durable Object │ nodes+FTS5, runs,
MCP, any harness │ tools registered from surface.js │ events, asks, members
│ │──▶ Vectorize — embeddings
runners ───────────▶│ /api/* — the same contract, plain HTTP │──▶ Workers AI — embed + rerank
curl, cron, BYO └──────────────────────────────────────────────┘
Every MCP tool has a plain-HTTP twin, so bring-your-own-agent never depends on MCP support. The projection every caller reads is derived and disposable, rebuildable from the tenant's own repository at any commit, which is why every answer carries the commit it reflects.
Every projected node, run, event, decision and member row carries a tenant slug; every read is scoped by it; a replace-mode projection push can only ever delete its own tenant's rows.
org/ in the repo, tenant hq) is projected
into the same production database customers use. The isolation that protects a customer is the isolation
the vendor personally depends on, and it is proven by a test that starts from a byte-faithful copy of
the pre-tenancy schema, migrates it, and asserts a second tenant's replace push leaves the first tenant
byte-identical. npm test, on every push
Rendered live from /api/surface. Roles gate at registration: a tool a role may
not use is a tool that role's session never sees.
| Tool | Roles | What it does |
|---|
| Method | Path | Auth | What |
|---|
The tool surface is declared once, in
src/surface.js.
The MCP server registers its tools from that declaration; /api/surface serves it;
ARCHITECTURE.md, the docs, /llms.txt
and this page render it. There is no step where a person updates documentation, there is one object,
and CI (npm run gen:check) fails any commit where a rendered copy disagrees with it.