remove folder duplication
This commit is contained in:
parent
82c64f5ad3
commit
05085b76e6
5 changed files with 0 additions and 478 deletions
|
|
@ -1,144 +0,0 @@
|
||||||
# SSE Server Transport Implementation for MCP
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
- **Bidirectional Communication**:
|
|
||||||
- Inbound: Receives messages through SSE connection
|
|
||||||
- Outbound: Sends messages via HTTP POST requests
|
|
||||||
|
|
||||||
- **Error Handling**:
|
|
||||||
- Automatic reconnection for transient failures
|
|
||||||
- Graceful shutdown capabilities
|
|
||||||
- Comprehensive error reporting
|
|
||||||
|
|
||||||
- **Message Flow**:
|
|
||||||
1. Client establishes SSE connection to `/sse` endpoint
|
|
||||||
2. Server sends 'endpoint' event with message URI
|
|
||||||
3. Client uses provided URI for outbound messages
|
|
||||||
|
|
||||||
## Technical Details
|
|
||||||
|
|
||||||
### Transport Architecture
|
|
||||||
|
|
||||||
The transport consists of two main processing pipelines:
|
|
||||||
|
|
||||||
1. **Inbound Processing**:
|
|
||||||
- Establishes SSE connection to `/sse` endpoint
|
|
||||||
- Handles two types of events:
|
|
||||||
- `message`: JSON-RPC protocol messages
|
|
||||||
- `endpoint`: Server-provided URI for outbound messages
|
|
||||||
- Implements automatic retry logic for connection failures
|
|
||||||
|
|
||||||
2. **Outbound Processing**:
|
|
||||||
- Sends messages via HTTP POST to server-provided endpoint
|
|
||||||
- Uses dedicated scheduler for sequential message processing
|
|
||||||
- Handles JSON serialization and HTTP communication
|
|
||||||
|
|
||||||
### Key Components
|
|
||||||
|
|
||||||
- **WebClient**: Handles HTTP communications for both SSE and POST requests
|
|
||||||
- **ObjectMapper**: Manages JSON serialization/deserialization
|
|
||||||
- **Scheduler**: Ensures sequential outbound message processing
|
|
||||||
- **Message Endpoint Sink**: Manages server-provided endpoint URI
|
|
||||||
|
|
||||||
## Usage Example
|
|
||||||
|
|
||||||
```java
|
|
||||||
// Create WebClient builder with base URL
|
|
||||||
WebClient.Builder webClientBuilder = WebClient.builder()
|
|
||||||
.baseUrl("http://localhost:3001");
|
|
||||||
|
|
||||||
// Initialize transport
|
|
||||||
SseClientTransport transport = new SseClientTransport(webClientBuilder);
|
|
||||||
|
|
||||||
// Create a JSON-RPC request
|
|
||||||
JSONRPCRequest request = new JSONRPCRequest(
|
|
||||||
McpSchema.JSONRPC_VERSION,
|
|
||||||
"method-name",
|
|
||||||
"request-id",
|
|
||||||
Map.of("key", "value")
|
|
||||||
);
|
|
||||||
|
|
||||||
// Send message
|
|
||||||
transport.sendMessage(request)
|
|
||||||
.subscribe(
|
|
||||||
success -> System.out.println("Message sent successfully"),
|
|
||||||
error -> System.err.println("Error sending message: " + error)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Graceful shutdown when done
|
|
||||||
transport.closeGracefully()
|
|
||||||
.subscribe();
|
|
||||||
```
|
|
||||||
|
|
||||||
## Implementation Details
|
|
||||||
|
|
||||||
### Message Processing
|
|
||||||
|
|
||||||
1. **Inbound Messages**:
|
|
||||||
- Received through SSE connection
|
|
||||||
- Automatically deserialized from JSON
|
|
||||||
- Routed to appropriate handlers based on event type
|
|
||||||
|
|
||||||
2. **Outbound Messages**:
|
|
||||||
- Serialized to JSON
|
|
||||||
- Sent via HTTP POST
|
|
||||||
- Processed sequentially on dedicated thread
|
|
||||||
|
|
||||||
### Error Handling
|
|
||||||
|
|
||||||
- **Connection Failures**:
|
|
||||||
- Automatic retry for transient failures
|
|
||||||
- Configurable retry policies
|
|
||||||
- Graceful handling of permanent failures
|
|
||||||
|
|
||||||
- **Message Processing Errors**:
|
|
||||||
- Comprehensive error reporting
|
|
||||||
- Clean failure handling
|
|
||||||
- Maintains system stability
|
|
||||||
|
|
||||||
### Shutdown Process
|
|
||||||
|
|
||||||
The transport implements a graceful shutdown mechanism that:
|
|
||||||
1. Marks transport as closing
|
|
||||||
2. Disposes of all subscriptions
|
|
||||||
3. Cleans up schedulers
|
|
||||||
4. Completes message endpoint sink
|
|
||||||
|
|
||||||
## Technical Specifications
|
|
||||||
|
|
||||||
- **Protocol**: HTTP with Server-Sent Events (SSE)
|
|
||||||
- **Message Format**: JSON-RPC 2.0
|
|
||||||
- **Content Type**: application/json for outbound, text/event-stream for inbound
|
|
||||||
- **Endpoints**:
|
|
||||||
- SSE Connection: `/sse`
|
|
||||||
- Message Endpoint: Dynamically provided by server
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- Spring WebFlux for reactive HTTP client
|
|
||||||
- Jackson for JSON processing
|
|
||||||
- Project Reactor for reactive streams
|
|
||||||
- SLF4J for logging
|
|
||||||
|
|
||||||
## Thread Safety
|
|
||||||
|
|
||||||
The implementation is thread-safe and designed for concurrent use:
|
|
||||||
- Inbound processing uses SSE event loop
|
|
||||||
- Outbound processing uses dedicated single-threaded scheduler
|
|
||||||
- State management uses thread-safe constructs
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
The implementation includes comprehensive tests covering:
|
|
||||||
- Message processing
|
|
||||||
- Error handling
|
|
||||||
- Connection management
|
|
||||||
- Shutdown procedures
|
|
||||||
- Edge cases and failure scenarios
|
|
||||||
|
|
||||||
For detailed test examples, see `SseClientTransportTests.java`.
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
# StdioClientTransport
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
The Stdio transport uses standard input/output streams for bidirectional communication between the client and server:
|
|
||||||
- Messages are sent to the server via stdout
|
|
||||||
- Messages are received from the server via stdin
|
|
||||||
- Error and debug information is sent via stderr
|
|
||||||
|
|
||||||
## Message Format
|
|
||||||
|
|
||||||
Messages are exchanged as newline-delimited JSON-RPC messages:
|
|
||||||
- Each message is a single line of JSON text
|
|
||||||
- Messages are terminated with a newline character (`\n`)
|
|
||||||
- Messages follow the JSON-RPC 2.0 specification
|
|
||||||
- UTF-8 encoding is used for all messages
|
|
||||||
|
|
||||||
### Message Types
|
|
||||||
|
|
||||||
The transport handles three types of JSON-RPC messages:
|
|
||||||
|
|
||||||
1. **Requests** - Messages with both `method` and `id` fields:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"jsonrpc": "2.0",
|
|
||||||
"id": 1,
|
|
||||||
"method": "example.method",
|
|
||||||
"params": {}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Notifications** - Messages with `method` but no `id` field:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"jsonrpc": "2.0",
|
|
||||||
"method": "example.notification",
|
|
||||||
"params": {}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Responses** - Messages with either `result` or `error` fields:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"jsonrpc": "2.0",
|
|
||||||
"id": 1,
|
|
||||||
"result": {}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Implementation Details
|
|
||||||
|
|
||||||
### Process Management
|
|
||||||
|
|
||||||
The transport manages a server process with:
|
|
||||||
- Command and arguments specified via `ServerParameters`
|
|
||||||
- Environment variables for configuration
|
|
||||||
- Proper process cleanup on shutdown
|
|
||||||
|
|
||||||
### Threading Model
|
|
||||||
|
|
||||||
The implementation uses three dedicated threads:
|
|
||||||
1. **Inbound** - Reads and processes messages from stdin
|
|
||||||
2. **Outbound** - Writes messages to stdout
|
|
||||||
3. **Error** - Handles stderr messages
|
|
||||||
|
|
||||||
### Error Handling
|
|
||||||
|
|
||||||
Errors are handled at multiple levels:
|
|
||||||
- Process startup failures
|
|
||||||
- Stream I/O errors
|
|
||||||
- Message parsing errors
|
|
||||||
- Process termination handling
|
|
||||||
|
|
||||||
## Usage Example
|
|
||||||
|
|
||||||
```java
|
|
||||||
// Create server parameters
|
|
||||||
ServerParameters params = ServerParameters.builder()
|
|
||||||
.command("path/to/server")
|
|
||||||
.args(List.of("--arg1", "value1"))
|
|
||||||
.env(Map.of("ENV_VAR", "value"))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Create transport
|
|
||||||
StdioClientTransport transport = new StdioClientTransport(params);
|
|
||||||
|
|
||||||
// Start transport
|
|
||||||
transport.start();
|
|
||||||
|
|
||||||
// Send message
|
|
||||||
JSONRPCRequest request = new JSONRPCRequest();
|
|
||||||
request.setId(1);
|
|
||||||
request.setMethod("example.method");
|
|
||||||
request.setParams(new HashMap<>());
|
|
||||||
transport.send(request);
|
|
||||||
|
|
||||||
// Close transport
|
|
||||||
transport.closeGracefully().block();
|
|
||||||
```
|
|
||||||
|
|
||||||
## Error Messages
|
|
||||||
|
|
||||||
Error messages from the server process are:
|
|
||||||
- Written to stderr
|
|
||||||
- Logged at ERROR level
|
|
||||||
- Emitted through the error sink for handling
|
|
||||||
- UTF-8 encoded
|
|
||||||
|
|
||||||
## Debugging
|
|
||||||
|
|
||||||
For debugging purposes:
|
|
||||||
1. Enable DEBUG level logging to see detailed message flow
|
|
||||||
2. Monitor stderr for server process errors
|
|
||||||
3. Check process exit codes for abnormal termination
|
|
||||||
|
|
||||||
## Implementation Notes
|
|
||||||
|
|
||||||
- The transport ensures thread safety through dedicated schedulers
|
|
||||||
- Messages are processed asynchronously using Project Reactor
|
|
||||||
- Resources are properly cleaned up on shutdown
|
|
||||||
- The implementation is resilient to various failure modes
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
# MCP Session Components
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
The MCP (Model Context Protocol) session components implement the [MCP specification](https://spec.modelcontextprotocol.io/) for managing bidirectional JSON-RPC communication between clients and model servers.
|
|
||||||
The implementation provides a robust foundation for request-response patterns and notification handling.
|
|
||||||
|
|
||||||
## Core Components
|
|
||||||
|
|
||||||
### McpSession Interface
|
|
||||||
|
|
||||||
The `McpSession` interface defines the contract for MCP communication with three primary operations:
|
|
||||||
|
|
||||||
1. Request-Response Communication
|
|
||||||
```java
|
|
||||||
<T> Mono<T> sendRequest(String method, Object requestParams, TypeReference<T> typeRef);
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Notification Handling
|
|
||||||
```java
|
|
||||||
Mono<Void> sendNotification(String method, Map<String, Object> params);
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Session Lifecycle Management
|
|
||||||
```java
|
|
||||||
Mono<Void> closeGracefully();
|
|
||||||
```
|
|
||||||
|
|
||||||
### DefaultMcpSession Implementation
|
|
||||||
|
|
||||||
The `DefaultMcpSession` provides the concrete implementation of the MCP session with the following key features:
|
|
||||||
|
|
||||||
#### 1. Message Correlation
|
|
||||||
- Uses unique request IDs combining session UUID prefix and atomic counter
|
|
||||||
- Maintains thread-safe tracking of pending responses
|
|
||||||
- Implements timeout management for requests
|
|
||||||
|
|
||||||
#### 2. Handler Registration
|
|
||||||
```java
|
|
||||||
public interface RequestHandler {
|
|
||||||
Mono<Object> handle(Object params);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface NotificationHandler {
|
|
||||||
Mono<Void> handle(Object params);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3. Transport Integration
|
|
||||||
- Abstracts transport details through `McpTransport` interface
|
|
||||||
- Supports different transport implementations (SSE, STDIO)
|
|
||||||
- Manages message serialization using Jackson
|
|
||||||
|
|
||||||
## Implementation Details
|
|
||||||
|
|
||||||
- The session processes three types of messages: McpSchema.JSONRPCResponse, McpSchema.JSONRPCRequest, McpSchema.JSONRPCNotificaiton.
|
|
||||||
- The implementation ensures thread safety through
|
|
||||||
|
|
||||||
### Error Handling
|
|
||||||
|
|
||||||
WIP
|
|
||||||
|
|
||||||
## Integration Guidelines
|
|
||||||
|
|
||||||
1. **Transport Selection**
|
|
||||||
- Choose appropriate transport (SSE, STDIO) based on use case
|
|
||||||
- Configure transport-specific parameters
|
|
||||||
- Handle transport lifecycle properly
|
|
||||||
|
|
||||||
2. **Message Handling**
|
|
||||||
- Register handlers before starting session
|
|
||||||
- Use appropriate error codes from MCP specification
|
|
||||||
- Implement proper request/response correlation
|
|
||||||
|
|
||||||
3. **Type Safety**
|
|
||||||
- Use appropriate TypeReference for response deserialization
|
|
||||||
- Validate request parameters
|
|
||||||
- Handle type conversion errors
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
||||||
@startuml Core Components
|
|
||||||
|
|
||||||
interface McpTransport {
|
|
||||||
+Mono<Void> connect(Function<Mono<JSONRPCMessage>,
|
|
||||||
Mono<JSONRPCMessage>> handler)
|
|
||||||
+Mono<Void> sendMessage()
|
|
||||||
+void close()
|
|
||||||
+Mono<Void> closeGracefully()
|
|
||||||
}
|
|
||||||
|
|
||||||
interface McpSession {
|
|
||||||
+<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 {
|
|
||||||
-McpTransport transport
|
|
||||||
-ObjectMapper objectMapper
|
|
||||||
}
|
|
||||||
|
|
||||||
class McpClient {
|
|
||||||
+{static} async()
|
|
||||||
+{static} sync()
|
|
||||||
}
|
|
||||||
|
|
||||||
class McpAsyncClient {
|
|
||||||
+Mono<InitializeResult> initialize()
|
|
||||||
+Mono<CallToolResult> callTool()
|
|
||||||
+Mono<ListToolsResult> listTools()
|
|
||||||
+Mono<ListResourcesResult> listResources()
|
|
||||||
+Mono<ReadResourceResult> readResource()
|
|
||||||
+Mono<ListPromptsResult> listPrompts()
|
|
||||||
+Mono<GetPromptResult> getPrompt()
|
|
||||||
}
|
|
||||||
|
|
||||||
class McpSyncClient {
|
|
||||||
+InitializeResult initialize()
|
|
||||||
+CallToolResult callTool()
|
|
||||||
+ListToolsResult listTools()
|
|
||||||
+ListResourcesResult listResources()
|
|
||||||
+ReadResourceResult readResource()
|
|
||||||
+ListPromptsResult listPrompts()
|
|
||||||
+GetPromptResult getPrompt()
|
|
||||||
}
|
|
||||||
|
|
||||||
class StdioClientTransport {
|
|
||||||
-Process serverProcess
|
|
||||||
-ServerParameters parameters
|
|
||||||
}
|
|
||||||
|
|
||||||
class SseClientTransport {
|
|
||||||
-WebClient webClient
|
|
||||||
}
|
|
||||||
|
|
||||||
class McpSchema {
|
|
||||||
+class ErrorCodes
|
|
||||||
+interface Request
|
|
||||||
+interface JSONRPCMessage
|
|
||||||
+interface ResourceContents
|
|
||||||
+interface Content
|
|
||||||
}
|
|
||||||
|
|
||||||
class McpError {
|
|
||||||
-int code
|
|
||||||
-String message
|
|
||||||
}
|
|
||||||
|
|
||||||
McpTransport <|-- StdioClientTransport
|
|
||||||
McpTransport <|-- SseClientTransport
|
|
||||||
McpSession <|-- DefaultMcpSession
|
|
||||||
DefaultMcpSession --o McpAsyncClient
|
|
||||||
McpClient ..> McpAsyncClient : creates
|
|
||||||
McpClient ..> McpSyncClient : creates
|
|
||||||
McpSyncClient o-- McpAsyncClient
|
|
||||||
DefaultMcpSession o-- McpTransport
|
|
||||||
McpSchema <.. McpSession : uses
|
|
||||||
McpError ..> McpSession : throws
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
|
|
||||||
@startuml Message Flow
|
|
||||||
|
|
||||||
package "MCP Schema" {
|
|
||||||
interface JSONRPCMessage {
|
|
||||||
+String jsonrpc()
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Request {
|
|
||||||
}
|
|
||||||
|
|
||||||
class InitializeRequest
|
|
||||||
class CallToolRequest
|
|
||||||
class CreateMessageRequest
|
|
||||||
class CompleteRequest
|
|
||||||
class GetPromptRequest
|
|
||||||
}
|
|
||||||
|
|
||||||
package "Resource Types" {
|
|
||||||
interface ResourceContents {
|
|
||||||
+String uri()
|
|
||||||
+String mimeType()
|
|
||||||
}
|
|
||||||
|
|
||||||
class TextResourceContents
|
|
||||||
class BlobResourceContents
|
|
||||||
|
|
||||||
interface Content {
|
|
||||||
+String type()
|
|
||||||
}
|
|
||||||
|
|
||||||
class TextContent
|
|
||||||
class ImageContent
|
|
||||||
class EmbeddedResource
|
|
||||||
}
|
|
||||||
|
|
||||||
JSONRPCMessage <|.. Request
|
|
||||||
Request <|.. InitializeRequest
|
|
||||||
Request <|.. CallToolRequest
|
|
||||||
Request <|.. CreateMessageRequest
|
|
||||||
Request <|.. CompleteRequest
|
|
||||||
Request <|.. GetPromptRequest
|
|
||||||
|
|
||||||
ResourceContents <|.. TextResourceContents
|
|
||||||
ResourceContents <|.. BlobResourceContents
|
|
||||||
|
|
||||||
Content <|.. TextContent
|
|
||||||
Content <|.. ImageContent
|
|
||||||
Content <|.. EmbeddedResource
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 28 KiB |
Loading…
Reference in a new issue