Skip to content

fix(mcp): exit serve process on stdin-close/SIGTERM#692

Closed
joshsteinvc wants to merge 1 commit intogarrytan:masterfrom
joshsteinvc:fix/mcp-stdin-close-shutdown
Closed

fix(mcp): exit serve process on stdin-close/SIGTERM#692
joshsteinvc wants to merge 1 commit intogarrytan:masterfrom
joshsteinvc:fix/mcp-stdin-close-shutdown

Conversation

@joshsteinvc
Copy link
Copy Markdown
Contributor

@joshsteinvc joshsteinvc commented May 6, 2026

Summary

The MCP stdio server in src/mcp/server.ts doesn't exit when its client disconnects. The bun process keeps running, holding open the PGLite data directory.

Symptom that surfaced this

Over days of normal use, 20+ orphaned gbrain serve processes accumulated. Because PGLite is single-writer, they contended for the write lock. Email sync hit its 15s per-put timeout on every page: 114 puts × 15s = 28.5min runs that wrote 0 emails. This was the root cause behind a "no gbrain run in 50h" alert in my setup.

Fix

After server.connect(transport), listen for the standard MCP stdio shutdown signals:

  • process.stdin end and close (client disconnect → EOF on stdin)
  • transport.onclose (MCP SDK's own signal)
  • SIGTERM / SIGINT / SIGHUP (orchestrator shutdown)

Each path calls engine.disconnect?.() and process.exit(0). A shuttingDown flag prevents double-execution if multiple signals fire.

Test plan

  • Reproduced original behavior: gbrain serve left running after Claude Code disconnected; orphans stacked up across days
  • With fix: stdin EOF → [gbrain-serve] shutdown: stdin end\n on stderr → process exits cleanly
  • Verified engine.disconnect() is awaited before exit so PGLite lock releases
  • No change to dispatch path or tool call behavior

Files

  • src/mcp/server.ts — +20 lines, no removals

🤖 Generated with Claude Code


View in Codesmith
Need help on this PR? Tag @codesmith with what you need.

  • Let Codesmith autofix CI failures and bot reviews

MCP stdio server was keeping the bun process alive indefinitely after
the client disconnected. Over days this accumulated 20+ orphaned
gbrain serve processes, all holding the PGLite directory open.
Since PGLite is single-writer, this caused write-lock contention that
made email-sync fail its 15s per-put timeout: 114 puts x 15s = 28.5min
runs with 0 emails written.

Now listens for stdin end/close, transport close, and SIGTERM/SIGINT/
SIGHUP; calls engine.disconnect() and exits cleanly.

Root cause for the no-gbrain-run-in-50h alert.
@garrytan
Copy link
Copy Markdown
Owner

Closing — your fix landed in master via the v0.30.3 fix-wave PR #776 (merged at ff53a4c9): "MCP serve exits on stdin-close / SIGTERM".

Thank you for the contribution — credit is preserved in the v0.30.3 CHANGELOG entry. 🙏

@garrytan garrytan closed this May 10, 2026
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.

2 participants