Files
codebase-memory-mcp/notes/token-reduction-changes.md
T
Andrew Hundt 7626a5b14f mcp.c: OOM-safe guards + notes/ documentation with mermaid diagrams
OOM fixes (applied to both feature branches):
1. trace_call_path: calloc for seen_out/seen_in dedup arrays gracefully
   degrades on OOM — skips dedup instead of NULL-dereference crash
2. build_snippet_response: head_tail combined buffer malloc falls back
   to head-only output on OOM instead of NULL snprintf

Documentation (notes/ folder):
- notes/token-reduction-changes.md: 8 RTK-inspired strategies, config
  system, real-world results, mermaid architecture diagram
- notes/reference-api-indexing-changes.md: 7-layer AI grounding defense,
  QN prefix format, deferred work, mermaid flow diagram
- notes/merged-branch-changes.md: branch lineage gitGraph, combined
  architecture diagram, snippet mode decision flow, token reduction
  pipeline per tool, test coverage, merge conflict resolution

Tests: 2064 passed, 0 failed
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-03-20 14:30:46 -04:00

5.1 KiB

Token Reduction Changes (branch: reduce-token-usage)

Overview

RTK-inspired token reduction for codebase-memory-mcp MCP tool responses. Reduces output token consumption by 72-99% depending on mode, without affecting indexing completeness. All changes are output-side only -- the full codebase is still indexed and stored; only query responses are trimmed.

Changed Files

File Change
src/mcp/mcp.c 8 token reduction strategies + config-backed defaults
src/cypher/cypher.c CYPHER_RESULT_CEILING 100,000 -> 10,000
src/store/store.c Pagination ORDER BY name, id for stable ordering
tests/test_token_reduction.c 22 new tests (826 lines)
tests/test_main.c Register suite_token_reduction
Makefile.cbm Add test source

Commits (7)

5448324 mcp.c: clarify code comments for token metadata, pagination, head_tail
e9d92ed mcp.c: remove include_dependencies schema from token-reduction branch
4873697 mcp.c: fix 6 issues found in code review
83b70ed mcp: config-backed defaults + magic-number-free tool descriptions
701d8a7 Makefile.cbm, test_main.c: remove depindex refs from token-reduction branch
3518cef mcp: fix summary mode aggregation limit + add pagination hint
bb23ea4 mcp: reduce token consumption via RTK-inspired filtering strategies

Strategies Implemented

1. Sane Default Limits (RTK: "Failure Focus")

Tool Parameter Before After Config Key
search_graph limit 500,000 50 search_limit
search_code limit 500,000 50 search_limit

Callers can still pass explicit higher limits. Config overrides via codebase-memory-mcp config set search_limit 200.

2. Smart Truncation for get_code_snippet (RTK: "Structure-Only" + "Failure Focus")

Three modes via the mode parameter:

Mode Behavior Savings
full (default) Full source up to max_lines (default 200) Variable
signature Signature, params, return type only ~99%
head_tail First 60% + last 40% with [... N lines omitted ...] ~50-70%

The head_tail mode preserves function signature (head) and return/cleanup code (tail), avoiding the dangerous blind-truncation problem where return types and error handling get silently cut.

3. Compact Mode (RTK: "Deduplication")

compact=true on search_graph and trace_call_path omits the name field when it's a suffix of qualified_name, saving ~15-25% per response.

4. Summary Mode (RTK: "Stats Extraction")

mode="summary" on search_graph returns aggregated counts instead of individual results:

{"total": 347, "by_label": {"Function": 200, "Class": 50}, "by_file_top20": {...}}

Savings: ~99% (1,317 bytes vs hundreds of KB).

5. Trace BFS Limit + Edge Case Fixes

  • Default max_results reduced from 100 to 25 (configurable via trace_max_results)
  • BFS cycle deduplication via seen_ids array
  • Ambiguous function names return candidates array with qualified names

6. query_graph Output Truncation (RTK: "Tree Compression")

max_output_bytes parameter (default 32KB) caps raw Cypher output. Replaces with a valid JSON metadata object (not mid-JSON truncation). Does NOT change max_rows which would break aggregation queries.

7. Token Metadata (RTK: "Tracking")

Every response includes _result_bytes and _est_tokens (bytes/4 heuristic) for context cost awareness.

8. Pagination Hint

When has_more=true, responses include a pagination_hint field guiding how to fetch the next page.

Architecture: Token Reduction is Output-Side Only

graph LR
    subgraph Indexing["Indexing (unchanged)"]
        A[Source Files] -->|tree-sitter parse| B[AST]
        B -->|multi-pass pipeline| C[Full Graph DB]
    end
    subgraph Querying["Query Response (reduced)"]
        C -->|SQL query| D[Full Result Set]
        D -->|limit/truncate/compact/summary| E[Reduced Response]
        E -->|+ _meta tokens| F[MCP Response]
    end
    style Indexing fill:#e8f5e9
    style Querying fill:#fff3e0

Config System

All defaults are runtime-configurable via cbm_config_get_int():

Config Key Default Controls
search_limit 50 Default limit for search_graph/search_code
snippet_max_lines 200 Default max lines for get_code_snippet
trace_max_results 25 Default max results for trace_call_path
query_max_output_bytes 32768 Default byte cap for query_graph output

Real-World Results (RTK codebase, 45,388 symbols)

Feature Bytes Savings
Summary mode 1,317 99.8% vs full
Compact mode 611 vs 2,237 72.7%
Signature mode 16 vs 2,489 99.4%
Default limit (50) 50 results 99.6% vs 13,818

Limitations

  • Summary mode caps at 10,000 results for aggregation (sufficient for most codebases)
  • max_lines=0 means unlimited, not zero lines
  • limit=0 in store.c maps to 500,000 (upstream behavior), NOT unlimited
  • No tee mode (full-output recovery after truncation) -- would require file-based caching