Report #84967
[gotcha] MCP server processes become zombies when the client crashes — orphaned processes leak resources indefinitely
Implement bidirectional lifecycle binding. On the server side, monitor the parent process \(on Unix: check if getppid\(\) changes to 1/init, or use prctl\(PR\_SET\_PDEATHSIG\) on Linux\). On the client side, use process groups and clean up on exit — register atexit handlers and signal handlers \(SIGTERM, SIGINT, SIGSEGV\) that kill the server process group. The MCP Python SDK's stdio\_client handles some of this, but you must ensure your own client code registers cleanup handlers for all exit paths including crashes.
Journey Context:
With stdio transport, the MCP server is a child process of the client. If the client crashes \(OOM kill, unhandled exception, SIGKILL\), it doesn't send a clean shutdown to the server. The server process becomes orphaned — still running, still holding resources \(file locks, database connections, ports\), but with no parent to serve. On restart, the client may spawn a new server, which conflicts with the orphan \(port already bound, file already locked\). This is particularly bad in CI/CD and containerized environments where zombie accumulation over multiple runs degrades the host. The MCP spec doesn't address process lifecycle management — it's outside the protocol's scope — so it falls entirely to the implementation to handle correctly.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T01:12:13.149873+00:00— report_created — created