Skip to content
This repository was archived by the owner on Feb 14, 2025. It is now read-only.

Commit bc281de

Browse files
committed
feat: add SSE transport and improve documentation
- Add Server-Sent Events (SSE) transport implementation with test coverage - Add detailed documentation for both SSE and STDIO transports - Extract common test logic into abstract base classes - Add testcontainers support for SSE integration tests - Replace System.out with SLF4J logging - Externalize dependency versions to properties - Implement endpoint event handling per MCP spec - Add message endpoint sink for reliable message routing - Improve error handling and graceful shutdown - Update core module README with expanded features and examples - Add dependency version properties and logging configuration - Update architecture and class diagrams Resolves #4
1 parent be31c61 commit bc281de

25 files changed

+1583
-162
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,17 @@ Spring AI MCP is an experimental project that provides Java and Spring Framework
1212

1313
The project consists of two main modules:
1414

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

1717
The core module provides a Java implementation of the Model Context Protocol specification. It includes:
1818
- Synchronous and asynchronous client implementations
1919
- Standard MCP operations support (tool discovery, resource management, prompt handling)
2020
- Stdio-based server transport
2121
- Reactive programming support using Project Reactor
2222

23-
### spring-ai-mcp-spring
23+
[find more](./spring-ai-mcp-core/README.md)
24+
25+
### [spring-ai-mcp-spring](./spring-ai-mcp-spring/README.md)
2426

2527
The Spring integration module provides Spring-specific functionality:
2628
- Integration with Spring AI's function calling system

pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,12 @@
7070
<assert4j.version>3.26.3</assert4j.version>
7171
<junit.version>5.11.3</junit.version>
7272
<mockito.version>5.11.0</mockito.version>
73+
<testcontainers.version>1.20.4</testcontainers.version>
7374

75+
<slf4j-api.version>2.0.16</slf4j-api.version>
76+
<logback.version>1.5.12</logback.version>
77+
<jackson.version>2.18.2</jackson.version>
78+
<springframework.version>6.1.13</springframework.version>
7479

7580
<!-- plugin versions -->
7681
<maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
@@ -347,4 +352,4 @@
347352
</repository>
348353
</repositories>
349354

350-
</project>
355+
</project>

spring-ai-mcp-architecture.jpg

155 KB
Loading

spring-ai-mcp-core/README.md

Lines changed: 106 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@ This SDK implements the Model Context Protocol, enabling seamless integration wi
1010

1111
- Synchronous and Asynchronous client implementations
1212
- Standard MCP operations support:
13+
- Protocol version compatibility negotiation
14+
- Client-server capability exchange
1315
- Tool discovery and execution
14-
- Resource management and templates
15-
- Prompt handling and management
16+
- Resource management with URI templates
1617
- Resource subscription system
18+
- Prompt handling and management
1719
- Server initialization and ping
18-
- Stdio-based server transport
20+
- Multiple transport implementations:
21+
- Stdio-based transport for process-based communication
22+
- SSE-based transport for HTTP streaming
1923
- Reactive programming support using Project Reactor
24+
- Configurable request timeouts
25+
- Customizable JSON serialization/deserialization
2026

2127
## Installation
2228

@@ -38,6 +44,41 @@ Detailed UML class diagrams showing the relationships between components can be
3844

3945
## Usage
4046

47+
### Transport Layer Options
48+
49+
The SDK provides two transport implementations:
50+
51+
#### StdioServerTransport
52+
Standard I/O based transport for process-based communication with MCP servers:
53+
54+
```java
55+
ServerParameters params = ServerParameters.builder("npx")
56+
.args("-y", "@modelcontextprotocol/server-everything", "dir")
57+
.build();
58+
McpTransport transport = new StdioServerTransport(params);
59+
```
60+
61+
#### SseServerTransport
62+
Server-Sent Events (SSE) based transport following the MCP HTTP with SSE transport specification:
63+
64+
```java
65+
WebClient.Builder webClientBuilder = WebClient.builder()
66+
.baseUrl("http://your-mcp-server");
67+
McpTransport transport = new SseServerTransport(webClientBuilder);
68+
69+
// Or with custom ObjectMapper
70+
ObjectMapper mapper = new ObjectMapper();
71+
McpTransport transport = new SseServerTransport(webClientBuilder, mapper);
72+
```
73+
74+
The SSE transport provides:
75+
- Bidirectional communication over HTTP
76+
- Automatic reconnection for transient failures
77+
- Inbound message streaming via SSE
78+
- Outbound message delivery via HTTP POST
79+
- Graceful shutdown handling
80+
- Configurable JSON serialization
81+
4182
### Sync Client Example
4283

4384
```java
@@ -47,139 +88,144 @@ ServerParameters params = ServerParameters.builder("npx")
4788
.build();
4889

4990
try (McpSyncClient client = McpClient.sync(new StdioServerTransport(params))) {
50-
// Initialize connection
91+
// Initialize connection with protocol version and capabilities
5192
McpSchema.InitializeResult initResult = client.initialize();
5293

53-
// List tools synchronously
54-
McpSchema.ListToolsResult tools = client.listTools(null);
94+
// List available tools
95+
McpSchema.ListToolsResult tools = client.listTools();
5596

56-
// Call tool synchronously
97+
// Execute a tool
5798
McpSchema.CallToolResult result = client.callTool(
5899
new McpSchema.CallToolRequest("echo", Map.of("message", "Hello!"))
59100
);
60101

61102
// Resource management
62-
McpSchema.ListResourcesResult resources = client.listResources(null);
103+
McpSchema.ListResourcesResult resources = client.listResources();
63104
McpSchema.ReadResourceResult resource = client.readResource(
64105
new McpSchema.ReadResourceRequest("resource-uri")
65106
);
66107

67-
// Prompt management
68-
ListPromptsResult prompts = client.listPrompts(null);
108+
// List and retrieve prompts
109+
ListPromptsResult prompts = client.listPrompts();
69110
GetPromptResult prompt = client.getPrompt(
70111
new McpSchema.GetPromptRequest("prompt-id", Map.of())
71112
);
72113
}
73114
```
74115

75-
### Async Client Example
116+
### Async Client Example with Custom Configuration
76117

77118
```java
78119
// Create server parameters
79120
ServerParameters params = ServerParameters.builder("npx")
80121
.args("-y", "@modelcontextprotocol/server-everything", "dir")
81122
.build();
82123

83-
// Initialize the async client
124+
// Initialize async client with custom timeout and object mapper
84125
McpAsyncClient client = McpClient.async(
85-
new StdioServerTransport(params)
126+
new StdioServerTransport(params),
127+
Duration.ofSeconds(30),
128+
new ObjectMapper()
86129
);
87130

88-
// Initialize the connection
89-
var promptResult = client.initialize()
90-
flatMap(result -> {
91-
// Connection initialized
92-
return client.listTools(null);
131+
// Initialize connection and chain operations
132+
var result = client.initialize()
133+
.flatMap(initResult -> {
134+
// Connection initialized with protocol version compatibility
135+
return client.listTools();
93136
})
94137
.flatMap(tools -> {
95-
// Process tools
138+
// Process available tools
96139
return client.callTool(new McpSchema.CallToolRequest("echo",
97140
Map.of("message", "Hello MCP!")));
98141
})
99-
.flatMap(result -> {
100-
// Handle tool result
101-
return client.listPrompts(null);
142+
.flatMap(toolResult -> {
143+
// Handle tool execution result
144+
return client.listPrompts();
102145
})
103146
.flatMap(prompts -> {
104147
// Process available prompts
105148
return client.getPrompt(new McpSchema.GetPromptRequest("prompt-id", Map.of()));
106149
});
107150

108-
// Handle prompt result, e.g. by blocking on it
109-
McpSchema.GetPromptResult result = promptResult.block();
110-
111-
// Resource management example
112-
var resourcesResult = client.listResources(null)
151+
// Subscribe to resource changes
152+
var subscription = client.listResources()
113153
.flatMap(resources -> {
114-
// Subscribe to resource changes
115154
return client.subscribeResource(new McpSchema.SubscribeRequest("resource-uri"));
116155
});
117156

118-
// Handle resources result
119-
resourcesResult.block();
157+
// Handle results reactively or block if needed
158+
McpSchema.GetPromptResult promptResult = result.block();
159+
subscription.block();
120160

121161
// Cleanup
122162
client.closeGracefully().block();
123163
```
124164

125165
## Architecture
126166

127-
The SDK follows a layered architecture:
167+
The SDK follows a layered architecture with clear separation of concerns:
128168

129169
### Core Components
130170

131-
- **McpClient**: Factory class for creating sync and async clients
132-
- **McpAsyncClient**: Primary async implementation using Project Reactor
133-
- **McpSyncClient**: Synchronous wrapper around the async client
171+
- **McpClient**: Factory class for creating sync and async clients with optional custom configuration
172+
- **McpAsyncClient**: Primary async implementation using Project Reactor for non-blocking operations
173+
- **McpSyncClient**: Synchronous wrapper around the async client for blocking operations
134174
- **McpSession**: Core session interface defining communication patterns
135-
- **McpTransport**: Transport layer interface
175+
- **McpTransport**: Transport layer interface for server communication
136176
- **McpSchema**: Comprehensive protocol schema definitions
137-
- **AbstractMcpTransport**: Base transport implementation
138-
- **StdioServerTransport**: Stdio-based server communication
177+
- **DefaultMcpSession**: Base implementation of the session management
178+
- **StdioServerTransport**: Standard I/O based server communication
179+
- **SseServerTransport**: HTTP-based transport using Server-Sent Events for bidirectional communication
139180

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

142183
### Key Interactions
143184

144-
1. Client initialization
145-
- Transport setup
146-
- Server connection establishment
147-
- Protocol handshake
185+
1. Client Initialization
186+
- Transport setup and connection establishment
187+
- Protocol version compatibility check
188+
- Capability negotiation
189+
- Implementation details exchange
148190

149191
2. Message Flow
150-
- JSON-RPC message creation
192+
- JSON-RPC message creation and validation
151193
- Transport layer handling
152-
- Response processing
153-
- Error handling
194+
- Response processing with type safety
195+
- Error handling with specific error codes
154196

155197
3. Resource Management
156-
- Resource listing and reading
157-
- Template management
158-
- Subscription handling
159-
- Change notifications
198+
- Resource discovery and listing
199+
- URI template-based resource access
200+
- Subscription system for change notifications
201+
- Resource content retrieval
160202

161203
4. Prompt System
162-
- Prompt discovery
163-
- Prompt retrieval
164-
- Change notifications
204+
- Prompt discovery and listing
205+
- Parameter-based prompt retrieval
206+
- Change notifications support
207+
- Prompt content management
165208

166209
5. Tool Execution
167-
- Tool discovery
168-
- Parameter validation
169-
- Execution handling
170-
- Result processing
210+
- Tool discovery and capability checking
211+
- Parameter validation and processing
212+
- Execution handling with timeout support
213+
- Result processing with error handling
171214

172215
## Error Handling
173216

174217
The SDK provides comprehensive error handling through the McpError class:
175218

176-
- Transport-level errors
177-
- Protocol violations
219+
- Protocol version incompatibility
220+
- Transport-level communication errors
221+
- JSON-RPC protocol violations
178222
- Tool execution failures
179-
- Resource access errors
180-
- Subscription handling errors
223+
- Resource access and subscription errors
181224
- Prompt management errors
182-
- Timeout handling
225+
- Request timeout handling
226+
- Server capability mismatches
227+
- SSE connection failures and retry handling
228+
- HTTP request/response errors
183229

184230
## Contributing
185231

0 commit comments

Comments
 (0)