AnthropicClaude Certified Architect – Foundations2026-102.2 Implement structured error responses for MCP tools
Classify failures before choosing recovery
Completed by the knowledge check
Learning objective
Classify transient, validation, permission, and business-rule failures using structured errorCategory, retryability, and explanation fields.
Core idea
An error flag says that execution failed; it does not say whether another attempt can succeed. Add a tool-defined error contract that separates the cause, the eligibility of an unchanged retry, and the explanation the agent needs. A temporary service outage, an invalid date, denied access, and an ineligible refund require different actions even when all four produce isError: true.
The exam guide names errorCategory, isRetryable, and human-readable descriptions. It also uses retriable: false for business-rule violations. These are application-defined metadata names, not standard MCP result fields. MCP defines isError, content, and structuredContent; your tool contract defines the classification inside the returned object. Pick one canonical retryability name, and translate any alternate spelling at an adapter boundary.
How it works
Define categories around the remedy
Use an explicit set of categories in your tool’s output contract. This lesson uses transient, validation, permission, and business as example errorCategory values. They implement the exam’s distinction without claiming that MCP reserves these enums.
The following classifications separate the recovery paths:
| Example category | Failed condition | Unchanged retry? | Appropriate next action |
|---|---|---|---|
transient | A dependency is temporarily unavailable | Yes, within assigned budget | Retry the same safe operation; report it if unresolved |
validation | A domain input is invalid | No | Correct the identified input before another call |
permission | The caller cannot access the requested resource | No | Resolve authorized access or report the limitation |
business | A valid request violates an enforced business rule | No | Explain the rejection and offer an allowed alternative |
A retry loop applied to every failure therefore repeats three kinds of call that cannot succeed unchanged.
Do not classify from an exception’s wording alone. A handler knows whether a request reached the dependency, which validation failed, and whether access was denied. Use those facts to construct the result. A generic “lookup failed” string forces the model to infer information the tool implementation already possesses.
For the protocol-versus-execution distinction, see 2.2.1. Here, a validation category means domain validation inside a recognized tool operation. A malformed MCP request still belongs to protocol error handling.
Make retryability describe an unchanged operation
Define isRetryable precisely: in this example contract, true means the same operation with the same valid inputs is eligible for a bounded retry. It does not mean “keep calling until it works,” and it does not guarantee success. A transient category can still return false when the local recovery budget is exhausted; see 2.2.5.
For a validation failure, set isRetryable: false for the unchanged call. If the agent corrects the input, the corrected call is a different recovery action. Anthropic documents that when a tool request is invalid or missing parameters, Claude retries 2-3 times with corrections before apologizing to the user; a validation result that names the field and acceptable form makes each of those corrections count. For a permission failure, repeating the same unauthorized call does not repair access. A recovery instruction can identify an approved authentication or authorization step without labeling blind repetition as retryable.
For a business-rule violation, isRetryable: false tells the agent that transport recovery does not change eligibility. See 2.2.3 for the customer-facing explanation. The Boolean should agree with the category and the explanation; “non-retryable” paired with “try the identical call again” is a contradictory contract.
Put metadata in a declared result shape
For an MCP server that supports structured results, use structuredContent for the tool-defined object and outputSchema to declare its shape. The MCP specification requires structured results to match a declared output schema and recommends client validation. Include both success and failure variants in the schema if the tool returns both; an error object should not violate a schema that only describes successful records.
Here is an example structured object inside an isError: true result:
{
"errorCategory": "validation",
"isRetryable": false,
"explanation": "The start date is later than the end date.",
"nextAction": "Correct the date range before calling search_orders."
}The names explanation and nextAction are also application fields. explanation states why the operation failed, while nextAction names the permitted change. A human-readable description can serve the same role under a different documented key. Consistent semantics matter more than inventing one universal vocabulary.
MCP recommends also returning serialized structured content in a text block for backward compatibility. Keep the text and object consistent. If one says retryable and the other says access denied, clients can make conflicting decisions from the same response.
The Agent SDK has a language-specific delivery boundary. Python’s in-process @tool decorator forwards only content and is_error from the handler’s return dictionary. Put this metadata in text content, or run a standalone MCP server to return structuredContent from Python. When structuredContent is set, Claude receives its JSON plus image or resource blocks from content; text blocks are not forwarded. Put every explanation Claude needs in the JSON, keeping the text copy for backward-compatible MCP clients.
Give actionable feedback without exposing internals
Anthropic recommends error responses that communicate specific, actionable improvements instead of opaque error codes or tracebacks. Its tool-call guidance contrasts a generic "failed" with "Rate limit exceeded. Retry after 60 seconds.", which says what went wrong and what to try next. For invalid input, identify the field and acceptable form. For permission failures, state the access limitation. For business failures, identify the relevant rule.
The MCP specification requires sanitized outputs and proper access controls. An explanation need not disclose a secret token, database query, or private record to be useful; describe the failed condition at the level the authorized caller can act on, and keep implementation detail in server-side diagnostics.
Key distinctions and trade-offs
Category versus retryability: Category identifies the cause family. Retryability identifies whether an unchanged operation is eligible to run again. Neither field replaces the other.
Correction versus retry: Changing an invalid date or obtaining authorized access changes the failed precondition. Repeating a valid lookup after a temporary outage is a retry.
Standard container versus custom payload: structuredContent is MCP. errorCategory, isRetryable, explanation, and nextAction belong to your tool schema. A client must understand that schema to enforce their meanings.
Standardize the envelope, not the message: uniform generic text makes recovery worse.
Architecture / decision scenario
A customer support agent searches orders and requests refunds through an MCP server. The order service times out before completing a read, so the lookup returns errorCategory: "transient", isRetryable: true, and an explanation of the missing result. A local recovery policy decides whether the remaining budget permits another attempt.
A reversed date range returns validation with isRetryable: false and the field correction. An unauthorized account returns permission with isRetryable: false; the agent requests the approved access step rather than probing alternate accounts. A refund outside the eligibility rule returns business with isRetryable: false and an explanation suitable for the customer.
All four results use isError: true, but the next actions differ. The client validates the structured contract and keeps any serialized text consistent. The agent receives enough information to recover, ask for a correction, resolve access, or communicate a final rejection without guessing from “Operation failed.”
Common exam traps
- Presenting
errorCategoryas a reserved MCP field. - Treating
isRetryable: trueas permission for unlimited retries. - Marking invalid input retryable because a corrected call could succeed.
- Using
isRetryableandretriableinconsistently across tools. - Returning a failure object that violates the declared
outputSchema.
Where the exam guide differs
The exam guide names errorCategory, isRetryable, and retriable: false. MCP defines the result fields content, structuredContent, and isError, while those error metadata names belong to the application payload inside the result. Read an exam option using errorCategory or isRetryable as that payload contract, not as a protocol field. The guide lists transient/validation/permission for errorCategory and separately requires business-rule failures; this lesson adds the illustrative business value to cover that requirement.
The exam guide (version 1.0, effective July 2026, first drafted in February 2026) names no MCP revision; it was written while revision 2025-11-25 was the published specification. This lesson cites revision 2026-07-28, a later revision, and the differences between the two do not change what it teaches for the exam. Revision 2026-07-28 widens structuredContent from a JSON object to any JSON value; the error payloads in this lesson are objects, valid under either revision.
What to remember
Return a structured cause, explicit retry eligibility, and an actionable explanation. MCP supplies the result container; your schema supplies the metadata semantics. Distinguish unchanged retries from corrections, access recovery, and business-policy decisions, then keep every representation of the result consistent.
Knowledge check
An HR assistant’s read_employee_file call is refused because its service account may not open executive files. The tool returns isError: true with the text “Something went wrong, try again”. Transcripts show the assistant sending the same call three more times before handing the request to a person. Which change stops the futile repeats without blocking retries of failures that can recover?
read_employee_file before each repeated callerrorCategory: "permission" and isRetryable: false with the reasonisError: false with an empty employee file for the refused requestsearch_orders rejects a request whose start date is later than its end date. A teammate proposes marking the failure isRetryable: true, because a call with corrected dates will succeed. Using the lesson’s example error contract, which result both classifies the failure and identifies the required correction?
errorCategory: "validation" , isRetryable: false , and a nextAction naming the date range to correcterrorCategory: "validation" , isRetryable: true , and a nextAction naming the date range to correcterrorCategory: "transient" , isRetryable: true , and an explanation that the search did not finisherrorCategory: "validation" , isRetryable: false , and an explanation reading “Invalid request”isRetryable describes the unchanged operation, and repeating the same reversed range can never succeed. A corrected call is a different recovery action, which the nextAction makes possible by naming the field to change. Marking the failure retryable invites identical repeats, and a generic “Invalid request” forces the model to guess what to fix.A tool declares an outputSchema that describes only its successful orders object. On failure it returns isError: true with structuredContent holding errorCategory, isRetryable and explanation, and the MCP client, which validates structured results, rejects every one of those failure responses. What is the correct fix?
isError: trueerrorCategory and isRetryable out of structuredContent to sit beside isErrororders object of the success shapeoutputSchema with a failure variant that declares the error fieldsisError ; disabling validation or hiding errors inside a fake success object breaks the contract instead of fixing it.A Python Agent SDK tool built with the @tool decorator and served by create_sdk_mcp_server returns a dictionary with content, "is_error": True and a structuredContent object holding errorCategory and isRetryable. Claude never sees the category or the retryability. Which change delivers them?
structuredContent key to structured_content while keeping the metadata objectcontent arrayerrorCategory and isRetryable to top-level keys beside the returned is_erroris_error to False while keeping the metadata in the returned structuredContent@tool decorator forwards only content and is_error from the handler’s return dictionary, whatever other keys it holds or however they are spelled. Metadata Claude must read therefore goes into text content , or the tool runs on a standalone MCP server that can return structuredContent . Clearing the error flag loses the failure signal and still delivers nothing extra.References
- Model Context Protocol, Tools
- Anthropic, Writing effective tools for agents
- Anthropic, Handle tool calls
- Anthropic, Claude Certified Architect – Foundations Exam Guide
- Anthropic, Give Claude custom tools
- Model Context Protocol, Key Changes, protocol revision 2026-07-28