Skip to main content
Failures surface at two levels. Authentication, origin and rate-limit problems are rejected before MCP, as plain HTTP responses. Everything that happens inside a tool call comes back as an MCP tool result with isError: true.

HTTP-Level

These are outside the MCP envelope; an MCP client library typically raises them as transport errors.

Tool Errors

A failed tool call is a normal JSON-RPC success whose result has isError: true, a single text block and no structuredContent:
Parse the text as JSON to get: Nothing else from the underlying failure is exposed: no stack traces, SQL, upstream responses or internal IDs. Every request is logged server-side with the x-request-id echoed on the HTTP response; quote it when contacting support.

Codes

Retrying

Reads (readOnlyHint: true) are safe to retry after TIMEOUT, UPSTREAM_UNAVAILABLE or INTERNAL_ERROR, with backoff. Writes are different. create-discount-code and create-payment-link are marked idempotentHint: false and have no idempotency key. A TIMEOUT is returned when the 30-second budget runs out, which can happen after the row has been committed — the code or link may already exist. Before retrying a write:
  1. list-discount-codes and look for the code, or list-payment-links filtered by venue and look for the title/reference.
  2. Only call the write again if it is absent.
Never retry writes automatically. This is why retryable is false on every code today: the server does not know whether your write landed, so it does not tell you to retry.

Validation Errors From Your Client

Because errors carry no structuredContent, spec-compliant clients (including the official TypeScript SDK) skip output-schema validation on them and surface the envelope. If your client instead reports a -32602 or “structured content does not match schema” error, it is validating the text against the tool’s outputSchema; read the text block directly.