A timeout shouldn’t become a second purchase.
Give your agent a durable operation record. Reuse confirmed results. Reject changed requests. Stop when the outcome is uncertain.
No signup. No card. No npm dependencies. Local SQLite.
01 CLAIM
Persist intent before calling the tool.
02 RESPONSE LOST
Was the purchase completed?
03 CHECK LOCAL STATE
Confirmed → replay result
Uncertain → stop and reconcile
Should the agent try again?
This browser simulation uses the SDK’s decision function. Run the downloaded demo to test real SQLite persistence and restart behavior.
Choose a scenario. No real payment is made.
Extract. Run. Inspect.
With Node.js 24+ installed, extract the SDK ZIP and run these commands inside its folder.
node demo.mjs node --test guard.test.mjs mcp-demo.test.mjs
The offline demo simulates a purchase, reopens its SQLite ledger, checks result replay, and blocks an uncertain retry. It makes no network calls.
Or connect the included local MCP demo
Use this configuration in a stdio-capable MCP client after replacing the two absolute paths. The demo uses mock purchases only and opens no network port.
{
"mcpServers": {
"agent-retry-guard-demo": {
"command": "node",
"args": ["/ABSOLUTE/PATH/mcp-demo.mjs", "--state-dir", "/PRIVATE/LOCAL/PATH/demo-state"]
}
}
}Call retry_guard_demo_purchase twice with the same order ID and amount. Expect one mock effect. Use a new order with mode: "lose_response" to test an uncertain operation. Full instructions and limitations.
Wrap the actual tool implementation
import { RetryGuard } from './guard.mjs';
const guard = new RetryGuard({
filename: './operations.sqlite', scope: 'company-123:production'
});
const result = await guard.run({
key: 'order-1001:purchase', action: 'merchant.example/purchase:v1',
input: { amountMinor: 50, currency: 'USD', productId: 'report-12' }
}, async ({ idempotencyKey }) => {
// Replace with your provider call; forward its idempotency key if supported.
return { receiptId: 'mock-only', idempotencyKey };
});Read integration, reconciliation and deployment instructions →
All relevant calls must pass through this guard using the same stable key, scope and persistent local database. Separate hosts or files are not coordinated. It does not hold funds, control a wallet, verify receipts or reverse a payment. Successful results are stored locally in plaintext; return minimal receipts.
A useful local edition today.
Local developer edition
Durable claims, stored JSON result replay, conflict detection and explicit uncertain states on one trusted host. SDK contains no telemetry.
Get v0.1.1Managed team edition
Proposed shared multi-host coordination and operator workflows. Not implemented or sold in this release. No preorder, subscription or future payment obligation.
Request a team pilot by emailOpens a draft in your own email app; nothing is sent automatically. Requests are non-binding and create no subscription or marketing signup. Do not include credentials or private logs. GitHub feedback is also available.
Built around a documented failure mode.
A lost response can leave a tool’s external effect ambiguous. A fresh request ID does not identify the original business operation.
MCP reproduction and its limitations · x402 application-level idempotency discussion
Existing alternatives and upstream fixes exist. This SDK is a small application-layer option, not a claim that MCP or x402 universally duplicate payments. A local MCP stdio demo with mock purchases is included. A production payment adapter and native x402 integration are not included.