bug: Task subagents receive empty MCP tool surface (main-thread works, subagent context drops all mcp__* tools) — Windows + Opus 4.7
Environment
| Field | Value |
|---|---|
| Claude Code build | Claude Code CLI on Windows 11 Enterprise 10.0.26100 |
| Model | Claude Opus 4.7 (1M context) |
| Shell | PowerShell 7 (pwsh -NoProfile) |
| MCP server under test | cv-catalog-mcp (own, pwsh stdio, < 1 s boot) |
| Reference MCP servers | powerbi-modeling-mcp (user-scope stdio, VS Code extension), plugin:context7:context7 (plugin), claude.ai/* (extension connectors) |
Summary
A stdio MCP server registered at user scope via claude mcp add -s user:
- Boots cleanly. Server logs
lint_ok 26 shards → ready; no handshake errors. Boot-to-ready < 1 s. - Registers per
claude mcp listandclaude mcp get. Status✓ Connected; ScopeUser config (available in all your projects). - Tools surface at the main-thread session. The deferred-tool manifest carries
mcp__cv-catalog-mcp__search_evidence,mcp__cv-catalog-mcp__get_skills_taxonomy,mcp__cv-catalog-mcp__list_recent_evidence,mcp__cv-catalog-mcp__get_profile_block.ToolSearch("select:mcp__cv-catalog-mcp__*")loads their schemas; calls succeed end-to-end with real return data. - But every MCP tool drops from Task-dispatched subagent contexts. A subagent whose
tools:frontmatter declaresRead, Grep, Glob, WebFetch, Write, ReadMcpResourceTool, ListMcpResourcesTool, mcp__cv-catalog-mcp__*reports its actual function manifest as only[Read, Grep, Glob, WebFetch, Write]. Everymcp__<server>__*entry is filtered out, plus the genericReadMcpResourceTool/ListMcpResourcesToolpair too — leaving the subagent with no path whatsoever to reach any registered MCP server.
The contrast (main-thread PASS / subagent FAIL on the same registration) is the binding repro signal — it isolates the bug to the Task-subagent MCP-inheritance layer rather than to server config or to a slow-init timeout.
Steps to reproduce
- Register a stdio MCP server at user scope:
``powershell``
claude mcp add -s user cv-catalog-mcp -- pwsh -NoProfile -File C:\path\to\apps\cv-catalog-mcp\run.ps1
Confirm:
``text``
claude mcp get cv-catalog-mcp
Scope: User config (available in all your projects)
Status: ✓ Connected
Type: stdio
- Open a fresh Claude Code session anywhere. Confirm the four
mcp__cv-catalog-mcp__*tools surface at the main thread:
``text``
ToolSearch("select:mcp__cv-catalog-mcp__search_evidence,...")
→ returns four <function> schemas; tool calls succeed.
- Dispatch an agent via the Task tool whose frontmatter declares those tools:
``yaml``
tools: Read, Grep, Glob, WebFetch, Write, ReadMcpResourceTool, ListMcpResourcesTool, mcp__cv-catalog-mcp__search_evidence, ...
- Ask the subagent to self-report its function manifest before any work. Observed manifest:
``text``
[Read, Grep, Glob, WebFetch, Write]
Every MCP entry — both mcp__* and the generic pair — silently dropped. The frontmatter declaration has no effect.
Expected / Actual
Expected. A subagent whose frontmatter declares mcp__<server>__* and/or ReadMcpResourceTool / ListMcpResourcesTool should receive those tools in its manifest at dispatch, matching the parent-session surface. Per the main-thread evidence, the registration itself is healthy.
Actual. Subagent manifest = parent manifest minus every MCP tool. The filter is silent — no warning, no fall-back path declared.
Diagnostic observations
- Server boot < 1 s — slow-init timeout (cf. #60224) is ruled out.
claude mcp listfrom the parent session and from a child shell both show✓ Connected. Main-threadmcp__cv-catalog-mcp__list_recent_evidencereturns real data.- The subagent drop is uniform: user / project scope; CLI-added or extension-installed; with or without env-var substitution /
cwd. Three sessions across both scopes all produce the same empty subagent manifest. - Subagent has no workaround path:
ReadMcpResourceTool/ListMcpResourcesToolare dropped too, so it cannot enumerate registered servers either.
Scope-and-registration table
| Server | Scope | Surface | Main-thread tools | Subagent tools |
|---|---|---|---|---|
| cv-catalog-mcp | User (CLI-added) | stdio | ✅ PRESENT | ❌ ABSENT |
| cv-catalog-mcp | Project (.mcp.json) | stdio | ❌ ABSENT | ❌ ABSENT |
| powerbi-modeling-mcp | User (VS Code extension) | stdio | ✅ PRESENT | ❌ ABSENT |
| plugin:context7:context7 | Plugin | (plugin) | ✅ PRESENT | (not tested) |
The shift between rows 1 and 2 isolates the project-scope-vs-user-scope registration question. The shift between rows 1 and 3 isolates the registration mechanism. The subagent column is uniformly broken, which is the binding finding.
Remediations attempted (none lift the subagent surface)
| Attempt | Main-thread surface | Subagent surface |
|---|---|---|
| Default .mcp.json shape (project-scope, no cwd) | ❌ | ❌ |
| Session restart | ❌ | ❌ |
| Add "cwd": "${workspaceFolder}" per the MCP docs reference shape | ❌ | ❌ |
| Re-register at user scope via claude mcp add -s user (absolute-path command) | ✅ | ❌ |
Asks
- Confirm whether MCP-tool inheritance into Task-dispatched subagent manifests is supported. The agent-frontmatter convention of declaring
mcp__<server>__*intools:suggests yes, but the runtime behaviour suggests no. - If supported, point to the diagnostic surface (subagent-context log?
--debugflag?) that would surface the filter reason. - If not supported, document the intended path for subagents to call MCP tools (e.g. via a parent-thread proxy pattern, or via expanding the subagent's available toolset).
- Confirm whether dropping
ReadMcpResourceTool/ListMcpResourcesToolfrom a subagent that declares them in its frontmatter is intentional. If yes, the docs should warn; if no, this is the same bug surface as (1).
Out of scope (deliberately)
Transport choice (stdio is correct — server reads local files); consumer code paths (verified by static review of the agent body against the spec + server-side round-trip tests → 33 / 33 pass); .mcp.json shape (same shape works for two distinct servers per claude mcp list); slow-init root cause (< 1 s boot rules out #60224).
Duplicate search
Closest existing issues at anthropics/claude-code:
- #58924 — project-scope
.mcp.jsonsilently skipped on Linux. Not a dup: theirclaude mcp listdoesn't surface the server at all; ours surfaces it✓ Connectedand surfaces its tools at the main thread. Our binding finding is the subagent-only drop. - #60224 — Windows + stdio tools dropped when
initialize> probe timeout (cited cold init ~16 s). Not a dup: our server boots < 1 s, tools work fine at main-thread. Slow-init is not the root cause for this surface. - #53865, #54803 — wildcards / user-scope-write-vs-read. Not dups.
The novel evidence is the main-thread-PASS / subagent-FAIL contrast on the same registration, which none of the above issues capture.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗