fix(mcp): exit on stdin close to prevent zombie MCP servers - #21
Merged
Conversation
The stdio MCP server only handled SIGINT/SIGTERM, so when a client died without sending a signal (Windows terminal close, Claude Code session exit, lost SSH pipe), the process kept running. Three zombies accumulated on a Win 11 ARM64 VM tonight, and Claude Code talked to one of the stale ones — so it served the pre-rebuild tool list and the AI couldn't see newly added tools. Hook into stdin 'end' and 'close' as a third exit path. Same cleanup sequence as the signal handlers (disposeAll + server.close + exit 0). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
end/closeso the MCP server exits when the client dies without sending a signal.disposeAll+server.close+process.exit(0)).Why
The stdio server only handled
SIGINT/SIGTERM. When Claude Code on Win 11 ARM64 closed its terminal (or the SSH pipe dropped), the MCP server kept running. Three zombienode ... cli.jsprocesses accumulated tonight. Claude Code reused one of the stale ones fortools/list, so the AI saw the pre-rebuild tool list and couldn't see newly added tools likeagentmark_desktop_list_targetseven though the on-disk dist had them.Symptom for users:
claude mcp listhangs at "Checking MCP server health…" andtasklist | findstr nodeshows multiplecli.jsprocesses. Workaround wasStop-Processon each one. This patch makes the workaround unnecessary.Test plan
pnpm test)pnpm build)claude, checkGet-CimInstance Win32_Process | ? CommandLine -like '*agentmark*'returns emptyps -ef | grep agentmark | grep -v grep🤖 Generated with Claude Code