mcp: gate prime and close events on protocol version 2025-11-25 (#696)

The prime and close SSE events (SEP-1699) were added in protocol version
2025-11-25. Only send these events when the client negotiates that
version or later.

- In servePOST, extract protocol version from InitializeParams for
initialize requests, otherwise use the Mcp-Protocol-Version header
- In serveGET/acquireStream, read protocol version from header
- Only set closeLocked callback when prime/close is supported
- Add unexported protocolVersion field to ClientSessionOptions for
testing

Fixes #686
This commit is contained in:
Robert Findley 2025-12-08 15:24:41 -05:00 • committed by GitHub
commit 87c81260e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -120,7 +120,11 @@ func (e unsupportedProtocolVersionError) Error() string {
}
// ClientSessionOptions is reserved for future use.
type ClientSessionOptions struct{}
type ClientSessionOptions struct {
// protocolVersion overrides the protocol version sent in the initialize
// request, for testing. If empty, latestProtocolVersion is used.
protocolVersion string
}
func (c *Client) capabilities() *ClientCapabilities {
caps := &ClientCapabilities{}
@ -151,14 +155,18 @@ func (c *Client) capabilities() *ClientCapabilities {
// when it is no longer needed. However, if the connection is closed by the
// server, calls or notifications will return an error wrapping
// [ErrConnectionClosed].
func (c *Client) Connect(ctx context.Context, t Transport, _ *ClientSessionOptions) (cs *ClientSession, err error) {
func (c *Client) Connect(ctx context.Context, t Transport, opts *ClientSessionOptions) (cs *ClientSession, err error) {
cs, err = connect(ctx, t, c, (*clientSessionState)(nil), nil)
if err != nil {
return nil, err
}
protocolVersion := latestProtocolVersion
if opts != nil && opts.protocolVersion != "" {
protocolVersion = opts.protocolVersion
}
params := &InitializeParams{
ProtocolVersion: latestProtocolVersion,
ProtocolVersion: protocolVersion,
ClientInfo: c.impl,
Capabilities: c.capabilities(),
}