Custom agents cannot use deferred MCP tools even when declared in mcpServers/tools frontmatter

Status Closed — not planned
Maintainer reply ✓ Yes — localden
Activity 14 comments · opened Feb 12, 2026 · closed May 23, 2026
💡 Likely answer: A maintainer (localden, collaborator) responded on this thread — see the highlighted reply below.

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

  1. Configure a Notion MCP server in the project (verified working via /mcp and ListMcpResourcesTool in the parent session).
  1. 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.
```

  1. Spawn the agent via the Task tool.
  1. The agent never calls mcp__notion__notion-search. It proceeds directly to Read/Glob calls and later reports it was "unable to access Notion documentation."

What I Tried

  • Adding mcpServers: notion to frontmatter — no effect
  • Adding mcp__notion__notion-search and mcp__notion__notion-fetch explicitly to tools: — no effect
  • Adding ToolSearch to tools: and instructing the agent to call ToolSearch with +notion first — 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 ListMcpResourcesTool and ToolSearch — 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

  1. Hard-inject MCP tools declared via mcpServers into the subagent's tool inventory (not deferred).
  2. Fail loudly if mcpServers declares a server that isn't configured, rather than silently proceeding without those tools.
  3. 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

View original on GitHub ↗

13 Comments

github-actions[bot] · 6 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/13605
  2. https://github.com/anthropics/claude-code/issues/21560
  3. https://github.com/anthropics/claude-code/issues/13898

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

juliettefournier-econ · 6 months ago

I have the same issue, and so do many users. Please fix it!

zelentsov-dev · 6 months ago

Confirming this issue on Claude Code 2.1.63 (macOS 25.3.0, March 2026).

Custom agent with mcpServers: asc-mcp and tools: Read, Grep, Glob in frontmatter. The MCP server (asc-mcp — App Store Connect) is configured at user scope (~/.claude.json), verified working from the main thread (successfully calls builds_list, apps_list, etc.).

The custom subagent silently ignores the MCP server — it never attempts to call any asc-mcp tools and instead fabricates plausible-looking results. No error is shown. The mcpServers frontmatter field has no observable effect.

Notably, this is not limited to project-scoped servers (.mcp.json) — user-scoped MCP servers in ~/.claude.json are equally invisible to custom subagents.

Related: #13898

verveguy · 5 months ago

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.

verveguy · 5 months ago

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.

JimmyWigerstedt · 5 months ago

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.

bhardwajkonark · 5 months ago

Worked around this by omitting tools: entirely and adding permissionMode: 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: bypassPermissions prevents the agent from getting stuck on permission prompts mid-execution since subagents can't ask for user confirmation.

sunipan · 5 months ago

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)

  • Gets 8 tools: Read, Write, Edit, Bash, Glob, Grep, ToolSearch, Skill
  • Can call ToolSearch("playwriter") → loads MCP tool schemas → successfully calls mcp__playwriter__execute

Test: Any custom agent from ~/.claude/agents/

  • Gets exactly 6 tools: Read, Write, Edit, Bash, Glob, Grep
  • No ToolSearch, no Skill, no Agent/Task, no MCP tools
  • This is true regardless of any frontmatter configuration

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 of tools: | 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:, and mcpServers: 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.

potterdigital · 4 months ago

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/ use CUSTOM_AGENT_DISALLOWED_TOOLS (same as ALL_AGENT_DISALLOWED_TOOLS), which does not include ToolSearchTool.

Built-in agents (general-purpose, Explore, Plan) use ASYNC_AGENT_ALLOWED_TOOLS, which explicitly includes ToolSearchTool and SkillTool.

Chain of Failure

  1. MCP servers connect to the subagent ✅ (via mcpServers frontmatter or inheritance)
  2. MCP tool names register as deferred ✅ (tool search is enabled by default)
  3. Agent needs ToolSearch to load deferred tool schemas
  4. ToolSearch is blocked by CUSTOM_AGENT_DISALLOWED_TOOLS
  5. Deferred MCP tools never materialize → agent sees 0 MCP tools

Evidence

  • general-purpose agent (built-in) spawned via Agent() → gets ToolSearch, successfully discovers and calls MCP tools (Perplexity, Context7, Serena, etc.)
  • Any custom agent from ~/.claude/agents/ → gets exactly 6 hardcoded tools (Read, Write, Edit, Bash, Grep, Glob), zero MCP tools
  • This is true regardless of frontmatter configuration: tools:, disallowedTools:, mcpServers:, allowed-tools: — none can override the code-level CUSTOM_AGENT_DISALLOWED_TOOLS

What 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 ideally SkillTool) to the custom agent tool pool — either by:

  1. Adding them to the allowed set for custom agents, or
  2. Removing them from CUSTOM_AGENT_DISALLOWED_TOOLS, or
  3. Allowing frontmatter tools: / disallowedTools: to override the code-level restrictions

This 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-purpose with 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.

barriault · 3 months ago

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:

  • Custom agent at .claude/agents/<name>.md with frontmatter tools: Read, Edit, Glob, Bash plus mcpServers: [some-server]. The MCP server is configured in the project's .mcp.json and claude mcp list shows it as ✓ Connected.
  • Main session has the MCP tools as deferred; ToolSearch select:mcp__<server>__<tool> materializes them and they work fine.
  • Subagent invoked via the Agent tool reports No such tool available: mcp__<server>__<tool> when it tries to call them.
  • A second custom agent (different name, different role, same mcpServers: [some-server] declaration) hits the same failure — so it's not agent-specific.
  • Adding the qualified MCP tool names explicitly to the tools: allowlist (tools: Read, Edit, Glob, Bash, mcp__<server>__<tool1>, mcp__<server>__<tool2>) does not change the outcome — the subagent still cannot call them.
  • Dispatching subagent_type="general-purpose" (the built-in agent) in the same session works fine — it has ToolSearch and can materialize the same MCP tools the custom agent could not see.

This matches the CUSTOM_AGENT_DISALLOWED_TOOLS excluding ToolSearchTool hypothesis exactly: deferred MCP tools are registered for the subagent but cannot be materialized because the subagent has no way to call ToolSearch. The frontmatter is being parsed (no errors), but the runtime tool inventory is hardcoded.

The proposed fix to either (a) remove ToolSearchTool from CUSTOM_AGENT_DISALLOWED_TOOLS or (b) honor tools: / 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)."

localden collaborator · 3 months ago

Thanks for the report. This is the same issue as #13898 (custom subagent missing project-scoped MCP registry). Consolidating tracking there.

potterdigital · 3 months ago
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

nebula2 · 2 months ago

Not planned? What is the reason for that?

Showing cached comments. Read the full discussion on GitHub ↗