← All posts

The Tool Tax: How Claude Code, Cursor, Copilot, and Codex Handle 200 MCP Tools

The four major coding agents converged on the same architectural pattern for dynamic MCP tool discovery — and shipped four incompatible implementations, each gated on different models. Here's what that costs in tokens, latency, and which workloads each agent can actually run.

Updated October 2026. Two corrections and a lot of movement since May. Codex CLI was already deferring MCP tools behind tool_search when this was published, and since v0.142 it defers every MCP tool on models that support search. VS Code issue #290356 was closed in January as fixed by virtual tools, and Copilot now uses tool search for Claude 4.5+ (rolling out to GPT-5.4+) and skips its 128-tool check for those models. Claude Code's tool search now covers Haiku 4.5+, gateways, and Vertex AI. On supported models, all four agents now load MCP schemas on demand; the sections below are corrected to match.

The Bottom Line

It is now normal for a developer to wire 5–15 MCP servers into a coding agent, exposing 100–300 tools. Loading every tool schema upfront on every turn imposes a steep tool tax: 50–140K tokens of input, slower startup, degraded selection accuracy past ~30–50 visible tools, and — on models without tool search — hard rejection at Copilot's 128-tool ceiling.

Claude Code, Cursor, OpenAI Codex CLI, and GitHub Copilot have all converged on the same architectural shape (defer schemas; load on demand) but ship four different implementations. The pattern is becoming industry standard. The interfaces are not interoperable. And the defaults, and which models get them, differ enough to change which workloads each agent can actually handle without manual intervention.

Agent Mechanism Default Upfront cost at 200 tools
Claude CodeAPI-native tool_search_toolOn~3–5K tokens
CursorFiles synced to disk + grepOn~2–4K tokens
GitHub CopilotTool search (newer models) + "virtual tools" embedding clustersModel-gated; clusters above threshold~5–10K; 128 cap on models without search
Codex CLIOpenAI tool_search (deferred MCP tools)On for models with search; eager otherwiseDeferred with search; ~50K / turn without

Why The Tool Tax Hurts

Each MCP tool schema (name, description, JSON-Schema parameters) costs roughly 250–700 tokens depending on verbosity. Measured in the wild:

  • mcp-omnisearch (20 tools): ~14,114 tokens — ~706 tokens/tool
  • playwright (21 tools): ~13,647 tokens — ~650 tokens/tool
  • Representative 10-server, 200-tool catalog: 50,000–140,000 tokens

Three failure modes compound at scale:

  1. Context displacement. On a 200K-token window, eager loading consumes 25–70% of context before the agent reads a single file.
  2. Selection accuracy collapse. Models lose tool-selection accuracy past ~30–50 visible tools. With 200, they reliably pick the wrong tool or miss the right one.
  3. Hard client limits. Copilot in VS Code rejects requests carrying more than 128 tools on models without tool search (GPT-4.1 among them). Virtual-tool grouping normally keeps requests under the cap; if grouping fails, the request is rejected before execution.

The fix is structurally the same everywhere: keep a tiny persistent surface (a search tool, a file index, cluster summaries) and expand full schemas on demand. How each agent implements that is where it gets interesting.

Claude Code: API-Native Tool Search

Anthropic ships tool_search_tool_regex_20251119 and tool_search_tool_bm25_20251119 as first-class API features. In Claude Code, MCP tools are deferred and discovered on demand by default; at session start the agent sees tool names, server instructions, and the search tool, plus full schemas only for tools marked alwaysLoad. When the agent needs a capability, it issues a regex or BM25 query, the API returns matching tool_reference blocks (up to 5 by default; the limit is adjustable), and those expand into full schemas only at the moment of use.

Limits worth knowing:

  • Catalog ceiling: 10,000 tools.
  • Descriptions are capped: 4,096 characters for server instructions and upfront tools, 16,384 for tools loaded through search (raised from 2,048; override with CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH).
  • On by default through gateways set with ANTHROPIC_BASE_URL (Claude Code retries without it if the gateway rejects it) and on Vertex AI for Claude 4.5-generation models and later. Azure-hosted Microsoft Foundry deployments reject it.
  • Works on current models, including Haiku 4.5 and the Claude 5 family; older models fall back to loading tools upfront.

For 200 tools, this collapses the upfront tool cost from ~50K to ~3–5K — a >90% reduction. Anthropic's published figure is >85% across typical multi-server setups.

Cursor: The File System Is The Index

Cursor explicitly rejected the dedicated-search-tool approach. Instead, it syncs MCP tool descriptions to a folder on disk. The agent receives only tool names in static context and discovers full schemas by grep-ing or semantic-searching the synced folder when a task calls for it.

This is part of a broader "everything is a file" strategy: Cursor applies the same primitive to Agent Skills, long terminal output, and oversized tool responses. The file surface unlocks capabilities the API-level approach can't — notably, surfacing MCP server status (re-authentication needed, server unhealthy) without forgetting the tools entirely.

A/B test results published in January 2026 reported a 46.9% reduction in total agent tokens on runs that called an MCP tool. Schema-only reduction is higher; the 46.9% is across all session content.

GitHub Copilot: Virtual Tools

Copilot took a third path: embedding-guided clustering. The November 2025 blog post calls the system "virtual tools" — functionally similar tools are grouped using an internal embedding model and cosine similarity, with each cluster summarized by a single model call (cached locally). The agent sees the cluster summaries and expands a cluster only when its task matches.

In published benchmarks (SWE-Lancer, SWEbench-Verified), this approach improved success rates by 2–5 percentage points with both GPT-5 and Sonnet 4.5, and cut response latency by ~400ms.

Since then Copilot has added a second mechanism, and the conditions depend on the model:

  • Tool search on newer models. VS Code 1.109 brought Anthropic's tool search to Copilot; it is on by default for Claude Sonnet 4.5+ and Opus 4.5+ and rolling out to GPT-5.4 and GPT-5.5, and 1.118 trimmed the always-loaded core to ~30 tools. For tool-search models, the 128-tool check is skipped.
  • 128-tool cap for everything else. Models without tool search (GPT-4.1 included) still hit a 128-tool limit. Virtual-tool grouping keeps requests under it unless grouping fails — for example during an embeddings-service outage. VS Code issue #290356 was closed on that basis in January 2026.
  • Threshold-gated clustering. Virtual tools activate when the experimental github.copilot.chat.virtualTools.threshold setting (default 128) is crossed; below threshold, tools are still loaded eagerly.

Copilot CLI followed in May 2026 with experimental tool search and deferred loading for MCP tools.

OpenAI Codex CLI: Model-Gated Tool Search

Codex CLI wires MCP tools to the OpenAI API's tool_search (defer_loading: true, GPT-5.4 and later). Since v0.142 it defers every MCP tool when the active model supports search; by v0.119 (April 2026) it already deferred them behind tool_search at 100+ tools or behind a feature flag. On models without search support, Codex still exposes every MCP tool on session start.

Static controls still matter:

  • enabled_tools = [...] and disabled_tools = [...] allow/deny lists per server
  • enabled = false to disable a server without removing config
  • Project-scoped .codex/config.toml for narrower scoping (trusted projects only)
  • mcp_optional_startup_grace_ms (default 1000) bounds how long optional servers can delay startup

Known scaling issues with many servers:

  • MCP startup used to sit on the first-turn critical path. Since CLI 0.162.1, optional servers get a shared, bounded grace period, so one slow server no longer stalls the session; servers declared as explicit dependencies still wait.
  • Sub-agents inherit the parent's MCP servers, and a custom agent file can't narrow them; per-agent MCP scoping is still an open issue (#20135).

On a model without search support, 200 tools still cost the full ~50K tokens on every turn — ~500K tokens of pure tool-definition overhead across a 10-turn session. On a search-capable model, Codex lands in the same deferred band as the others.

Token Economics At 200 Tools

The following figures assume a representative MCP catalog with ~250 tokens per tool schema (conservative; verbose servers run 2–3× higher).

Agent Upfront Per-turn 10-turn overhead
Claude Code (tool_search on)3–5K3–5K + ~500 per expansion30–50K
Cursor (DCD on)2–4K2–4K + ~400 per file read20–40K
GitHub Copilot (virtual tools, <128)5–10K5–10K + cluster expansions50–100K
Codex CLI (model without search)50K50K500K

On a 200K-token window, eager loading — Codex on a model without search, or any agent with deferral switched off — consumes 25% of context before any work starts; with verbose servers, this rises to 70%. The deferred paths leave essentially all of context available for the actual task. Over a multi-turn session, eager per-turn cost compounds linearly — what costs $X in the first turn costs ~$10X across ten turns.

Practical Guidance

For multi-MCP workloads (5+ servers, 100+ tools), agent choice materially affects what's possible:

  1. Verify defaults are active. Claude Code: tool search is on by default, gateways included; confirm ENABLE_TOOL_SEARCH is not false and CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS is unset (it forces tool search off); auto / auto:N defer only past a context threshold. Copilot: use a tool-search model (Claude Sonnet/Opus 4.5+, GPT-5.4+ as it rolls out); on other models, lower github.copilot.chat.virtualTools.threshold (default 128) to start clustering earlier. Cursor: dynamic context discovery is on by default — no action needed.
  2. For Codex CLI: run a model that supports tool_search so MCP tools are deferred. Still scope with project-level .codex/config.toml and enabled_tools allowlists — sub-agents inherit every server. Treat global MCP config as a superset; on models without search, expect 30–50 active tools max for healthy operation.
  3. For Copilot at 128+ tools on a model without tool search: the cap is enforced at the VS Code layer before the agent processes anything. Virtual-tool grouping keeps you under it unless grouping fails. Trim selected tools manually, split work across sessions, or switch to a tool-search model.
  4. MCP server design: prefix tool names by server (matrix_query_*, quality_metric_*) so search and clustering have clean signal. Keep tool descriptions concise — Claude Code caps them at 4,096 characters for upfront tools and server instructions.

Where The Standard Is Heading

All four implementations solve the same problem and converge on the same architectural shape: a small persistent surface (search tool, file index, cluster summaries) plus on-demand schema expansion. None of the wire formats interoperate. As of the 2026-07-28 spec revision, MCP itself ships notifications/tools/list_changed for dynamic catalogs but no standardized search/defer primitive that clients and servers agree on. A Progressive Disclosure working group is now exploring grouping and tool search as extensions; nothing has shipped in the spec yet.

The pattern is industry-standard. The interface is not. Anthropic's tool_search_tool_*, OpenAI's tool_search + defer_loading, Cursor's file sync, and Copilot's virtual tools each remain vendor-specific. Until MCP adds a discovery primitive, each agent's behavior at scale will diverge in the ways documented here.

The Draft Angle

Dynamic tool discovery solves the inbound tool-tax problem — how the agent navigates a huge external catalog. It does not solve the outbound problem: how the agent navigates your codebase. That's what Draft's local knowledge graph is for. Deterministic answers to "what calls this function" and "what does this change touch" are served live from a local engine (codebase-memory-mcp) and queried on demand via shell wrappers — no committed snapshot files, no staleness. Different problem, same lesson: defer everything, expand on demand, keep the persistent surface small.

Sources

  • Anthropic: tool search tool documentation, Claude Code MCP docs
  • Cursor blog: "Dynamic context discovery" (January 2026)
  • GitHub blog: "How we're making GitHub Copilot smarter with fewer tools" (November 2025)
  • OpenAI Developers: Codex CLI MCP reference, tool_search API guide
  • Real-world MCP tool-cost measurements: Scott Spence, October 2025
  • VS Code issue #290356 (128-tool cap; closed as fixed by virtual tools, January 2026)
  • VS Code release notes 1.109 and 1.118 (tool search, compact tool core)
  • GitHub Copilot CLI issue #2992 (sub-agent tool scoping, April 2026) and changelog 1.0.49 (deferred MCP tools)
  • Codex CLI release 0.119.0 and PR #29486 (MCP tools deferred under tool_search)
  • Codex CLI issue #21318 (MCP startup blocking, May 2026; closed October 2026) and issue #20135 (per-agent MCP scoping)
  • MCP specification 2026-07-28 changelog; Progressive Disclosure working group