Commands

agent-commerce doctor

Diagnose config, gateway, backend, protocol and payment health — against the live gateway.

Usagebash
agent-commerce doctor [--config <path>] [--env-file <path>] [--gateway <url>] [--json]

Options

--config <path>
Path to the config.
--env-file <path>
Load environment variables before reading the config. Variables already set in the environment take precedence.
--gateway <url>default: derived from config, else http://localhost:8080
The running gateway to check against.
--jsondefault: false
Machine-readable JSON instead of the formatted report.

Output

console
$ npm run agent-commerce -- doctor --config config-demo.yaml

PASS  Config               valid: 2 resource(s), merchant "Demo Data Store" (using local chain manifest .deploy/local.json for X402_ASSET, X402_ASSET_NAME, X402_ASSET_VERSION, X402_ASSET_DECIMALS, MERCHANT_WALLET, X402_FACILITATOR_PRIVATE_KEY)
PASS  Gateway              healthy and ready at http://127.0.0.1:8080
PASS  Backend              2/2 backend host(s) reachable
PASS  Protocols            http=on mcp=on (/mcp) a2a=off acp=off
INFO  A2A                  disabled
INFO  ACP                  disabled
INFO  AP2                  disabled
PASS  Payments             x402 v2 (scheme=exact) enabled - LOCAL dev chain (eip155:31337), destination=0x7099…79C8, facilitator=local (in-process), paymentFlow=authorization
INFO  Payments (MPP)       MPP not configured
PASS  Storage              sqlite schema v5 writable; receipts=2
PASS  Transactions         none unresolved
PASS  Protocol versions    reported by gateway /.well-known/agent-commerce

Score: 8/8 checks passed

doctor compares the live gateway with your resolved config for each rail and resource with its own offers: offer order, network, token, payee and transfer method, plus decimals and payment flows when published. Any mismatch fails the check.

Checks

CheckLooks at
Configthe same validation as validate
Gatewayhealth and readiness at the gateway URL. A 403 from /ready fails the check because the gateway rejected the probe's hostname. The URL comes from --gateway or, when omitted, server.host and the configured port; wildcard bind addresses use loopback
Backendwhether each backend host is reachable
Protocolswhich surfaces are on, and their mounts
A2A · ACP · AP2status and pinned spec, plus enabled-feature checks: A2A unsupported; ACP auth, idempotency, checkout mapping and unsupported; AP2 trust (issuers/key counts), replay store, resources and unsupported. The ACP idempotency and AP2 replay lines include legacy import status (below)
Paymentsx402 rail, deployment mode, each offer's network and destination, facilitator and payment flow, compared with the live gateway
Payments (offers)health of each published offer, naming failures; reasons appear in the gateway's debug log. Shown for multiple rail offers or resource overrides
Payments (MPP)the same for MPP, with its recipient and pinned drafts; INFO when MPP is not configured
Payments (quotes)whether local config and the gateway agree on enabling ERC-8409 quotes, and whether the published issuer matches the address derived from quote.signerPrivateKey. On a mismatch, check the gateway's config and restart it if the key was rotated
Mainnet safety, Mainnet safety (MPP)mainnet safeguards for each offered network, including anonymous facilitator access and accepted assets: x402 allows the network's USDC or another EVM token with full metadata; MPP requires its canonical asset
Storageschema, writability, receipt count and nonzero undelivered/uncertain counts. Warns below schema v5, which start migrates
Transactionsunresolved journal entries by state, WARN when any remain; see GET /api/transactions?unresolved=true or run reconcile
Authorization holdsWARN: reserved AP2 holds over 15 minutes old without payment attempts; reconcile releases them with AP2 enabled
ACP claimsINFO: unresolved ACP claims; same-key retries get 409 idempotency_unresolved
Payment retry keysINFO: unexpired unresolved payment retry keys from idempotency.redelivery; matching retries on enabled resources get 409 payment_identifier_unresolved
Protocol versionspins reported by /.well-known/agent-commerce, or local pins if unreachable

doctor reads the receipt database without migration, imports or ACP claim recovery. It can run beside a live gateway, including version 2.5.

Deprecated store files

For enabled AP2 or ACP, the AP2 replay store and ACP idempotency lines check authorization.ap2.replay.path and protocols.acp.idempotency.path against the import records in the receipt database:

StatusWhen
PASSthe key is unset, with no import needed or an import already recorded
WARNthe key remains set: its file awaits import, was imported, is missing or is :memory:. Remove the key after the import/check is recorded
FAILstart would refuse a changed import path, an unwritable unimported file, or an unset/missing source with evidence of past feature use but no recorded import/check
StatusMeaningScored
PASShealthyyes
WARNworking, with a caveat — e.g. an unauthenticated mainnet facilitatoryes
FAILbroken; the run exits 1yes
INFOcontext only, e.g. a disabled adapterno

JSON output

json
{
  "checks": [
    { "name": "Config", "status": "PASS", "detail": "valid: 2 resource(s), merchant "Demo Data Store" …" },
    { "name": "Gateway", "status": "PASS", "detail": "healthy and ready at http://127.0.0.1:8080" },
    { "name": "A2A", "status": "INFO", "detail": "disabled" }
  ],
  "score": { "passed": 8, "total": 8 },
  "exitCode": 0
}
Run agent-commerce doctor --json after every deploy: it exits non-zero on any FAIL.