[BUG] Cross-conversation stdio MCP serialization — parallel Chat sessions block on shared local MCP servers (Desktop Commander, Filesystem)
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?
In Claude Desktop's Chat tab, two open conversations cannot execute tool calls against the same local stdio MCP server concurrently. When Chat A invokes a tool call on a shared MCP server (e.g., Desktop Commander, Filesystem), any tool call issued from Chat B against the same server blocks until Chat A's call returns. Chat B's UI shows "thinking" / spinning indefinitely.
This is distinct from:
- #31427 (intra-conversation blocking — single chat can't multitask while one MCP call is in flight)
- #43642 (single-turn multi-call stdio failures on macOS)
- #14353 (in-message parallel MCP regression in v2.0.71)
Those describe behavior within one conversation. This issue is about the shared resource between conversations: the Chat tab appears to maintain one MCP client connection per server across all open Chat conversations, with no per-conversation isolation and no request pipelining on the stdio pipe. Long-running tool calls in one chat starve every other chat that needs the same MCP server.
Architectural impact: parallel Chat workflows that touch local filesystem/shell tools are effectively single-threaded, even though pure-inference workflows parallelize fine.
What Should Happen?
Each Chat conversation should either:
(a) maintain its own MCP client connection per server, or
(b) pipeline JSON-RPC requests over a shared connection using request IDs (which MCP already supports), so independent conversations don't starve each other.
Long-running tool calls in Conversation A should not block tool calls in Conversation B.
Error Messages/Logs
No error messages. Conversation B simply hangs in "thinking" state. No entries in mcp-server-*.log indicating queued/blocked requests during the wait window — the second request only appears in the log when Conversation A's call completes, indicating the block is at the Desktop app's MCP client dispatcher, not at the server.
Log location: ~/Library/Logs/Claude/
- main.log
- mcp.log
- mcp-server-desktop-commander.log
Steps to Reproduce
- Configure Desktop Commander (or any stdio MCP server with shell access) in claude_desktop_config.json.
- Open Claude Desktop, Chat tab. Open Conversation A.
- In Conversation A, prompt: "Run
sleep 60 && echo donevia Desktop Commander." - While Conversation A's tool call is in flight, open a second Conversation B (different project or same project).
- In Conversation B, prompt: "List files in /Users/<me>/Documents via Desktop Commander."
- Observe: Conversation B's tool call does not execute. It remains in "thinking" state until Conversation A's sleep returns ~60s later. Conversation B's call then executes immediately after.
Reproducible 100% of the time on macOS 15.x with multiple stdio MCP servers (Desktop Commander, Filesystem MCP, iMessages MCP).
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
Claude 1.7196.0 (2dbd78) 2026-05-12T05:34:40.000Z
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
This bottleneck makes the "multiple projects open in parallel" workflow unusable for any user whose work depends on local MCP servers. Inference parallelizes across conversations; tool calls do not. For users running multiple long-context project workflows (each with its own filesystem/shell needs), this forces sequential rather than parallel work.
Suggested fix paths:
- Per-conversation MCP client connections (simple, higher resource cost).
- Proper JSON-RPC request multiplexing over shared stdio (lower cost, matches MCP spec intent — request IDs already exist for this).
- At minimum, surface a "MCP server busy" indicator in the blocked conversation's UI so users understand the wait is structural, not a hang.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗