MCP Idempotency
Idempotency means the same request can be safely retried without creating duplicates or unintended side effects. If a network call fails and you don't know whether the server processed it, you can resend the request with the same idempotency key and get the same result — no double-creation.
How It Works
Pass _meta.idempotencyKey at the JSON-RPC params level — not inside arguments. This is per the MCP specification:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create_lnkify",
"arguments": { "target": "https://example.com", "slug": "my-link" },
"_meta": { "idempotencyKey": "unique-key-123" }
},
"id": 4
}If the same key is used again, the server returns the cached result from the original operation. No duplicate shortlink is created.
Supported Tools
| Tool | Idempotency |
|---|---|
create_lnkify | Supported |
update_lnkifies | Supported |
delete_lnkifies | Supported |
whoami | Natively idempotent (read-only) |
list_lnkifies | Natively idempotent (read-only) |
get_lnkify | Natively idempotent (read-only) |
get_hit_stats | Natively idempotent (read-only) |
Read-only tools don't need explicit idempotency keys because repeating them has no side effects.
Implementation
The idempotency cache uses a pluggable storage adapter selected by the server's REDIS_URL setting:
- Redis-backed when
REDIS_URLis set — keys and cached responses are shared across all replicas (with distributed locking), so a retry that lands on a different replica is still deduplicated, and entries survive a single replica restarting. - In-memory otherwise — per-process and cleared on restart (fine for single-replica deployments).
In both cases:
- Cache entries expire after a set TTL.
- Keys must be unique per operation — if you reuse a key across different tool calls, only the first result is stored.
Choosing Keys
Use UUIDs or unique request IDs as your idempotency keys:
"req-550e8400-e29b-41d4-a716-446655440000"Never reuse keys for different logical operations. A key that successfully created link A, then later attempted as a create for link B, will return the cached result of A.
Best Practice
Always include an idempotency key for every write operation (create_lnkify, update_lnkifies, delete_lnkifies). This makes your integration resilient to network timeouts and failures.
Next: Discovery