Custom Subagents Cannot Access Project-Scoped MCP Servers (Hallucinate Instead)

Resolved 💬 18 comments Opened Dec 13, 2025 by YS-Crabtree Closed May 23, 2026
💡 Likely answer: A maintainer (localden, collaborator) responded on this thread — see the highlighted reply below.

Summary

Custom subagents defined in .claude/agents/ cannot call MCP tools from locally-configured MCP servers (project-level .mcp.json). Instead of making actual MCP calls, subagents hallucinate plausible-looking results. Globally-configured MCP servers (~/.claude/mcp.json) work correctly in the same subagents.

Environment

  • Claude Code Version: 2.0.68
  • OS: macOS Darwin 24.6.0
  • Shell: zsh

Steps to Reproduce

1. Set up a local MCP server

Create .mcp.json in project root:

{
  "mcpServers": {
    "padc-validator": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/project/mcp-servers/validator", "server.py"]
    }
  }
}

2. Create a custom subagent

Create .claude/agents/test-validator.md:

---
name: test-validator
model: haiku
description: Test agent for MCP validation
tools:
  - mcp__padc-validator__validate_python_syntax
---

# Test Validator

When asked to validate Python code, call `mcp__padc-validator__validate_python_syntax` with the provided code and report the exact result.

3. Verify MCP server works from main thread

From the main Claude Code session, call the MCP tool directly:

Call: mcp__padc-validator__validate_python_syntax
Args: {"code": "def broken(\n    return 42"}

Expected result: {"valid": false, "error": "'(' was never closed", "line": 1, "column": 11}

4. Test the same call via custom subagent

Spawn the custom subagent and ask it to validate the same code:

Task tool with subagent_type="test-validator"
Prompt: "Validate this Python code: def broken(\n    return 42"

Expected result: Same error as main thread ('(' was never closed, line 1, column 11)

Actual result: Subagent returns a hallucinated error like invalid syntax (<unknown>, line 2) - different error message, different line number

5. Verify built-in subagent works correctly

Test the same MCP call using the built-in general-purpose subagent:

Task tool with subagent_type="general-purpose"
Prompt: "Call mcp__padc-validator__validate_python_syntax with code 'def broken(\n    return 42' and report the exact result"

Result: Returns correct error ('(' was never closed, line 1, column 11)

6. Verify global MCP servers work in custom subagents

If you have a globally-configured MCP server (e.g., Playwright in ~/.claude/mcp.json), test it via a custom subagent:

Result: Works correctly - returns real data, not hallucinated

Evidence from Investigation

Test Matrix

| Subagent Type | MCP Server Location | Result |
|---------------|---------------------|--------|
| Built-in (general-purpose) | Local (.mcp.json) | ✅ Works |
| Built-in (general-purpose) | Global (~/.claude/mcp.json) | ✅ Works |
| Custom (.claude/agents/) | Local (.mcp.json) | ❌ Hallucinates |
| Custom (.claude/agents/) | Global (~/.claude/mcp.json) | ✅ Works |

Hallucination Evidence

Using intentionally broken Python code def broken(\n return 42:

  • Real MCP result: '(' was never closed, line 1, column 11
  • Custom subagent (foreground): invalid syntax (<unknown>, line 2) - WRONG
  • Custom subagent (background): SyntaxError: unexpected indent - WRONG (different hallucination)
  • Built-in subagent: '(' was never closed, line 1, column 11 - CORRECT

The hallucinated errors are syntactically plausible but factually incorrect, confirming the subagent is not actually calling the MCP tool.

What We Ruled Out

  • Not a model issue: Tested with both haiku and sonnet models - same behavior
  • Not a tools restriction issue: Tested with tools: field present and omitted - same behavior
  • Not a foreground/background issue: Both execution modes hallucinate
  • Not a tool calling syntax issue: Subagents can call built-in tools (Read, Write, etc.) correctly

Documentation Conflict

The sub-agents documentation states:

"MCP Tools: Subagents can access MCP tools from configured MCP servers. When the tools field is omitted, subagents inherit all MCP tools available to the main thread."

This implies custom subagents should have access to all MCP servers, including local ones. The current behavior contradicts this documentation.

Expected Behavior

Custom subagents should be able to call MCP tools from locally-configured MCP servers (.mcp.json) the same way they can call:

  1. Built-in tools (Read, Write, Glob, Grep, Bash)
  2. Globally-configured MCP tools (~/.claude/mcp.json)

Actual Behavior

Custom subagents cannot call locally-configured MCP tools. Instead, they generate hallucinated responses that look like real MCP tool results but contain incorrect data.

Impact

This bug prevents using custom subagents for workflows that depend on local MCP servers, such as:

  • Code validation pipelines
  • Project-specific tool integrations
  • Custom development workflows

The hallucination behavior is particularly problematic because:

  1. Results look valid, making the bug hard to detect
  2. Different runs produce different hallucinated results
  3. No error message indicates the MCP call failed

Workarounds

  1. Use built-in general-purpose subagent for tasks requiring local MCP tools
  2. Move MCP servers to global config (~/.claude/mcp.json) if project-agnostic
  3. Perform MCP calls at orchestrator level and pass results to subagents

Suggested Fix

Ensure custom subagents defined in .claude/agents/ have access to locally-configured MCP servers from the project's .mcp.json file, consistent with how built-in subagents and globally-configured MCP servers behave.

View original on GitHub ↗

18 Comments

github-actions[bot] · 7 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/13605
  2. https://github.com/anthropics/claude-code/issues/13890
  3. https://github.com/anthropics/claude-code/issues/13254

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

YS-Crabtree · 7 months ago

Update: Confirmed Workaround

Further testing has confirmed that user-scoped MCP servers work correctly in custom subagents, while project-scoped MCP servers do not.

Working Workaround

Add MCP servers with --scope user instead of using project-level .mcp.json:

claude mcp add my-server --scope user -- command arg1 arg2

This stores the server in ~/.claude.json at the user level, and custom subagents can access it correctly.

Updated Test Matrix

| Subagent Type | MCP Server Scope | Result |
|---------------|------------------|--------|
| Built-in (general-purpose) | Project (.mcp.json) | ✅ Works |
| Built-in (general-purpose) | User (--scope user) | ✅ Works |
| Custom (.claude/agents/) | Project (.mcp.json) | ❌ Hallucinates |
| Custom (.claude/agents/) | User (--scope user) | ✅ Works |

Conclusion

The bug is specifically in how project-scoped MCP server configurations are inherited by custom subagents. User-scoped servers are inherited correctly.

Trade-off of workaround: User-scoped servers require absolute paths and are available across all projects, so this works best for tools that aren't project-specific.

dsull111 · 7 months ago

@YS-Crabtree Ive tried the above workaround, but the MCP tool calls for custom asynchronous agents still fail

| Agent Type | Execution Mode | MCP Access |
|----------------------------|----------------|------------|
| Custom | Sync | ✅ Works |
| Custom | Async | ❌ Fails |
| Built-in (general-purpose) | Sync | ✅ Works |
| Built-in (general-purpose) | Async | ❌ Fails |

The async agent is trying to use Bash commands instead of calling the actual MCP function tools. Removing the project-scoped config didn't help.

The issue persists: async agents don't see MCP tools as callable functions, regardless of:

  • Custom vs built-in agent type
  • Project vs user MCP scope
  • With or without project .mcp.json

This appears to be a fundamental bug in how Claude Code passes MCP connections to background agents. Only sync
agents inherit the connections.

jemshit · 6 months ago

@dsull111 how do you run it synchronously? run_in_background: false does not seem to have an effect?

shyney7 · 5 months ago

Is this even getting any attention from anthropic? It's such a critical issue that makes sub agents useless hallucinating token wasters.

@dsull111 how do you change sub agent execution mode to sync?
It seems that all my custom sub agents even if i just launch one don't have access to my user scope MCP servers.

ahfx · 5 months ago

Yeah this is a frustrating issue. I've attempted the work around from @dsull111 but had no luck.

claude --version
2.1.15 (Claude Code)
macOS 15.6.1 (24G90)
shyney7 · 5 months ago

Even when spawning a general purpose sub agent and specifying the tools he has access to like which mcp server, that sub agent seems also not to have access to the mcp server like context7 and instead does webfetch research...

keepanitreel · 5 months ago

Potentially related: #25152 — Zed IDE's agent_servers.claude.default_mode: "bypassPermissions" setting also causes severe sub-agent hallucination.

Same symptom: sub-agents fabricate realistic but completely false data (database results, file contents, config values) instead of failing. The bypassPermissions setting may be altering how context/constraints are passed to sub-agents in a way that triggers the same hallucination behavior described here. Removing the setting immediately resolved the issue.

verveguy · 4 months ago

Confirmed fixed in @anthropic-ai/claude-agent-sdk@0.2.63 (Claude Code 2.1.30+).

We verified this with a standalone test: a custom subagent with tools including mcp__atlassian__* successfully called an Atlassian MCP server and returned real Confluence data — no hallucination.

Requirements for it to work:

  • SDK version >=0.2.63
  • Custom agent must explicitly declare MCP tool patterns in its tools configuration (e.g., mcp__atlassian__*)
  • MCP server configured at the top-level client

See also: https://github.com/anthropics/claude-code/issues/13605#issuecomment-3981267292

Butanium · 4 months ago

Can confirm this doens't work :(

zelentsov-dev · 4 months ago

Still reproducible on Claude Code 2.1.63 (macOS 25.3.0).

Adding a data point: the issue extends beyond project-scoped servers. Custom subagent with mcpServers: asc-mcp declared in frontmatter cannot access a user-scoped MCP server configured in ~/.claude.json. Main thread calls the same server successfully. The subagent hallucinates results without any error indication.

Re @verveguy's comment about the fix in 2.1.30+ — can confirm it does not resolve the issue for custom agents defined in .claude/agents/. The mcpServers frontmatter field appears to be completely ignored at runtime.

See also #25200 for additional reproduction details.

verveguy · 4 months ago

I retract my earlier statement that it works on 0.2.63. It does not work reliably on 0.2.63 nor on the latest 0.2.70

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 · 4 months ago

We're hitting this too on Claude Code 2.1.76 (Windows).

Our setup: a plugin (Unimind) that defines custom agents in .claude/agents/ with inline MCP server definitions in the frontmatter using type: url and Streamable HTTP transport:

mcpServers:

  • vault-read:

type: url
url: "${MEMORY_MCP_URL}/mcp/read/mcp"
headers:
Authorization: "Bearer ${MCP_AUTH_TOKEN}"

The MCP server is confirmed working — we did a full handshake test via curl (POST with proper Accept: application/json, text/event-stream header) and got a 200 with valid initialize response, session ID, and reported capabilities.

But when the agents spawn, every MCP tool returns "No such tool available." The tools are never registered. No error is surfaced — agents just silently have no MCP tools.

This matches @verveguy's finding. Our agents don't use a tools: field at all, yet MCP tools from the mcpServers frontmatter are completely ignored. The env vars (MEMORY_MCP_URL, MCP_AUTH_TOKEN) are set and the permissions (mcp__vault-read__, mcp__vault-write__) are granted in ~/.claude/settings.json.

This is a blocker for any plugin architecture that gives agents their own MCP server connections.

TheDarkchip · 3 months ago

I got the custom subagents from the lean4-skills plugin to use the lean4 mcp by using the full specifier in the agent tools definition.

e.g.
lean_goal -> mcp__lean-lsp__lean_goal
lean_hover_info -> mcp__lean-lsp__lean_hover_info

In my case it also worked to ask Claude under what identifier the mcp functions appear.

❯ With what identifiers are the lean4 mcp commands shown to you?

⏺ The Lean 4 MCP tools are available with the prefix mcp__lean-lsp__ followed by the tool name:

  - mcp__lean-lsp__lean_build
  - mcp__lean-lsp__lean_code_actions
  - mcp__lean-lsp__lean_completions
  - mcp__lean-lsp__lean_declaration_file
  - mcp__lean-lsp__lean_diagnostic_messages
  - mcp__lean-lsp__lean_file_outline
  - mcp__lean-lsp__lean_get_widget_source
  - mcp__lean-lsp__lean_get_widgets
  - mcp__lean-lsp__lean_goal
  - mcp__lean-lsp__lean_hammer_premise
  - mcp__lean-lsp__lean_hover_info
  - mcp__lean-lsp__lean_leanfinder
  - mcp__lean-lsp__lean_leansearch
  - mcp__lean-lsp__lean_local_search
  - mcp__lean-lsp__lean_loogle
  - mcp__lean-lsp__lean_multi_attempt
  - mcp__lean-lsp__lean_profile_proof
  - mcp__lean-lsp__lean_references
  - mcp__lean-lsp__lean_run_code
  - mcp__lean-lsp__lean_state_search
  - mcp__lean-lsp__lean_term_goal
  - mcp__lean-lsp__lean_verify

  The pattern is mcp__lean-lsp__lean_<tool_name>.
chris-castillo-dev · 2 months ago

Hitting this on Claude Code 2.1.116. The scope appears broader than the current issue title suggests — sharing a reproduction matrix in case it's useful.

TL;DR

All MCP servers (local + plugin) fail to propagate to subagents spawned from inside a git worktree, regardless of subagent type or MCP registration scope. The asymmetry is worktree-boundary-specific, not scope-specific and not subagent-type-specific.

Reproduction matrix (2026-04-21, Claude Code 2.1.116)

All probes used the same pattern: a subagent is spawned with a 3-step prompt — Bash echo STEP1, call the MCP tool, Bash echo STEP3, and report PASS/FAIL verbatim. The Bash bookends prove the subagent actually ran.

| Context | Subagent type | MCP | Scope | Result |
|---|---|---|---|:-:|
| Main repo | researcher (custom) | local codebase-graph | project .mcp.json | ✅ PASS |
| Main repo | implementer (custom) | local codebase-graph | project .mcp.json | ✅ PASS |
| Main repo | tester (custom) | plugin context-mode | project (plugin-loaded) | ✅ PASS |
| Main repo | debugger (custom) | plugin Playwright | project (plugin-loaded) | ✅ PASS (tool in toolset) |
| Worktree | researcher (custom) | local codebase-graph | project .mcp.json | ❌ FAIL (No such tool available) |
| Worktree | general-purpose (built-in) | local codebase-graph | project .mcp.json | ❌ FAIL (not in loaded tool list, not in deferred tools retrievable via ToolSearch) |

Top-level Claude sessions inside the worktree see all MCPs fine — claude mcp get codebase-graph in the worktree shows Scope: Project config (shared via .mcp.json), ✓ Connected. It's only subagents that lose access.

We also previously verified the same failure mode against user-scope MCPs (registered via claude mcp add --scope user, visible in ~/.claude.json) — identical worktree-subagent gap, identical main-repo-subagent success. So scope is not the variable; worktree boundary is.

Workaround we've shipped

Given both scopes hit the same wall and the degradation is silent (subagent falls back to grep/glob quietly, or fails hard on browser-required MCPs like Playwright), we added a hard preflight refusal to our pipeline orchestrator:

# scripts/workflow.py cmd_init()
if (PROJECT_ROOT / ".git").is_file():
    _error(
        "Pipeline cannot start from a git worktree: MCP servers do not "
        "propagate to subagents inside worktrees "
        "(anthropics/claude-code#13898). Start from the main repo instead.",
        {"project_root": str(PROJECT_ROOT)},
    )

This refuses pipeline initialization from any worktree with a clear error pointing to this issue. Worktrees remain usable for isolated dev work, experiments, and anything not routed through subagents.

Suggested issue-title update

"Subagents spawned from worktrees cannot access MCP servers (project-scope, user-scope, plugin; custom and built-in subagent types)" — current framing "Custom Subagents Cannot Access Project-Scoped MCP Servers" is narrower than the actual symptom, which may obscure prioritization.

Happy to provide provenance-log extracts (PreToolUse/PostToolUse events with Bash bookends) if a maintainer wants deeper diagnostics.

verveguy · 1 month ago

Please fix this! see #25200 for yet more evidence.

localden collaborator · 1 month ago

Thanks for the report. This was fixed in the 2.1.x series (confirmed working in 2.1.116 and later). Custom subagents now inherit the project's MCP server registry. If you are seeing a worktree-specific variant of this, please follow #47733.

github-actions[bot] · 3 days ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.