Skip to content

Commit 8f1efa4

Browse files
committed
fix(upstream): capture stderr output before MCP initialization
Previously, stderr monitoring started only after successful MCP initialize() handshake. This caused startup errors (like missing API keys or credentials) to be invisible in logs when initialization timed out. Now stderr monitoring begins immediately after process start, before the initialize() call. This ensures all process output is captured and logged, making debugging connection failures much easier.
1 parent fe4b8f9 commit 8f1efa4

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,4 @@ data/
7979
.cursor/
8080
assets/mcpproxy.icns
8181
build-info.json
82+
.claude/

internal/upstream/core/connection.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,17 @@ func (c *Client) connectStdio(ctx context.Context) error {
358358
return fmt.Errorf("failed to start stdio client: %w", err)
359359
}
360360

361+
// CRITICAL FIX: Enable stderr monitoring IMMEDIATELY after starting the process
362+
// This ensures we capture startup errors (like missing API keys) even if
363+
// initialization fails with timeout. Previously, stderr monitoring started
364+
// after successful initialization, so early errors were never logged.
365+
c.stderr = stdioTransport.Stderr()
366+
if c.stderr != nil {
367+
c.StartStderrMonitoring()
368+
c.logger.Debug("Started early stderr monitoring to capture startup errors",
369+
zap.String("server", c.config.Name))
370+
}
371+
361372
// IMPORTANT: Perform MCP initialize() handshake for stdio transports as well,
362373
// so c.serverInfo is populated and tool discovery/search can proceed.
363374
// Use the caller's context with timeout to avoid hanging.
@@ -459,11 +470,8 @@ func (c *Client) connectStdio(ctx context.Context) error {
459470
}
460471
}
461472

462-
// Enable stderr monitoring for Docker containers
463-
c.stderr = stdioTransport.Stderr()
464-
if c.stderr != nil {
465-
c.StartStderrMonitoring()
466-
}
473+
// Note: stderr monitoring was already started earlier (right after Start())
474+
// to capture startup errors before initialization completes
467475

468476
// Start process monitoring if we have the process reference OR it's a Docker command
469477
if c.processCmd != nil {

0 commit comments

Comments
 (0)