From a337dfa7fdaa8a0258d7853d92512f9bc6943fd6 Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Tue, 7 Oct 2025 14:39:13 +0000 Subject: [PATCH 1/2] mcp: don't close stdout when shutting down the stdio transport 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 111887b4..ec39180b 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 connected using [NewInMemoryTranports], which +// returns two transports connected to each other. type InMemoryTransport struct { rwc io.ReadWriteCloser } From 47d7bdd61b3dcc38ed32371809f5a08619dac059 Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Tue, 7 Oct 2025 14:54:47 +0000 Subject: [PATCH 2/2] fix typos --- mcp/transport.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mcp/transport.go b/mcp/transport.go index ec39180b..f2f93f4b 100644 --- a/mcp/transport.go +++ b/mcp/transport.go @@ -115,8 +115,8 @@ 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 connected using [NewInMemoryTranports], which -// returns two transports connected to each other. +// InMemoryTransports should be constructed using [NewInMemoryTransports], +// which returns two transports connected to each other. type InMemoryTransport struct { rwc io.ReadWriteCloser }