mcp: Implement support for SEP-2575 on client side (#975)
Implements the client half of the SEP-2575 / `2026-06-30` protocol. This CL is client-only; server-side `server/discover` is still a `MethodNotFound` stub. ### Changes - **`server/discover` probe in `Client.Connect()`** (`client.go`). When the caller opts into `protocolVersion >= 2026-06-30`, the client probes the server with `server/discover` before falling back to the legacy `initialize` handshake. - **Per-request `_meta` injection** (`shared.go`, `injectRequestMeta`). For`>= 2026-06-30` sessions every outgoing request gets the SEP-2575 triple (`protocolVersion`, `clientInfo`, `clientCapabilities`). - **Server-side fix**: `ServerSession.handle` no longer pre-populates `state.InitializeParams` from a `server/discover` request's `_meta`, so a subsequent fallback `initialize` is not rejected as a duplicate. ### Fallback rules Client falls back to the legacy `initialize` handshake when discover returns: - `MethodNotFound` (-32601), - `UnsupportedProtocolVersionError` (-32004), - an HTTP `Bad Request` (substring-matched on the error message, to interop with pre-2026-06-30 servers). Fixes #966
This commit is contained in:
parent
d54751a8ee
commit
c60a318d22
2 changed files with 1010 additions and 96 deletions
|
|
@ -720,7 +720,7 @@ func (c *Connection) write(ctx context.Context, msg Message) error {
|
|||
|
||||
// For cancelled or rejected requests, we don't set the writeErr (which would
|
||||
// break the connection). They can just be returned to the caller.
|
||||
if err != nil && ctx.Err() == nil && !errors.Is(err, ErrRejected) {
|
||||
if err != nil && ctx.Err() == nil && !errors.Is(err, ErrRejected) && !errors.Is(err, ErrUnsupportedProtocolVersion) && !errors.Is(err, ErrMethodNotFound) {
|
||||
// The call to Write failed, and since ctx.Err() is nil we can't attribute
|
||||
// the failure (even indirectly) to Context cancellation. The writer appears
|
||||
// to be broken, and future writes are likely to also fail.
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ var (
|
|||
// ErrUnknown should be used for all non coded errors.
|
||||
ErrUnknown = NewError(-32001, "unknown error")
|
||||
// ErrServerClosing is returned for calls that arrive while the server is closing.
|
||||
ErrServerClosing = NewError(-32004, "server is closing")
|
||||
ErrServerClosing = NewError(-32006, "server is closing")
|
||||
// ErrClientClosing is a dummy error returned for calls initiated while the client is closing.
|
||||
ErrClientClosing = NewError(-32003, "client is closing")
|
||||
|
||||
|
|
@ -45,6 +45,8 @@ var (
|
|||
// should be returned to the caller to indicate that the specific request is
|
||||
// invalid in the current context.
|
||||
ErrRejected = NewError(-32005, "rejected by transport")
|
||||
// ErrUnsupportedProtocolVersion is returned when a server does not support the protocol version.
|
||||
ErrUnsupportedProtocolVersion = NewError(-32004, "unsupported protocol version")
|
||||
)
|
||||
|
||||
const wireVersion = "2.0"
|
||||
|
|
|
|||
Loading…
Reference in a new issue