From a817f6141278c4bc2078d44c34e2f5c774c7e204 Mon Sep 17 00:00:00 2001 From: Guglielmo Colombo Date: Wed, 24 Jun 2026 14:08:43 +0200 Subject: [PATCH] mcp: add Cacheable fields to DiscoverResult (#1022) This PR add the Cacheable fields to the DiscoverResult, as it was added later (https://github.com/modelcontextprotocol/modelcontextprotocol/commit/8e4c2322cafa0924183c587f55401d9d93a23feb) --- docs/protocol.md | 18 ++++++------------ docs/server.md | 2 +- docs/troubleshooting.md | 5 ++--- mcp/protocol.go | 1 + mcp/server.go | 6 ++++-- mcp/testdata/conformance/server/discover.txtar | 2 ++ mcp/transport_example_test.go | 2 +- 7 files changed, 17 insertions(+), 19 deletions(-) diff --git a/docs/protocol.md b/docs/protocol.md index 5f043f2..408442e 100644 --- a/docs/protocol.md +++ b/docs/protocol.md @@ -77,19 +77,13 @@ it is the client's responsibility to end the session. func Example_lifecycle() { ctx := context.Background() - // Create a client and server. - // Wait for the client to initialize the session. + // Create a client and server. Under protocol version 2026-07-28, there + // is no dedicated initialize/initialized handshake: the session is + // implicitly live the moment the client issues its first request. client := mcp.NewClient(&mcp.Implementation{Name: "client", Version: "v0.0.1"}, nil) - server := mcp.NewServer(&mcp.Implementation{Name: "server", Version: "v0.0.1"}, &mcp.ServerOptions{ - InitializedHandler: func(context.Context, *mcp.InitializedRequest) { - fmt.Println("initialized!") - }, - }) + server := mcp.NewServer(&mcp.Implementation{Name: "server", Version: "v0.0.1"}, nil) // Connect the server and client using in-memory transports. - // - // Connect the server first so that it's ready to receive initialization - // messages from the client. t1, t2 := mcp.NewInMemoryTransports() serverSession, err := server.Connect(ctx, t1, nil) if err != nil { @@ -108,7 +102,7 @@ func Example_lifecycle() { if err := serverSession.Wait(); err != nil { log.Fatal(err) } - // Output: initialized! + // Output: } ``` @@ -213,7 +207,7 @@ func ExampleStreamableHTTPHandler() { defer httpServer.Close() // The SDK is currently permissive of some missing keys in "params". - resp := mustPostMessage(`{"jsonrpc": "2.0", "id": 1, "method":"initialize", "params": {}}`, httpServer.URL) + resp := mustPostMessage(`{"jsonrpc": "2.0", "id": 1, "method":"initialize", "params": {"protocolVersion":"2025-11-25"}}`, httpServer.URL) fmt.Println(resp) // Output: // {"jsonrpc":"2.0","id":1,"result":{"capabilities":{"logging":{}},"protocolVersion":"2025-11-25","serverInfo":{"name":"server","version":"v0.1.0"}}} diff --git a/docs/server.md b/docs/server.md index e7ee307..cddb14a 100644 --- a/docs/server.md +++ b/docs/server.md @@ -531,7 +531,7 @@ func Example_mrtr() { // uses it to fulfil any input request the tool handler returns. c := mcp.NewClient(&mcp.Implementation{Name: "client", Version: "v0.0.1"}, &mcp.ClientOptions{ ElicitationHandler: func(_ context.Context, _ *mcp.ElicitRequest) (*mcp.ElicitResult, error) { - return &mcp.ElicitResult{Action: "accept", Content: map[string]any{"name": "Ada"}}, nil + return &mcp.ElicitResult{Action: "accept", Content: map[string]any{"name": "MCP Go"}}, nil }, }) diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 1a0c367..0e792a3 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -50,9 +50,8 @@ func ExampleLoggingTransport() { } // Output: - // read: {"jsonrpc":"2.0","id":1,"result":{"capabilities":{"logging":{}},"protocolVersion":"2025-11-25","serverInfo":{"name":"server","version":"v0.0.1"}}} - // write: {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"clientInfo":{"name":"client","version":"v0.0.1"},"protocolVersion":"2025-11-25","capabilities":{"roots":{"listChanged":true}}}} - // write: {"jsonrpc":"2.0","method":"notifications/initialized","params":{}} + // read: {"jsonrpc":"2.0","id":1,"result":{"ttlMs":0,"cacheScope":"public","supportedVersions":["2026-07-28","2025-11-25","2025-06-18","2025-03-26","2024-11-05"],"capabilities":{"logging":{}},"serverInfo":{"name":"server","version":"v0.0.1"}}} + // write: {"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/clientCapabilities":{"roots":{"listChanged":true}},"io.modelcontextprotocol/clientInfo":{"name":"client","version":"v0.0.1"},"io.modelcontextprotocol/protocolVersion":"2026-07-28"}}} } ``` diff --git a/mcp/protocol.go b/mcp/protocol.go index f3c2efc..f077c6d 100644 --- a/mcp/protocol.go +++ b/mcp/protocol.go @@ -1129,6 +1129,7 @@ func (x *DiscoverParams) SetProgressToken(t any) { setProgressToken(x, t) } type DiscoverResult struct { Meta `json:"_meta,omitempty"` + Cacheable // The versions of the Model Context Protocol that the server supports. SupportedVersions []string `json:"supportedVersions"` // The server's capabilities. diff --git a/mcp/server.go b/mcp/server.go index 4cc9ae4..e07d3c2 100644 --- a/mcp/server.go +++ b/mcp/server.go @@ -869,12 +869,14 @@ func (s *Server) discover(_ context.Context, req *ServerRequest[*DiscoverParams] ClientInfo: req.ClientInfo(), } }) - return &DiscoverResult{ + res := &DiscoverResult{ SupportedVersions: versions, Capabilities: s.capabilities(), ServerInfo: s.impl, Instructions: s.opts.Instructions, - }, nil + } + res.setDefaultCacheableValues() + return res, nil } // filterSupportedVersions returns the subset of [supportedProtocolVersions] diff --git a/mcp/testdata/conformance/server/discover.txtar b/mcp/testdata/conformance/server/discover.txtar index a2fbde7..9b8276c 100644 --- a/mcp/testdata/conformance/server/discover.txtar +++ b/mcp/testdata/conformance/server/discover.txtar @@ -21,6 +21,8 @@ supports, its capabilities, and its identity. "jsonrpc": "2.0", "id": 1, "result": { + "ttlMs": 0, + "cacheScope": "public", "supportedVersions": [ "2026-07-28", "2025-11-25", diff --git a/mcp/transport_example_test.go b/mcp/transport_example_test.go index 2a9d745..1920233 100644 --- a/mcp/transport_example_test.go +++ b/mcp/transport_example_test.go @@ -42,7 +42,7 @@ func ExampleLoggingTransport() { } // Output: - // read: {"jsonrpc":"2.0","id":1,"result":{"supportedVersions":["2026-07-28","2025-11-25","2025-06-18","2025-03-26","2024-11-05"],"capabilities":{"logging":{}},"serverInfo":{"name":"server","version":"v0.0.1"}}} + // read: {"jsonrpc":"2.0","id":1,"result":{"ttlMs":0,"cacheScope":"public","supportedVersions":["2026-07-28","2025-11-25","2025-06-18","2025-03-26","2024-11-05"],"capabilities":{"logging":{}},"serverInfo":{"name":"server","version":"v0.0.1"}}} // write: {"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/clientCapabilities":{"roots":{"listChanged":true}},"io.modelcontextprotocol/clientInfo":{"name":"client","version":"v0.0.1"},"io.modelcontextprotocol/protocolVersion":"2026-07-28"}}} }