Skip to content

feat(mcp): reduce agent token burn with text-v1 format and code_read cap - #42

Merged
jlitola merged 2 commits into
mainfrom
candied-bugle
Apr 28, 2026
Merged

feat(mcp): reduce agent token burn with text-v1 format and code_read cap#42
jlitola merged 2 commits into
mainfrom
candied-bugle

Conversation

@jlitola

@jlitola jlitola commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Real-session traces showed GitHits MCP responses dominating agent context (4M tokens / session), driven by JSON wrapping plus broad code_read calls (300-600 line windows, occasional unbounded reads).
  • This change adds a compact text-v1 default to search / code_files / code_grep, hard-caps code_read at 150 lines per call on the MCP surface, and rewrites the MCP server instructions block to lead with delegation guidance.

Results across three test sessions

Run Total tokens code_read max single payload
baseline (githits1) 2.43M 22.8 KB
text format only (githits2) 4.05M 22.8 KB
text format + code_read cap (githits3) 2.06M 6.8 KB

Total dropped 4.06M → 2.06M; max code_read dropped 22.8 KB → 6.8 KB.

Changes

Tool surface

  • Add format: "json" \| "text" \| "text-v1" to search, code_files, and code_grep. Default is text-v1; programmatic / parity callers opt into JSON.
  • New text formatters in src/shared/{unified-search,list-files,grep-repo}-text.ts — ASCII-only, snapshot-tested.
  • MCP-side cap on code_read (MCP_READ_MAX_SPAN = 150) with a hint field describing returned vs. requested ranges. CLI githits code read bypasses the cap so humans piping whole files still works.
  • Hint reads the actual returned range from the response payload (not the pre-clamp request) and is suppressed when the cap was a no-op (file fits within cap or returned range reaches EOF).

Instructions

  • Expand CORE_BLOCK trigger criteria to cover comparative cross-OSS questions and "how does X actually work" archaeology.
  • Strengthened MULTI_TURN_TIP leads the gated package-tools section: "Delegate multi-call work to a sub-agent. Code-navigation tools are inherently multi-call — answering even simple questions usually takes 3-10 tool calls..."
  • New REFERENCE_FIRST_TIP workflow paragraph after the per-tool bullets.
  • Per-tool bullets and DESCRIPTION constants rewritten to reflect text-v1 defaults instead of JSON-shaped fields.

Docs

  • docs/implementation/tools.md documents the text-v1 spec (per-tool anatomy), the code_read cap and hint field, and the expanded server-instructions composition.

Test plan

  • bun test — 1446 tests passing
  • bun run build — clean
  • Three real-session runs against .mcp.json showing the token / payload reductions above
  • Codex review pass 1 — fixed before merge: ASCII separators only, text-v1 versioning, dropped invalid feedback footer / license field / > snippet prefix from draft, replaced code_read truncation hint with envelope hint field
  • Codex review pass 2 — fixed before merge: hint suppression refactored to use actual returned span (not explicitness flags); doc-comments updated; parity test header refreshed; implicit-default test coverage added
  • Codex review pass 3 — fixed before merge: hint now reports actual returned range from payload (not pre-clamp request), suppresses when cap is no-op or response reaches EOF; per-tool bullets describe text-v1 default behavior

Open follow-ups (not in this PR)

  • Multi-range code_read (accept ranges: Array<{start_line, end_line}> with per-range cap and total cap) — only worth it if the fixed cap doesn't deliver enough savings on real traffic.
  • format: "text-v1" on search_status once the format has soaked elsewhere.
  • Once stable, consider text-v2 that drops the query= echo from the search header and the score field.

🤖 Generated with Claude Code

jlitola and others added 2 commits April 28, 2026 12:24
Real-session traces showed GitHits MCP responses dominating agent
context (4M tokens / session), driven by JSON wrapping on every tool
plus broad code_read calls (300-600 line windows, occasional
unbounded reads). This change adds a compact text-v1 default to
search / code_files / code_grep, hard-caps code_read at 150 lines
per call on the MCP surface, and rewrites the MCP server
instructions block to lead with delegation guidance.

Across three test sessions the changes brought total tokens from
4.06M -> 2.06M and code_read max single payload from 22.8 KB ->
6.8 KB.

- Add `format: "json" | "text" | "text-v1"` to search, code_files,
  and code_grep tools. Default flipped to text-v1; programmatic /
  parity callers opt into JSON.
- Add MCP-side cap (MCP_READ_MAX_SPAN = 150) to code_read with a
  `hint` field describing returned vs. requested ranges. CLI command
  bypasses the cap so humans can still pipe whole files.
- Hint reports the actual returned range (from the response payload)
  and is suppressed when the cap was a no-op (file fits within cap)
  or when the returned range reaches end of file.
- Expand mcp-instructions CORE_BLOCK trigger criteria to cover
  comparative cross-OSS questions and "how does X actually work"
  archaeology. Add gated REFERENCE_FIRST_TIP and a strengthened
  MULTI_TURN_TIP that leads the package-tools section.
- Update per-tool bullets and DESCRIPTIONs to reflect text-v1
  defaults instead of JSON-shaped fields.
- Document text-v1 format spec, code_read cap, and `hint` field in
  docs/implementation/tools.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex review of #42 flagged two stale claims in
docs/implementation/tools.md:

- The envelope listing for code_read omitted the optional hint? field.
- The span-cap section claimed the hint appears whenever clamping
  fires, which contradicts the shipped suppression logic (no-op cap
  on small files, returned range reaching EOF).

Update the envelope schema to include hint?, and rewrite the cap
section to describe when the hint is actually emitted vs. suppressed,
matching shouldEmitCappedHint in src/tools/read-file.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jlitola
jlitola merged commit 56aa875 into main Apr 28, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant