DEV Community

tappers
tappers

Posted on Originally published at tappers.hashnode.dev

The Hidden "Schema Tax" of MCP Tools: Dumping 32 Tool Schemas vs. On-Demand Tool Search (-92.7% Input Tokens)

💡 AI Labo Benchmark Series — Experiment E14 (Ranked #5 out of 41 Patterns)

This post is part of our empirical benchmark series testing AI coding agent harness patterns inside network-isolated Proxmox VMs against a hidden 20-case grading suite.


Metadata & Experiment Identity

  • Experiment ID: E14 (Backlog Candidate C010)
  • Run ID: e14-20261028-vm218-01
  • Sandbox Environment: Proxmox Isolated VM VM218 (ai-e14-218, 0 NICs, virtio-serial QGA relay, systemd UID separation)
  • Model: gemini-3.8-flash (thinkingLevel: LOW)
  • Pattern Under Test: Claude Code ENABLE_TOOL_SEARCH=auto & Lazy MCP Tool Loading — "Upfront Monolithic Schema Dump (32 Tools) vs. Progressive On-Demand Tool Search"

1. Executive Summary (TL;DR)

Connecting Model Context Protocol (MCP) servers—Kubernetes, AWS, GitHub, Datadog, PagerDuty, Stripe, Terraform—makes an AI coding agent vastly more capable, but it introduces two severe failure modes when all tool definitions are injected upfront:

  1. The "Schema Tax": Detailed JSON Schemas average 700 to 800 tokens per tool. Injecting 32 MCP tool schemas into the system prompt forces you to pay 25,000+ input tokens on every single turn—even before the agent reads a single file.
  2. Tool Confusion (Decoy Misfires): When 32 tool schemas sit flat in the context window, the model frequently calls similarly named deprecated or staging tools (e.g., verify_legacy_v1_router or patch_staging_mirror_files) instead of the active production tool.

To quantify how Progressive Tool Schema Disclosure (ENABLE_TOOL_SEARCH=auto) solves both problems, we benchmarked a 3-module cloud incident triage and SLA remediation pipeline (router.py, remediator.py, dossier.py) inside isolated Proxmox VM VM218:

  • Mode A (MonolithicSchema): Injects all 32 enterprise MCP tool JSON Schemas into the prompt on every turn.
  • Mode B (ProgressiveToolSearch): Injects only 1 lightweight meta-tool (search_tools, 120 tokens) on Turn 1. The agent queries search_tools(query="remediation") (22 output tokens) to dynamically load only the 2 active production tool schemas needed for the task.

Key Result

Replacing the 32-tool upfront schema dump with search_tools cut Turn 1 input tokens by -90.1% (25,646 ➔ 2,544) and cumulative input tokens by -92.7% (79,773 ➔ 5,844 tokens, 13.65x reduction). Even more importantly, filtering out 28 irrelevant and 2 deprecated decoy tools reduced decoy tool misfires from 2 ➔ 0, cutting API cost by -84.8% ($0.0737 ➔ $0.0112) and execution time by -48.5% (1.94x faster).

Metric Mode A: Upfront Monolithic Dump (MonolithicSchema) Mode B: On-Demand Tool Search (ProgressiveToolSearch) Delta / Improvement
Hidden Grading Suite Score (20 Cases) 20 / 20 (100%) 20 / 20 (100%) Both passed all 20 cases
Injected Tool Schemas per Turn 32 schemas (Every turn) 1 schema (Turn 1) ➔ 2 schemas (Turn 2) -93.8% schema reduction (28 tools isolated)
Decoy / Deprecated Tool Misfires 2 misfires (Turn 1, Turn 2) 0 misfires (Zero tool confusion) -100% (Eliminated decoy calls)
LLM Calls (model_calls) 3 calls 2 calls (1 search + 1 submit) -33.3% fewer calls
Total File Edits (file_edits) 6 edits 3 edits (1 per module) -50.0% reduction
Turn 1 Input Tokens 25,646 tokens 2,544 tokens -90.1% first-turn savings
Cumulative Input Tokens (promptTokenCount) 79,773 tokens 5,844 tokens -92.7% (13.65x token efficiency)
Cumulative Output Tokens (candidatesTokenCount) 3,686 tokens 1,825 tokens (Turn 1 used only 22 tok) -50.5% reduction
Total Tokens Consumed 83,459 tokens 7,669 tokens -90.8% (10.88x overall reduction)
Elapsed Execution Time (elapsed_seconds) 37.00 sec 19.06 sec -48.5% (1.94x faster)
Estimated API Cost (estimated_micro_usd) $0.0737 (73,653 micro-USD) $0.0112 (11,228 micro-USD) -84.8% (6.56x cheaper)

2. Experiment Architecture & Tool Discovery Workflow

+-------------------------------------------------------------------------+
| Proxmox Isolated VM218 (0 NICs, virtio-serial QGA, systemd UID split)   |
|  Enterprise MCP Tool Registry (32 Total Tools):                         |
|   - 2 Active Production Tools (verify_pipeline_suite, submit_bundle)    |
|   - 2 Deprecated / Staging Decoy Tools (legacy_v1, staging_mirror)      |
|   - 28 Unrelated Cloud/Infra MCP Tools (K8s, AWS, Stripe, Kafka, etc.)  |
|                                                                         |
|  +-------------------------------------------------------------------+  |
|  | Mode A: MonolithicSchema (All 32 JSON Schemas Injected Every Turn)|  |
|  |  - Turn 1 (25,646 in): Calls decoy `verify_legacy_v1_router`      |  |
|  |  - Turn 2 (26,397 in): Calls decoy `patch_staging_mirror_files`   |  |
|  |  - Turn 3 (27,730 in): Calls `submit_remediation_bundle`          |  |
|  |  --> Total: 79,773 input tokens / 2 decoy misfires / 37.00 sec    |  |
|  +-------------------------------------------------------------------+  |
|                                                                         |
|  +-------------------------------------------------------------------+  |
|  | Mode B: ProgressiveToolSearch (ENABLE_TOOL_SEARCH=auto)           |  |
|  |  - Turn 1 (2,544 in, 1 schema):                                   |  |
|  |      Calls `search_tools(query="remediation")` (22 output tokens) |  |
|  |      --> Loads ONLY 2 active production schemas (filters 30 out)  |  |
|  |  - Turn 2 (3,300 in, 2 schemas):                                  |  |
|  |      Calls `submit_remediation_bundle` (All 3 files in 1 shot)    |  |
|  |  --> Total: 5,844 input tokens / 0 decoy misfires / 19.06 sec     |  |
|  +-------------------------------------------------------------------+  |
+-------------------------------------------------------------------------+
Enter fullscreen mode Exit fullscreen mode

3. Turn-by-Turn Token & Tool Execution Breakdown

Inspecting usage.json and execution-traces.json across all 5 LLM calls (seq 0..4) shows how the upfront schema tax compounds—and how on-demand search eliminates it:

Seq Mode Node ID Tool Called Injected Schemas Decoy Misfire? Input Tokens Output Tokens Cost (micro-USD)
0 Mode A monolithic_schema_turn_1 verify_legacy_v1_router 32 Yes (True) 25,646 634 21,612 ($0.0216)
1 Mode A monolithic_schema_turn_2 patch_staging_mirror_files 32 Yes (True) 26,397 1,224 24,388 ($0.0244)
2 Mode A monolithic_schema_turn_3 submit_remediation_bundle 32 No (False) 27,730 1,828 27,653 ($0.0277)
3 Mode B progressive_search_turn_1 search_tools (query="remediation") 1 No (False) 2,544 22 1,991 ($0.0020)
4 Mode B progressive_search_turn_2 submit_remediation_bundle 2 No (False) 3,300 1,803 9,237 ($0.0092)

Two Critical Takeaways from the Trace

  1. You Pay the Schema Tax on Every Turn—Not Just Turn 1: In Mode A, having 32 detailed MCP schemas in the system prompt cost 25,646 tokens before the agent wrote a single line of code. Because the agent needed 3 turns to recover from decoy tool calls, those exact same 32 schemas were billed three times—burning over 70,000 input tokens on unused JSON schema definitions alone.
  2. A 22-Token Search Call Is Faster Than a 0-Search Monolithic Prompt: A common objection to lazy tool loading is "Won't an extra search_tools round-trip slow the agent down?" The empirical data proves the exact opposite: Mode B's Turn 1 generated just 22 output tokens ({"query": "remediation", "tool": "search_tools"}), and because it avoided prefilling 25k tokens per turn and eliminated 2 decoy misfires, Mode B finished in 19.06 seconds vs. 37.00 seconds (1.94x faster).

4. All 20 Hidden Grading Suite Results (labjudge14)

Both modes achieved 20 / 20 (100%) on the hidden grading suite verifying router.py, remediator.py, and dossier.py:

# Test Case ID Invariant / Boundary Verified Mode A (32 Schemas) Mode B (Tool Search)
1–6 router_01 to router_06 service_id / severity (SEV1–SEV3) normalization, non-mutation, bool rejection, 0 downtime allowed 6 / 6 PASS 6 / 6 PASS
7–15 remediator_01 to remediator_09 First-seen order, conflict check, 300 vs 301 error bps surcharge, 15000 tier boundary, sla_shield cap 9 / 9 PASS 9 / 9 PASS
16–20 e2e_01 to e2e_05 # separator, signed zero (PLAN_COVERAGE: -0), zero-downtime dossier, line order, error propagation 5 / 5 PASS 5 / 5 PASS
Total 20 Hidden Cases — 20 / 20 (100%) 20 / 20 (100%)

5. Practical Takeaway: When and How to Enable Lazy Tool Loading

  1. Never inject more than 10 full JSON tool schemas upfront: Once your connected MCP servers exceed 10–15 tools, switch to Progressive Tool Disclosure (such as ENABLE_TOOL_SEARCH=auto in Claude Code, or lazy MCP schema files loaded on demand via a search_tools / call_mcp_tool dispatcher).
  2. Filter out DEPRECATED and non-production tools inside the search index: Instead of letting the LLM guess between verify_legacy_v1_router and verify_pipeline_suite, enforce status == "PRODUCTION_ACTIVE" filtering inside your search_tools handler so decoy tools never enter the context window.

🔗 Continue Reading the Series

Top comments (1)

Collapse
 
arcwrightai profile image
arcwrightai •

This matches what I keep seeing in practice. The boring parts are where the wins are.