Prevent duplicate agent emails when a request times out
Persist a send identity before submission and separate definitive failures from uncertain provider outcomes.
Keep operation identity stable across model continuations, worker restarts and uncertain network outcomes.
An agent can think about the same task in several turns, retry a transport request or restart after a crash. None of those events necessarily creates a new external action. Store one operation identity for the exact authorized effect before executing it. Include the selected account or inbox, relevant resource revision and important arguments in the saved proposal. A model-generated request ID is useful for conversation correlation, but it is not a substitute for durable business identity. A new turn should recover pending work before inventing another send or purchase attempt.
Lupin’s MCP catalog marks journaled operations and extends their schemas with a required idempotency_key. Sends, replies and draft sends explicitly require one. Phone mutations, browser creation, container lifecycle changes and app execution preserve stable operation keys through their corresponding REST path. Supply a value of the required length from private application state rather than letting the model regenerate it on every retry. The request header can also carry an operation key where supported, but the discovered tool schema is the clearest client-facing contract for that call.
Some resource creates, such as inboxes, drafts, domains, projects and webhooks, use client_id to recover the original resource. Autonomous registration has a separate required secret Idempotency-Key with stronger length and confidentiality requirements. Keep these mechanisms distinct in your data model. A generic one-size-fits-all retry wrapper can accidentally omit the right body field or reuse a sensitive registration secret on ordinary operations. Give each operation family a deliberate identity rule and document what an exact replay is expected to return.
A provider timeout can leave an action accepted but unconfirmed. The durable journal retains uncertain outcomes and reservations so a later recovery can reconcile rather than repeat the external effect. Inspect the recorded operation and known resource state before deciding what comes next. A different idempotency key is a new action, not a safer retry. Likewise, a changed payload under an old key is not an acceptable way to update an approved proposal. Resolve the earlier attempt before asking for a revised external effect.
Lupin’s consumer agent derives transport identity from a durable once-only approval. External MCP clients must implement their own consent interface and preserve the same relationship between approved snapshot and operation key. A replayed result should be reported as recovered evidence, not as a second newly performed action. Denials and cancellations should not enter an automatic retry queue. Read-only calls may be repeatable, but they still need bounded timeouts and normal rate-limit handling rather than unlimited tool loops.
Use a fixture provider that accepts once and then drops the response. Restart the client, replay the saved identity and assert no second provider call occurs. Add a concurrent duplicate and a changed-argument conflict in your application policy. Your next step is an operation table with pending, accepted, failed and uncertain states that survives both model turns and process restarts.
Reviewed against checked-in Lupin API handlers and documentation. Example requests were not executed against live providers.
Prepared with AI assistance by Lupin editorial. How we research and maintain these guides.