Plan: MCP client ergonomics — cheaper turns, cheaper tokens
Status: drafted 2026-07-04 · Repo: demarkus (demarkus-mcp client) + demarkus-memory plugin · Decisions D1–D4 open (recommendations inline)
Problem
The main consumers of the soul and the knowledge system are MCP agents (Claude Code, Claude Desktop). For them the unit of cost is not the QUIC round-trip — it is the model turn per tool call and the context tokens per result. Today:
- Orientation costs a chain of turns: lookup → fetch → backlinks → fetch…
mark_fetchalways returns the whole body. Append-heavy status docs grow unbounded (the library roadmap is the live example — one fetch is a five- figure token spend), and agents usually need one section.- Agents re-fetch unchanged docs across a long session; every re-read pays full price.
- 14 tools per joined surface × several surfaces = schema budget + verb choice-paralysis.
Measured constraint (journal 2026-06-21): the link graph is hub-and-spoke (73% leaves) — computed graph queries (paths, centrality, communities) mostly re-derive the index tree, so the pre-made graph is NOT where client headroom is. Turns and tokens are.
Workstreams (priority order)
W1 — mark_fetch outline/section mode (token economy)
url#<heading-anchor>returns just that section (client slices the fetched markdown; no protocol change).- Outline mode returns the heading tree + opening paragraph + doc stats (version, modified, size, tags) with a "fetch url#section for detail" hint.
- Client caches the full body per session, so section follow-ups are free.
W2 — mark_explore composite (turn economy)
One tool call returns a neighborhood card for a URL: outline-mode head of the doc + backlinks (titles) + outbound links (titles) + sibling listing, each entry one line. Composes FETCH/LOOKUP/graph client-side. Caps per section (~10) with honest "+N more". Replaces the common 3–4-turn orientation chain.
W3 — session etag/version dedup
Re-fetch of an unchanged doc returns unchanged since v<N> (fetched earlier this session) instead of the body. Changed docs return the body plus a
version delta note. Per-process cache; a force param overrides.
W4 — polish (cheap, alongside)
- Tool descriptions teach the strategy: lookup-first, filters, explore for
orientation,
#sectionfetches, when NOT to fetch full bodies. - Plugin session-start injection stays the primary orientation channel (the index hubs ARE the map — Leiden finding); keep hub injection current.
Deferred / non-goals
- Client graph queries (path, common-neighbors, centrality): re-test when the knowledge system develops reciprocal cross-reference density (journal 2026-06-21's trigger). Not now.
- Server-side FTS / semantic search: real, but a server lane — separate plan when picked up.
- MCP resources + prompts (Desktop attach-without-turns): nice follow-up after W1–W3; needs demarkus-mcp resource support end-to-end.
- Lean tool profile (consumer vs authoring subsets): only if schema budget shows up as real pain; Claude Code already defers tool loading.
Decisions to settle
- D1 — outline default. Options: (a) opt-in param only; (b) outline by default for all; (c) size-adaptive: full body under ~8KB, outline above, always overridable (recommended — small docs keep today's behavior, monsters stop flooding context, no consumer breaks silently: the outline says how to get the rest).
- D2 — explore card contents. Recommended: outline head + backlinks + outbound + siblings, 10/section cap. Open: include lookup-by-shared-tags? (lean no for v1 — tag noise.)
- D3 — dedup scope. Recommended: per-process session, version+etag
keyed,
forceoverride; no cross-session persistence (staleness risk > saving). - D4 — where W1 slicing lives. Recommended: demarkus-mcp only (client
slices); the library's
openlibrarian tool adopts the same convention separately if wanted. Alternative: a shared client/markdown package in demarkus both consume.
Acceptance
A scripted orientation scenario ("what is project X, what phase, who decided") run before/after: tool turns and result tokens both drop materially (target: orientation ≤2 turns; no full-body fetch of an append-heavy status doc unless forced). Existing skills/hook flows (session-start, /promote, journal appends) unchanged.
Order
W1 → W3 (both inside mark_fetch's path, ship together) → W2 → W4 tool- description pass → then MCP resources/prompts as the follow-up phase.
SETTLED (2026-07-04, Fritz — all four on recommendation)
- D1: size-adaptive — full body under ~8KB, outline above, always overridable.
- D2: doc + backlinks + outbound + siblings, 10/section cap (no same-tag section in v1).
- D3: per-session dedup — version+etag keyed,
forceoverride, no cross-session persistence. - D4: shared package in demarkus (client-side markdown outline/section
slicing) — demarkus-mcp consumes now, the library's librarian
openadopts later.
Build order stands: W1 (+W3 together) → W2 → W4. Work lives in the
demarkus repo (demarkus-mcp + a shared client markdown package).