examples/MCP-tools Public
id: 0002-tool-errors-are-results
type: decision
owner: justin
reviewed: 2026-10-13
status: accepted
0002 Tool errors are results
Context
A tool can fail in two ways in MCP. A JSON-RPC error (-32602 and friends) tells the client the request itself was bad. A tool result with isError: true tells the model the call went through and here is what went wrong. Many clients show JSON-RPC errors to the user, or retry, and never put them in front of the model.
Most of our failures are the model's to fix: a unit we do not know, a time zone that does not exist, an instant without an offset.
Decision
Every failure inside a tool call comes back as a result with isError: true and a message written for the model:
- A tool throws
ToolErrorfor anything the caller can fix. The message says what was wrong and gives an example of what would work. - Arguments that fail the input schema are answered by the SDK the same way, with zod's message.
- Any other exception is logged and returned as an
isErrorresult saying the server failed and the same input will fail again, so the model does not loop.
JSON-RPC errors are left for protocol problems: malformed JSON, an unknown method, a missing Accept header.
Consequences
- Models correct themselves on the next call (
furlongbecomesft,Mars/BasebecomesUTC) instead of giving up. - Error messages are part of the interface and are tested like output. Changing one is a behavior change.
- Usage counts can report errors per tool, which shows where descriptions need work; see [[usage-counts]].