Domain 2 · Lesson 2 · Tool Design & MCP (18%)
Structured Error Responses for MCP Tools
Task Statement 2.2 — an error is data the agent reasons over, not a dead end.
Course progress: Domain 2 ▸ lesson 2 of ~4
A generic "Operation failed" tells the agent nothing. It can't decide whether to retry, rephrase, escalate, or explain. Structured errors turn failures into decisions.
The isError flag + structured metadata
MCP uses an isError flag to signal a tool failure back to the agent. But the flag alone isn't enough — attach metadata:
errorCategory: transient / validation / business / permission
isRetryable (or retriable): boolean
- a human-readable description the agent can relay to the user
The error taxonomy (know all four)
| Category | Example | Retryable? | Agent should… |
| Transient | Timeout, service unavailable | Yes | Retry (ideally recover locally) |
| Validation | Malformed input | After fixing input | Correct the input, then retry |
| Business | Policy violation (refund too large) | No | Explain to the user; don't retry |
| Permission | Not authorized | No | Escalate / request access |
Why it matters
Returning isRetryable: false on a business error prevents wasted retry loops and lets the agent give a customer-friendly explanation instead of hammering the tool.
Two distinctions the exam tests
Access failure ≠ empty result
A timeout (access failure) needs a retry decision. A valid empty result (query succeeded, zero matches) is a success — the agent should treat "no orders found" differently from "couldn't reach the order service." Collapsing them is a classic bug.
Local recovery before propagation: a subagent should handle transient failures itself (retry locally) and only propagate up errors it can't resolve — and when it does, include what it attempted and any partial results (this bridges into Domain 5's error propagation).
Check yourself
A refund exceeds policy. The MCP tool should return an error that is categorized as:
- Transient with isRetryable true so the agent tries again shortly
- Business with isRetryable false and a customer-friendly reason
- Validation with a prompt to reformat and resubmit the request
- Permission with an instruction to request elevated access rights
Correct: option 2. A policy violation is a business error, non-retryable; the agent should explain, not retry. Marking it transient/validation would trigger pointless retries; permission is a different failure class.
An order query returns zero rows because the customer genuinely has no orders. The tool should signal this as:
- An error with isError set so the agent retries the lookup
- A transient failure so the coordinator attempts an alternative
- A successful result containing an empty set, not an error
- A permission error indicating the records are inaccessible now
Correct: option 3. A valid empty result is a successful query with no matches — distinct from an access failure. Flagging it as an error causes needless retries and can misreport "no data" as "system down."
Decision rules
Failure → return category + isRetryable + readable message. Business/permission → not retryable, explain/escalate. Transient → retry, recover locally first. Zero matches → success with empty set, never an error.
Ask your teacher. Want the exact MCP error payload shape, or how local recovery interacts with coordinator propagation (Domain 5)? Ask.