Skip to content

Commit 8c39fb8

Browse files
committed
feat: implement Streamable HTTP transport and refactor SSE transport to reactive streams
This change imporves the transport layer with reactive patterns and adds support for the latest MCP specification while maintaining backward compatibility with existing SSE transport. - Add HttpClientStreamableHttpTransport implementing 2025-03-26 MCP Streamable HTTP spec - Add ResponseSubscribers utility for handling SSE and JSON HTTP responses - Refactor HttpClientSseClientTransport to use reactive streams instead of CompletableFuture - Replace FlowSseClient with direct reactive stream handling - Use Disposable-based connection management instead of CountDownLatch - Replace message endpoint discovery with Sinks.One approach - Add resiliency tests using Toxiproxy for network failure scenarios - Minor type safety improvements in StdioClientTransport and DefaultMcpTransportStream Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
1 parent 9ebff0c commit 8c39fb8

16 files changed

+1533
-166
lines changed

mcp-spring/mcp-spring-webflux/src/test/java/io/modelcontextprotocol/client/WebClientStreamableHttpAsyncClientTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package io.modelcontextprotocol.client;
22

3-
import io.modelcontextprotocol.client.transport.WebClientStreamableHttpTransport;
4-
import io.modelcontextprotocol.spec.McpClientTransport;
53
import org.junit.jupiter.api.Timeout;
4+
import org.springframework.web.reactive.function.client.WebClient;
65
import org.testcontainers.containers.GenericContainer;
76
import org.testcontainers.containers.wait.strategy.Wait;
87

9-
import org.springframework.web.reactive.function.client.WebClient;
8+
import io.modelcontextprotocol.client.transport.WebClientStreamableHttpTransport;
9+
import io.modelcontextprotocol.spec.McpClientTransport;
1010

1111
@Timeout(15)
1212
public class WebClientStreamableHttpAsyncClientTests extends AbstractMcpAsyncClientTests {

mcp-spring/mcp-spring-webflux/src/test/java/io/modelcontextprotocol/client/WebClientStreamableHttpSyncClientTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package io.modelcontextprotocol.client;
22

3-
import io.modelcontextprotocol.client.transport.WebClientStreamableHttpTransport;
4-
import io.modelcontextprotocol.spec.McpClientTransport;
53
import org.junit.jupiter.api.Timeout;
4+
import org.springframework.web.reactive.function.client.WebClient;
65
import org.testcontainers.containers.GenericContainer;
76
import org.testcontainers.containers.wait.strategy.Wait;
87

9-
import org.springframework.web.reactive.function.client.WebClient;
8+
import io.modelcontextprotocol.client.transport.WebClientStreamableHttpTransport;
9+
import io.modelcontextprotocol.spec.McpClientTransport;
1010

1111
@Timeout(15)
1212
public class WebClientStreamableHttpSyncClientTests extends AbstractMcpSyncClientTests {

mcp/pom.xml

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,11 @@
141141

142142
<!-- Mockito cannot mock this class: class java.net.http.HttpClient. the bytebuddy helps. -->
143143
<dependency>
144-
<groupId>net.bytebuddy</groupId>
145-
<artifactId>byte-buddy</artifactId>
146-
<version>${byte-buddy.version}</version>
147-
<scope>test</scope>
148-
</dependency>
144+
<groupId>net.bytebuddy</groupId>
145+
<artifactId>byte-buddy</artifactId>
146+
<version>${byte-buddy.version}</version>
147+
<scope>test</scope>
148+
</dependency>
149149
<dependency>
150150
<groupId>io.projectreactor</groupId>
151151
<artifactId>reactor-test</artifactId>
@@ -202,6 +202,14 @@
202202
<scope>test</scope>
203203
</dependency>
204204

205+
<dependency>
206+
<groupId>org.testcontainers</groupId>
207+
<artifactId>toxiproxy</artifactId>
208+
<version>${toxiproxy.version}</version>
209+
<scope>test</scope>
210+
</dependency>
211+
212+
205213
</dependencies>
206214

207215

0 commit comments

Comments
 (0)