Skip to content

Latest commit

 

History

History
154 lines (124 loc) · 4.03 KB

File metadata and controls

154 lines (124 loc) · 4.03 KB

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

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

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

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
client.sendRequest("method", params)
    .retry(3) // Retry up to 3 times
    .onErrorResume(McpError.class, error -> {
        // Handle failure after retries
        return Mono.empty();
    });
  1. Fallback Values
client.sendRequest("method", params)
    .onErrorReturn(McpError.class, fallbackValue);
  1. Circuit Breaking
// Using Resilience4j or similar library
CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("mcpClient");
client.sendRequest("method", params)
    .transform(CircuitBreakerOperator.of(circuitBreaker));

Error Logging and Monitoring

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

@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

@Test
void testMcpError() {
    McpError error = new McpError("Test error");
    assertEquals("Test error", error.getMessage());
    
    assertThrows(McpError.class, () -> {
        throw new McpError("Test error");
    });
}