Sub-agents spawned via Agent tool don't reliably inherit MCP tools (inconsistent with docs)
Summary
Sub-agents spawned directly via the Agent tool do not receive MCP tool access, even though the documentation states that sub-agents inherit all tools from the parent session (including MCP tools) by default.
Environment
- Claude Code version: latest (claude-sonnet-4-6)
- Platform: macOS Darwin 25.3.0
- MCP server: Atlassian (Jira)
Observed Behavior
Sub-agents spawned within a skill's execution context → ✅ MCP tools available (e.g. jira_get_issue, jira_search_fields, jira_create_issue — 17 successful MCP calls made)
Sub-agents spawned directly via the Agent tool (outside a skill context) → ❌ MCP tools not available. The agent reports only standard tools (Bash, Glob, Grep, Read, Edit, Write, etc.) and has no Jira/Atlassian tools in its tool list.
Reproduction Steps
- Configure an Atlassian MCP server in Claude Code (
~/.claude/settings.json) - Verify MCP is working (e.g. via a skill that uses Jira tools successfully)
- Directly spawn a
general-purposesub-agent via theAgenttool:
````
Agent tool:
subagent_type: general-purpose
prompt: "Call jira_get_issue with issue_key 'PROJ-123' and return the result"
- Observe that the sub-agent reports no MCP tools in its available tool list and cannot make the call
Expected Behavior
Per the documentation:
Subagents can use any of Claude Code's internal tools. By default, subagents inherit all tools from the main conversation, including MCP tools.
Sub-agents spawned via the Agent tool should have access to the same MCP tools available in the parent session, regardless of whether they are invoked within a skill context or directly.
Additional Context
The inconsistency is specifically between:
- Skill-invoked agents → MCP tools ✅
- Directly spawned agents (via
Agenttool in main conversation) → MCP tools ❌
This suggests the skill execution framework passes MCP context through correctly, but the direct Agent tool invocation does not.
11 Comments
Additional reproduction data — 3 scenarios with controlled tests
I ran into the same issue while trying to give MCP tools (Serena LSP, Context7 docs) to GSD workflow subagents. I set up 3 controlled tests that narrow down exactly when MCP propagation works vs. fails.
Environment
Test matrix
| # | Flow | MCP tools available? | Details |
|---|------|---------------------|---------|
| 1 |
Agent(subagent_type: "gsd-executor")— no skill context | NO | Only standard tools (Bash, Read, Edit, etc.). Zeromcp__*tools. Agent fell back to mcporter CLI bridge. || 2 |
Skill("mcp-test-wrapper")→ thenAgent(subagent_type: "general-purpose")spawned from within skill | YES | All 49+ MCP tools available:mcp__plugin_serena_serena__*(27 tools),mcp__plugin_context7_context7__*(2),mcp__figma__*(15),mcp__ide__*(2). Serenaactivate_project+get_symbols_overviewworked with persistent state across calls. || 3 |
Skill("gsd:execute-phase")→ orchestrator logic (reads workflow, runs CLI tools, analyzes JSON) → thenAgent(subagent_type: "gsd-executor")| NO | Despite being spawned from within a skill context, the executor agent had zeromcp__*tools — same as Test 1. |Key finding: propagation depends on spawn depth/timing, not just skill context
Test 2 vs Test 3 is the critical comparison:
This suggests the MCP context is available right after skill loading but gets lost after the main agent performs other tool calls before spawning the subagent. The intermediate orchestration work (even though it's still within the same skill context) breaks the propagation chain.
Reproduction steps for Test 2 (MCP works)
~/.claude/skills/mcp-test-wrapper/SKILL.md:Skill("mcp-test-wrapper")→ thenAgent(prompt: "Use ToolSearch query='mcp__' and list results")Reproduction steps for Test 3 (MCP fails)
Impact
This blocks any orchestrator pattern (like GSD, or custom workflow skills) from giving MCP tools to executor subagents, since orchestrators inherently do intermediate work before spawning agents. The workaround of wrapping everything in a skill only works for the trivial case of immediate agent spawning.
Workaround (partial)
For stateless MCP servers (Context7, Perplexity), using a CLI bridge like mcporter works. For stateful servers (Serena LSP), there is no viable workaround — each CLI call spawns a new process, losing session state.
A
UserPromptSubmithook (which fires in subagent sessions too) can inject CLAUDE.md content:This hook fires in both parent and subagent sessions, ensuring CLAUDE.md rules are always present.
+1 on this. Reliable MCP tool access in subagents spawned via the Agent tool would be a significant capability unlock. Looking forward to seeing this addressed.
+1, been fighting this problem across multiple projects for weeks without success.
Additional data — propagation depends on frontmatter
tools:declaration shapeConfirming this still reproduces on Claude Code 2.1.147 (macOS, Darwin 25.5.0) on 2026-05-22. Adding to lucasilvano1's spawn-depth/timing finding upthread (2.1.72): our probes today show a second axis of failure — the shape of the spawned subagent's
tools:frontmatter declaration affects whetherToolSearch(and the deferred-tools channel behind it) propagates at all.Three-probe matrix
All probes spawned directly via the orchestrator-CSO's Task tool, no skill wrapper, no intermediate work — to isolate the declaration-shape variable from lucasilvano1's spawn-depth/timing finding.
| Probe | Frontmatter
tools:declaration |ToolSearchin subagent surface? | Can reachmcp__claude_ai_Atlassian__*schemas? ||---|---|---|---|
|
architect(custom.claude/agents/sdlc/architect.md) | Enumerated:Read, Write, Edit, Glob, Grep, Bash, Task, WebSearch(noToolSearch) | No | No path — no ToolSearch to load them via ||
general-purpose(built-in) | Wildcard:*| Yes | Yes — ToolSearch returnedmcp__claude_ai_Atlassian__fetch,getAccessibleAtlassianResources,_Atlassian_2__fetchschemas cleanly ||
Explore(built-in) | Exclusion-style:All tools except Agent, ExitPlanMode, Edit, Write, NotebookEdit(ToolSearch NOT in the excluded list) | No | Self-reportedmcp__*tools visible directly (unverified — no invocation attempted) |Finding
Only the wildcard
tools: *declaration propagatesToolSearchto spawned subagents. Both enumerated-include (architect) and enumerated-exclude (Explore) declarations stripToolSearchfrom the subagent's function-call surface — even when, as withExplore,ToolSearchisn't in the excluded list. That collapses the entire deferred-tools channel, which is the only waymcp__claude_ai_Atlassian__*and similar MCP schemas are reachable at session level.Methodology caveat
These are LLM-self-reports of the function-call schema present in the subagent's system prompt. An LLM can't emit a call for a tool not in its schema (the harness rejects malformed calls client-side), so absence-from-schema is behaviourally equivalent to "the tool is unavailable" for any LLM-driven subagent. We didn't invoke any MCP tool during probes (deliberate — no Atlassian / Confluence write side-effects from a diagnostic).
One unresolved mixed signal
The
Exploreprobe self-reportedmcp__claude_ai_Atlassian__*tools as "directly visible in schema" whilearchitectreported none. We couldn't resolve which is accurate without an actual MCP invocation; flagging for any maintainer who wants to repro on a non-MCP-side-effect tool. The load-bearing finding (ToolSearch stripping) is independent of this.Possible local workaround — untested, and harder to test than expected
Naming
ToolSearchexplicitly in a subagent's enumeratedtools:list might bring it back. We attempted to probe this today by dropping a throwawayprobe-toolsearch.mdagent file withtools: Read, Bash, ToolSearchinto.claude/agents/and spawning it viaTask(subagent_type: "probe-toolsearch", ...). The call failed with:So a third, adjacent observation falls out: agent definitions are loaded at session start, not discovered dynamically. Adding a new
.claude/agents/<name>.mdfile mid-session doesn't make it spawnable; the harness'ssubagent_typeregistry is frozen at session boot. That has its own implication — even if namingToolSearchexplicitly in an agent'stools:line does fix this, rolling the workaround out requires every consumer to restart their session, which complicates the mitigation story.The explicit-naming test itself is still the natural next probe — just needs a fresh session to register the probe agent. We'll do that out-of-band and follow up if the result is conclusive. Issue #46424 (the sibling Task-propagation gap) is the reason for the caveat: it shows even declared tools (
Task,Glob,Grepinarchitect'stools:line) can still be filtered at runtime, so the same filter may stripToolSearcheven when declared.Operational shape
We orchestrate cross-product clinical-workflow tooling and need MCP-mediated Atlassian writes (Confluence pages, Jira comments) from subagents at the end of each chain phase. The current workaround is an orchestrator-side replay command (
/sdlc:sync-atlassian) that posts queued writes from the root context where MCP propagates correctly. Works, but adds a hop and breaks single-agent atomicity. The fix that retires it is whatever closes this issue.The new
tools:frontmatter finding is a useful clue because it separates two questions that look identical from the subagent's POV:A small diagnostic receipt would make this much easier to debug without logging raw schemas or prompts. Something like:
For this issue, the acceptance test I would want is not just “subagent can call MCP”. It is the matrix staying explainable:
tools: *vs explicit include vs exclusion styleToolSearchdeclared vs absentIf a subagent is intentionally sandboxed, the receipt should say “excluded by policy”. If it should inherit
ToolSearchbut does not, it should say where the channel was stripped. That would prevent a lot of the current guesswork around whether this is skill timing, agent registry boot-time loading, frontmatter parsing, or runtime filtering.I turned the diagnostic shape from my previous comment into a runnable, privacy-safe fixture so people can compare subagent ToolSearch propagation cases without dumping raw tool schemas/prompts.
Try it from the published package/source:
Release/source: https://github.com/caioribeiroclw-pixel/pluribus/releases/tag/v0.3.29
What the receipt captures: spawn path, skill-context flag, parent intermediate-tool-call bucket,
tools:declaration shape, ToolSearch declared vs actually exposed, parent/subagent MCP server buckets, loaded/deferred tool-definition buckets, and a filter reason. It intentionally records hashes/buckets only — no raw schemas, prompts, private paths, or raw tool declarations.This does not prove semantic tool relevance or successful runtime tool calls; it is just meant to make the current inheritance/declaration/runtime-filtering failure modes auditable as separate axes.
I believe everything else is a red herring except for the
toolsfrontmatter.If I set tools to include
ToolSearchand the full name of my MCP server tools, the subagents can call them.If I set
tools: *they also work.Just
ToolSearchalone was not sufficient.Claude Code v2.1.153.
If I do not include
ToolSearchin thetoolslist, it does not call the MCP server.If I try to wildcard the MCP endpoints in the
toolslist, it does not call the MCP server.Setting
disallowedToolswithouttoolsalso calls the MCP server successfully.Filed #66581 for a related variant: the same MCP tool stripping affects top-level custom agents (via
--agent/agentsetting), not just subagents. Notably, the workarounds confirmed here for subagents (explicitToolSearch+ MCP names,disallowedTools-only) do NOT work for top-level agents. Onlytools: "*"works.One additional finding from testing on v2.1.169:
tools: "*"alone surfaced ~128 MCP tools across all configured servers, buttools: "*"combined withdisallowedTools: [NotebookEdit]reduced that to 7 MCP tools across 3 servers.disallowedToolsappears to trigger a different resolution path that partially breaks wildcard MCP loading.