MCP Error Handling Extension: Structured Failures and Retry Strategy

Every MCP tool failure should return a structured response the agent can act on — not an opaque error that forces the agent to guess.

MCP Extensions Error Handling

Why Structured Error Handling Matters

An MCP tool that fails with an unstructured error forces the calling agent to guess what went wrong. The agent may retry indefinitely, report a nonsensical error to the user, or silently drop the failed action. None of these is acceptable in a production enterprise deployment.

Structured error handling means every MCP tool failure returns a response the agent can act on: a machine-readable error code, a human-readable description, and enough context to decide what to do next.

The Standard Error Response Format

Every MCP tool should return a consistent response object whether it succeeds or fails:

  • success: boolean — did the tool call succeed?
  • data: object — the result data (present on success, null on failure)
  • error_code: string — machine-readable error category (e.g., NOT_FOUND, PERMISSION_DENIED, SYSTEM_UNAVAILABLE, VALIDATION_ERROR)
  • error_message: string — human-readable description of what went wrong
  • retry_recommended: boolean — should the agent try again?
  • retry_after_seconds: integer — if retrying, how long to wait

Error Categories and Agent Behavior

Data table
Error CodeMeaningAgent Should
NOT_FOUNDThe requested resource doesn't existInform user, stop retrying
PERMISSION_DENIEDAgent lacks authorization for this actionEscalate to human, stop retrying
VALIDATION_ERRORInput parameters are invalidReport validation details, allow correction
SYSTEM_UNAVAILABLETarget system is temporarily downRetry with backoff after retry_after_seconds
RATE_LIMITEDToo many calls in the time windowPause and retry after retry_after_seconds

Retry Strategy

Agents should implement exponential backoff with jitter for retryable errors. Never retry PERMISSION_DENIED or NOT_FOUND — these won't resolve with retries. Always retry SYSTEM_UNAVAILABLE and RATE_LIMITED with the specified delay.

Put these cookbook patterns to work

Get started