Support 2026-07-28 as the Latest Protocol Version

## Motivation and Context

Clients that require MCP 2026-07-28, such as ChatGPT, reject connections because the SDK
does not advertise that version: `Server#init` answers a 2026-07-28 request with 2025-11-25,
the Streamable HTTP transport 400s an `MCP-Protocol-Version: 2026-07-28` header,
and `server/discover` omits the version from `supportedVersions`.

Making 2026-07-28 the latest entry in `SUPPORTED_STABLE_PROTOCOL_VERSIONS` fixes all three at once,
since they all read that list. The version now serves both lifecycles of the SEP-2575 dual-era model:
negotiable through the legacy `initialize` handshake, and simultaneously the version of
the per-request modern lifecycle.

Parts of the 2026-07-28 feature set remain unimplemented, such as the stateless modern lifecycle
over the transports, and are being built separately. This change deliberately limits itself to
the version bump, focusing first on eliminating the connection errors that 2026-07-28 clients hit.

Known follow-up: the in-progress modern HTTP path routes requests to the sessionless modern lifecycle
when the header version is absent from `SUPPORTED_STABLE_PROTOCOL_VERSIONS`, so that routing predicate
needs rework on top of this change.

Closes #474

## How Has This Been Tested?

New regression tests: `initialize` with `protocolVersion: "2026-07-28"` echoes it back (`server_test.rb`),
a follow-up POST with `MCP-Protocol-Version: 2026-07-28` passes header validation
(`streamable_http_transport_test.rb`), and `Configuration.new(protocol_version: "2026-07-28")` is accepted
(`configuration_test.rb`).

`bundle exec rake test` passes (1454 runs, 0 failures). The conformance server suite passes 30/30.
The client `initialize` scenario is added to the expected-failures baseline: the conformance framework pins
the client's requested version to 2025-11-25 and does not accept 2026-07-28 yet; the entry carries a TODO
to remove it when the framework catches up.

## Breaking Changes

Servers that do not pin `configuration.protocol_version` now answer version negotiation fallbacks
and default client requests with 2026-07-28 instead of 2025-11-25. 2025-11-25 remains fully supported
and negotiable; clients that request it are unaffected.
This commit is contained in:
Koichi ITO 2026-07-31 12:27:58 +09:00
commit dc25610162

View file

@ -22,7 +22,7 @@ Call `MCP::Client#connect` to perform the MCP [initialization handshake](https:/
```ruby
client.connect
# => { "protocolVersion" => "2025-11-25", "capabilities" => {...}, "serverInfo" => {...} }
# => { "protocolVersion" => "2026-07-28", "capabilities" => {...}, "serverInfo" => {...} }
client.connected? # => true
client.server_info # => cached InitializeResult
@ -99,7 +99,7 @@ After `connect` succeeds, the HTTP transport captures the `Mcp-Session-Id` heade
```ruby
http_transport.session_id # => "abc123..."
http_transport.protocol_version # => "2025-11-25"
http_transport.protocol_version # => "2026-07-28"
```
If the server terminates the session, subsequent requests return HTTP 404 and the transport raises `MCP::Client::SessionExpiredError` (a subclass of `RequestHandlerError`). Session state is cleared automatically; callers should start a new session by calling `connect` again.