Skip to content

docs: document best practice for handling argument errors in MCP tools#891

Open
radeshgovind-2005 wants to merge 1 commit intomodelcontextprotocol:mainfrom
radeshgovind-2005:docs/error-handling-best-practices
Open

docs: document best practice for handling argument errors in MCP tools#891
radeshgovind-2005 wants to merge 1 commit intomodelcontextprotocol:mainfrom
radeshgovind-2005:docs/error-handling-best-practices

Conversation

@radeshgovind-2005
Copy link
Copy Markdown

Resolves #356

Clarify the two-tier error model:

  • Recoverable tool errors: use CallToolResult with isError(true)
  • Protocol-level errors: throw McpError / let exceptions propagate as JSON-RPC errors

Motivation and Context

Issue #356 raised uncertainty about whether tool argument errors should throw
exceptions or be returned as CallToolResult. The maintainer clarified the correct
approach in the thread but it was not yet documented. This PR formalizes that guidance.

How Has This Been Tested?

Documentation-only change. The full test suite passes locally (747 tests, 0 failures).

Breaking Changes

None.

Types of changes

  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added or updated documentation as needed

Additional context

The new section was added under the existing ## Error Handling section in
docs/server.md to keep all error-related documentation in one place.

…ations

Resolves modelcontextprotocol#356

Clarify the two-tier error model:
- Recoverable tool errors: use CallToolResult with isError(true)
- Protocol-level errors: throw McpError / let exceptions propagate as JSON-RPC errors
Copy link
Copy Markdown
Contributor

@Kehrlann Kehrlann left a comment

Choose a reason for hiding this comment

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

Looks good. A few comments in the PR.

Comment on lines +809 to +817
```java
// Example: missing required argument
if (lastName == null || lastName.isBlank()) {
return CallToolResult.builder()
.content(List.of(new McpSchema.TextContent("Missing required argument: last_name")))
.isError(true)
.build();
}
```
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?


**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), not for input validation.
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.

Suggested change
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), not for input validation.
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.

Comment on lines +834 to +835
| Missing / invalid argument | `CallToolResult` with `isError=true` |
| Domain validation failure | `CallToolResult` with `isError=true` |
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.

Both cases are the same, let's fold them together.

Suggested change
| Missing / invalid argument | `CallToolResult` with `isError=true` |
| Domain validation failure | `CallToolResult` with `isError=true` |
| Domain validation failure | `CallToolResult` with `isError=true` |

@Kehrlann Kehrlann self-assigned this Apr 1, 2026
@Kehrlann Kehrlann added documentation Improvements or additions to documentation waiting for user Waiting for user feedback or more details labels Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation waiting for user Waiting for user feedback or more details

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Document best Practice for Handling Argument Errors in MCP Tool Rendering

2 participants