java-sdk/docs/ref-errors.md
Christian Tzolov abd0facf4e feat: Add MCP server with Server stdio/sse transport improve MCP client
- Implement MCP server with async/sync support and builder pattern configuration
 - Add Server stdio/SSE transport layers with robust error handling
 - Convert McpClient and McpServer to interfaces for better extensibility
 - Add sampling capabilities for LLM interactions (text/image)
 - Implement dynamic root management and runtime tool management
 - Add comprehensive prompt and resource capabilities
 - Add support for dynamic root management (add/remove roots at runtime)

 Architecture Changes

 - Introduce registration records for tools, resources, and prompts
 - Improve thread safety with concurrent collections
 - Enhance resource template handling
 - Implement builder patterns for Server/Client capabilities
 - Add support for server capabilities and implementation info

Transport Layer:
 - Implement SseServerTransport with SSE endpoints
 - Add StdioServerTransport for process-based communication
 - Reorganize transport packages for better organization
 - Improve transport error handling and shutdown processes

Documentation:

 - Add detailed MCP reference documentation
 - Include architecture diagrams and API documentation
 - Add comprehensive test coverage for all components
 - Include sample projects demonstrating stdio/SSE transports

BREAKING CHANGES:

 Transport Package Reorganization

 - Move StdioClientTransport to o.s.ai.mcp.client.transport
 - Move SseClientTransport to o.s.ai.mcp.client.transport
 - Move ServerParameters to o.s.ai.mcp.client.transport
 - StdioClientTransport.errorHandler changed to private with
   setter method Migration: Use setErrorHandler() method
   instead of direct field access

 API Changes

 - Replace static factory methods with builder pattern
 - Update ServerCapabilities to use builder pattern
 - Make StdioClientTransport.errorHandler private with setter
 - Replace rootsListProvider with direct root management
 - Remove deprecated static factory methods

Resolves #27,#25,#24,#11
Related to #12
2024-12-28 21:03:29 +01:00

154 lines
4 KiB
Markdown

# MCP Error Handling Reference
## McpError Class
`org.springframework.ai.mcp.spec.McpError`
The `McpError` class is a runtime exception that represents errors that occur during Model Context Protocol (MCP) operations. It extends `RuntimeException` and provides a way to encapsulate error information from the MCP protocol.
### Overview
The McpError class is designed to handle various error scenarios that can occur during MCP communication, including protocol errors, transport errors, and application-specific errors.
### Class Definition
```java
public class McpError extends RuntimeException {
public McpError(Object error) {
super(error.toString());
}
}
```
### Common Error Scenarios
1. **Transport Errors**
- Connection failures
- Timeout errors
- Protocol violations
2. **Protocol Errors**
- Invalid JSON-RPC messages
- Missing required fields
- Invalid method names
3. **Application Errors**
- Tool execution failures
- Resource access errors
- Invalid parameters
### Error Handling Best Practices
#### Client-Side Error Handling
```java
McpClient client = McpClient.using(transport)
.async();
client.sendRequest("method", params)
.onErrorResume(McpError.class, error -> {
// Handle MCP-specific errors
logger.error("MCP error occurred: {}", error.getMessage());
return Mono.empty();
})
.onErrorResume(Exception.class, error -> {
// Handle other exceptions
logger.error("Unexpected error: {}", error.getMessage());
return Mono.empty();
});
```
#### Server-Side Error Handling
```java
McpServer.using(transport)
.tool(new McpSchema.Tool("example", "Example tool", inputSchema),
args -> {
try {
// Tool implementation
return new McpSchema.CallToolResult(result);
}
catch (Exception e) {
// Convert to MCP error
throw new McpError("Tool execution failed: " + e.getMessage());
}
})
.async();
```
### Implementation Notes
- McpError is a runtime exception, so it doesn't require explicit declaration in method signatures
- The error message is created by calling toString() on the provided error object
- Error handling should be implemented at both client and server sides
- Reactive error handling using Project Reactor's error operators is recommended
- Consider logging errors for debugging and monitoring purposes
### Error Recovery Strategies
1. **Retry Logic**
```java
client.sendRequest("method", params)
.retry(3) // Retry up to 3 times
.onErrorResume(McpError.class, error -> {
// Handle failure after retries
return Mono.empty();
});
```
2. **Fallback Values**
```java
client.sendRequest("method", params)
.onErrorReturn(McpError.class, fallbackValue);
```
3. **Circuit Breaking**
```java
// Using Resilience4j or similar library
CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("mcpClient");
client.sendRequest("method", params)
.transform(CircuitBreakerOperator.of(circuitBreaker));
```
### Error Logging and Monitoring
```java
client.sendRequest("method", params)
.doOnError(McpError.class, error -> {
// Log error details
logger.error("MCP error: {}", error.getMessage());
// Update metrics
errorCounter.increment();
});
```
### Integration with Spring Error Handling
```java
@ControllerAdvice
public class McpErrorHandler {
@ExceptionHandler(McpError.class)
public ResponseEntity<ErrorResponse> handleMcpError(McpError error) {
ErrorResponse response = new ErrorResponse(
"MCP_ERROR",
error.getMessage()
);
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(response);
}
}
```
### Testing Error Scenarios
```java
@Test
void testMcpError() {
McpError error = new McpError("Test error");
assertEquals("Test error", error.getMessage());
assertThrows(McpError.class, () -> {
throw new McpError("Test error");
});
}