Skip to content

Commit

Permalink
Refactor the mcp-core module
Browse files Browse the repository at this point in the history
- The core module has been refactored to remove unnecessary abstraction
  between the SSE transport and the STDIO transport.
- Tests have been improved and no longer complain about multiple
  subscriptions to single-subscriber Sink.
- SSE transport layer is now assuming non-blocking execution and no longer
  makes thread hops when not needed.
- Decouple ObjectMapper and error handling from AbstractMcpTransport
  and remove later.

Additional improvements:

- Rename transport classes to better reflect client-side role (*ServerTransport -> *ClientTransport)
- Introduce fluent builder pattern for client configuration
- Simplify DefaultMcpSession by removing ObjectMapper dependency
- Move unmarshal responsibility to transport layer
- Update documentation and diagrams to reflect new architecture
- Clean up test implementations
  • Loading branch information
chemicL authored and tzolov committed Dec 19, 2024
1 parent 8b2ce26 commit 7a98a93
Show file tree
Hide file tree
Showing 30 changed files with 560 additions and 761 deletions.
18 changes: 8 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
# Spring AI MCP

Java SDK for the Model Context Protocol (MCP), providing seamless integration between Java and Spring applications and MCP-compliant AI models and tools.
Java SDK for the Model Context Protocol (MCP), providing seamless integration between Java and Spring applications and MCP-compliant AI resources and tools.

## Overview

Spring AI MCP is an experimental project that provides Java and Spring Framework integration for the [Model Context Protocol](https://modelcontextprotocol.org/docs/concepts/architecture). It enables Spring applications to interact with AI models and tools through a standardized interface, supporting both synchronous and asynchronous communication patterns.
Spring AI MCP is an experimental project that provides Java and Spring Framework integration for the [Model Context Protocol](https://modelcontextprotocol.org/docs/concepts/architecture). It enables Java applications to interact with AI models and tools through a standardized interface, supporting both synchronous and asynchronous communication patterns.

<img src="spring-ai-mcp-architecture.jpg" width="600">

## Modules

The project consists of two main modules:

### [spring-ai-mcp-core](./spring-ai-mcp-core/README.md)
### [mcp-core](./spring-ai-mcp-core/README.md)

The core module provides a Java implementation of the Model Context Protocol specification. It includes:
- Synchronous and asynchronous client implementations
- Standard MCP operations support (tool discovery, resource management, prompt handling)
- Stdio-based server transport
- Reactive programming support using Project Reactor
- Standard MCP operations support (tool discovery, resource management, prompt handling). Support for request and notificaiotn handling.
- [Stdio](https://spec.modelcontextprotocol.io/specification/basic/transports/#stdio) and [SSE](https://spec.modelcontextprotocol.io/specification/basic/transports/#http-with-sse) transport implementations.
- [Find more](./spring-ai-mcp-core/README.md).

[find more](./spring-ai-mcp-core/README.md)

### [spring-ai-mcp-spring](./spring-ai-mcp-spring/README.md)
### [mcp-spring](./spring-ai-mcp-spring/README.md)

The Spring integration module provides Spring-specific functionality:
- Integration with Spring AI's function calling system
- Spring-friendly abstractions for MCP clients
- Automatic conversion between JSON and Java objects for tool arguments
- Auto-configurations (WIP)

## Requirements

Expand Down
31 changes: 12 additions & 19 deletions spring-ai-mcp-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ This SDK implements the Model Context Protocol, enabling seamless integration wi
- Multiple transport implementations:
- Stdio-based transport for process-based communication
- SSE-based transport for HTTP streaming
- Reactive programming support using Project Reactor
- Configurable request timeouts
- Customizable JSON serialization/deserialization

Expand All @@ -32,43 +31,37 @@ Add the following dependency to your Maven project:
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-ai-mcp-core</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
```

## Documentation

Detailed UML class diagrams showing the relationships between components can be found in [docs/class-diagrams.puml](docs/class-diagrams.puml). The diagrams include:
- Core Components: Shows the main interfaces, classes, and their relationships
- Message Flow: Illustrates the message and resource type hierarchies

## Usage

### Transport Layer Options

The SDK provides two transport implementations:

#### StdioServerTransport
#### StdioClientTransport
Standard I/O based transport for process-based communication with MCP servers:

```java
ServerParameters params = ServerParameters.builder("npx")
.args("-y", "@modelcontextprotocol/server-everything", "dir")
.build();
McpTransport transport = new StdioServerTransport(params);
McpTransport transport = new StdioClientTransport(params);
```

#### SseServerTransport
#### SseClientTransport
Server-Sent Events (SSE) based transport following the MCP HTTP with SSE transport specification:

```java
WebClient.Builder webClientBuilder = WebClient.builder()
.baseUrl("http://your-mcp-server");
McpTransport transport = new SseServerTransport(webClientBuilder);
McpTransport transport = new SseClientTransport(webClientBuilder);

// Or with custom ObjectMapper
ObjectMapper mapper = new ObjectMapper();
McpTransport transport = new SseServerTransport(webClientBuilder, mapper);
McpTransport transport = new SseClientTransport(webClientBuilder, mapper);
```

The SSE transport provides:
Expand All @@ -87,7 +80,7 @@ ServerParameters params = ServerParameters.builder("npx")
.args("-y", "@modelcontextprotocol/server-everything", "dir")
.build();

try (McpSyncClient client = McpClient.sync(new StdioServerTransport(params))) {
try (McpSyncClient client = McpClient.sync(new StdioClientTransport(params))) {
// Initialize connection with protocol version and capabilities
McpSchema.InitializeResult initResult = client.initialize();

Expand Down Expand Up @@ -123,7 +116,7 @@ ServerParameters params = ServerParameters.builder("npx")

// Initialize async client with custom timeout and object mapper
McpAsyncClient client = McpClient.async(
new StdioServerTransport(params),
new StdioClientTransport(params),
Duration.ofSeconds(30),
new ObjectMapper()
);
Expand Down Expand Up @@ -172,11 +165,11 @@ The SDK follows a layered architecture with clear separation of concerns:
- **McpAsyncClient**: Primary async implementation using Project Reactor for non-blocking operations
- **McpSyncClient**: Synchronous wrapper around the async client for blocking operations
- **McpSession**: Core session interface defining communication patterns
- **McpTransport**: Transport layer interface for server communication
- **McpTransport**: Transport layer interface for client/server communication
- **McpSchema**: Comprehensive protocol schema definitions
- **DefaultMcpSession**: Base implementation of the session management
- **StdioServerTransport**: Standard I/O based server communication
- **SseServerTransport**: HTTP-based transport using Server-Sent Events for bidirectional communication
- **DefaultMcpSession**: Default implementation of the session management
- **StdioClientTransport**: Standard I/O based client to server communication
- **SseClientTransport**: HTTP-based transport using Server-Sent Events for bidirectional client-sever communication

<img src="docs/spring-ai-mcp-uml-classdiagram.svg" width="600"/>

Expand Down
6 changes: 3 additions & 3 deletions spring-ai-mcp-core/docs/CLIENT.SSE.TRANSPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview

The `SseServerTransport` class implements the Model Context Protocol (MCP) HTTP with SSE transport specification, providing a bidirectional communication channel between clients and servers. This implementation is part of the Spring AI MCP Core library and follows the [MCP HTTP with SSE Transport Specification](https://spec.modelcontextprotocol.io/specification/basic/transports/#http-with-sse).
The `SseClientTransport` class implements the Model Context Protocol (MCP) HTTP with SSE transport specification, providing a bidirectional communication channel between clients and servers. This implementation is part of the Spring AI MCP Core library and follows the [MCP HTTP with SSE Transport Specification](https://spec.modelcontextprotocol.io/specification/basic/transports/#http-with-sse).

## Key Features

Expand Down Expand Up @@ -53,7 +53,7 @@ WebClient.Builder webClientBuilder = WebClient.builder()
.baseUrl("http://localhost:3001");

// Initialize transport
SseServerTransport transport = new SseServerTransport(webClientBuilder);
SseClientTransport transport = new SseClientTransport(webClientBuilder);

// Create a JSON-RPC request
JSONRPCRequest request = new JSONRPCRequest(
Expand Down Expand Up @@ -141,4 +141,4 @@ The implementation includes comprehensive tests covering:
- Shutdown procedures
- Edge cases and failure scenarios

For detailed test examples, see `SseServerTransportTests.java`.
For detailed test examples, see `SseClientTransportTests.java`.
6 changes: 3 additions & 3 deletions spring-ai-mcp-core/docs/CLIENT.STDIO.TRANSPORT.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# StdioServerTransport
# StdioClientTransport

The `StdioServerTransport` class implements the [MCP Stdio Transport](https://spec.modelcontextprotocol.io/specification/basic/transports/#stdio) specification, providing communication with MCP servers over standard input/output streams.
The `StdioClientTransport` class implements the [MCP Stdio Transport](https://spec.modelcontextprotocol.io/specification/basic/transports/#stdio) specification, providing communication with MCP servers over standard input/output streams.

## Overview

Expand Down Expand Up @@ -84,7 +84,7 @@ ServerParameters params = ServerParameters.builder()
.build();

// Create transport
StdioServerTransport transport = new StdioServerTransport(params);
StdioClientTransport transport = new StdioClientTransport(params);

// Start transport
transport.start();
Expand Down
30 changes: 11 additions & 19 deletions spring-ai-mcp-core/docs/class-diagrams.puml
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
@startuml Core Components

interface McpTransport {
+void start()
+Mono<Void> connect(Function<Mono<JSONRPCMessage>,
Mono<JSONRPCMessage>> handler)
+Mono<Void> sendMessage()
+void close()
+Mono<Void> closeGracefully()
+void setInboudMessageHandler()
+void setInboundErrorHandler()
+Mono<Void> sendMessage()
}

abstract class AbstractMcpTransport {
#ObjectMapper objectMapper
#getInboundSink()
#getOutboundSink()
#getErrorSink()
}

interface McpSession {
+<T> Mono<T> sendRequest()
+Mono<Void> sendNotification()
+<T> Mono<T> sendRequest(String method, Object requestParams, TypeReference<T> typeRef)
+Mono<Void> sendNotification(String method, Map<String, Object> params)
+Mono<Void> closeGracefully()
+close()
}

class DefaultMcpSession {
Expand Down Expand Up @@ -52,12 +45,12 @@ class McpSyncClient {
+GetPromptResult getPrompt()
}

class StdioServerTransport {
class StdioClientTransport {
-Process serverProcess
-ServerParameters parameters
}

class SseServerTransport {
class SseClientTransport {
-WebClient webClient
}

Expand All @@ -74,11 +67,10 @@ class McpError {
-String message
}

McpTransport <|.. AbstractMcpTransport
AbstractMcpTransport <|-- StdioServerTransport
AbstractMcpTransport <|-- SseServerTransport
McpTransport <|-- StdioClientTransport
McpTransport <|-- SseClientTransport
McpSession <|-- DefaultMcpSession
DefaultMcpSession <|-- McpAsyncClient
DefaultMcpSession --o McpAsyncClient
McpClient ..> McpAsyncClient : creates
McpClient ..> McpSyncClient : creates
McpSyncClient o-- McpAsyncClient
Expand Down
2 changes: 1 addition & 1 deletion spring-ai-mcp-core/docs/spring-ai-mcp-uml-classdiagram.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 7a98a93

Please sign in to comment.