[BUG] Subagent teardown kills the parent session's stdio MCP server when both declare the same inline server
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
A subagent can declare an inline stdio MCP server in its frontmatter. If that config is identical to a server the parent session already has, the subagent reuses the parent's connection. When the subagent finishes, Claude Code calls cleanup() on that connection. This sends SIGINT and then SIGTERM to the shared server process. The parent session marks the server failed and drops its tools. It doesn't reconnect until the user runs /mcp.
The most common trigger is a main-thread agent (claude --agent X) that spawns a subagent of the same type X. Both build the same config from the same agent file, so no change to the agent file can avoid the collision.
when the subagent ends, the echo MCP log (~/.cache/claude-cli-nodejs/<cwd>/mcp-logs-echo/) shows:
(see Error Messages/Logs)
/mcp shows echo as failed. The parent can't call mcp__echo__ping until you reconnect it from /mcp.
The same thing happens with two different agent files (lead as the main thread, worker as the subagent) when their inline echo definitions are identical.
What Should Happen?
the parent's echo server stays connected, and the third call succeeds.
Error Messages/Logs
From `~/.cache/claude-cli-nodejs/<cwd>/mcp-logs-echo/` when the subagent ends:
Sending SIGINT to MCP server process
MCP server process exited cleanly
Steps to Reproduce
- Save a minimal stdio MCP server as
/tmp/echo_server.py:
```python
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("echo")
@mcp.tool()
def ping() -> str:
return "pong"
mcp.run()
```
- Save
~/.claude/agents/lead.md:
```markdown
---
name: lead
description: Test agent that declares an inline MCP server
mcpServers:
- echo:
command: python3
args: ["/tmp/echo_server.py"]
---
You are a test agent.
```
- Run
claude --agent lead. - Send this prompt: "Call mcp__echo__ping. Then spawn a
leadsubagent that calls mcp__echo__ping and returns. Then call mcp__echo__ping again."
Claude Model
Not sure / Multiple models
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.295
Platform
AWS Bedrock
Operating System
Other Linux
Terminal/Shell
iTerm2
Additional Information
Root cause (from reading the 2.1.295 bundle)
connectToServeris memoized in a map shared by the whole session. The key is${name}-${hash(config)}. The hash dropsscopeand plugin metadata. It keepscommand,args,env, andagentSource.- Main-thread frontmatter servers (
agentMcpSpecsToScopedConfigs) and subagent frontmatter servers both become{...config, scope: "agent", agentSource}. Two cases produce the same key, and the subagent then gets the parent's existing connection:
- a main thread and a subagent of the same type
- two agent files from the same source with identical inline configs
- Subagent MCP setup sets
isNewlyCreated: truefor every inline spec. String references getfalse. Setup doesn't check whetherconnectToServerreturned a connection that already existed. When the subagent ends, setup callscleanup()on every connected client markedisNewlyCreated. For stdio,cleanup()sends SIGINT and then SIGTERM to the process. - The REPL
onclosehandler auto-reconnects only non-stdio transports (type !== "stdio" && type !== "sdk"). For stdio, it marks the clientfailed, which removes its tools.
Subagent tool lists put parent tools first and dedupe by name. So when the parent has the server, the subagent never calls its own connection. The teardown is its only effect.
Other trigger
Two subagents of the same type can run at the same time and both declare the server, while the parent doesn't have it. They share one connection. When the first one finishes, it kills the process during the second one's in-flight tool call.
Workaround
Give each agent file's inline server a distinct config, for example an unused env variable set to the agent name. This separates different agent types. It can't separate a main thread from a subagent of the same type, or two concurrent subagents of the same type.
Suggested fix
- In subagent MCP setup, treat a connection as owned only if it wasn't in the
connectToServercache before the dial. Clean up only owned connections. - Alternatively, refcount memoized connections and close a connection on its last release.
- Optionally, have the REPL
onclosehandler re-dial a stdio server that another owner'scleanup()closed, instead of marking itfailed.
Related
- #84638 reports the same content-keyed sharing between concurrent subagents with byte-identical inline configs. That report covers the loss of isolation. This one covers the teardown: the shared connection belongs to the main session too, and the subagent kills it. #84638 was closed as stale on 2026-10-05. The behavior is still present in 2.1.295.
- #86040 reports the teardown symptom. Claude Code sends SIGINT and SIGTERM to a healthy stdio server, and a background
Agenttask stops at the same second. It was closed as stale without a root cause. This may be the cause.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗