MCP Tool Error Handling: isError, Error Categories and Retries

When a tool fails, the agent can only recover sensibly if it knows why. A generic “Operation failed” leads to pointless retries of policy violations and early surrender on simple timeouts. This is Task Statement 2.2.

Advertisement
📖 What You’ll Learn: You will be able to design MCP tool errors that let Claude retry what is worth retrying and explain or escalate the rest.

🚨 The isError pattern

MCP tools signal failure with isError: true in the tool result. Put structured metadata in the content:

{
  "isError": true,
  "content": [{"type": "text", "text": "{\"errorCategory\": \"business\", \"isRetryable\": false, \"message\": \"Refund window is 30 days; this order was delivered 41 days ago.\", \"customerMessage\": \"This order is outside our 30-day refund window.\"}"}]
}

🚨 Four error categories

CategoryExampleRetryable?Agent should…
TransientTimeout, 503YesRetry with backoff
ValidationBad date formatYes, after fixing inputCorrect and retry
BusinessPolicy limit exceededNoExplain or escalate
PermissionNot authorisedNoEscalate or request access

🚨 Empty result is not an error

“No orders found for this customer” is a successful query with zero matches. A database timeout is an access failure. Reporting empty results as errors triggers retries; reporting failures as empty results hides problems.

📘 Local recovery in multi-agent systems

Subagents should handle transient failures themselves and propagate only what they can’t resolve — with what they attempted and any partial results — so the coordinator can decide what to do next.

Advertisement

🧪 Exam-Style Practice Questions

Try these before opening the answers. They use the same scenario style as the real exam.

Question 1. An MCP tool times out. What should it return?

  • A. A Python stack trace
  • B. A result with `isError: true` and structured metadata (category transient, retryable)
  • C. An empty array
  • D. Nothing; let the client hang
Show answer

Answer: B. It's structured and actionable. C disguises a failure as "no data". A is noisy and possibly leaks internals. D is broken behaviour.

Question 2. A search returns no matching orders for a valid customer. How should the tool report this?

  • A. As an error with `isRetryable: true`
  • B. By throwing a timeout
  • C. As a successful result with an empty list
  • D. As a permission error
Show answer

Answer: C. A valid query with zero matches is a success. Treating it as an error (A, D, B) triggers pointless retries or escalation.

Question 3. Which error should **not** be retried?

  • A. Network timeout
  • B. 503 Service Unavailable
  • C. Rate limited
  • D. "Refund exceeds the 30-day policy window"
Show answer

Answer: D. A business-rule violation: retrying won't change the outcome, so explain it or escalate. B, A and C are transient.

Advertisement

📝 Assignment

Do these tasks in order. Each one has a Done when check, so you know when it is complete. The stretch task is optional but close to what the exam expects from an architect. Keep your answers in one notes file or Git repository, and revisit them in your final week of revision together with the cheat sheet in the last lesson of this course.

  1. Task 1: List three failures your own tools can produce and classify each as transient, validation, business or permission.
    ✅ Done when: Each failure is assigned exactly one category and marked retryable or not retryable, with a reason.
  2. Task 2: Write the JSON error body for a business-rule failure, including a customer-friendly message.
    ✅ Done when: Your JSON includes isError, errorCategory, isRetryable and a message a customer could read without confusion.
  3. Stretch: make a subagent retry a transient error locally and report partial results to the coordinator only if it still fails.
    ✅ Done when: A simulated timeout is retried inside the subagent, and only a persistent failure reaches the coordinator with partial results.
Advertisement

❓ Frequently Asked Questions

🤔 What is the isError flag in MCP?

A field on the tool result that tells the client and Claude the tool call failed.

🤔 Which errors should not be retried?

Business-rule violations and permission errors. Retrying cannot change their outcome.

🤔 Is no results an error?

No. A valid query that matches nothing is a successful result with an empty list.

🤔 Why is 'Operation failed' a bad error message?

It hides whether the failure is temporary, caused by bad input or a policy, so the agent cannot choose a sensible recovery.

🏁 Summary

  • Return isError plus errorCategory, isRetryable and a readable message.
  • Business and permission errors are not retryable.
  • Empty ≠ failure.
📝 Test yourself: Mock Test 2 · Mock Test 3 (30 scenario-based questions in 60 minutes, with explanations).

Next, continue with MCP Integration in Claude Code: Scopes, Resources and Built-in Tools.

🎬 Prefer video? Watch QA, automation and AI testing tutorials on the SQA Tools YouTube channel.

Independent study material by SQA Tools. Not affiliated with, endorsed by or sponsored by Anthropic. Claude is a trademark of Anthropic. Mock questions are original practice items, not real exam content. Exam facts checked against Anthropic's official exam guides and certification FAQ on 11 November 2026.