Proposals · SEP-2145 · Accepted

Standardize `tools/call` Failure Reporting

Standards Track · Created 2026-01-23 · Source

Abstract

This SEP proposes clarifying and extending tools/call error handling so that more tool-invocation failure modes are reported as Tool Execution Errors (i.e., a successful JSON-RPC response containing a CallToolResult with isError: true), rather than as JSON-RPC Protocol Errors.

Building on SEP-1303 (input validation errors), this SEP focuses on: (1) tool resolution failures (unknown tool names, tools that are present but not callable due to server policy/disablement), and (2) output validation failures for tools that declare an outputSchema but return missing or non-conforming structuredContent.

The goal is to make these failures consistently visible to language models (and other clients), improving self-correction and recovery behavior.

Motivation

SEP-1303 established that tool input validation failures are most useful when returned as tool execution errors, because models can read the message and self-correct.

In practice, additional tools/call failure modes are similarly actionable (or at least strategically useful) to surface to the model:

Today, the draft schema documentation states that "errors in finding the tool" should be protocol errors, and SEP-1303 retained that categorization when it went Final. This SEP proposes reversing that decision so that resolution failures are model-visible. The current split causes inconsistent implementations and pushes "out-of-the-box" behavior into client-specific policy, which many hosts will not implement.

Specification

Terminology

Imported from upstream. Proposed as modelcontextprotocol#2145 by @KKonstantinov on 2026-01-23, where it was still open on 2026-09-25. Accepted into omcp on its technical merit. The text is the author's; only the status, the sponsor field, and documentation links were changed on import.

Reviewed 2026-09-25 — accepted. The document carries every required section, and a prototype a reviewer can run is cited at https://github.com/modelcontextprotocol/typescript-sdk/pull/1389. Conformance tests and the reference documentation chapter are still required before Final.

Normative requirements (server behavior)

Given a tools/call request that satisfies the CallToolRequest schema (i.e., it is not malformed at the protocol level), servers:

  1. MUST report tool input validation failures as Tool Execution Errors (extending the categorization established by SEP-1303).

    • This includes failures of JSON Schema validation against the tool's inputSchema as well as additional programmatic validation (ranges, invariants, cross-field checks, etc.).
  2. MUST report tool resolution failures as Tool Execution Errors, including:

    • Unknown tool: params.name does not match any callable tool.
    • Tool not callable: the tool exists conceptually but cannot be executed (e.g., disabled, unavailable, policy-restricted).
  3. MUST report tool execution failures as Tool Execution Errors, including:

    • Exceptions thrown by the tool implementation.
    • Timeouts or server-internal aborts that occur during tool execution (if the server can still return a CallToolResult). Client-initiated cancellation continues to follow the cancellation utility.
  4. SHOULD report output validation failures as Tool Execution Errors when a tool declares an outputSchema, including:

    • structuredContent is missing when the server/tool intended to provide structured output.
    • structuredContent is present but does not conform to outputSchema.
    • structuredContent is present but is not an object (root must be type: "object").

    Note: tools.mdx already requires "Servers MUST provide structured results that conform to outputSchema" and "Clients SHOULD validate." This requirement is defense-in-depth: when a server fails to conform, it SHOULD also report the failure as a Tool Execution Error rather than returning silently invalid output.

  5. MUST use Protocol Errors only for protocol-level failures, such as:

    • Malformed requests that fail to satisfy the CallToolRequest schema (e.g., missing params, wrong types).
    • JSON-RPC method-level failures (e.g., tools/call method not supported / not implemented).
    • Server failures that prevent constructing a CallToolResult at all (e.g., unrecoverable internal errors before tool invocation can be represented as a result).

Error message guidance (non-normative)

When returning Tool Execution Errors, servers SHOULD include a short, actionable message in the first content item (typically a text content block). Recommended patterns:

Servers SHOULD avoid leaking sensitive policy details in messages.

Examples

Protocol error (malformed request)

If the request is invalid at the CallToolRequest schema level (e.g., missing params.name, invalid params type, etc.), the server returns a JSON-RPC error response.

{
  "jsonrpc": "2.0",
  "id": 3,
  "error": {
    "code": -32602,
    "message": "Invalid params"
  }
}

Tool execution error (unknown tool)

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Unknown tool: invalid_tool_name. Re-run tools/list and retry."
      }
    ],
    "isError": true
  }
}

Tool execution error (tool not callable / disabled / policy-restricted)

{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Tool unavailable: update_flight_details. This tool is disabled or policy-restricted."
      }
    ],
    "isError": true
  }
}

Tool execution error (output schema validation failure)

{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Tool produced invalid structured output for get_weather: structuredContent did not conform to outputSchema."
      }
    ],
    "isError": true
  }
}

Specification text changes (draft targets)

This SEP intends to update the draft specification text in:

Proposed draft wording for docs/specification/draft/server/tools.mdx (Error Handling)

## Error Handling

Tools use two error reporting mechanisms:

1. **Protocol Errors**: Standard JSON-RPC errors for protocol-level issues like:
   - Malformed requests (requests that fail to satisfy [CallToolRequest schema](/specification/draft/schema#calltoolrequest))
   - Server errors (when the server cannot return a tool result)
   - Unsupported methods (e.g., server does not implement `tools/call`)

2. **Tool Execution Errors**: Reported in tool results with `isError: true`:
   - Tool resolution failures (unknown tool name)
   - Tool availability failures (disabled, unavailable, policy-restricted)
   - Input validation errors (e.g., date in wrong format, value out of range; arguments do not match tool `inputSchema`)
   - Output validation errors (e.g., tool declared `outputSchema` but returned missing or non-conforming `structuredContent`)
   - API failures
   - Business logic errors

**Tool Execution Errors** contain actionable feedback that language models can use to self-correct and retry with adjusted parameters or alternative strategies.
**Protocol Errors** indicate issues with the request structure or method support itself.
Clients **SHOULD** provide tool execution errors to language models to enable self-correction.
Clients **MAY** provide protocol errors to language models, though these are less likely to result in successful recovery.

Proposed adjustment to CallToolResult.isError documentation (draft schema)

This SEP proposes changing the CallToolResult.isError documentation to treat "errors in finding the tool" as a Tool Execution Error for tools/call (i.e., return CallToolResult with isError: true) when the request itself is well-formed.

Rationale

Backward Compatibility

This SEP does not change JSON-RPC framing or introduce new required fields.

However, it is a behavioral change for servers that currently return Protocol Errors for tool resolution and output validation failures. Clients that rely on a JSON-RPC error response for these cases will need to handle CallToolResult.isError: true equivalently.

Notably, typescript-sdk#1389 (merged March 2026) recently changed the TypeScript SDK to return protocol errors for unknown tools, conforming to the current spec. Accepting this SEP would require reverting that change. python-sdk#1872 proposes a similar alignment for the Python SDK and would also need to be reconsidered.

Mitigations:

Security Implications

Reference Implementation

The Python SDK currently wraps exceptions and returns CallToolResult with isError: true for unknown tools and other failures. The TypeScript SDK previously did the same, but typescript-sdk#1389 (merged March 2026) reverted it to protocol errors for unknown tools to conform with the current spec text. Accepting this SEP would require re-reverting the TypeScript SDK.

This SEP's reference implementation would be a documentation + SDK conformance update:

Alternatives Considered

Open Questions

Acknowledgments

All participants in https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1303