Skip to content

Commit d250b38

Browse files
soniricoMarcos
and
Marcos
authored
fix(server): resolve stdio server context cancellation bug (#331)
* fix(server): resolve stdio server context cancellation bug Fix a critical bug in the stdio server's readNextLine function that was causing "Error reading input" and "context cancelled" errors when Claude Desktop attempted to connect to MCP servers. The issue was in the select-default pattern that would immediately bypass context cancellation checks and proceed with blocking ReadString operations even when the context was cancelled. This prevented proper cleanup and caused connection failures. Changes: - Remove problematic select-default pattern in readNextLine goroutine - Simplify the read logic to directly call reader.ReadString('\n') - Maintain proper done channel handling for result communication - Ensure context cancellation is respected throughout the read operation This resolves connection issues introduced in version 0.30.0 where the stdio transport became unreliable for client connections. Fixes: stdio server connection failures with Claude Desktop * refactor: remove redudant signaling channels --------- Co-authored-by: Marcos <[email protected]>
1 parent d5847c0 commit d250b38

File tree

1 file changed

+11
-27
lines changed

1 file changed

+11
-27
lines changed

server/stdio.go

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -189,39 +189,23 @@ func (s *StdioServer) processInputStream(ctx context.Context, reader *bufio.Read
189189
// returns an empty string and the context's error. EOF is returned when the input
190190
// stream is closed.
191191
func (s *StdioServer) readNextLine(ctx context.Context, reader *bufio.Reader) (string, error) {
192-
readChan := make(chan string, 1)
193-
errChan := make(chan error, 1)
194-
done := make(chan struct{})
195-
defer close(done)
192+
type result struct {
193+
line string
194+
err error
195+
}
196+
197+
resultCh := make(chan result, 1)
196198

197199
go func() {
198-
select {
199-
case <-done:
200-
return
201-
default:
202-
line, err := reader.ReadString('\n')
203-
if err != nil {
204-
select {
205-
case errChan <- err:
206-
case <-done:
207-
}
208-
return
209-
}
210-
select {
211-
case readChan <- line:
212-
case <-done:
213-
}
214-
return
215-
}
200+
line, err := reader.ReadString('\n')
201+
resultCh <- result{line: line, err: err}
216202
}()
217203

218204
select {
219205
case <-ctx.Done():
220-
return "", ctx.Err()
221-
case err := <-errChan:
222-
return "", err
223-
case line := <-readChan:
224-
return line, nil
206+
return "", nil
207+
case res := <-resultCh:
208+
return res.line, res.err
225209
}
226210
}
227211

0 commit comments

Comments
 (0)