[Enhancement] Reap MCP child processes on parent claude exit — portable-workspace external drives get corrupted by orphan handles
Use case: portable Claude Code workspace on an external SSD
I run Claude Code on an external SSD that physically shuttles between a Mac and a Windows desktop, with the same project directories accessible on both OSes (exFAT-formatted for cross-platform read/write). This is a common setup for solo developers / business owners who don't have a fixed workstation but want one consistent project tree.
The problem: MCP child processes outlive their parent Claude Code session and lock the SSD
After a few days of normal use (open Claude → work on a project on the SSD → close terminal or /exit), I end up with multiple orphan MCP server processes (firebase-tools mcp, shopify-dev-mcp, npm exec wrappers) holding open file handles on the SSD. They survive past Claude Code sessions and prevent safe ejection of the drive.
Today's diagnostic on Mac: 12 orphan MCP processes across 4 detached claude CLI processes (3 of which had tty=?? — terminals long since closed). Each Claude session had spawned 3 MCP children (firebase + shopify + npm wrapper). None had been cleaned up.
On Windows it's worse: no SIGHUP, so closing PowerShell silently orphans the parent claude.exe along with its MCP children. Defender's real-time scanning compounds the problem by holding additional handles.
The downstream consequence: filesystem corruption
When the drive can't be ejected cleanly, the user eventually force-unplugs. On the next Windows mount, the exFAT dirty bit is set, Windows reports wrong free-space numbers ("Full Repair Needed" in the Volume status), and chkdsk /f is the only fix. In my case chkdsk.exe was being silently blocked by the antivirus stack and would not run at all (exited in 0 seconds with no output), so the volume stayed dirty indefinitely. macOS fsck_exfat cleared it cleanly when I moved the drive there — but that's only because I happen to have both OSes available.
This isn't theoretical — I went through the full cycle today: chkdsk-blocked-by-AV → drive yanked → exFAT dirty bit → wrong free space → Mac fsck recovery. The chain started with "can't eject because MCP children won't release the drive."
Related but distinct issues
- #51516 — Child claude processes orphan on
/exitin WSL (closely related, but WSL-specific) - #50783 — agent-browser Chrome processes orphan after session ends (same shape, different child)
- #29058 — Docker MCP containers not stopped when session ends (same shape, container variant)
- #49671 — Team shutdown_request acknowledged but teammates never terminate
- #47612 — Pre-exit hook feature request
What distinguishes this issue: the orphan-process pattern has a tangible, recurring data-corruption impact for users on portable workspaces, not just a memory/CPU leak. And it's cross-platform — same root cause, different downstream symptoms on Mac vs Windows.
Reproduction
- Use Claude Code CLI on a project whose CWD is on an exFAT external drive
- Have user-scope MCP servers configured (e.g., the official
firebase-tools mcp,shopify-dev-mcp) - Close the terminal window without typing
/exit - Check
ps aux | grep mcp— MCP child processes are still running - Repeat across multiple sessions over a few days
- Try to eject the SSD — fails because of stale file handles
- Force-unplug → on Windows, dirty bit set on next mount
Proposed solutions (any one would help)
- A reliable
SessionTerminatehook that fires on SIGHUP/terminal-close, not just on/exit. The currentSessionEndhook explicitly documents that it "may not run on ungraceful terminations" — this is the gap.
- MCP child-process tracking with parent-death detection. When the parent
claudeprocess exits or becomes orphaned (PPID=1), automatically send SIGTERM/SIGKILL to children. On Windows, register a process tree via job objects so termination cascades correctly.
- A
claude mcp reaporclaude doctor --cleansubcommand that finds and kills orphan MCP children whose parent claude process is no longer attached to a terminal. Even a manual mitigation would help — currently users have to write custompgrep/Get-CimInstancescripts.
- Explicit documentation of the orphan-process risk for users on portable drives + a recommended pre-eject workflow, until a proper fix lands.
My current workaround (in case helpful as a reference)
I had to build my own safe-eject scripts for both OSes:
- macOS:
lsof +Dto find blockers +pgrep -f "firebase-tools.*mcp|shopify-dev-mcp"+ parent-PID inspection +diskutil eject - Windows:
Get-CimInstance Win32_Processwith command-line regex + parent-process inspection +Shell.ApplicationCOM eject
Plus permanent on-volume markers (.metadata_never_index, .fseventsd/no_log on Mac; disabled IndexingEnabled on Windows) to stop the indexers from compounding the problem.
This works but it's user infrastructure that Claude Code itself should arguably own — especially given the data-loss-adjacent failure mode.
Environment
- Claude Code: latest stable (v2.1.144 area)
- Mac: macOS 14 Sequoia, external Extreme SSD via USB-C
- Windows: Windows 11, same physical drive
- MCP servers:
firebase-tools(Node.js),shopify-dev-mcp(Node.js), via user-scope configuration - Filesystem: exFAT (the only practical cross-platform option for >32 GB drives)
Happy to provide more diagnostic logs or test patches.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗