Zenaique

When should a production MCP client NOT retry a failed tools/call?

MCQ·Medium·4.0 · 0·~1 min·Asked atAirbnbArize AiCursor·Relevant atAnthropicLangChainMicrosoftOpenAI
Attempt it
TL;DR

Do not retry a side-effecting tool when a transport failure leaves it ambiguous whether the original call already ran; a blind retry can double-charge or double-write.

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

Think about hitting Submit on a checkout page and the screen freezing. Did the payment go through, or not? If you click Submit again to be safe, you might get charged twice. The safe move is to check the order history first, not blindly resubmit. A production MCP client faces the same problem. When a tool call times out, the client cannot tell whether the server already ran the tool before the connection dropped. For a read like list files, retrying is harmless. For a write like send payment, retrying could fire it twice. So the rule is: retry freely when the action is safe to repeat, but never blindly retry an action that changes the world when you are unsure it already happened.

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.

Retry handling looks trivial until a tool call moves money. The naive design wraps every MCP tools/call in a retry loop with exponential backoff and ships it. That works for reads and quietly corrupts state for writes. This question probes whether a candidate understands that retry safety is a property of the operation, not a property of the error code alone.

The core tension is delivery semantics. Network transports give you at-most-once or at-least-once delivery, never exactly-once for free. A retry policy is how you choose between them per tool. At-most-once means you never duplicate but you may lose work. At-least-once means you never lose but you may duplicate. Exactly-once is what you actually want, and you only get it by adding deduplication on top, not from the transport itself. Get it wrong on a payment tool and a single dropped connection becomes a duplicate charge.

MCP makes this concrete because a single host session can hold both read-only and side-effecting tools, fanned out across several connected servers. A uniform retry policy that treats them all like an HTTP GET is the trap. This deep dive separates the two kinds of failures an MCP client sees, explains why an ambiguous timeout is the genuinely dangerous case, shows how idempotency keys let you retry writes safely, and ends with a layered policy you can defend in an interview.

Two failure classes the client must distinguish

An MCP client receives failures in two structurally different shapes, and conflating them is the most common production bug.

A protocol error is a JSON-RPC error object. The response carries an error field with a code and message. Codes like -32700 (parse error), -32600 (invalid request), -32601 (method not found), and -32602 (invalid params) are defined by JSON-RPC. They mean the request itself was malformed or the method does not exist. These are permanent, design-time bugs, not runtime blips. Retrying a -32601 a hundred times still finds no method, and each retry just wastes a backoff window before you surface the real problem.

A tool error is completely different. The call succeeded at the protocol level, the server ran the tool, and the tool decided it failed. MCP surfaces this as a normal tools/call result whose payload sets isError: true with content describing what went wrong. This is a logical failure, like an API returning a validation message: bad arguments, a missing record, a downstream refusal. You surface it to the model or the user so the next turn can correct course; you do not treat it as a transport hiccup and retry it. A model that sees the isError content can often fix its own arguments and call again, which is a deliberate retry, not a blind one.

The rule of thumb: an error object means the message never reached the tool, an isError result means it did. Different cause, different response. Getting this split wrong is how teams end up hammering a server with retries for a request that was never going to succeed.

What is actually safe to retry
The ambiguous-write hazard
Making writes retryable with idempotency keys
Putting it into a production policy
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.
FailureShapeRetry?
Transport timeout, read-only toolNo response / socket dropYes, with backoff
Transport timeout, side-effecting toolNo response / socket dropOnly with an idempotency key
HTTP 503 / 5xxServer overloadedYes if safe to repeat
JSON-RPC -32601 / -32602Protocol error objectNo, permanent
Tool result with isError trueValid result, logical failureNo, surface it

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

  • Stripe's API uses Idempotency-Key headers so a retried charge after a timeout settles exactly once; an MCP payment tool should mirror this.
  • Claude Code and Cursor MCP clients retry transient stdio and HTTP transport errors but surface isError tool results straight to the model.
Sign in to see more production examples.

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

QHow would you design an idempotency key scheme so a retried side-effecting MCP tool call settles exactly once?
A

Mint a UUID per logical operation on the client, pass it on every retry, and have the server store keys with results so a duplicate key returns the cached outcome instead of re-executing.

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

Retrying every failure with blanket backoff. That double-fires non-idempotent tools whenever a timeout hides a call that actually succeeded.

Sign in to see all red flags and common mistakes.

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

  • The difference between a protocol error and a tool-level isError result

  • Why an ambiguous timeout makes a side-effecting retry unsafe

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