Phase 7d: Block API + MCP Tools
Goal: Expose block-level read/write operations via new API endpoints and MCP tools. Enable agents to read one section, update one section, and navigate via TOC — without touching the full document.
Owner: Dev agent
Repos: pal-e-docs (API endpoints), pal-e-docs-mcp (MCP tools)
Depends on: Phase 7c (blocks populated in DB)
Parent phase: Phase 7 (Block-Structured Content Model)
Why This Phase
Blocks exist in the database but agents can't use them yet. This phase adds the API and MCP surface that makes block-level access real. This is where the token savings become measurable.
New API Endpoints
| Endpoint | Method | What It Does |
|---|---|---|
| <code>/notes/{slug}/toc</code> | GET | Returns heading blocks only — note's table of contents with anchor IDs |
| <code>/notes/{slug}/blocks</code> | GET | Returns all blocks for a note (ordered by position) |
| <code>/notes/{slug}/blocks/{anchor_id}</code> | GET | Returns a single block (or section: heading + content blocks until next heading) |
| <code>/notes/{slug}/blocks/{anchor_id}</code> | PUT | Updates a single block's content. Triggers recompile of compiled_page. |
| <code>/notes/{slug}/blocks</code> | POST | Insert a new block at a given position. Triggers recompile. |
| <code>/notes/{slug}/blocks/{anchor_id}</code> | DELETE | Remove a block. Triggers recompile. |
New MCP Tools (pal-e-docs-mcp)
| Tool | Wraps | Token Impact |
|---|---|---|
| <code>get_note_toc(slug)</code> | GET /notes/{slug}/toc | ~50 tokens vs ~2,360 for get_note (plan avg) |
| <code>get_block(slug, anchor_id)</code> | GET /notes/{slug}/blocks/{anchor_id} | ~200 tokens vs ~2,360 for get_note |
| <code>update_block(slug, anchor_id, content)</code> | PUT /notes/{slug}/blocks/{anchor_id} | ~100 tokens vs ~2,360 for update_note |
| <code>create_block(slug, block_type, content, after_anchor)</code> | POST /notes/{slug}/blocks | Targeted insertion without full rewrite |
| <code>delete_block(slug, anchor_id)</code> | DELETE /notes/{slug}/blocks/{anchor_id} | Targeted deletion without full rewrite |
Backward Compatibility
get_notecontinues to returnhtml_contentas beforeupdate_notewithhtml_contentcontinues to work — internally re-parses into blocks and recompiles- New tools are additive — agents can gradually adopt block-level access
- On block write (update/create/delete): recompile
compiled_pages.htmland updatehtml_contenton the note (keeps both in sync)
Acceptance Criteria
- All 6 API endpoints working with tests
- All 5 MCP tools deployed and functional
get_note_tocreturns heading structure for a plan in ~50 tokensget_blockreturns one section of a plan in ~200 tokensupdate_blockupdates one section without touching others- Block writes trigger recompile of
compiled_pagesandhtml_content - Existing
get_note/update_notebehavior unchanged
Benchmark Target
Run Phase 7 benchmark re-test after this phase ships. Compare against
benchmark-phase7-block-baseline:- Targeted read: 2,360 tokens → ~200 tokens (target: 92% reduction)
- Targeted update: 2,360 tokens → ~100 tokens (target: 96% reduction)
- TOC navigation: 2,360 tokens → ~50 tokens (target: 98% reduction)
Related
phase-postgres-7c-backfill-migration— blocks must be populatedphase-postgres-8-mcp-optimization— Phase 8 builds on these toolsbenchmark-phase7-block-baseline— baseline for re-test