bug: Task subagents receive empty MCP tool surface (main-thread works, subagent context drops all mcp__* tools) — Windows + Opus 4.7

Resolved 💬 1 comment Opened May 26, 2026 by ashley-seymour Closed Jun 9, 2026

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:

  1. Boots cleanly. Server logs lint_ok 26 shards → ready; no handshake errors. Boot-to-ready < 1 s.
  2. Registers per claude mcp list and claude mcp get. Status ✓ Connected; Scope User config (available in all your projects).
  3. 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.
  4. But every MCP tool drops from Task-dispatched subagent contexts. A subagent whose tools: frontmatter declares Read, Grep, Glob, WebFetch, Write, ReadMcpResourceTool, ListMcpResourcesTool, mcp__cv-catalog-mcp__* reports its actual function manifest as only [Read, Grep, Glob, WebFetch, Write]. Every mcp__<server>__* entry is filtered out, plus the generic ReadMcpResourceTool / ListMcpResourcesTool pair 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

  1. 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
``

  1. 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.
``

  1. 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, ...
``

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

  1. Server boot < 1 s — slow-init timeout (cf. #60224) is ruled out.
  2. claude mcp list from the parent session and from a child shell both show ✓ Connected. Main-thread mcp__cv-catalog-mcp__list_recent_evidence returns real data.
  3. 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.
  4. Subagent has no workaround path: ReadMcpResourceTool / ListMcpResourcesTool are 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

  1. Confirm whether MCP-tool inheritance into Task-dispatched subagent manifests is supported. The agent-frontmatter convention of declaring mcp__<server>__* in tools: suggests yes, but the runtime behaviour suggests no.
  2. If supported, point to the diagnostic surface (subagent-context log? --debug flag?) that would surface the filter reason.
  3. 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).
  4. Confirm whether dropping ReadMcpResourceTool / ListMcpResourcesTool from 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.json silently skipped on Linux. Not a dup: their claude mcp list doesn't surface the server at all; ours surfaces it ✓ Connected and 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.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗