Skip to content

Implement MCP Protocol Version Negotiation #131

@galatanovidiu

Description

@galatanovidiu

Context

The adapter currently hardcodes protocolVersion: '2025-11-25' in the InitializeResult without reading the client's requested version. Per the MCP spec, the server MUST negotiate the protocol version based on what both sides support.

Additionally, the MCP-Protocol-Version HTTP header is not read or validated on subsequent requests.

Research

Compared both spec versions (2025-06-18 and 2025-11-25) and the official TypeScript SDK (v1.x branch) implementation.

Key findings from the TS SDK (server/index.ts_oninitialize):

  • Maintains a SUPPORTED_PROTOCOL_VERSIONS array
  • If client requests a supported version → echo it back; otherwise → return LATEST_PROTOCOL_VERSION
  • Capabilities are NOT filtered by version — feature gating is done through capability negotiation, not protocol version
  • Single set of types/schemas (latest version) — no per-version DTOs needed

Differences between 2025-06-18 and 2025-11-25:

  • New in 2025-11-25: tasks capability + tasks/* methods, Elicitation URL mode, extended Implementation fields
  • Shared (identical): tools, resources, prompts, ping, logging, completions, transport, sessions

The adapter's current surface uses only shared features, making this a low-risk change.

Plan

  1. Add SUPPORTED_PROTOCOL_VERSIONS constant
  2. Implement negotiation in InitializeHandler — read client version, echo if supported, fallback to LATEST
  3. Store negotiated version in sessionSessionManager already stores client params, add negotiated version
  4. Validate MCP-Protocol-Version header on HTTP requests — return 400 if invalid/unsupported (per spec)
  5. Add filter hook (mcp_adapter_negotiated_protocol_version) — for overriding version per-client (e.g. Cloud Desktop)
  6. Fix tests — current tests expect LATEST but code returns hardcoded 2025-06-18
  7. Update docs — README, guides still reference 2025-06-18 in examples

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions