feat(mcp): reduce agent token burn with text-v1 format and code_read cap - #42
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
code_readcalls (300-600 line windows, occasional unbounded reads).text-v1default tosearch/code_files/code_grep, hard-capscode_readat 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
Total dropped 4.06M → 2.06M; max
code_readdropped 22.8 KB → 6.8 KB.Changes
Tool surface
format: "json" \| "text" \| "text-v1"tosearch,code_files, andcode_grep. Default istext-v1; programmatic / parity callers opt into JSON.src/shared/{unified-search,list-files,grep-repo}-text.ts— ASCII-only, snapshot-tested.code_read(MCP_READ_MAX_SPAN = 150) with ahintfield describing returned vs. requested ranges. CLIgithits code readbypasses the cap so humans piping whole files still works.Instructions
CORE_BLOCKtrigger criteria to cover comparative cross-OSS questions and "how does X actually work" archaeology.MULTI_TURN_TIPleads 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..."REFERENCE_FIRST_TIPworkflow paragraph after the per-tool bullets.DESCRIPTIONconstants rewritten to reflect text-v1 defaults instead of JSON-shaped fields.Docs
docs/implementation/tools.mddocuments the text-v1 spec (per-tool anatomy), thecode_readcap andhintfield, and the expanded server-instructions composition.Test plan
bun test— 1446 tests passingbun run build— clean.mcp.jsonshowing the token / payload reductions abovetext-v1versioning, dropped invalidfeedbackfooter /licensefield />snippet prefix from draft, replacedcode_readtruncation hint with envelopehintfieldOpen follow-ups (not in this PR)
code_read(acceptranges: 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"onsearch_statusonce the format has soaked elsewhere.text-v2that drops thequery=echo from the search header and thescorefield.🤖 Generated with Claude Code