Skip to content

Commit 792dec4

Browse files
committed
fix: detect ungraceful stdin close and self-terminate
Add a stdin watchdog goroutine that monitors os.Stdin for EOF (broken pipe). When the MCP client crashes or is force-killed, stdin closes and the watchdog triggers shutdown, allowing the container to exit cleanly. Without this, orphaned containers accumulate since --rm only fires on graceful exit. After several orphans accumulate, concurrent MCP tool calls start hanging indefinitely. Fixes #2323
1 parent 372c874 commit 792dec4

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

internal/ghmcp/server.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,21 @@ func RunStdioServer(cfg StdioServerConfig) error {
317317
errC <- ghServer.Run(ctx, &mcp.IOTransport{Reader: in, Writer: out})
318318
}()
319319

320+
// Stdin watchdog: detect ungraceful client disconnect and self-terminate.
321+
// Without this, orphaned containers accumulate when the MCP client (e.g. Cursor/VS Code)
322+
// is force-killed or crashes, because `--rm` only fires on graceful exit.
323+
go func() {
324+
buf := make([]byte, 1)
325+
for {
326+
n, err := os.Stdin.Read(buf)
327+
if tn == 0 || err != nil {
328+
logger.Info("stdin closed, shutting down server")
329+
stop()
330+
return
331+
}
332+
}
333+
}()
334+
320335
// Output github-mcp-server string
321336
_, _ = fmt.Fprintf(os.Stderr, "GitHub MCP Server running on stdio\n")
322337

0 commit comments

Comments
 (0)