From 5c4784404b987b087f2704bb4c2a033d8dab9e10 Mon Sep 17 00:00:00 2001 From: RameshReddy Adutla Date: Wed, 4 Mar 2026 21:10:26 +0000 Subject: [PATCH] Move markInitialized/reconnect after status code check in Streamable HTTP transport When the server returns a non-2xx status code (e.g. 405 Method Not Allowed), markInitialized() and reconnect() were called before the status code was checked. This caused an unnecessary GET request, which is problematic when using transport fallback (Streamable HTTP -> SSE) as it creates duplicate SSE sessions on the server. Move markInitialized() and reconnect() inside the 2xx success branch so they are only called when the server actually accepted the connection. Fixes modelcontextprotocol#773 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../HttpClientStreamableHttpTransport.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java index d6b01e17f..3988c9009 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java @@ -478,19 +478,20 @@ public Mono sendMessage(McpSchema.JSONRPCMessage sentMessage) { })).onErrorMap(CompletionException.class, t -> t.getCause()).onErrorComplete().subscribe(); })).flatMap(responseEvent -> { - if (transportSession.markInitialized( - responseEvent.responseInfo().headers().firstValue("mcp-session-id").orElseGet(() -> null))) { - // Once we have a session, we try to open an async stream for - // the server to send notifications and requests out-of-band. - - reconnect(null).contextWrite(deliveredSink.contextView()).subscribe(); - } - String sessionRepresentation = sessionIdOrPlaceholder(transportSession); int statusCode = responseEvent.responseInfo().statusCode(); if (statusCode >= 200 && statusCode < 300) { + if (transportSession.markInitialized(responseEvent.responseInfo() + .headers() + .firstValue("mcp-session-id") + .orElseGet(() -> null))) { + // Once we have a session, we try to open an async stream + // for the server to send notifications and requests + // out-of-band. + reconnect(null).contextWrite(deliveredSink.contextView()).subscribe(); + } String contentType = responseEvent.responseInfo() .headers()