Skip to content

A server connection using stdio transport cannot be closed gracefully #107

@chriscasola

Description

@chriscasola

Describe the bug
When calling Connect on a server using mcp.NewStdioTransport and then subsequently calling Close() on the server session, the Close() call never returns.

To Reproduce

Run this mainprog:

func main() {
	server := mcp.NewServer("test-server", "1.0.0", nil)

	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	serverSession, err := server.Connect(ctx, mcp.NewStdioTransport())
	if err != nil {
		panic(err)
	}
	fmt.Println("started")

	<-ctx.Done()
	fmt.Println("stopping")
	if err := serverSession.Close(); err != nil {
		panic(err)
	}

	fmt.Println("stopped")
}

After observing the "started" message, stop the program with CTRL-C.

The "stopping" message will be logged, but "stopped" is not logged and the program does not exit.

Expected behavior
The program should exit.

Logs
NA

Additional context
I think this is happening because jsonrpc2.Connection expects the reader.Read to return here after Close() is called but it does not. See this comment.

I think this is because the reader is a json.Decoder which will not return when the underlying reader is closed.

If this explanation makes sense, I can work on a fix, just let me know.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions