What happened?
Description
Qwen Code's MCP client fails to maintain stable connections with MCP servers using Spring AI's Streamable HTTP transport. The client intermittently reports
Gateway Time-out and TypeError: fetch failed errors.
Root Cause
After investigation, I found that Qwen Code's StreamableHTTPClientTransport uses GET method to establish the SSE long-lived connection:
// From @modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js
async _startOrAuthSse(options) {
const headers = await this._commonHeaders();
headers.set("Accept", "text/event-stream");
const response = await fetch(this._url, {
method: "GET", // ← Uses GET method
headers,
signal: this._abortController?.signal
});
However, Spring AI 1.1.5's WebMvcStreamableServerTransportProvider only supports POST method for SSE connections. GET requests return 400 Bad Request.
Evidence
| Request |
Accept Header |
Result |
| POST |
text/event-stream, application/json |
✅ 200 OK |
| GET |
text/event-stream |
❌ 400 Bad Request |
| GET |
text/event-stream, application/json |
❌ 400 Bad Request |
curl test:
POST works
curl -X POST https://<your-mcp-server>/mcp \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream, application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize",...}'
Returns: 200 OK
GET fails
curl -X GET https://<your-mcp-server>/mcp \
-H "Accept: text/event-stream"
Returns: 400 Bad Request
Connection Flow Analysis
The reason "it works at first but then fails" is due to the MCP connection sequence:
| Step |
Method |
Purpose |
Result |
| 1. Initialize |
POST |
Establish session, get session ID |
✅ Success |
| 2. Tool discovery |
POST |
Get tool list |
✅ Success |
| 3. SSE long-lived connection |
GET |
Receive server push notifications |
❌ Failed (400) |
Error timeline:
Startup → POST initialize success → POST tool discovery success → Tools available
↓
GET SSE connection fails → Error: "Failed to open SSE stream"
↓
Health check detects disconnected → Triggers reconnection
↓
Reconnect: POST initialize success → GET SSE connection fails again → Loop
User experience:
- Initially tools work (POST succeeds)
- Soon errors appear (GET SSE connection fails)
- Intermittently usable (POST still works during reconnection gaps)
Environment
- Qwen Code Version: 0.15.11
- MCP Server: Spring AI 1.1.5 (
spring-ai-starter-mcp-server-webmvc)
- Protocol: Streamable HTTP (
spring.ai.mcp.server.protocol=STREAMABLE)
- OS: Linux
Expected Behavior
The MCP client should use POST method for SSE connections when using Streamable HTTP transport, as required by the MCP specification and Spring
implementation.
Actual Behavior
The client uses GET method for SSE connections, which Spring AI rejects with 400 Bad Request. This causes:
- Initial connection may succeed (POST for initialize works)
- SSE long-lived connection fails (GET rejected)
- Client reports
Gateway Time-out or fetch failed
- Health check triggers reconnection, but SSE connection fails again
Suggested Fix
Modify StreamableHTTPClientTransport._startOrAuthSse() to use POST method instead of GET for establishing SSE connections, or support both methods based
on server capabilities.
What did you expect to happen?
The MCP client should use POST method for SSE connections when using Streamable HTTP transport, as required by the MCP specification and Spring
implementation.
Client information
Client Information
Run qwen to enter the interactive CLI, then run the /about command.
$ qwen /about
# paste output here
Login information
No response
Anything else we need to know?
No response
What happened?
Description
Qwen Code's MCP client fails to maintain stable connections with MCP servers using Spring AI's Streamable HTTP transport. The client intermittently reports
Gateway Time-outandTypeError: fetch failederrors.Root Cause
After investigation, I found that Qwen Code's
StreamableHTTPClientTransportuses GET method to establish the SSE long-lived connection:However, Spring AI 1.1.5's
WebMvcStreamableServerTransportProvideronly supports POST method for SSE connections. GET requests return400 Bad Request.Evidence
text/event-stream, application/jsontext/event-streamtext/event-stream, application/jsoncurl test:
Connection Flow Analysis
The reason "it works at first but then fails" is due to the MCP connection sequence:
Error timeline:
User experience:
Environment
spring-ai-starter-mcp-server-webmvc)spring.ai.mcp.server.protocol=STREAMABLE)Expected Behavior
The MCP client should use POST method for SSE connections when using Streamable HTTP transport, as required by the MCP specification and Spring
implementation.
Actual Behavior
The client uses GET method for SSE connections, which Spring AI rejects with 400 Bad Request. This causes:
Gateway Time-outorfetch failedSuggested Fix
Modify
StreamableHTTPClientTransport._startOrAuthSse()to use POST method instead of GET for establishing SSE connections, or support both methods basedon server capabilities.
What did you expect to happen?
The MCP client should use POST method for SSE connections when using Streamable HTTP transport, as required by the MCP specification and Spring
implementation.
Client information
Client Information
Run
qwento enter the interactive CLI, then run the/aboutcommand.Login information
No response
Anything else we need to know?
No response