From 792dec4d12f7b81a2b941a134605e7db1240c332 Mon Sep 17 00:00:00 2001 From: D2758695161 <13510221939@163.com> Date: Tue, 14 Apr 2026 18:15:36 +0800 Subject: [PATCH] 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 --- internal/ghmcp/server.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/internal/ghmcp/server.go b/internal/ghmcp/server.go index 5dfaf596c..2923e2be5 100644 --- a/internal/ghmcp/server.go +++ b/internal/ghmcp/server.go @@ -317,6 +317,21 @@ func RunStdioServer(cfg StdioServerConfig) error { errC <- ghServer.Run(ctx, &mcp.IOTransport{Reader: in, Writer: out}) }() + // Stdin watchdog: detect ungraceful client disconnect and self-terminate. + // Without this, orphaned containers accumulate when the MCP client (e.g. Cursor/VS Code) + // is force-killed or crashes, because `--rm` only fires on graceful exit. + go func() { + buf := make([]byte, 1) + for { + n, err := os.Stdin.Read(buf) + if tn == 0 || err != nil { + logger.Info("stdin closed, shutting down server") + stop() + return + } + } + }() + // Output github-mcp-server string _, _ = fmt.Fprintf(os.Stderr, "GitHub MCP Server running on stdio\n")