Skip to content

fix(mcp): use negotiated protocol version in transport request headers#14427

Open
hiteshbandhu wants to merge 1 commit intovercel:mainfrom
hiteshbandhu:fix/mcp-protocol-version-header
Open

fix(mcp): use negotiated protocol version in transport request headers#14427
hiteshbandhu wants to merge 1 commit intovercel:mainfrom
hiteshbandhu:fix/mcp-protocol-version-header

Conversation

@hiteshbandhu
Copy link
Copy Markdown

@hiteshbandhu hiteshbandhu commented Apr 14, 2026

Summary

Fixes #14413.

After a successful initialize handshake, HttpMCPTransport and SseMCPTransport were sending mcp-protocol-version: 2025-11-25 (LATEST_PROTOCOL_VERSION) in every subsequent request header — ignoring the version the server actually negotiated down to. The MCP spec says the client SHOULD use the negotiated version in all post-init requests.

Real-world impact

Two confirmed broken server types:

Figma Dev Mode MCP (supports up to 2025-06-18) — reported by @stevering in #14413.

FastMCP < 2.12.0 (supports up to 2025-06-18) — the failure always occurs on notifications/initialized, the very first post-init message:

Error [MCPClientError]: MCP HTTP Transport Error: POSTing to endpoint (HTTP 400):
{"jsonrpc":"2.0","id":"server-error","error":{"code":-32600,"message":
"Bad Request: Unsupported protocol version: 2025-11-25.
Supported versions: 2024-11-05, 2025-03-26, 2025-06-18"}}
    at async tv.send (...)
    at async t_.notification (...)   ← notifications/initialized
    at async t_.init (...)

The server correctly negotiates down to 2025-06-18 during initialize, but the client ignores that and keeps sending 2025-11-25 in subsequent headers — causing the server to reject every post-init request.

What changed

  • MCPTransport interface — added optional protocolVersion?: string | null field so the client can inject the negotiated version into any transport after init. Custom transports that don't set it are unaffected.
  • SseMCPTransport + HttpMCPTransport — added protocolVersion: string | null = null; commonHeaders() now uses this.protocolVersion ?? LATEST_PROTOCOL_VERSION (falls back to latest only before the handshake completes).
  • DefaultMCPClient.init() — after the SUPPORTED_PROTOCOL_VERSIONS check and capability storage, sets this.transport.protocolVersion = result.protocolVersion.
  • Tests — added regression tests in both transport test files that set protocolVersion and assert subsequent request headers use the negotiated value.

Test plan

  • pnpm test in packages/mcp — 181 tests pass (node + edge)
  • Regression tests added: should use negotiated protocol version in POST headers after protocolVersion is set in both mcp-sse-transport.test.ts and mcp-http-transport.test.ts
  • No example added under examples/ — the bug requires a live third-party MCP server, which cannot run in CI. The regression tests cover the same code path.

Credit: @stevering filed the detailed report, provided the repro trace against a real Figma Desktop MCP server, and validated this exact patch locally via pnpm patch. Thank you!

This PR was developed with AI assistance. All contribution guidelines — branch naming, patch-only changeset, PR title format, test coverage, pre-commit hooks — were followed as specified in CONTRIBUTING.md and CLAUDE.md.

After a successful initialize handshake, HttpMCPTransport and SseMCPTransport
were hardcoding LATEST_PROTOCOL_VERSION (2025-11-25) in every subsequent request
header instead of the version actually negotiated with the server. This caused
400 errors against servers that only support older versions — notably Figma Dev
Mode MCP (supports up to 2025-06-18).

DefaultMCPClient now stores result.protocolVersion on the transport after init,
and both transports use it in commonHeaders(), falling back to
LATEST_PROTOCOL_VERSION only before the handshake completes.

Fixes vercel#14413. Thanks to @stevering for the detailed report and local validation.
@tigent tigent bot added ai/mcp related to `@ai-sdk/mcp` package bug Something isn't working as documented labels Apr 14, 2026
@hiteshbandhu
Copy link
Copy Markdown
Author

Hey @gr2m, would appreciate a quick review !

@stevering
Copy link
Copy Markdown

@hiteshbandhu thank you for the investiguation 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai/mcp related to `@ai-sdk/mcp` package bug Something isn't working as documented

Projects

None yet

2 participants