Feature Book[02]
[A documentation workspace where an agent writes the docs and a human keeps editing them. An MCP server lets Claude document a codebase straight into the workspace: point it at a repository, approve the page tree, and the pages land where they stay editable in the browser.]
Stack
Features
MCP Documentation Server
Claude connects over OAuth 2.1 with dynamic client registration — no key to paste. The client discovers the authorization server from an unauthenticated 401, registers itself, and the token it receives is scoped to the workspaces that user belongs to and nothing else.
Section-Level Updates
Docs are updated one section at a time: getPageOutline for the block id, then updatePageSection. The call never carries the rest of the document, so an edit cannot silently drop a paragraph it was not asked about.
Conflict Detection
updatePageSection refuses with a conflict rather than reverting a page that moved between the read and the write — the agent is told to re-read instead of overwriting a human edit.
Persisted Block Editor
BlockNote in two forms — embeddable in MDX pages, and persisted to Postgres under /projects. Every page has read-only version restore points, and the page tree lives in the layout so it survives navigation.
Revocable Access
Every connected client is listed under Settings → MCP access, named after the client. Revoking one is a click and stops that client immediately without touching the others; headless clients get a personal access token from the same panel.
What I did
- Enforced a hard server boundary: `app/` never imports Prisma, it calls
server/actions. Everything server-only lives underserver/, withlib/as the shared middle importable from both. - Built round-trip verification for the editor:
blocks:checkpushes a document through a real editor instance and diffs it, catching blocks the editor would silently drop. - Added `sections:backfill` and `sections:verify` to re-derive every page's Section rows and prove they still reassemble into the original document.
- Found and fixed an untypechecked corner of the repo —
tsconfigincluded only**/*.ts, leaving the four scripts that write to the database unchecked; one had been silently broken by bad import paths. - Documented a schema-migration route that avoids Prisma's shadow database, which would otherwise create and drop against an instance whose public schema belongs to another app.