refactor: Split transport implementations into modules

Split the  transport implementations into dedicated modules to improve modularity
and reduce core dependencies.

Added shared test module for common test utilities.

Key changes:

- Create mcp-transport/mcp-webflux-sse-transport module
 - Move SseClientTransport → WebFluxSseClientTransport
 - Move SseServerTransport → WebFluxSseServerTransport
 - Move related tests and utilities

- Create mcp-transport/mcp-webmvc-sse-transport module
 - Add new WebMvcSseServerTransport implementation
 - Add corresponding tests and integration tests

- Add framework-independent SSE client implementations to core module
 - Add FlowSseClient using java.net.http
 - Add HttpClientSseClientTransport using java.net.http

- Keep StdioClientTransport/StdioServerTransport in core (no external deps)

- Create mcp-test module for shared test infrastructure
 - Move abstract test base classes
 - Move shared test utilities and mocks
 - Update test dependencies

The modular approach allows users to choose between:

- Framework-specific implementations (WebFlux/WebMVC)
- Pure Java implementations (java.net.http)
- Basic implementations (STDIO)

Add breaking changes readme: 0.5.0-BREAKING-CHANGES.md

Resolves #54
This commit is contained in:
Christian Tzolov 2025-01-08 16:21:21 +01:00
commit 611f3258d6

View file

@ -1,25 +1,35 @@
= Java MCP SDK
Java SDK implementation of the Model Context Protocol, enabling seamless integration with language models and AI tools.
Java SDK implementation of the link:https://modelcontextprotocol.io/introduction[Model Context Protocol], enabling seamless integration with language models and AI tools.
== Features
* Synchronous and Asynchronous MCP Client and MCP Server implementations
* Standard MCP operations support:
** Protocol version compatibility negotiation
** Tool discovery, execution, list change notifications
** Resource management with URI templates
** Roots list management and notifications
** Prompt handling and management
** Smampling support for AI model interactions
** Protocol link:https://spec.modelcontextprotocol.io/specification/2024-11-05/basic/lifecycle/#initialization[version compatibility negotiation]
** link:https://spec.modelcontextprotocol.io/specification/2024-11-05/server/tools/[Tool] discovery, execution, list change notifications
** link:https://spec.modelcontextprotocol.io/specification/2024-11-05/server/resources/[Resource] management with URI templates
** link:https://spec.modelcontextprotocol.io/specification/2024-11-05/client/roots/[Roots] list management and notifications
** link:https://spec.modelcontextprotocol.io/specification/2024-11-05/server/prompts/[Prompt] handling and management
** link:https://spec.modelcontextprotocol.io/specification/2024-11-05/client/sampling/[Sampling] support for AI model interactions
* Multiple transport implementations:
** Stdio-based transport for process-based communication
** SSE-based transport for HTTP streaming
** Core transports:
*** Stdio-based transport for process-based communication
*** Java HttpClient-based SSE transport for HTTP streaming
** Spring-based transports:
*** WebFlux SSE transport for reactive HTTP streaming
*** WebMVC SSE transport for servlet-based HTTP streaming
=== Dependencies
Add the following dependency to your Maven project:
[tabs]
======
Maven::
+
The core MCP functionality:
+
[source,xml]
----
<dependency>
@ -28,6 +38,51 @@ Add the following dependency to your Maven project:
<version>0.5.0-SNAPSHOT</version>
</dependency>
----
+
For HTTP SSE transport implementations, add one of the following dependencies
(Note that you already have HTTP Client SSE client transport in the core module):
+
[source,xml]
----
<!-- Spring WebFlux-based SSE client and server transport -->
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>mcp-webflux-sse-transport</artifactId>
<version>0.5.0-SNAPSHOT</version>
</dependency>
<!-- Spring WebMVC-based SSE server transport -->
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>mcp-webmvc-sse-transport</artifactId>
<version>0.5.0-SNAPSHOT</version>
</dependency>
----
Gradle::
+
The core MCP functionality:
+
[source,groovy]
----
dependencies {
implementation 'org.springframework.experimental:mcp'
}
----
+
For HTTP SSE transport implementations, add one of the following dependencies
(note that you already have HTTP Client SSE client transport in the core module):
+
[source,groovy]
----
// Spring WebFlux-based SSE client and server transport
implementation 'org.springframework.experimental:mcp-webflux-sse-transport'
// Spring WebMVC-based SSE server transport
implementation 'org.springframework.experimental:mcp-webmvc-sse-transport'
----
======
== Architecture
@ -37,7 +92,9 @@ The SDK follows a layered architecture with clear separation of concerns:
* *Client/Server Layer*: Both use McpSession for sync/async operations, with McpClient handling client-side protocol operations and McpServer managing server-side protocol operations.
* *Session Layer (McpSession)*: Manages communication patterns and state using DefaultMcpSession implementation.
* *Transport Layer (McpTransport)*: Handles JSON-RPC message serialization/deserialization via StdioTransport (stdin/stdout) and SseTransport (HTTP streaming).
* *Transport Layer (McpTransport)*: Handles JSON-RPC message serialization/deserialization via:
** StdioTransport (stdin/stdout) in the core module
** HTTP SSE transports in dedicated transport modules (Java HttpClient, Spring WebFlux, Spring WebMVC)
Following class diagram illustrates the layered architecture of the MCP SDK, showing the relationships between core interfaces (McpTransport, McpSession), their implementations, and the client/server components. It highlights how the transport layer connects to sessions, which in turn support both synchronous and asynchronous client/server implementations.
@ -187,23 +244,36 @@ The transport layer handles the communication between MCP clients and servers, p
======
STDIO::
+
Creates transport for in-process based communication
+
[source,java]
----
// Create transport for process-based communication
ServerParameters params = ServerParameters.builder("npx")
.args("-y", "@modelcontextprotocol/server-everything", "dir")
.build();
McpTransport transport = new StdioClientTransport(params);
----
SSE::
+
SSE (HttpClient)::
+
Creates a framework agnostic (pure Java API) SSE client transport.
Included in the core `mcp` module.
+
[source,java]
----
McpTransport transport = new HttpClientSseClientTransport("http://your-mcp-server");
----
+
SSE (WebFlux)::
+
Creates WebFlux-based SSE client transport.
Requires the `mcp-webflux-sse-transport` dependency.
+
[source,java]
----
// Create transport for HTTP streaming
WebClient.Builder webClientBuilder = WebClient.builder()
.baseUrl("http://your-mcp-server");
McpTransport transport = new SseClientTransport(webClientBuilder);
McpTransport transport = new WebFluxSseClientTransport(webClientBuilder);
----
======
@ -381,29 +451,72 @@ The server transport layer implements the server-side communication protocols, e
======
STDIO::
+
Create in-process based transport
+
[source,java]
----
// Create transport with custom ObjectMapper
ObjectMapper mapper = new ObjectMapper();
StdioServerTransport transport = new StdioServerTransport(mapper);
StdioServerTransport transport = new StdioServerTransport(new ObjectMapper());
----
+
Provides bidirectional JSON-RPC message handling over standard input/output streams with non-blocking message processing, serialization/deserialization, and graceful shutdown support.
SSE::
SSE (WebFlux)::
+
Creates WebFlux-based SSE server transport.
Requires the `mcp-webflux-sse-transport` dependency.
+
[source,java]
----
// Create SSE transport
ObjectMapper mapper = new ObjectMapper();
String messageEndpoint = "/mcp/message";
SseServerTransport transport = new SseServerTransport(mapper, messageEndpoint);
@Configuration
class McpConfig {
@Bean
WebFluxSseServerTransport webFluxSseServerTransport(ObjectMapper mapper) {
return new WebFluxSseServerTransport(mapper, "/mcp/message");
}
// Get router function for web server configuration
RouterFunction<?> router = transport.getRouterFunction();
@Bean
RouterFunction<?> mcpRouterFunction(WebFluxSseServerTransport transport) {
return transport.getRouterFunction();
}
}
----
+
Implements the MCP HTTP with SSE transport specification, providing concurrent client connections through SSE endpoints with message routing, session management, and graceful shutdown capabilities.
Implements the MCP HTTP with SSE transport specification, providing:
+
* Reactive HTTP streaming with WebFlux
* Concurrent client connections through SSE endpoints
* Message routing and session management
* Graceful shutdown capabilities
SSE (WebMvc)::
+
Creates WebMvc-based SSE server transport.
Requires the `mcp-webmvc-sse-transport` dependency.
+
[source,java]
----
@Configuration
@EnableWebMvc
class McpConfig {
@Bean
WebMvcSseServerTransport webMvcSseServerTransport(ObjectMapper mapper) {
return new WebMvcSseServerTransport(mapper, "/mcp/message");
}
@Bean
RouterFunction<ServerResponse> mcpRouterFunction(WebMvcSseServerTransport transport) {
return transport.getRouterFunction();
}
}
----
+
Implements the MCP HTTP with SSE transport specification, providing:
+
* Servlet-based HTTP streaming with Spring MVC
* Concurrent client connections through SSE endpoints
* Message routing and session management
* Graceful shutdown capabilities
======
=== Server Capabilities