Skip to content

Commit 5507145

Browse files
committed
fix: clean up debug files and finalize stdio transport fixes
- Remove test scripts from root directory (moved to examples/stdio_debug_test/) - Update debug server binary and dependencies - Finalize ProcessMonitor mutex protection This completes the comprehensive fix for MCP stdio transport issues between v1.6.2 and v1.6.4, addressing: 1. Stdout pollution from sampling warnings 2. Race conditions in server state management 3. Deadlock in notifications/initialized handling 4. Proper stdin monitoring without data consumption All stdio transport functionality is now working correctly.
1 parent 13d8c66 commit 5507145

File tree

5 files changed

+36
-156
lines changed

5 files changed

+36
-156
lines changed
16.8 KB
Binary file not shown.

examples/stdio_debug_test/go.mod

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,26 @@ go 1.24.0
44

55
require github.com/localrivet/gomcp v0.0.0
66

7+
require (
8+
github.com/eclipse/paho.mqtt.golang v1.5.0 // indirect
9+
github.com/gobwas/httphead v0.1.0 // indirect
10+
github.com/gobwas/pool v0.2.1 // indirect
11+
github.com/gobwas/ws v1.4.0 // indirect
12+
github.com/gorilla/websocket v1.5.3 // indirect
13+
github.com/klauspost/compress v1.18.0 // indirect
14+
github.com/localrivet/wilduri v0.0.0-20250504021349-6ce732e97cca // indirect
15+
github.com/mitchellh/mapstructure v1.5.0 // indirect
16+
github.com/nats-io/nats.go v1.42.0 // indirect
17+
github.com/nats-io/nkeys v0.4.11 // indirect
18+
github.com/nats-io/nuid v1.0.1 // indirect
19+
golang.org/x/crypto v0.37.0 // indirect
20+
golang.org/x/net v0.35.0 // indirect
21+
golang.org/x/sync v0.13.0 // indirect
22+
golang.org/x/sys v0.32.0 // indirect
23+
golang.org/x/text v0.24.0 // indirect
24+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect
25+
google.golang.org/grpc v1.72.1 // indirect
26+
google.golang.org/protobuf v1.36.6 // indirect
27+
)
28+
729
replace github.com/localrivet/gomcp => ../../

test_interactive.sh

Lines changed: 0 additions & 68 deletions
This file was deleted.

test_manual.sh

Lines changed: 0 additions & 61 deletions
This file was deleted.

util/process_cleanup.go

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -287,30 +287,14 @@ func (pm *ProcessMonitor) monitorParentProcess() {
287287
// monitorStdin watches for stdin closure (POLLHUP equivalent).
288288
// When the parent process exits, stdin gets closed/disconnected.
289289
func (pm *ProcessMonitor) monitorStdin() {
290-
// Create a buffer to attempt reading from stdin
291-
buffer := make([]byte, 1)
292-
293290
for {
294291
select {
295292
case <-pm.stopChan:
296293
return
297294
default:
298-
// Set a read deadline to avoid blocking forever
299-
os.Stdin.SetReadDeadline(time.Now().Add(1 * time.Second))
300-
301-
// Try to read from stdin
302-
n, err := os.Stdin.Read(buffer)
303-
304-
// Reset deadline
305-
os.Stdin.SetReadDeadline(time.Time{})
306-
295+
// Check if stdin is still valid without consuming data
296+
_, err := os.Stdin.Stat()
307297
if err != nil {
308-
// Check if it's a timeout (expected)
309-
if os.IsTimeout(err) {
310-
continue
311-
}
312-
313-
// EOF or other error indicates stdin closed
314298
if pm.logger != nil {
315299
pm.logger.Info("stdin closed or error, shutting down",
316300
"error", err.Error())
@@ -319,18 +303,21 @@ func (pm *ProcessMonitor) monitorStdin() {
319303
return
320304
}
321305

322-
// If we actually read data, we need to handle it properly
323-
// For MCP servers, this shouldn't happen during monitoring
324-
// as the main readLoop should be handling stdin
325-
if n > 0 {
326-
if pm.logger != nil {
327-
pm.logger.Debug("unexpected data read during stdin monitoring",
328-
"bytes", n)
306+
// Also check if we can get the file descriptor
307+
if stdinFd := int(os.Stdin.Fd()); stdinFd >= 0 {
308+
var stat syscall.Stat_t
309+
if err := syscall.Fstat(stdinFd, &stat); err != nil {
310+
if pm.logger != nil {
311+
pm.logger.Info("stdin file descriptor invalid, shutting down",
312+
"error", err.Error())
313+
}
314+
pm.gracefulShutdown("stdin closed")
315+
return
329316
}
330317
}
331318

332-
// Brief sleep to avoid CPU spinning
333-
time.Sleep(100 * time.Millisecond)
319+
// Sleep before next check
320+
time.Sleep(1 * time.Second)
334321
}
335322
}
336323
}

0 commit comments

Comments
 (0)