2026-07-04 — MCP client ergonomics planned (from the library session)
Discussion started as "optimize agent traversal of the knowledge graph," reframed by Fritz to the MCP-client perspective (Claude Code/Desktop as the main consumers). Key grounding: the 06-21 Leiden measurement — hub-and-spoke graph, computed graph queries mostly re-derive the index tree — so client headroom is turns and tokens, not graph algorithms.
Plan recorded + settled:
/plans/mcp-client-ergonomics.md —
W1 size-adaptive outline/#section fetch (8KB gate) · W3 per-session
version+etag dedup · W2 mark_explore neighborhood card (doc + backlinks +
outbound + siblings, 10/cap) · W4 tool-description strategy pass. D1–D4 all
settled on recommendation (size-adaptive; full card; per-session; shared
client/ slicing package). Deferred: client graph queries (Leiden re-test
trigger), server FTS (separate lane), MCP resources/prompts (follow-up),
lean tool profiles.
Pickup notes with repo pointers are in the plan (code:
client/cmd/demarkus-mcp/main.go; new package beside client/{fetch,graph, links}). Next session in ~/latebit/demarkus starts at W1+W3.
(Same day, library side: v0.16.0 UX round + v0.17.0 pane-scroll-default merged and deployed — see /demarkus-library/journal/2026-07-03-ux.md and ADR 0007.)
MCP client ergonomics — W1–W4 built (feature/mcp-client-ergonomics)
Implemented the whole plan (/plans/mcp-client-ergonomics.md) in one pass on
branch feature/mcp-client-ergonomics; awaiting Fritz's commit.
- client/mdoutline (new package, D4): pure functions over markdown —
Headings(goldmark parse, GitHub-style slug anchors with taken-anchor dedup: Notes/Notes/Notes-1 → notes, notes-1, notes-1-1),Section(subtree slice, lenient: accepts raw heading text re-slugged, case-insensitive),Outline,OpeningParagraph,Anchors. Edge cases tested: setext headings,#inside code fences and indented blocks, inline code in headings, duplicate anchors. - W1 (size-adaptive fetch): mark_fetch returns full body <8KB; above it
mode: outline(heading tree with anchors + per-section line counts, opening paragraph,fetch url#<anchor>hint).url#anchorslices at any size;force=truealways full body. Section-not-found errors list available anchors. - W3 (session dedup): per-process map (host+path → version,etag),
recorded ONLY when a full body was actually returned (outline/section
fetches never arm it — otherwise the outline→section flow would break).
Unchanged re-fetch →
status: unchanged … since vN; changed → body +note: changed since this session's earlier fetch (vX -> vY); force busts. - W2 (mark_explore): neighborhood card in one call — outline head + opening paragraph + outbound links (title'd, deduped) + backlinks (graph store, degrades to a note) + parent-dir siblings (LIST, degrades on failure), all capped at 10 with honest "+N more". New files explore.go / explore_test.go.
- W4: descriptions for fetch/lookup/list/backlinks/explore now teach the strategy (lookup-first, explore to orient, #section for detail, full bodies rarely needed).
Verified live against soul.demarkus.io by driving the built binary over
stdio: /demarkus-library/roadmap.md (51,939 bytes) → 5,892-char outline;
#next-phases-queued slice 874 chars; guidelines.md fetched twice → second
gets status: unchanged (201 chars), force re-reads; explore card on
/demarkus-library/index.md orients in one turn. Acceptance met: project +
phase answerable in ≤2 turns, no full roadmap fetch.
Gotcha worth remembering: mcp-go serves stdio tool calls concurrently — two same-doc fetches raced and completed out of order, which is exactly why the dedup map is mutex-guarded.
Not done (deferred per plan): broker gateway parity for outline/dedup (its
mirrored formatResult contract is untouched — new behavior is client-side
only), MCP resources/prompts follow-up, library librarian open adoption of
mdoutline.