Repository navigation
proposal: mcp: add ClientSession.Discover to send server/discover on demand #1424
Copy link
Copy link
Closed
Closed
Copy link
Description
Is your feature request related to a problem? Please describe.
In 2026-07-28 ping is removed, and server/discover is the spec's lightweight way to learn a server's identity, capabilities, supported versions and cache hints (ttlMs/cacheScope). Servers MUST implement it, and clients MAY call it at any time. go-sdk sends it only inside Client.Connect, and there's no public way to send it afterwards:
ClientSessionhas noDiscovermethod. The result is folded intoInitializeResult(), and theDiscoverResultcache fields are dropped.mcp.AddSendingCustomMethodrefuses the method:
package main
import (
"fmt"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
type discoverParams struct{ mcp.ParamsBase }
type discoverResult struct {
mcp.ResultBase
SupportedVersions []string `json:"supportedVersions"`
}
func main() {
c := mcp.NewClient(&mcp.Implementation{Name: "repro", Version: "0.0.1"}, nil)
err := mcp.AddSendingCustomMethod[*discoverParams, *discoverResult](c, "server/discover")
fmt.Println("AddSendingCustomMethod(server/discover):", err)
}Output (v1.8.0 and main @ 3ebc6d1):
AddSendingCustomMethod(server/discover): mcp: AddSendingCustomMethod: "server/discover" shadows a standard MCP method
Concrete uses we have:
- Health and liveness on a modern session.
Pingis gone on 2026-07-28 sessions (and after mcp: fail Ping fast on 2026-07-28 sessions #1378 it fails fast there).ListToolsisn't a substitute, because the SDK answers it from its ownttlMscache without contacting the server. Today we open a second transport connection and write raw JSON-RPC, which for stdio means spawning a second server process. - Refreshing server metadata (capabilities, instructions,
serverInfo) after theDiscoverResultttlMsexpires, without reconnecting. - Diagnostics, such as "which versions does this server support?", in an
integration test-style command.
Describe the solution you'd like
// Discover sends a server/discover request on the session's transport and
// returns the server's result, including Cacheable fields. It is valid on
// sessions negotiated at 2026-07-28 or later.
func (cs *ClientSession) Discover(ctx context.Context, params *DiscoverParams) (*DiscoverResult, error)- It uses the session's negotiated version and
_metatriple, like other requests. - On a legacy (≤ 2025-11-25) session it returns an error without sending anything, the way
Pingis handled on modern sessions in mcp: fail Ping fast on 2026-07-28 sessions #1378. - It returns
*DiscoverResultunchanged, so callers seeSupportedVersions,Capabilities,Instructions,TTLMs/CacheScopeandserverInfoin_meta. - Optionally,
Client.Connectcould use the same internal path, so behavior stays identical.
Describe alternatives you've considered
- Allow
AddSendingCustomMethodforserver/discoveronly. It's untyped and contradicts the "standard method" guard, so it's worse than a typed method. - Keep using a second raw connection. That works, but costs a process spawn per probe on stdio and duplicates
_metaconstruction outside the SDK.
Additional context
- MCP 2026-07-28
server/discover: https://modelcontextprotocol.io/specification/2026-07-28/server/discover ("Callingserver/discoveris optional for clients… useful… for presenting server information") - MCP 2026-07-28 Versioning ("Servers MUST implement
server/discover. Clients MAY call it…"): https://modelcontextprotocol.io/specification/2026-07-28/basic/versioning#protocol-version-negotiation - Environment: go-sdk v1.8.0 and
main@ 3ebc6d1;go version go1.27.2 linux/amd64.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
mcp: export cs.Discover for server/discover (modelcontextprotocol#1428)