Skip to main content

Architecture overview

One Node 24 process (session-bus serve) owns one SQLite database and exposes 7 MCP tools over Streamable HTTP. Claude Code connects to it as an HTTP MCP server. An optional per-session stdio shim polls it and pushes new mail into an idle session.

Components​

ComponentWhat it isWrites
serveHTTP MCP server, stateless: one MCP server object per request.bus.db, bus.db.lock
Admin CLIprincipal, token, session release, doctor, backup, restore. Runs on the bus host and opens the DB directly.bus.db
channel (shim)stdio MCP server for one session. HTTP client of the bus.shim-<name>.lock, shim-<name>.json
scripts/bus-headers.shClaude Code headersHelper. Prints the Authorization header.nothing

Two ways to reach the bus​

  • Tailscale serve (default). serve listens on 127.0.0.1:47910. tailscale serve exposes it as https://<bus-host>.<tailnet>.ts.net:8443/mcp. Needs HTTPS certificates enabled on the tailnet.
  • Direct tailnet bind (fallback). BUS_HOST=$(tailscale ip -4) makes serve listen on the host's tailnet address. Reached at http://<bus-host>.<tailnet>.ts.net:47910/mcp. Traffic is still inside the tailnet's WireGuard tunnel.

Any other bind address is refused. See Security model.

Dependencies​

Runtime: @modelcontextprotocol/sdk, zod and @cogs/auth (token minting and verification). Storage is the built-in node:sqlite. There is no web framework and no external database.

Sizes, for orientation​

src/ is about 1,600 lines of TypeScript across 16 files. bash scripts/gate.sh 6 runs the typecheck, build, the Vitest suite, scripts/smoke.sh, scripts/e2e.sh and the documentation checks.

Further reading​