Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions docs/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -795,3 +795,42 @@ Supported logging levels (in order of increasing severity): DEBUG (0), INFO (1),
## Error Handling

The SDK provides comprehensive error handling through the McpError class, covering protocol compatibility, transport communication, JSON-RPC messaging, tool execution, resource management, prompt handling, timeouts, and connection issues. This unified error handling approach ensures consistent and reliable error management across both synchronous and asynchronous operations.

### Error Handling in Tool Implementations

#### Two Tiers of Errors

MCP distinguishes between two categories of errors in tool execution:

**1. Tool-Level Errors (Recoverable by the LLM)**

Use `CallToolResult` with `isError(true)` for validation failures, missing arguments, or domain errors the LLM can act on and retry.

```java
// Example: Domain validation failure (e.g., invalid email format)
if (!emailAddress.matches("^[A-Za-z0-9+_.-]+@(.+)$")) {
return CallToolResult.builder()
.content(List.of(new McpSchema.TextContent("Invalid argument: 'email' must be a valid email address.")))
.isError(true)
.build();
}
```
Comment on lines +809 to +817
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example is a bit contrived, because MCP already has semantics for input parameter "required".

Please change it to something more realistic, e.g. validating an address, or an email?


The LLM receives this as part of the normal tool response and can self-correct in a subsequent interaction.

**2. Protocol-Level Errors (Unrecoverable)**

Uncaught exceptions from a tool handler are mapped to a JSON-RPC error response. Use this only for truly unexpected failures (e.g., infrastructure errors such as DB timeout), not for input validation.

```java
// This propagates as a JSON-RPC error — use sparingly
throw new McpError(McpSchema.ErrorCodes.INTERNAL_ERROR, "Unexpected failure");
```

#### Decision Guide

| Situation | Approach |
|------------------------------------|---------------------------------------|
| Domain validation failure | `CallToolResult` with `isError=true` |
| Infrastructure / unexpected error | Throw `McpError` or let it propagate |
| Partial success with a warning | `CallToolResult` with warning in text |