Custom agents cannot use deferred MCP tools even when declared in mcpServers/tools frontmatter
Description
Custom agents defined in .claude/agents/ cannot access MCP tools at runtime, even when the MCP server is declared via mcpServers in the agent frontmatter and the specific tool names are listed in tools.
Reproduction Steps
- Configure a Notion MCP server in the project (verified working via
/mcpandListMcpResourcesToolin the parent session).
- Create a custom agent at
.claude/agents/api-v2.md:
```yaml
---
name: api-v2
tools: Read, ToolSearch, mcp__notion__notion-search, mcp__notion__notion-fetch
mcpServers: notion
model: opus
---
# v2 API Builder Agent
## First Step: Load Standards from Notion
Your VERY FIRST tool call must be:
mcp__notion__notion-search(query: "API V2 Standards")
Do NOT skip this step.
```
- Spawn the agent via the
Tasktool.
- The agent never calls
mcp__notion__notion-search. It proceeds directly toRead/Globcalls and later reports it was "unable to access Notion documentation."
What I Tried
- Adding
mcpServers: notionto frontmatter — no effect - Adding
mcp__notion__notion-searchandmcp__notion__notion-fetchexplicitly totools:— no effect - Adding
ToolSearchtotools:and instructing the agent to callToolSearchwith+notionfirst — agent doesn't call it - Escalating prompt urgency ("VERY FIRST tool call", "CRITICAL", "Do NOT skip") — ignored by both Sonnet and Opus
- Verifying the MCP server works in the parent session via
ListMcpResourcesToolandToolSearch— tools load and work correctly in the parent context
Expected Behavior
When a custom agent declares mcpServers: notion and lists MCP tools in tools:, those tools should be available and callable by the subagent at runtime — either pre-loaded or discoverable via ToolSearch.
Actual Behavior
The MCP tools appear to not be injected into the subagent's tool inventory at all. The agent never attempts to call them, suggesting they aren't present in its available tools, regardless of frontmatter declarations.
Suggested Improvements
- Hard-inject MCP tools declared via
mcpServersinto the subagent's tool inventory (not deferred). - Fail loudly if
mcpServersdeclares a server that isn't configured, rather than silently proceeding without those tools. - Document whether/how deferred MCP tools can be made available to custom agents.
Environment
- Claude Code CLI
- macOS (Darwin 25.2.0)
- Notion MCP server via
@notionhq/notion-mcp-server
Showing cached comments. Read the full discussion on GitHub ↗
13 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
I have the same issue, and so do many users. Please fix it!
Confirming this issue on Claude Code 2.1.63 (macOS 25.3.0, March 2026).
Custom agent with
mcpServers: asc-mcpandtools: Read, Grep, Globin frontmatter. The MCP server (asc-mcp— App Store Connect) is configured at user scope (~/.claude.json), verified working from the main thread (successfully callsbuilds_list,apps_list, etc.).The custom subagent silently ignores the MCP server — it never attempts to call any
asc-mcptools and instead fabricates plausible-looking results. No error is shown. ThemcpServersfrontmatter field has no observable effect.Notably, this is not limited to project-scoped servers (
.mcp.json) — user-scoped MCP servers in~/.claude.jsonare equally invisible to custom subagents.Related: #13898
Confirmed. This continues to be a problem even in the latest claude agent SDK builds. MCP tools are simply not available to subagents. This renders subagents useless for breaking off subcontext windows for noisy MCP tool interactions. Indeed, subagents are relegated to built-in tools only, which is an enormous limitation.
HOWEVER
IFF I set the frontmatter of the .claude/agents/my-test-agent.md to tools: * OR I omit the tools: line altogether THEN all tools are visible including all MCP tools.
Any attempt to restrict the tool list causes ALL MCP tools to be removed from the subagent scope.
Same issue here — Claude Code 2.1.76, Windows.
Our agents declare MCP servers inline in frontmatter (Streamable HTTP, type: url with auth headers). Server is confirmed alive and passing the MCP handshake correctly (tested via curl — 200 OK, valid initialize response, capabilities reported). But the subagents get zero MCP tools at runtime. No error, just silent failure.
Adding to the evidence: this also affects inline MCP server definitions (where the URL and headers are specified directly in the agent YAML), not just references to pre-configured server names. The mcpServers frontmatter field appears to be entirely non-functional for custom agents regardless of how the server is specified.
Worked around this by omitting
tools:entirely and addingpermissionMode: bypassPermissions. I am using Claude Code with--dangerously-skip-permissions.The key: don't declare tools: or mcpServers: in the frontmatter at all. As @verveguy mentioned, when you specify
tools:, it acts as a restrictive allowlist that doesn't properly include MCP tools. Omitting it gives the subagent access to everything the parent session has, including all deferred MCP tools (loadable via ToolSearch).permissionMode: bypassPermissionsprevents the agent from getting stuck on permission prompts mid-execution since subagents can't ask for user confirmation.Additional findings from independent investigation (v2.1.81, macOS arm64)
Filed #38920 before finding this issue — closing that as a duplicate and adding our findings here.
Key discovery: ToolSearch is the missing piece
The root cause isn't just that MCP tools aren't inherited — it's that custom agents don't receive
ToolSearch, which is required to discover deferred MCP tools.Test: Built-in general-purpose agent (no
subagent_type)ToolSearch("playwriter")→ loads MCP tool schemas → successfully callsmcp__playwriter__executeTest: Any custom agent from
~/.claude/agents/Exhaustive test matrix (all produce exactly 6 tools)
| Frontmatter config | Result |
|---|---|
|
tools:with explicit MCP tool names | 6 tools ||
tools:omitted entirely (should inherit all per docs) | 6 tools ||
disallowedTools:instead oftools:| 6 tools ||
mcpServers:referencing configured servers by name | 6 tools ||
mcpServers:with inline server definitions | 6 tools ||
permissionMode: bypassPermissions| 6 tools || All combinations of the above | 6 tools |
Implication
Custom agents appear to use a completely different code path than built-in agents. The frontmatter fields
tools:,disallowedTools:, andmcpServers:have zero effect on the actual tools available at runtime — the agent always gets the same hardcoded 6.The fix likely needs to ensure custom agents go through the same tool inheritance path as built-in agents, which includes ToolSearch for deferred MCP tool discovery.
Workaround
Use the general-purpose agent (omit
subagent_type) with custom instructions in the prompt. It gets ToolSearch, can discover MCP tools, and call them successfully.Root Cause Analysis from Source Code
After extensive investigation, I've identified the exact root cause of this issue by examining the Claude Code source architecture.
The Problem
Custom agents defined in
~/.claude/agents/useCUSTOM_AGENT_DISALLOWED_TOOLS(same asALL_AGENT_DISALLOWED_TOOLS), which does not includeToolSearchTool.Built-in agents (general-purpose, Explore, Plan) use
ASYNC_AGENT_ALLOWED_TOOLS, which explicitly includesToolSearchToolandSkillTool.Chain of Failure
mcpServersfrontmatter or inheritance)ToolSearchto load deferred tool schemasToolSearchis blocked byCUSTOM_AGENT_DISALLOWED_TOOLS❌Evidence
Agent()→ getsToolSearch, successfully discovers and calls MCP tools (Perplexity, Context7, Serena, etc.)~/.claude/agents/→ gets exactly 6 hardcoded tools (Read, Write, Edit, Bash, Grep, Glob), zero MCP toolstools:,disallowedTools:,mcpServers:,allowed-tools:— none can override the code-levelCUSTOM_AGENT_DISALLOWED_TOOLSWhat Changed
This worked in Claude Code v2.1.45 (February 2026). Confirmed via session logs showing a custom agent successfully calling
ToolSearch("serena symbol replace rename")and receiving 5 Serena tools. Broken somewhere between v2.1.45 and v2.1.92.Proposed Fix
Add
ToolSearchTool(and ideallySkillTool) to the custom agent tool pool — either by:CUSTOM_AGENT_DISALLOWED_TOOLS, ortools:/disallowedTools:to override the code-level restrictionsThis would restore MCP tool access for custom agents without any other behavioral changes, since the MCP servers already connect and register deferred tools — they just can't be materialized without
ToolSearch.Impact
This blocks all custom agent workflows that rely on MCP tools (database queries, documentation lookups, research, browser automation, etc.). The only workaround is using
general-purposewith embedded system prompts, which loses the benefits of reusable agent definitions.Tested on: Claude Code v2.1.92, macOS, with Perplexity, Context7, Serena, and other MCP servers configured.
Confirming this is still broken on v2.1.139 (current as of writing). potterdigital's RCA holds — the bug is the same shape they describe.
Repro on my end:
.claude/agents/<name>.mdwith frontmattertools: Read, Edit, Glob, BashplusmcpServers: [some-server]. The MCP server is configured in the project's.mcp.jsonandclaude mcp listshows it as✓ Connected.ToolSearch select:mcp__<server>__<tool>materializes them and they work fine.Agenttool reportsNo such tool available: mcp__<server>__<tool>when it tries to call them.mcpServers: [some-server]declaration) hits the same failure — so it's not agent-specific.tools:allowlist (tools: Read, Edit, Glob, Bash, mcp__<server>__<tool1>, mcp__<server>__<tool2>) does not change the outcome — the subagent still cannot call them.subagent_type="general-purpose"(the built-in agent) in the same session works fine — it hasToolSearchand can materialize the same MCP tools the custom agent could not see.This matches the
CUSTOM_AGENT_DISALLOWED_TOOLSexcludingToolSearchToolhypothesis exactly: deferred MCP tools are registered for the subagent but cannot be materialized because the subagent has no way to callToolSearch. The frontmatter is being parsed (no errors), but the runtime tool inventory is hardcoded.The proposed fix to either (a) remove
ToolSearchToolfromCUSTOM_AGENT_DISALLOWED_TOOLSor (b) honortools:/mcpServers:overrides at the code level would unblock this — both seem reasonable.This is a fairly serious limitation for any architecture that uses custom subagents to enforce capability boundaries while still needing MCP access for the work those subagents do. The current state forces a choice between "use custom agents (lose MCP)" and "use general-purpose with inlined prompts (lose the reusable agent definition)."
Thanks for the report. This is the same issue as #13898 (custom subagent missing project-scoped MCP registry). Consolidating tracking there.
You're welcome! Happy to see the staff replying. I love using Claude Code and want to help any way I can. @localden
Not planned? What is the reason for that?