spring-projects / spring-projects/spring-ai

WebFlux streamable HTTP reconnect GET /mcp uses the latest client protocol version instead of the negotiated one

Open
#6,573 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage
Dominant language
Java
Stars
9.5k
Forks
2.9k
Avg merge
1d 7h
Merged PRs (30d)
6

Description

Bug description

In the WebFlux streamable HTTP MCP client transport, the background reconnect GET /mcp request does not consistently use the negotiated protocol version.

After initialize, the server may negotiate the protocol down to an older supported version. Subsequent POST requests correctly use that negotiated version, but the reconnect GET /mcp request still sends the client's latest supported version instead.

This creates an internal inconsistency in the transport: the same session continues with different mcp-protocol-version values depending on the request type.


What I verified

I reproduced this against the existing WebFlux version-negotiation integration test setup.

Using a client configured with:

  • 2025-11-25
  • 2263-03-18

and a server that negotiates down to 2025-11-25:

  • the initialize request advertises the latest client-supported version, which is expected
  • subsequent POST requests use 2025-11-25, which is correct
  • the reconnect GET /mcp request uses 2263-03-18, which appears incorrect

I also noticed there is already a FIXME in the existing integration test mentioning this exact gap.


Relevant code

The reconnect GET path reads the protocol version from Reactor context and falls back to latestSupportedProtocolVersion:

  • WebClientStreamableHttpTransport.reconnect(...)

The POST path also reads from context, but in practice it keeps the negotiated version when triggered from the initialized request flow.

This makes the reconnect GET path behave differently from the rest of the negotiated session.


Steps to reproduce

  1. Use WebClientStreamableHttpTransport with supported protocol versions:
    • 2025-11-25
    • 2263-03-18
  2. Initialize a client against a test server that negotiates down to 2025-11-25
  3. Trigger a normal tool call after initialization
  4. Record outgoing transport requests
  5. Compare the mcp-protocol-version header on:
    • non-initialize POST requests
    • reconnect GET /mcp request

Actual behavior

The reconnect GET /mcp request sends:

mcp-protocol-version: 2263-03-18

while the rest of the established session uses:

mcp-protocol-version: 2025-11-25

Expected behavior

Once the protocol has been negotiated, all subsequent requests for that transport session, including reconnect GET /mcp, should use the negotiated protocol version rather than the client's latest supported version.


Why this looks like a real bug

There is already an inline comment in the existing integration test acknowledging the problem:

// FIXME: Set the correct protocol version on GET /mcp

So this seems to be a known gap in the current implementation rather than an ambiguous interpretation.


Environment

  • Spring AI: current main branch
  • Module: mcp/transport/mcp-spring-webflux

Notes

I reproduced this locally with a temporary regression test added to the existing integration test suite and confirmed that it fails consistently until the reconnect GET path is corrected.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at WebClientStreamableHttpTransport.reconnect(...) and inspect how the reconnect GET reads the protocol version from Reactor context and applies its fallback. Then run the existing WebFlux version-negotiation integration test, including the FIXME scenario. Done means the reconnect GET uses the negotiated version, matching subsequent POST requests for the session.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.