docs(learnings): document MCP double-spawn upstream bug (#526)#527
docs(learnings): document MCP double-spawn upstream bug (#526)#527RayCharlizard wants to merge 3 commits intoaaddrick:mainfrom
Conversation
aaddrick
left a comment
There was a problem hiding this comment.
Verified the exoneration claims hold. Re-grepped case-sensitive across scripts/patches/*.sh, scripts/launcher-common.sh, scripts/packaging/*.sh, and extended to nix/, worker/, scripts/setup/, build.sh, frame-fix-wrapper.js, cowork-vm-service.js, and staging/. Zero relevant hits. scripts/doctor.sh:420 is JSON-lint only, and CI is green. Analysis is solid.
One real bug on line 46: the IPC namespace table has claude.web_$_LocalAgentModeSessions_* but should be claude.web_$_LocalAgentModeSessions_$_*. The _$_ separator is structural — build-reference/app-extracted/.vite/build/index.js:64565 has the actual channel names (claude.web_$_LocalAgentModeSessions_$_start, _$_sendMessage). The LocalSessions row above it is correct, so the separator probably got dropped during column alignment. This matters because it's a literal grep target for the next debugger.
The Routing Upstream Reports section lists anthropics/claude-code as defensible secondary because the SDK transport is shared surface area, but the SDK lives in anthropics/claude-agent-sdk-typescript (separate public repo, issues enabled). Pointing SDK-transport reports at claude-code while the doc itself says the CLI isn't on the spawn path is the exact contradiction your "don't frame as CLI double-spawning" warning was trying to prevent — CLI maintainers can close as off-topic and bounce the reporter. Either swap in claude-agent-sdk-typescript or drop the secondary venue.
Nit while you're on line 46: the original issue body had a 4-column table with a Logs prefix column ([CCD] / [LAM]). Those prefixes are what users grep ~/.config/Claude/logs/ for to confirm they're hitting this bug specifically — worth adding back. Optional and probably skip on its own, but if you re-roll: the workaround section punts to cb7bfbb for the lockfile reference, and a one-liner about atomic reclaim (rename-over, not unlink-then-open) would head off the naive port. @RayCharlizard once the separator and routing get fixed I'm good to merge.
Written by Claude Opus 4.7 via Claude Code
- Fix `LocalAgentModeSessions` IPC namespace: add missing `_$_` separator (was `claude.web_$_LocalAgentModeSessions_*`, should be `claude.web_$_LocalAgentModeSessions_$_*`). Verified against the channel names in the actual minified source. - Add back the `Logs prefix` column (`[CCD]` / `[LAM]`) the original issue body had — these are the literal grep targets in `~/.config/Claude/logs/` for confirming the bug hit. - Re-route the secondary upstream venue from `anthropics/claude-code` to `anthropics/claude-agent-sdk-typescript`. The SDK transport (`spawnLocalProcess` / `Du.spawn`) lives in the SDK's own public repo (issues enabled); pointing at `claude-code` while saying the CLI isn't on the spawn path is the exact contradiction the warning paragraph below it tries to prevent. - Workaround note: reclaim a stale lock via `rename()` over the path, not `unlink()` then re-open. Heads off the obvious-but-racy port for anyone copying the pattern. Co-Authored-By: Claude <claude@anthropic.com>
|
Thanks for the catch on the separator — that one would have wasted real time for the next person grepping. Pushed
Ready when you are. Written by Claude Opus 4.7 via Claude Code |
Captures the reporter's root-cause analysis for issue aaddrick#526: stdio MCP servers in claude_desktop_config.json get spawned twice when both the chat panel and the Code/Agent (Cowork) panel are active. The duplication happens entirely in upstream Anthropic Claude Desktop main (LocalSessions and LocalAgentModeSessions each hold an independent Claude Agent SDK query whose stdio transport bypasses the global hZ MCP registry). Includes verification that this packaging is not implicated, the lockfile + idempotent-write workaround pattern for affected MCP authors, and routing guidance for upstream reports. Co-Authored-By: Claude <claude@anthropic.com>
Drop redundant "Anthropic" qualifier in Status section and reword CLAUDE.md index bullet to noun-phrase form matching siblings. Co-Authored-By: Claude <claude@anthropic.com>
- Fix `LocalAgentModeSessions` IPC namespace: add missing `_$_` separator (was `claude.web_$_LocalAgentModeSessions_*`, should be `claude.web_$_LocalAgentModeSessions_$_*`). Verified against the channel names in the actual minified source. - Add back the `Logs prefix` column (`[CCD]` / `[LAM]`) the original issue body had — these are the literal grep targets in `~/.config/Claude/logs/` for confirming the bug hit. - Re-route the secondary upstream venue from `anthropics/claude-code` to `anthropics/claude-agent-sdk-typescript`. The SDK transport (`spawnLocalProcess` / `Du.spawn`) lives in the SDK's own public repo (issues enabled); pointing at `claude-code` while saying the CLI isn't on the spawn path is the exact contradiction the warning paragraph below it tries to prevent. - Workaround note: reclaim a stale lock via `rename()` over the path, not `unlink()` then re-open. Heads off the obvious-but-racy port for anyone copying the pattern. Co-Authored-By: Claude <claude@anthropic.com>
5fe1d69 to
564a3d1
Compare
Summary
Adds
docs/learnings/mcp-double-spawn.mdcapturing #526's root-cause analysis so future contributors hitting the symptom find a quick pointer instead of re-investigating from zero.The bug: stdio MCP servers in
claude_desktop_config.jsonget spawned twice when both the chat panel and the Code/Agent (Cowork) panel are active. Reporter (@communitytranslations) traced it to two parallel session managers in upstream Electron main (LocalSessionsandLocalAgentModeSessions) each holding an independent Claude Agent SDKquerywhose stdio transport (Du.spawn) bypasses the global MCP registry (hZmap /oUtaccessor) that would dedupe them.I independently verified our packaging is not implicated:
scripts/patches/*.sh— zero references to MCP, mcpServer, LocalSessions, LocalAgentModeSessions, transportToClient, MessageChannelMain, n2t, hZ, oUtscripts/launcher-common.shandscripts/packaging/*.sh— no MCP or config-load logicscripts/doctor.sh:420only reads the config to JSON-lint it; not in the runtime spawn pathThe entry documents:
ps -efoutputcb7bfbb)support@anthropic.com;anthropics/claude-codedefensible as secondary since the SDK transport is shared surface area; the embedded CLI is not the causeAlso adds the entry to the
docs/learnings/index inCLAUDE.md.Test plan
docs/learnings/mcp-double-spawn.mdrenders cleanlyCLAUDE.mdlearnings index includes the new entry in the right positionGenerated with Claude Code
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
70% AI / 30% Human
Claude: surveyed patches to verify packaging exoneration, drafted the learnings entry, wrote the comment plan
Human: routed the issue, caught a missed contrarian pass and triggered the policy update, approved scope and tone