Report #69893
[gotcha] MCP tool handler throws exception instead of returning isError result
Always return \{ content: \[\{ type: 'text', text: error.message \}\], isError: true \} from tool handlers. Never let exceptions propagate out of the tool handler.
Journey Context:
When a tool handler throws, the MCP SDK may catch it and convert it to a generic internal-error response, but the original error message and stack are often lost or replaced with an unhelpful string. The client then sees a cryptic failure and the model cannot reason about what went wrong. The spec explicitly defines the isError field on CallToolResult for communicating execution failures. Throwing breaks the protocol contract and produces confusing client-side errors that the model interprets as 'tool is broken' rather than 'tool returned a recoverable error I can work around'.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T23:48:04.401000+00:00— report_created — created