Zenaique

Complete the correct MCP error response shape for a tool logic failure

Fill in blank·Hard·4.0 · 0·~1 min·Asked atCharacter AiHclIBM·Relevant atAnthropicLangChain
Attempt it
When a tool's business logic fails (e.g. a database query error), the server must return the error as a successful JSON-RPC `` (not the `error` field). The content array item should contain the error message, and the `` flag must be set to `true` to signal that the tool invocation failed. This contrasts with JSON-RPC protocol errors, which use the `` field for issues like unknown methods.
TL;DR

A tool logic failure rides the JSON-RPC `result` with `isError: true` so the model sees it; only protocol faults like unknown methods use the `error` field.

Memory aid
Sign in to see the mnemonic that makes this stick.
Easy to grasp

Imagine ordering food through a waiter. If the kitchen burns your dish, the waiter still comes back to your table and tells you 'sorry, the dish failed' so you can decide what to do next. That is a tool error: the request was understood, but the work failed, and the result comes back to you with a 'this went wrong' note attached. Now imagine you mumble an order for a dish that does not exist on the menu. The waiter cannot even take the order. That is a protocol error: the request itself was malformed. MCP keeps these two cases on separate tracks, so the model gets handed the kitchen failures it can react to, while the truly broken requests bounce back differently.

Concept explanation~2 min read

Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.

This question is rated hard for a reason: it sits exactly on the seam where the Model Context Protocol meets its JSON-RPC transport, and getting the seam wrong is one of the most common production MCP bugs. The instinct from years of API design is that an error is an error, so it should go in the error field. MCP deliberately breaks that instinct, and candidates who have only built REST services almost always answer it wrong on the first pass.

The core idea is that there are two different kinds of failure, with two different audiences. A tool that ran and failed produces information the model must see and act on. A request that was never executable produces a fault the host must absorb. MCP routes these to two separate channels so each audience gets what it needs. The boolean that distinguishes them, isError, is small, but the design philosophy behind it is the whole answer.

This deep dive walks through both channels, the exact response shapes, why the design routes recoverable failures through the success path, the production discipline that keeps the two from leaking into each other, and the security surface that error content opens up once it reaches the model.

Two failure modes, two channels

Start with the transport. MCP messages are JSON-RPC 2.0. Every response is either a success carrying a result object, or a failure carrying an error object with a numeric code and a message. That envelope is fixed by JSON-RPC and predates MCP entirely. The specification reserves a band of codes for transport faults, and application code is expected to stay out of that band.

MCP then layers tool semantics on top. A tools/call request invokes a named tool with arguments. Two completely different things can go wrong, and they map to the two envelopes. The whole difficulty of the question is that both can follow a single tools/call, so naming the right channel for each is the skill being tested.

The first mode is a protocol error. The request was malformed, the method name is unknown, or the parameters failed validation before any tool logic ran. The call never reached the tool. These map cleanly to the JSON-RPC error field, with standard codes such as method-not-found or invalid-params. The defining trait is that no business logic executed; the fault is in the request itself.

The second mode is a tool execution error. The method exists, the arguments parsed, the tool ran, and its business logic failed: a query errored, a file was missing, an upstream API returned 500. The tool genuinely executed and genuinely failed. This does not use the error field at all. The request was perfectly well-formed and fully understood; only the downstream work fell over, and that distinction is what dictates the response shape.

The exact shape of a tool error
Why route failures through the success path
The production discipline
How a client tells the two apart
Sign in to unlock the full deep dive.

Situations where this technique stops working.

Sign in to see when this approach fails.

2–4 min · Everything important, quickly.

Sign in to see the quick scan of the deep dive.
typescript
// Tool logic failure -> result with isError, NOT a thrown JSON-RPC error
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  try {
    const rows = await runQuery(request.params.arguments.sql);
    return { content: [{ type: "text", text: JSON.stringify(rows) }] };
  } catch (err) {
    return {
      content: [{ type: "text", text: `Query failed: ${err.message}` }],
      isError: true // model sees this and can react
    };
  }
});
AspectTool execution errorJSON-RPC protocol error
Where it livesresult, with isError trueerror field, with a code
What failedTool logic ran and threwRequest never executed
ExamplesDB timeout, missing file, API 500Unknown method, bad params, malformed JSON
Who reactsThe model reads and retriesThe host catches and logs
Visible to modelYes, in the content arrayNo, intercepted by the host

Real products, models, and research that use this idea.

  • The official MCP filesystem server returns isError true with a message when a read targets a missing path, rather than throwing a JSON-RPC error.
  • Claude Code surfaces an isError tool result back into the model's context so Claude Opus 4.7 can retry a failed shell command on the next turn.
Sign in to see more production examples.

What an interviewer would ask next. Try answering before peeking at the approach.

QHow should a client distinguish a tool error from a protocol error when both can appear after a tools/call?
A

Check the response envelope first: an error field means a protocol fault; a result with isError true means the tool ran and failed. Branch the handler on which envelope arrived.

2 more follow-ups an interviewer would ask next. Sign in to reveal them.

Red flags & common mistakes

The phrases that signal junior thinking. Click to expand.

Most common mistake

Returning a tool failure as a JSON-RPC error. That hides it from the model, which can no longer see the message or self-correct on the next turn.

Sign in to see all red flags and common mistakes.

60 second bullets to scan on the way to the call.

  • The two error channels MCP exposes and how they differ

  • Which channel a tool business logic failure uses

Sign in to unlock the revision sheet.

Primary sources. Browse if you want the original framing.

Similar questions

Same topic, related formats. Practice these next.

4 curated
Next question
What is the Model Context Protocol (MCP) and what problem does it solve?
MCQ·Easy