MCP server subprocesses not cleaned up when terminal is closed

Resolved 💬 3 comments Opened Mar 18, 2026 by light-echo-3 Closed Mar 21, 2026

Bug Description

When a Claude Code session exits abnormally (e.g., terminal window closed directly instead of using /exit or Ctrl+C), the MCP server subprocesses spawned by Claude Code are not properly terminated. They become orphan processes that persist indefinitely.

Steps to Reproduce

  1. Start a Claude Code session in a terminal (with MCP servers configured, e.g., lark-mcp, playwright-mcp, firebase-mcp, etc.)
  2. Close the terminal window directly (click the X button) instead of gracefully exiting Claude Code
  3. Run ps aux | grep mcp to check for remaining processes

Expected Behavior

All MCP server subprocesses should be terminated when the parent Claude Code process exits, regardless of how it exits.

Actual Behavior

MCP subprocesses become orphan processes (terminal shows ?? in ps aux output) and continue running indefinitely. Over time, this accumulates many zombie processes consuming system resources.

Example of orphan processes found:

hudequan  79032  0.0  0.0  ??  S  node .../lark-mcp mcp ...
hudequan  73931  0.0  0.0  ??  S  node .../lark-mcp mcp ...
hudequan  72009  0.0  0.0  ??  S  node .../lark-mcp mcp ...
hudequan  87532  0.0  0.1  ??  S  node .../chrome-devtools-mcp ...
hudequan  87516  0.0  0.1  ??  S  npm exec chrome-devtools-mcp@latest ...

In one session, I found 7 groups of orphan lark-mcp processes plus chrome-devtools-mcp processes — all from previous Claude Code sessions that were not gracefully terminated.

Environment

  • OS: macOS (Darwin 24.6.0)
  • Claude Code: Latest version
  • MCP servers affected: All types (lark-mcp, playwright-mcp, chrome-devtools-mcp, firebase-mcp, figma-developer-mcp, aliyun-sls-mcp, mcp-media-processor)

Suggested Fix

  • Use process group signals (e.g., SIGHUP propagation) to ensure child processes are terminated when the parent exits
  • Register cleanup handlers for SIGTERM, SIGHUP, and SIGINT signals
  • Consider using prctl(PR_SET_PDEATHSIG) on Linux or equivalent mechanism on macOS to auto-terminate children when parent dies
  • As a fallback, MCP subprocesses could periodically check if their parent PID is still alive and self-terminate if not

Workaround

Manually kill orphan processes:

ps aux | grep -iE "lark-mcp|playwright-mcp|firebase mcp|chrome-devtools-mcp|figma-developer-mcp|aliyun-sls-mcp|mcp-sever-media-processor" | grep -v grep | awk '$7 == "??" {print $2}' | xargs kill

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗