Subagents fail with 'prompt is too long' when user has many MCP servers (tool definitions exceed 200k)

Open 💬 21 comments Opened Mar 23, 2026 by TweedBeetle

Problem

When a user has many MCP servers configured at the user level, subagents (Explore, Plan, general-purpose) fail immediately with prompt is too long: 209117 tokens > 200000 maximum before executing a single tool call. The TUI shows Done (0 tool uses · 0 tokens · 44s) with no error visible to the user.

Root Cause

Subagents inherit all MCP tool definitions from the parent session. Each tool definition includes a full JSON schema. With many MCP servers, the tool schemas alone exceed Sonnet's 200k context limit.

Reproduction

Setup: 34 MCP servers configured in ~/.claude.json (Bright Data, Discord, GitHub, Gmail, Playwright, Sentry, YouTube, etc.) totaling ~566 MCP tools.

Main session: Opus 4.6 (1M context) on Claude Max — works fine, 209k of tool schemas fits within 1M.

Subagent spawn: Any Agent call (Explore, Plan, general-purpose) → Sonnet 200k → immediate API error:

"error": "invalid_request"
"errorDetails": "prompt is too long: 209117 tokens > 200000 maximum"

The user prompt was ~156 tokens. The Explore system prompt is ~500 tokens. The remaining ~208,000 tokens are tool definitions.

Subagent JSONL evidence (from agent-a4ff9338a6a5a0f09.jsonl):

{
  "error": "invalid_request",
  "errorDetails": "400 {\"type\":\"error\",\"error\":{\"type\":\"invalid_request_error\",\"message\":\"prompt is too long: 209117 tokens > 200000 maximum\"}}"
}

Version: Claude Code v2.1.81, macOS, Claude Max subscription.

Why This Isn't a Duplicate

Previous issues were auto-closed incorrectly:

  • #29157 ("Intelligently disable MCP tools for subagents") → auto-duped to #10668 ("Tool names must be unique"), which was a completely different bug fixed in v2.0.31
  • #27208 ("Hierarchical deferred tool discovery") → auto-duped to #23508 ("Lazy MCP tool group loading"), which was closed as stale without resolution

The underlying problem — subagents receiving all MCP tool schemas regardless of relevance, causing context overflow — remains unfixed.

Proposed Solutions (any would work)

  1. Apply deferred/ToolSearch to subagents — The main session already uses deferred tools (tool names listed, schemas loaded on demand via ToolSearch). Subagents should get the same treatment.
  2. Filter tools by subagent type — Explore agents don't need Canva, Stripe, Discord, etc. Only pass tools relevant to the subagent's declared tool set.
  3. Inherit parent model — If the main session is Opus 1M, subagents should also get 1M context (or at least Sonnet 1M if available on the plan).
  4. Graceful degradation — If tool definitions exceed the subagent's context, prune least-relevant MCP tools rather than failing silently.

Workarounds

  • Pass model: "opus" explicitly on Agent calls (costs more quota)
  • Reduce MCP servers in ~/.claude.json (defeats the purpose of having them)
  • Move servers to project-level configs (tedious, easy to forget)

Impact

Any Claude Max user with 15+ MCP servers will hit this. The failure is completely silent in the TUI — users see "0 tool uses · 0 tokens" and have no idea why. This makes Explore, Plan, and general-purpose agents unusable for power users.

View original on GitHub ↗

21 Comments

github-actions[bot] · 3 months ago

Found 2 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/31623
  2. https://github.com/anthropics/claude-code/issues/29157

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

Cianai · 3 months ago

Not a duplicate of #10668 or #31623 — this is a distinct bug, not a feature request.

#10668 was about non-unique tool names causing conflicts (fixed in v2.0.31). This issue is about tool schema volume exceeding the subagent context window.

#31623 is the feature request for the real fix (deferred tool loading for subagents). This issue is the bug report documenting the broken behavior that fix would address. Both should remain open — one tracks the symptom, the other the solution.

Reproducing independently: I hit this on v2.1.81 with 25 MCP servers (~450 tools) on Claude Max (Opus 1M main session). Every Explore/Plan/general-purpose subagent fails immediately with Prompt is too long. Workaround: model: "opus" on all Agent calls, which defeats the purpose of lighter subagents.

The auto-close bot's duplicate detection is pattern-matching on keywords, not understanding the issue semantics. Please keep this open.

samargy · 3 months ago

Also have the exact same issue.

draciunescu · 3 months ago

Having the same issue.

StefanJVA · 3 months ago

I have the same issue (and it actually cost me a bunch of tokens because opus is executing subagents that eventually fail)

duda-web · 3 months ago

I have the same issue

nprisbrey · 3 months ago

I also had this same issue in #42822. Only figured it out after having Claude Code look at itself. There needs to be a message informing the user why things are broken.

akremer · 3 months ago

Also experiencing this issue. Solutions 1 or 2 seem the most sensible and forward-looking.

brandonrule11 · 3 months ago

This is quite painful. Does anyone have a workaround? Tool search has been a huge unlock for me, but now subagents are completely broken

sam100x · 3 months ago

+1, same issue

aak204 · 3 months ago

Hit this exact wall. Subagents just choke on the massive tool schema before they even start reasoning. As a workaround, I wrote a proxy in Go (toolc) that sits between the editor and the MCP servers. It squashes the configs into a single, filtered endpoint. Doesn't fix Claude Code's native inheritance, but it stops the token bleeding today.
Repo: https://github.com/aak204/Tool-Catalog-Compiler

XardasLord · 3 months ago

Same here +1

m13v · 3 months ago

i run 28 MCP servers in my user config right now, roughly 400 tools. main session on Opus 1M works fine but subagents fail every single time. the silent failure is the worst part, i spent two days thinking my Explore agents were just being lazy before i found the JSONL error logs. the proxy approach aak204 mentioned is what i ended up doing too, basically a tool router that only exposes the 15-20 tools relevant to a given task context. cut my subagent tool schema from ~180k tokens down to ~35k. the real fix should be solution 1, deferred ToolSearch already works great in the main session and there is zero reason subagents should not get the same treatment. loading full JSON schemas for 400 tools that the subagent will never touch is just waste.

davidbordenwi · 2 months ago

Hitting this at a lower MCP count than previously reported — adding a data point.

Setup: 10 MCP servers (4 claude.ai connectors + 6 stdio), ~274 tools total. Claude Max, Opus 4.7 1M parent session.

Failure: Explore subagent (built-in, haiku, 200K cap) fails at spawn:

"prompt is too long: 213431 tokens > 200000 maximum"

The user prompt was 6 words; the entire overrun is inlined MCP tool schemas.

Bisection evidence for Solution #1 (apply ToolSearch deferral to subagents):

  • claude --strict-mcp-config --mcp-config '{}' --agent Explore -p "OK" → succeeds at 2,015 tokens.
  • Same command without --strict-mcp-config → fails at 213,431 tokens.
  • Delta ≈ 211K tokens of MCP schema, 100% of which the subagent never touches.

Workarounds tested (all confirmed broken or limited on this setup):

  • ENABLE_TOOL_SEARCH=true → no effect on subagent spawn (still 213,431 tokens). Parent-only.
  • User-scope ~/.claude/agents/Explore.md with narrow tools: → built-in definition wins; 213,465 tokens.
  • Per-project ~/.claude.json.projects[path].disabledMcpServers → works, but:
  • Must be populated before session-start (live edits mid-session are ignored).
  • Must be maintained per project as new MCPs are added.

10 MCPs is a low-enough threshold that this affects users well below "power user" territory. Solution #1 (apply ToolSearch deferral to subagent spawns) is the only mitigation that does not require per-user maintenance as MCP ecosystems grow.

madisonrickert · 2 months ago

Adding a few data points not yet in the thread, in case helpful for triage. Reproduced on CLI 2.1.121, Opus 4.7, macOS Darwin 25.3.0.

Two distinct failure modes from the same root cause. This thread documents the loud one (immediate Prompt is too long). I also hit a quieter, more dangerous one in a real session before realizing what was going on:

  1. Loud: dispatch payload just over the limit → hard Prompt is too long rejection, agent never executes.
  2. Quiet: dispatch payload just under at spawn but no headroom for the tool results → Explore dispatches successfully, runs a few Read calls, then auto-compacts mid-run. The post-compaction continuation appears to misread its own compaction summary as a parent-conversation handoff and returns a hallucinated meta-reply like:

> "I can see from the system summary that I've already completed a thorough analysis... You're currently in plan mode... Would you like me to create a detailed plan document?"

No actual code excerpts come back. The toolUseResult for that real session showed totalTokens: 185_759, cache_read_input_tokens: 174_240, readCount: 6, totalDurationMs: 137_279 — i.e. the agent was clearly running and reading files, just couldn't carry the results back through the context squeeze. This is much harder to diagnose than the loud failure because it looks like the agent simply gave a bad answer.

Quantitative dispatch table (single fresh claude -p session, default config, 13 dispatches with progressively shorter prompts, parent told to dispatch one Explore subagent):

| Subagent prompt length | Result |
|---|---|
| 1711 / 990 / 728 / 591 / 508 / 341 / 298 / 161 / 86 / 52 / 40 / 20 / 11 / 10 chars | Prompt is too long |
| 4 ("test") / 2 ("hi") | Generic Explore greeting (no work) |

Note the failure isn't proportional to user prompt length — even an 11-char prompt ("read api.ts") was rejected. The cliff is hard, which is consistent with the parent ambient context (skill catalog + MCP tool schemas) consuming nearly the full budget before the user prompt is appended.

Workaround that fully resolved it for me: claude -p --disable-slash-commands --strict-mcp-config <prompt>. Same prompt that failed 13× in default config succeeded on the first dispatch (1 dispatch, 6,701 chars of accurate ground-truth output, 56 s vs 389 s, $0.30 vs $1.53). This is a useful diagnostic flag combo to suggest to users hitting this — confirms the cause and gives them an immediate escape valve.

Worth noting that skills/plugins also contribute, not only MCP tool schemas. With a heavy ~/.claude/plugins load, even users with modest MCP setups can hit this. The thread is MCP-centric; the broader fix needs to consider skill catalog injection too. (See also #40104 — "Skills with context: fork still inject all MCP tool definitions into subagent, ignoring allowed-tools" — and the feature request #38044 for per-agent context filtering.)

Possible secondary bug: the toolUseResult for my real-session failure included editFileCount: 1 on an Explore agent, even though the agent description says Explore has access to "All tools except Agent, ExitPlanMode, Edit, Write, NotebookEdit". Could be a denied call counted in stats, but worth a sanity check that Explore truly cannot reach Edit at runtime.

junaidtitan · 2 months ago

566 MCP tools pushing subagents past 200k is rough. While Cozempic (https://github.com/Ruya-AI/cozempic) operates on session JSONL rather than tool definitions, it can help keep the non-tool portion of context as small as possible so there is more headroom. Its metadata-strip, thinking-blocks, and tool-result-age strategies remove stale bulk from the session, and the guard daemon auto-prunes before sessions get dangerously large. pipx install cozempic — every byte of context saved is headroom reclaimed.

gabiudrescu · 1 month ago

Adding a data point with a specific observation about deferred tools.

Setup: Claude Code desktop (macOS), Claude Max, Opus 4.7 parent session, ~15 MCP servers including PostHog (~200+ tools), GTM, Chrome, Calendar, Gmail, Maps, toktoken, vestige, and several others.

Confirmed reproduction:

  • Haiku subagent: Prompt is too long — 0 tokens, 0 tool uses, fails in ~1s
  • Sonnet subagent: succeeds — 28k tokens, 1 tool use, ~8.5s

Observation not yet in this thread: In the parent session, all MCP tools appear as deferred — only tool names are listed in the system context, schemas are loaded on demand via ToolSearch. Despite this, subagents still receive the full schemas at spawn time and fail. This means the deferral mechanism that works correctly in the parent session is not applied at subagent dispatch.

This strengthens the case for Solution #1 (apply ToolSearch deferral to subagent spawns): the infrastructure already exists and works in the parent — it's just not being used when constructing the subagent's initial prompt.

Workaround confirmed: Setting CLAUDE_CODE_SUBAGENT_MODEL=claude-sonnet-4-6 works, but Sonnet's 200k window is not a long-term fix as MCP ecosystems grow.

caioribeiroclw-pixel · 1 month ago

Adding a concrete debugging shape that may help separate the two failure modes in this thread:

  1. subagent fails at boot because inherited MCP schemas/tool lists already exceed the model context; and
  2. subagent starts, but has no headroom left for tool output, so the parent sees a tiny/low-signal result.

The minimal receipt/debug event I would want here is not raw tool schemas. It is a context-budget breakdown like:

  • available MCP servers/tools;
  • loaded vs deferred/suppressed tool definitions;
  • skill/rule/memory listing counts if they are injected too;
  • startup token bucket and remaining token bucket before task #1;
  • whether bulky child output was returned raw to the parent or only as a bounded summary.

I wrote this up with runnable fixtures here: https://github.com/caioribeiroclw-pixel/pluribus/blob/main/docs/context-budget-receipts.md

The relevant examples are:

  • subagent boot budget: examples/context-input-evidence/subagent-context-budget-otel-trace.json
  • subagent delegation boundary: examples/context-input-evidence/subagent-delegation-otel-trace.json
  • MCP manager isolation: examples/context-input-evidence/claudekit-mcp-manager-otel-trace.json

The important bit for Claude Code itself could be much smaller than the full fixture: a /context or JSONL event that says “566 tools available, 20 loaded, 546 deferred/suppressed, ~35k startup tokens, ~165k remaining”, without copying schemas, prompts, args, results, or private paths. That would make this issue much easier to triage and would also tell users whether a proxy/router/ToolSearch-style workaround actually kept schemas out of the subagent.

abhinas90 · 1 month ago

Hit this exact issue. The core problem is Claude Code sends the full union of all MCP tool definitions to every subagent regardless of what they need.

Workaround that helped: organize MCP servers into role-specific configs (code-analysis, deployment, testing) and only load the subset each subagent needs. Dropped our token blow-up from 209k to ~60k for most subagents.

What we really need is per-agent MCP injection — let the orchestrator decide which servers each subagent gets. The lazy-loading MCP pattern would fix this.

caioribeiroclw-pixel · 1 month ago

This data point is useful because it separates two controls that often get conflated:

  • lazy discovery: schemas stay out of context until needed; and
  • injection policy: which servers/tools a given subagent is even allowed to discover.

Per-agent MCP injection feels like the right primitive here. Role-specific configs are a good workaround, but the receipt/debug output should make the policy visible so users do not have to infer it from token blow-ups.

A small acceptance check for the fix could be something like:

subagent=testing
available_servers=testing,github
excluded_servers=deployment,posthog,gmail,...
loaded_tool_definitions=0 or small bucket
deferred_tool_definitions=N
startup_tokens_bucket=~60k

That would prove the orchestrator did not pass the full MCP union to a subagent, while still avoiding raw schemas or private paths. It also gives users a way to compare the manual role-specific-config workaround against a future built-in policy.

dereekb · 1 month ago

I ran into this myself after starting to add more tools.

I mentioned this in #38928, and after seeing both of these threads I was wondering if Claude hallucinated a fix, but it suggested to me creating a custom agent that overrides the default Explore agent, and having that agent only allowed with the following header to restrict the tools:

---
name: Explore
description: Read-only search agent for broad fan-out searches across the codebase — sweeping many files, directories, or naming conventions when you only need the conclusion, not the file dumps. Reads excerpts rather than whole files; it locates and summarizes code, it does not review or audit it. Specify search breadth ("medium" for moderate exploration, "very thorough" for many locations / naming conventions). Lean variant: only the filesystem search tools are loaded (no MCP catalog), so it launches reliably even when many MCP servers are connected.
tools: Read, Grep, Glob, Bash
---

...

The subagent is restricted to just those tools alone. This workaround seems to be working as far as I can tell.