MCP & agent ergonomics: token-efficiency and missing affordances
| Field | Value |
|---|---|
| Date finalised | 2026-06-05 |
| Author | Rômulo Febasi romulo@febasi.com.br (Claude-assisted) |
| Scope | How to make Synapse’s MCP surface cheaper and easier for Claude (and other agents) to drive: token savings, missing tools/affordances, plugin/skill packaging. Grounded in the v0.5 code. |
| Status | draft |
| Inputs | Code audit of src/mcp/ + src/core/mcp/; Anthropic “Writing effective tools for AI agents”, “Code execution with MCP”, “Advanced tool use”; MCP 2026 spec (structuredContent/outputSchema, resources, pagination); the v0.5 SKILL.md/LLM.md work. |
| Out of scope | The semantic layer internals (ADR-008); the identity onboarding (SYN-170..173); anything requiring a protocol change to rmcp. |
Executive summary
Synapse’s MCP surface is correct and safe (propose/accept is solid) but not yet optimised for token cost or agent ergonomics. Three cheap fixes pay off immediately: bound the one unbounded read (list_by_type), return structuredContent + compact JSON instead of pretty-printed text, and attach ResourceLinks to reads (entities are already exposed as resources, but tools don’t link to them). Beyond that, a small set of new affordances (a batch read, a workspace-overview digest, a recent_changes delta tool, and batch proposals) would cut the round-trips and exploratory reads that dominate an agent’s token budget. The strategic bet is the Anthropic code-execution-with-MCP pattern (intermediate data never enters context) and shipping Synapse as a one-install Claude plugin (skill + MCP + hooks).
1. Context and premisses
v0.5 ships 15 MCP tools (4 local read, 4 federation read, reindex, replay_proposal, 5 write proposals). Responses are built by mcp::helpers::json_content → serde_json::to_string_pretty wrapped as a text content block. Entities, the manifest, the server-card and recent audit are exposed as resources (synapse://entity/{type}/{id}, paginated). The propose/accept invariant (BR-12.3) is enforced in core::pending::enqueue. The freshness banner is conditional (only when a noteworthy signal exists): already well-behaved.
Assumed: agents are the primary consumer of the MCP door, and their token budget is the scarce resource. The SKILL.md/LLM.md (v0.5, in synapse-releases) already teach correct usage; this brief is about making the server cheaper, not just the docs.
2. Market scan
2.1 Anthropic: writing effective tools for agents
Core principles: avoid tool overload / overlapping tools; namespace related tools; implement response constraints (pagination, range, filtering, truncation with sane defaults) for anything that could flood context; tool descriptions are load-bearing and should be prompt-engineered.
What this means for Synapse: list_by_type violates the response-constraint principle: it takes only type + status, no limit/cursor (src/mcp/args.rs ListArgs), so a big workspace returns everything. search_knowledge and federated_search already cap with limit; list_by_type is the outlier. Fix first.
2.2 MCP 2026 spec: structuredContent, outputSchema, resource links
Tools may return structuredContent (machine-readable JSON conforming to an outputSchema) alongside text; clients parse it programmatically instead of the model re-reading a text blob. Results may carry ResourceLink/EmbeddedResource blocks pointing at resources the client can fetch (and cache) lazily.
What this means for Synapse: today every tool returns pretty-printed JSON as text (json_content). Two wins: (a) emit structuredContent + a tool outputSchema, and drop the pretty-print (whitespace is pure token waste); (b) since entities are already resources, have search_knowledge hits and get_entity return a ResourceLink to synapse://entity/{type}/{id} so a resource-caching client can avoid re-fetching, and the agent can defer reading the body until it’s sure it needs it.
2.3 Anthropic: code execution with MCP (the 98% pattern)
Presenting MCP servers as a code API the agent writes against: loading only the tools it needs and keeping intermediate results in the execution environment: cut token usage by up to 98% in Anthropic’s tests. The “Tool Search Tool” discovers tools on demand (~85% reduction) so the full tool catalogue isn’t loaded upfront.
What this means for Synapse: the CLI analog already exists and is the right shape: syn export --as json | jq '…' filters/aggregates outside the model’s context. The MCP door has no equivalent: an agent must pull data into context to filter it. A constrained, read-only query tool (a safe expression over the workspace JSON, or a thin jq-like projection) would let agents compute answers without the rows entering context. This is the highest-leverage bet.
3. Cross-check vs the current server
| Affordance | Status today | Gap |
|---|---|---|
| Bounded reads | search/federated cap; list_by_type does not | Add limit + cursor |
| Machine-readable results | JSON as pretty text, no outputSchema | structuredContent + compact JSON |
| Lazy/cacheable reads | entities are resources, but tools don’t link them | ResourceLink on hits + get_entity |
| Batch reads | one get_entity per call | get_entities / resource multi-read |
| Field projection | get_entity returns the whole markdown | optional fields projection |
| Orientation | none (agent must list+search to learn the shape) | workspace_overview digest |
| Deltas | none (re-reads everything each session) | recent_changes {since} |
| Batch writes | one proposal per call | propose_batch → one accept |
| Pre-validation | update_status validates at accept time | valid_statuses/dry-run to cut rejects |
| Compute-out-of-context | CLI has `export | jq`; MCP has nothing |
4. Positioning
The moat is local-first + auditable propose/accept. No SaaS competitor can match “the model proposes, the human signs off, every write is provenance-stamped and replayable” while keeping data on the laptop. Token-efficiency and agent ergonomics are table stakes that make the moat usable; they are not the moat. Lane to occupy: “the second brain agents drive cheaply and can’t silently corrupt.”
5. Recommendation
| # | Block | Justification | Cost | Defensible? |
|---|---|---|---|---|
| 1 | Bound list_by_type (limit+cursor) | Closes the one unbounded read; Anthropic principle #1 | S | Hygiene |
| 2 | structuredContent + compact JSON | Token + parse win on every read; spec-aligned | M | Hygiene |
| 3 | ResourceLink on reads | Lazy/cacheable reads; entities already are resources | S | Leverages existing resources |
| 4 | workspace_overview digest tool | Kills the explore-cost; one call to orient | M | Product |
| 5 | recent_changes {since} delta | Recurring agents pull deltas, not the world | M | Product (audit/timeline exist) |
| 6 | get_entities batch + fields projection | Fewer round-trips; read only needed fields | M | Hygiene |
| 7 | propose_batch (one bundle, one accept) | Fewer round-trips; one human sign-off | M | Fits propose/accept |
| 8 | read-only query tool (compute-out-of-context) | The 98% pattern; biggest token lever | L | Moat-adjacent |
Non-goals for now: protocol-level changes; a full code-execution sandbox; dropping any existing tool.
6. Disruptive bets
- Compute-out-of-context
query: a safe, read-only projection/aggregation over the workspace (jq-subset or a whitelisted expression) so an agent answers “how many blocked tasks per owner” without a single row entering its context. The local-first design makes this safe (no remote data exfil) in a way a SaaS MCP cannot casually offer. - Synapse as a one-install Claude plugin:
.claude-plugin/plugin.jsonbundling the skill + the MCP server config + hooks (e.g., aSessionStarthook that runssyn doctor/syn pending list). Onecp/marketplace install wires the whole loop. Agents that don’t speak MCP still get the skill. - Proposal “context snapshot” as a first-class agent contract: every write tool already accepts
context; lean into it sosyn audit replaycan re-run a proposal against a newer model and flag drift. This is an auditability feature no hosted assistant offers: sell it. recent_changesas the agent’s memory diff: a recurring agent (daily standup, weekly review) reads only what changed since its last run; pair with a server-issued cursor so the agent is stateless.
7. Ticket sketch (provisional IDs)
| Sketch ID | Block | Size |
|---|---|---|
| SYN-176 | list_by_type limit + cursor | S |
| SYN-177 | structuredContent + outputSchema + compact JSON on all reads | M |
| SYN-178 | ResourceLink to synapse://entity/... on search hits + get_entity | S |
| SYN-179 | workspace_overview digest tool (counts + key/recent) | M |
| SYN-180 | recent_changes {since} delta tool (over audit/timeline) | M |
| SYN-181 | get_entities batch + optional fields projection | M |
| SYN-182 | propose_batch (one pending bundle, one accept) | M |
| SYN-183 | read-only query tool (compute-out-of-context): spike first | L |
| SYN-184 | Synapse Claude plugin package (skill + MCP + hooks) | M |
8. Risk register
| Risk | Severity | Mitigation |
|---|---|---|
structuredContent not supported by all clients | Low | Keep the text block too (dual emit); spec says clients ignore unknown fields |
query tool = injection / DoS surface | High | Read-only, whitelisted ops, row/time caps; spike (SYN-183) before commit |
| Tool sprawl (15 → 20+) dilutes the catalogue | Med | Namespace (synapse_*); lean on the skill + Tool Search; retire overlaps |
| Batch tools complicate the audit trail | Med | One pending row per logical write even under propose_batch; bundle only the accept UX |
9. Open decisions
- Adopt
structuredContentnow, or wait until the dominant client (Claude Code) renders it? (Recommend: dual-emit now: cost is low.) - Is the
querytool worth the security surface, or issyn export --as json | jq(CLI) enough and we just teach agents to shell out? (Spike SYN-183 to decide.) - Namespace the tools (
synapse_*) now (breaking for existing configs) or at v1.0 with the frozen MCP surface? - Should
workspace_overviewandrecent_changesbe tools or resources (or both)? Resources are cacheable; tools are discoverable.
10. References
- Writing effective tools for AI agents: Anthropic
- Code execution with MCP: Anthropic
- Advanced tool use: Anthropic
- MCP spec: Tools (structuredContent / outputSchema)
- Agent Skills open standard · llms.txt
- Code:
src/mcp/{server,helpers,resources,freshness,args}.rs,src/core/mcp/*.rs.