Part of #5743. Split out of #6002 (item 7) so that issue can close — neither of these is fixable in this repo.
Both were surfaced by tracing why pkg/mcp/parser_integration_test.go changed behaviour under the go-sdk v1.7 bump (#5993). Both are worth reporting to toolhive-core, and possibly modelcontextprotocol/go-sdk.
(a) server/discover is sent over the deprecated HTTP+SSE message channel
MCP 2026-07-28 defines exactly two transport bindings — stdio and Streamable HTTP. mcpcompat's SSE server uses go-sdk's NewSSEHandler, whose transport implements no ProtocolVersionSupporter gate (only streamable.go does), so filterSupportedVersions advertises 2026-07-28 and the Modern-first client negotiates Modern over a 2024-11-05 transport. The Modern revision constrains the Streamable HTTP binding, not whatever an SDK pushes through a legacy channel — so this is non-conformant client/server behaviour, not spec.
Worth knowing: this produces an apparent contradiction inside ToolHive that is not a bug. parser_integration_test.go observes Modern negotiation over an sse-labelled endpoint, while probeRevision asserts that can never happen. Both are correct, because they are different layers: mcpcompat's SSE client reaches /messages, whereas vMCP's modernCall only ever POSTs to BaseURL, which is the /sse path. Anyone reconciling those two facts should read this issue first.
(b) mcpcompat/client.Initialize silently ignores the caller's requested ProtocolVersion
It calls Connect(ctx, tr, nil) with nil ClientSessionOptions, so the negotiated version is always latestProtocolVersion; only ClientInfo and Capabilities carry over from the caller's InitializeRequest. A caller explicitly asking for 2024-11-05 gets 2026-07-28 requested on the wire, with no error and no warning.
parser_integration_test.go does exactly this, which is why that test's behaviour changed on the v1.7 bump.
Work
- File both against
toolhive-core; escalate (a) to modelcontextprotocol/go-sdk if the gate belongs in the SDK's SSE transport rather than the shim.
- Link back here so the in-repo contradiction in (a) stays explained.
Generated with Claude Code
Part of #5743. Split out of #6002 (item 7) so that issue can close — neither of these is fixable in this repo.
Both were surfaced by tracing why
pkg/mcp/parser_integration_test.gochanged behaviour under the go-sdk v1.7 bump (#5993). Both are worth reporting totoolhive-core, and possiblymodelcontextprotocol/go-sdk.(a)
server/discoveris sent over the deprecated HTTP+SSE message channelMCP 2026-07-28 defines exactly two transport bindings — stdio and Streamable HTTP.
mcpcompat's SSE server uses go-sdk'sNewSSEHandler, whose transport implements noProtocolVersionSupportergate (onlystreamable.godoes), sofilterSupportedVersionsadvertises2026-07-28and the Modern-first client negotiates Modern over a 2024-11-05 transport. The Modern revision constrains the Streamable HTTP binding, not whatever an SDK pushes through a legacy channel — so this is non-conformant client/server behaviour, not spec.Worth knowing: this produces an apparent contradiction inside ToolHive that is not a bug.
parser_integration_test.goobserves Modern negotiation over ansse-labelled endpoint, whileprobeRevisionasserts that can never happen. Both are correct, because they are different layers:mcpcompat's SSE client reaches/messages, whereas vMCP'smodernCallonly ever POSTs toBaseURL, which is the/ssepath. Anyone reconciling those two facts should read this issue first.(b)
mcpcompat/client.Initializesilently ignores the caller's requestedProtocolVersionIt calls
Connect(ctx, tr, nil)with nilClientSessionOptions, so the negotiated version is alwayslatestProtocolVersion; onlyClientInfoandCapabilitiescarry over from the caller'sInitializeRequest. A caller explicitly asking for2024-11-05gets2026-07-28requested on the wire, with no error and no warning.parser_integration_test.godoes exactly this, which is why that test's behaviour changed on the v1.7 bump.Work
toolhive-core; escalate (a) tomodelcontextprotocol/go-sdkif the gate belongs in the SDK's SSE transport rather than the shim.Generated with Claude Code