Skip to content

Commit a4f5935

Browse files
irwin-chequerclaude
andcommitted
Fix: Move markInitialized() and reconnect() after status code check
When connecting to an MCP server that doesn't support Streamable HTTP transport (returns 405 Method Not Allowed), the transports still called markInitialized() and reconnect() before checking the status code, which triggered unnecessary GET requests. This caused issues when using transport fallback (Streamable HTTP → SSE), as duplicate SSE sessions were created on the upstream server. This fix moves markInitialized() and reconnect() inside the success status code check (2xx), so they are only called for successful responses. Fixes #773 Related to #362 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent a47920c commit a4f5935

File tree

2 files changed

+18
-15
lines changed

2 files changed

+18
-15
lines changed

mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -466,19 +466,21 @@ public Mono<Void> sendMessage(McpSchema.JSONRPCMessage sentMessage) {
466466
})).onErrorMap(CompletionException.class, t -> t.getCause()).onErrorComplete().subscribe();
467467

468468
})).flatMap(responseEvent -> {
469-
if (transportSession.markInitialized(
470-
responseEvent.responseInfo().headers().firstValue("mcp-session-id").orElseGet(() -> null))) {
471-
// Once we have a session, we try to open an async stream for
472-
// the server to send notifications and requests out-of-band.
473-
474-
reconnect(null).contextWrite(deliveredSink.contextView()).subscribe();
475-
}
476-
477469
String sessionRepresentation = sessionIdOrPlaceholder(transportSession);
478470

479471
int statusCode = responseEvent.responseInfo().statusCode();
480472

481473
if (statusCode >= 200 && statusCode < 300) {
474+
// Only initialize session and open async stream for successful
475+
// responses
476+
if (transportSession.markInitialized(responseEvent.responseInfo()
477+
.headers()
478+
.firstValue("mcp-session-id")
479+
.orElseGet(() -> null))) {
480+
// Once we have a session, we try to open an async stream for
481+
// the server to send notifications and requests out-of-band.
482+
reconnect(null).contextWrite(deliveredSink.contextView()).subscribe();
483+
}
482484

483485
String contentType = responseEvent.responseInfo()
484486
.headers()

mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/client/transport/WebClientStreamableHttpTransport.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -310,18 +310,19 @@ public Mono<Void> sendMessage(McpSchema.JSONRPCMessage message) {
310310
})
311311
.bodyValue(jsonText)
312312
.exchangeToFlux(response -> {
313-
if (transportSession
314-
.markInitialized(response.headers().asHttpHeaders().getFirst(HttpHeaders.MCP_SESSION_ID))) {
315-
// Once we have a session, we try to open an async stream for
316-
// the server to send notifications and requests out-of-band.
317-
reconnect(null).contextWrite(sink.contextView()).subscribe();
318-
}
319-
320313
String sessionRepresentation = sessionIdOrPlaceholder(transportSession);
321314

322315
// The spec mentions only ACCEPTED, but the existing SDKs can return
323316
// 200 OK for notifications
324317
if (response.statusCode().is2xxSuccessful()) {
318+
// Only initialize session and open async stream for successful
319+
// responses
320+
if (transportSession
321+
.markInitialized(response.headers().asHttpHeaders().getFirst(HttpHeaders.MCP_SESSION_ID))) {
322+
// Once we have a session, we try to open an async stream for
323+
// the server to send notifications and requests out-of-band.
324+
reconnect(null).contextWrite(sink.contextView()).subscribe();
325+
}
325326
Optional<MediaType> contentType = response.headers().contentType();
326327
long contentLength = response.headers().contentLength().orElse(-1);
327328
// Existing SDKs consume notifications with no response body nor

0 commit comments

Comments
 (0)