From e8685b30224a20449f67bc5ec3afb98da2bd84f3 Mon Sep 17 00:00:00 2001 From: Robert Findley Date: Tue, 7 Oct 2025 11:08:38 -0400 Subject: [PATCH] mcp: don't close stdout when shutting down the stdio transport (#562) We need to close stdin when the stdio transport is shut down, to unblock its read loop. However, we don't technically need to close stdout. Fixes #548 --- mcp/transport.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/mcp/transport.go b/mcp/transport.go index 111887b..f2f93f4 100644 --- a/mcp/transport.go +++ b/mcp/transport.go @@ -90,9 +90,16 @@ type StdioTransport struct{} // Connect implements the [Transport] interface. func (*StdioTransport) Connect(context.Context) (Connection, error) { - return newIOConn(rwc{os.Stdin, os.Stdout}), nil + return newIOConn(rwc{os.Stdin, nopCloserWriter{os.Stdout}}), nil } +// nopCloserWriter is an io.WriteCloser with a trivial Close method. +type nopCloserWriter struct { + io.Writer +} + +func (nopCloserWriter) Close() error { return nil } + // An IOTransport is a [Transport] that communicates over separate // io.ReadCloser and io.WriteCloser using newline-delimited JSON. type IOTransport struct { @@ -107,6 +114,9 @@ func (t *IOTransport) Connect(context.Context) (Connection, error) { // An InMemoryTransport is a [Transport] that communicates over an in-memory // network connection, using newline-delimited JSON. +// +// InMemoryTransports should be constructed using [NewInMemoryTransports], +// which returns two transports connected to each other. type InMemoryTransport struct { rwc io.ReadWriteCloser }