Why idempotency matters for MCP tools
MCP tools increasingly do more than retrieve information. They can issue refunds, create tickets, provision resources, send messages, place orders, update accounts and mutate production systems.
Those operations can cross several boundaries: agent, MCP client, MCP server, application service and external provider. A failure at any boundary can hide the outcome of a write that already completed downstream.
Transport attempts are not business operations
The most important distinction is between a logical operation and a transport attempt.
Logical operation: refund order_4821 once
Attempt 1: request sent, response lost
Attempt 2: retry of the same refund intent
If attempt 2 receives a brand-new identity, the downstream system may reasonably treat it as a new refund. Idempotency requires the retries to remain bound to the same logical operation.
Stable idempotency identity
A safe identity should represent the business intent being protected, not a transient request object or random retry attempt. The exact key design depends on the application, but the rule is consistent: same logical operation, same stable identity.
Useful inputs can include a durable business identifier, operation type, tenant or account scope and a stable user-approved intent identifier. Avoid deriving retry identity from timestamps, per-attempt UUIDs or values that change every time the agent calls the tool.
Idempotency keys are necessary in many systems, but not sufficient everywhere
Provider-native idempotency is valuable when the downstream service supports it. The safest implementation passes a stable key through to the provider rather than generating a fresh provider key for every retry.
But not every provider supports idempotency keys, and a key alone may not resolve every ambiguous state. Systems also need durable local state and, for supported integrations, a way to reconcile external provider truth when the acknowledgement is missing.
MCP's idempotentHint describes intent
MCP tool annotations include idempotentHint. The MCP maintainers describe tool annotations as hints: they communicate expected behavior to clients but are not guaranteed enforcement.
That makes the annotation useful for risk-aware clients, but the tool implementation still has to make repeated logical operations safe in practice.
The ambiguous outcome is the hard case
- The agent calls a state-changing MCP tool.
- The downstream provider performs the action.
- The response is lost.
- The caller sees a timeout.
- The caller does not know whether the side effect happened.
At this point, neither "success" nor "failure" is justified by transport evidence alone. The execution truth is UNKNOWN.
The Once execution model
Once uses stable operation identity, durable state, replay and provider-specific reconciliation for supported paths.
CONFIRMED → replay or suppress
ABSENT → execute
UNKNOWN → block or reconcile
This is deliberately narrower than claiming universal exactly-once execution. The goal is to avoid blind duplicate execution when the real-world outcome can be determined or must remain unresolved.
A practical MCP idempotency checklist
- Identify consequential tools. Start with operations that can change external state.
- Define logical identity. Decide what makes two attempts the same business operation.
- Reuse that identity across retries. Do not mint a fresh key per attempt.
- Persist execution state durably. The decision must survive process and transport failures.
- Pass through provider-native keys where supported. Keep provider and application retry identity aligned when possible.
- Reconcile ambiguous outcomes. Query sufficiently authoritative provider truth before allowing another external effect.
- Preserve UNKNOWN when truth cannot be established. Do not convert uncertainty into automatic permission to retry.
Example: create-order MCP tool
operation_id = "customer_91:create_order:cart_733"
attempt 1 → provider creates order → acknowledgement lost
attempt 2 → same operation_id
provider/order truth confirms original order
→ replay confirmed result
→ do not create a second order
The important property is not the exact string format. It is that the second attempt represents the same logical business operation and can be reconciled against durable execution truth.
When MCP idempotency should be evaluated
Evaluate an execution-safety layer when all four conditions are true:
- The tool can change external state.
- The same logical operation may be retried.
- The first attempt can become ambiguous after a timeout, lost response, crash, queue redelivery or similar failure.
- Blind duplicate execution would be undesirable or costly.
When it is usually unnecessary
Pure reads, search, retrieval and generation-only tools generally do not need this pattern because repeating them does not create the same class of consequential duplicate external effect.
MCP idempotency versus MCP retry safety
Idempotency is the mechanism that keeps repeated logical operations from producing unintended duplicate effects. MCP retry safety is the broader decision problem around when another attempt is permitted, how ambiguity is reconciled and what happens when execution truth remains unknown.
For the general autonomous-software version of the problem, see AI agent retry safety. For the failure state itself, see ambiguous timeout handling.
Primary references
The MCP maintainers' tool-annotation guidance explains that idempotentHint is part of a risk vocabulary and that annotations are hints rather than guaranteed truth: Tool Annotations as Risk Vocabulary.
GitHub's MCP Scripts retry policy recommends idempotency safeguards before retrying state-changing tools and explicit side-effect checks when a failed attempt may already have produced external effects: MCP Scripts Specification — Retry Policy.
Add execution safety to consequential MCP writes
Once is designed for tool boundaries where retries can otherwise become duplicate external side effects.
npx -y @once-agent/mcp
Official MCP Registry identity: io.github.stringsofthemind-oss/once
Run the retry simulation · MCP retry safety · AI agent retry safety · Claude Code · Cursor · MCP package · Source