diff --git a/docs/client.md b/docs/client.md index 8fc75441..6ce20c90 100644 --- a/docs/client.md +++ b/docs/client.md @@ -53,9 +53,11 @@ func Example_roots() { // Connect the server and client... t1, t2 := mcp.NewInMemoryTransports() - if _, err := s.Connect(ctx, t1, nil); err != nil { + serverSession, err := s.Connect(ctx, t1, nil) + if err != nil { log.Fatal(err) } + defer serverSession.Close() clientSession, err := c.Connect(ctx, t2, nil) if err != nil { diff --git a/docs/protocol.md b/docs/protocol.md index 3a031af9..6d22c4b5 100644 --- a/docs/protocol.md +++ b/docs/protocol.md @@ -148,6 +148,7 @@ To create a streamable MCP server, you create a `StreamableHTTPHandler` and pass it an `mcp.Server`: ```go +// TODO: Until we have a way to clean up abandoned sessions, this test will leak goroutines (see #499) func ExampleStreamableHTTPHandler() { // Create a new streamable handler, using the same MCP server for every request. // @@ -185,6 +186,19 @@ client, err := mcp.Connect(ctx, transport, &mcp.ClientOptions{...}) The `StreamableClientTransport` handles the HTTP requests and communicates with the server using the streamable transport protocol. +#### Resumability and Redelivery + +By default, the streamable server does not support [resumability or +redelivery](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#resumability-and-redelivery) +of messages, because doing so requires either a persistent storage solution or +unbounded memory usage (see also +[#580](https://github.com/modelcontextprotocol/go-sdk/issues/580)). + +To enable resumability, set `StreamableHTTPOptions.EventStore` to a non-nil +value. The SDK provides a `MemoryEventStore` for testing or simple use cases; +for production use it is generally advisable to use a more sophisticated +implementation. + #### Stateless Mode The streamable server supports a _stateless mode_ by setting diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 38410ad5..c22a279d 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -33,7 +33,7 @@ func ExampleLoggingTransport() { if err != nil { log.Fatal(err) } - defer serverSession.Wait() + defer serverSession.Close() client := mcp.NewClient(&mcp.Implementation{Name: "client", Version: "v0.0.1"}, nil) var b bytes.Buffer @@ -71,7 +71,7 @@ func ExampleStreamableHTTPHandler_middleware() { server := mcp.NewServer(&mcp.Implementation{Name: "server", Version: "v0.1.0"}, nil) handler := mcp.NewStreamableHTTPHandler(func(r *http.Request) *mcp.Server { return server - }, nil) + }, &mcp.StreamableHTTPOptions{Stateless: true}) loggingHandler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { // Example debugging; you could also capture the response. body, err := io.ReadAll(req.Body) diff --git a/internal/docs/protocol.src.md b/internal/docs/protocol.src.md index e85374a8..b0874ccf 100644 --- a/internal/docs/protocol.src.md +++ b/internal/docs/protocol.src.md @@ -112,6 +112,19 @@ client, err := mcp.Connect(ctx, transport, &mcp.ClientOptions{...}) The `StreamableClientTransport` handles the HTTP requests and communicates with the server using the streamable transport protocol. +#### Resumability and Redelivery + +By default, the streamable server does not support [resumability or +redelivery](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#resumability-and-redelivery) +of messages, because doing so requires either a persistent storage solution or +unbounded memory usage (see also +[#580](https://github.com/modelcontextprotocol/go-sdk/issues/580)). + +To enable resumability, set `StreamableHTTPOptions.EventStore` to a non-nil +value. The SDK provides a `MemoryEventStore` for testing or simple use cases; +for production use it is generally advisable to use a more sophisticated +implementation. + #### Stateless Mode The streamable server supports a _stateless mode_ by setting