Sub-agents spawned via Agent tool don't reliably inherit MCP tools (inconsistent with docs)

Status Open
Maintainer reply None cached
Activity 11 comments · opened Mar 3, 2026

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

  1. Configure an Atlassian MCP server in Claude Code (~/.claude/settings.json)
  2. Verify MCP is working (e.g. via a skill that uses Jira tools successfully)
  3. Directly spawn a general-purpose sub-agent via the Agent tool:

``
Agent tool:
subagent_type: general-purpose
prompt: "Call jira_get_issue with issue_key 'PROJ-123' and return the result"
``

  1. 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 Agent tool in main conversation) → MCP tools ❌

This suggests the skill execution framework passes MCP context through correctly, but the direct Agent tool invocation does not.

View original on GitHub ↗

11 Comments

lucasilvano1 · 5 months ago

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

  • Claude Code version: 2.1.72
  • Platform: macOS Darwin 25.3.0 (arm64)
  • MCP servers tested: Serena (LSP-based, stateful), Context7 (stateless docs), Figma, IDE

Test matrix

| # | Flow | MCP tools available? | Details |
|---|------|---------------------|---------|
| 1 | Agent(subagent_type: "gsd-executor") — no skill context | NO | Only standard tools (Bash, Read, Edit, etc.). Zero mcp__* tools. Agent fell back to mcporter CLI bridge. |
| 2 | Skill("mcp-test-wrapper") → then Agent(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). Serena activate_project + get_symbols_overview worked with persistent state across calls. |
| 3 | Skill("gsd:execute-phase") → orchestrator logic (reads workflow, runs CLI tools, analyzes JSON) → then Agent(subagent_type: "gsd-executor") | NO | Despite being spawned from within a skill context, the executor agent had zero mcp__* 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:

  • Test 2: Skill loads → main agent immediately spawns subagent → MCP propagates ✅
  • Test 3: Skill loads → main agent does intermediate work (reads files, runs bash commands, processes JSON) → then spawns subagent → MCP does NOT propagate ❌

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)

  1. Create a minimal skill at ~/.claude/skills/mcp-test-wrapper/SKILL.md:
---
name: mcp-test-wrapper
description: Test MCP propagation
---
Spawn a general-purpose subagent that lists all mcp__* tools via ToolSearch.
  1. Invoke: Skill("mcp-test-wrapper") → then Agent(prompt: "Use ToolSearch query='mcp__' and list results")
  2. Observe: subagent has full MCP tool access

Reproduction steps for Test 3 (MCP fails)

  1. From within a skill context, have the main agent do any intermediate work (e.g., read a file, run a bash command)
  2. Then spawn a subagent
  3. Observe: subagent has NO MCP tools

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.

yurukusa · 5 months ago

A UserPromptSubmit hook (which fires in subagent sessions too) can inject CLAUDE.md content:

MARKER="/tmp/cc-claudemd-injected-$$"
[ -f "$MARKER" ] && exit 0
touch "$MARKER"
CONTEXT=""
for f in CLAUDE.md .claude/CLAUDE.md; do
    [ -f "$f" ] && CONTEXT+="$(cat "$f")
"
done
[ -z "$CONTEXT" ] && exit 0
jq -n --arg ctx "CLAUDE.md rules (injected via hook for subagent inheritance):
$CONTEXT" '{"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","additionalContext":$ctx}}'
exit 0

This hook fires in both parent and subagent sessions, ensuring CLAUDE.md rules are always present.

stefmf · 4 months ago

+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.

daywhirls · 4 months ago

+1, been fighting this problem across multiple projects for weeks without success.

bconolly · 3 months ago

Additional data — propagation depends on frontmatter tools: declaration shape

Confirming 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 whether ToolSearch (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 | ToolSearch in subagent surface? | Can reach mcp__claude_ai_Atlassian__* schemas? |
|---|---|---|---|
| architect (custom .claude/agents/sdlc/architect.md) | Enumerated: Read, Write, Edit, Glob, Grep, Bash, Task, WebSearch (no ToolSearch) | No | No path — no ToolSearch to load them via |
| general-purpose (built-in) | Wildcard: * | Yes | Yes — ToolSearch returned mcp__claude_ai_Atlassian__fetch, getAccessibleAtlassianResources, _Atlassian_2__fetch schemas cleanly |
| Explore (built-in) | Exclusion-style: All tools except Agent, ExitPlanMode, Edit, Write, NotebookEdit (ToolSearch NOT in the excluded list) | No | Self-reported mcp__* tools visible directly (unverified — no invocation attempted) |

Finding

Only the wildcard tools: * declaration propagates ToolSearch to spawned subagents. Both enumerated-include (architect) and enumerated-exclude (Explore) declarations strip ToolSearch from the subagent's function-call surface — even when, as with Explore, ToolSearch isn't in the excluded list. That collapses the entire deferred-tools channel, which is the only way mcp__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 Explore probe self-reported mcp__claude_ai_Atlassian__* tools as "directly visible in schema" while architect reported 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 ToolSearch explicitly in a subagent's enumerated tools: list might bring it back. We attempted to probe this today by dropping a throwaway probe-toolsearch.md agent file with tools: Read, Bash, ToolSearch into .claude/agents/ and spawning it via Task(subagent_type: "probe-toolsearch", ...). The call failed with:

Agent type 'probe-toolsearch' not found. Available agents: architect, claude, claude-code-guide, …

So a third, adjacent observation falls out: agent definitions are loaded at session start, not discovered dynamically. Adding a new .claude/agents/<name>.md file mid-session doesn't make it spawnable; the harness's subagent_type registry is frozen at session boot. That has its own implication — even if naming ToolSearch explicitly in an agent's tools: 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, Grep in architect's tools: line) can still be filtered at runtime, so the same filter may strip ToolSearch even 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.

caioribeiroclw-pixel · 3 months ago

The new tools: frontmatter finding is a useful clue because it separates two questions that look identical from the subagent's POV:

  1. did the parent/orchestrator intend to make MCP/ToolSearch available to this subagent?
  2. did the runtime actually expose the deferred-tool channel after spawn?

A small diagnostic receipt would make this much easier to debug without logging raw schemas or prompts. Something like:

{
  "subagent_type": "architect",
  "spawn_path": "Task",
  "skill_context_active": true,
  "parent_intermediate_tool_calls_bucket": "1-5",
  "agent_tools_declared_shape": "enumerated_include",
  "toolsearch_declared": false,
  "toolsearch_exposed_to_subagent": false,
  "mcp_server_count_parent_bucket": "1-10",
  "mcp_servers_available_to_subagent_bucket": "0",
  "deferred_tool_definitions_bucket": "0",
  "filtered_by": "frontmatter_tools_policy_or_runtime_filter",
  "privacy_raw_tool_schemas_logged": false
}

For this issue, the acceptance test I would want is not just “subagent can call MCP”. It is the matrix staying explainable:

  • immediate spawn vs spawn after parent tool calls
  • tools: * vs explicit include vs exclusion style
  • ToolSearch declared vs absent
  • stateful MCP vs stateless MCP

If a subagent is intentionally sandboxed, the receipt should say “excluded by policy”. If it should inherit ToolSearch but 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.

caioribeiroclw-pixel · 3 months ago

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:

npx --yes pluribus-context@latest --version
node examples/context-input-evidence/convert-subagent-toolsearch-propagation-log.mjs

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.

bmarker · 2 months ago

I believe everything else is a red herring except for the tools frontmatter.

If I set tools to include ToolSearch and the full name of my MCP server tools, the subagents can call them.
If I set tools: * they also work.

Just ToolSearch alone was not sufficient.

Claude Code v2.1.153.

bmarker · 2 months ago

If I do not include ToolSearch in the tools list, it does not call the MCP server.
If I try to wildcard the MCP endpoints in the tools list, it does not call the MCP server.

bmarker · 2 months ago

Setting disallowedTools without tools also calls the MCP server successfully.

CharlyRipp · 2 months ago

Filed #66581 for a related variant: the same MCP tool stripping affects top-level custom agents (via --agent / agent setting), not just subagents. Notably, the workarounds confirmed here for subagents (explicit ToolSearch + MCP names, disallowedTools-only) do NOT work for top-level agents. Only tools: "*" works.

One additional finding from testing on v2.1.169: tools: "*" alone surfaced ~128 MCP tools across all configured servers, but tools: "*" combined with disallowedTools: [NotebookEdit] reduced that to 7 MCP tools across 3 servers. disallowedTools appears to trigger a different resolution path that partially breaks wildcard MCP loading.