Skip to content

fix(mcp): reap MCP child processes on process exit - #2059

Open
YOMXXX wants to merge 2 commits into
XiaomiMiMo:mainfrom
YOMXXX:fix/mcp-child-reap
Open

fix(mcp): reap MCP child processes on process exit#2059
YOMXXX wants to merge 2 commits into
XiaomiMiMo:mainfrom
YOMXXX:fix/mcp-child-reap

Conversation

@YOMXXX

@YOMXXX YOMXXX commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #1892. MCP child processes were orphaned when MiMoCode exited/restarted (reparented to PID 1, ~2 procs/~81MB leaked per restart; 22 shell+MCP pairs = 1.7GB observed).

Root cause: packages/opencode/src/mcp/index.ts already kills MCP server children + descendants in an addFinalizer (on Effect teardown). But the app's exit path does NOT dispose the instance — the TUI's onExit doesn't call instance.dispose(), and crash/SIGTERM never runs Effect teardown. So MCP children survived the process.

Fix: a module-level mcpChildPids registry + process-level exit handlers:

  • Populated with transport.pid on each local MCP connect (success path only).
  • Pruned in closeClient (disconnect/reconnect) so the exit handler can never SIGTERM a recycled PID.
  • process.on("exit") + SIGTERM run reapMcpChildren() — a synchronous recursive pgrep -P kill of each tracked PID and its descendants (the graceful finalizer stays for Effect teardown).
  • SIGINT deliberately NOT hooked so TUI Ctrl+C still uses graceful teardown.

Test Plan

  • Real-process test: reapMcpChildren terminates a registered process; a two-level tree test covers a non-leaf PID; finally cleanup prevents leaked sleep processes.
  • bun test test/mcp/reap.test.ts — 3 pass (10× stable); bun typecheck clean; MCP suite 115 pass no regression.

Notes

  • Best-effort POSIX fix (uses pgrep); no-op/degraded on Windows.
  • The SIGTERM handler deliberately exit(0) after reaping (masks the signal's non-zero code for supervisors); documented in code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP child processes orphaned on restart — memory leak

1 participant