All posts
x402September 29, 2026·9 min read

How EVIDIQ's x402 Pay-Per-Call MCP Server Actually Works

Your agent wants to check whether a counterparty is real before sending 50 USDT0 for an API call. It hits EVIDIQ's verify_agent tool, gets a 402 challenge back, signs an EIP-3009 authorization, retries — and 800ms later has a tamper-evident trust report with a 0-100 score and an explicit recommendation. Here's the actual wire protocol that makes that work, because we think anyone integrating it should know what their client is doing on the wire.

The Wire Protocol, Byte by Byte

An x402 pay-per-call MCP server is an MCP endpoint that exposes paid tools to AI agents and uses the x402 HTTP 402 Payment Required protocol to charge per call in stablecoins like USDT0 on X Layer, settling via EIP-3009 transferWithAuthorization so the payer signs off-chain without holding gas.

So what does that look like in practice when your agent wants to call verify_agent? Three round trips — two of them free, one of them paid.

  1. POST https://evidiq.dev/mcp with a JSON-RPC body like { "method": "tools/call", "params": { "name": "verify_agent", "arguments": { ... } } }.
  2. The server returns 402 Payment Required with a JSON body whose accepts[] array describes exactly what it will accept.
  3. The client signs an EIP-3009 transferWithAuthorization message and retries with header X-PAYMENT: <base64-json>.

That third response is the one that returns the actual trust report. The body is the same JSON-RPC payload, but with a result containing the score, recommendation, evidence references, and the on-chain tx hash anchoring the canonical report to 0G Storage.

Why three trips instead of one? Because the 402 challenge carries the live amount, the payTo address, and the asset address — those values can change. Our server signs the 402, but the client signs the payment. Hardcoding any of those fields client-side is a bug; the x402 pay-per-call MCP server treats the 402 as the source of truth for what will actually be charged.

If you've never seen an MCP server before, the EVIDIQ docs walk through the install path. The short version: it's a JSON-RPC surface that an agent discovers and calls like any other tool.

Reading an accepts[] Object

[IMAGE_PROMPT: A modern flat illustration showing a JSON document titled 'accepts[]' on a dark navy background. The document has eight highlighted fields stacked vertically — 'scheme', 'network', 'amount', 'asset', 'payTo', 'extra.name', 'extra.version', 'extra.resource' — each tagged with a small magnifying-glass icon and a cyan accent stripe. A stylized inspector figure with a clipboard stands to the right pointing at the 'amount' field. Color palette: dark navy background, cyan and amber accents, soft gradients. No readable text beyond the field names. Tech/developer aesthetic, no brand logos.]

Here's a real accepts[] array we pulled from a probe earlier this week. Walk through it with us — every field is load-bearing.

  • scheme: "exact". Tells the client this is a fixed-amount charge, not a streaming or subscription variant. Anything other than "exact" means a different client flow.
  • network: "x-layer". EVM chain identifier for our settler. Mistaking this for mainnet means the EIP-712 domain separator will be wrong and the signature will fail.
  • asset: the ERC-20 contract address on that network, in our case USDT0. Sign against the wrong address and the signature is unrecoverable.
  • amount: a string-encoded atomic unit, e.g. "100000" for 0.10 USDT0 because USDT0 uses 6 decimals.
  • payTo: EVIDIQ's settler EOA. Payment lands here, then the settler forwards it.
  • extra.name / extra.version: "USDT0" and "1". Part of the EIP-712 domain, so a typo here produces the wrong domain separator and a silent rejection.
  • extra.resource: the URL of the MCP server that issued the challenge. This binds the signature to the endpoint, so a signed authorization can't be lifted off one tool and replayed against another.
  • extra.description: human-readable label shown in client UIs.

What happens when a client gets one wrong? Suppose a developer hardcodes amount: "1000000" thinking it means 1 USDT0 — they pay $10 instead of $0.10. Worse, a client that ignores the network field and signs with the Ethereum mainnet domain will produce a signature the settler cannot verify, and the request returns 402 again with error: "invalid_signature". We've published the full field reference in our EVIDIQ docs so integrators don't have to guess.

One field that surprises people: extra.resource. It's not decorative. Including it in the EIP-712 domain is what prevents an attacker from lifting a signed authorization off one tool and replaying it against another. Cryptographers call this domain binding; we just call it sane defaults.

EIP-3009 Without the Cryptography Lecture

The piece that makes the x402 pay-per-call MCP server feel almost magical for an autonomous agent is EIP-3009's transferWithAuthorization. The short version: it lets an ERC-20 holder sign a message off-chain that says "the contract may debit my balance by N tokens, addressed to recipient X, valid until time T, with nonce N." No gas is spent on the signature, and the signature is portable — you can hand it to a relayer.

That's where our settler comes in. EVIDIQ never holds funds, so the signed authorization goes to a public settler service. The settler:

  1. Verifies the signature against the asset contract's DOMAIN_SEPARATOR.
  2. Calls transferWithAuthorization on the USDT0 contract, paying its own gas in X Layer's native token.
  3. Records the on-chain tx hash and returns it to the MCP server.
  4. The MCP server then issues the actual verify_agent result, and anchors the canonical report to 0G Storage (mainnet) so it can't be tampered with after the fact.

Why this matters for agent builders: your agent doesn't need ETH or OKB to use EVIDIQ. It only needs USDT0 and a signing key. That's the whole reason we picked X Layer in 2026 — gasless-ish from the caller's perspective. The full tokenomics, settler address, and reorg handling live in the EVIDIQ Operator docs.

We built the capability probe to do its own live reachability check against the agent's endpoint — a bounded ~6s GET that confirms TLS, resolves the machine-readable skill/agent-card/MCP surface, and feeds the capability score. Every one of those probes is paid for with the same x402 pay-per-call MCP server flow, so the trust layer pays its own bills rather than leaning on a free-tier subsidy.

What Happens on a Bad Signature or Late Nonce

[IMAGE_PROMPT: A modern flat illustration on a dark navy background showing three divergent paths radiating from a central signed envelope labeled 'X-PAYMENT'. The first path ends at a clock face (expired timestamp). The second ends at two overlapping paper sheets (reused nonce). The third ends at a broken chain link (wrong domain separator). Each endpoint is tagged with an amber warning pip. A small cyan checkmark path runs along the bottom showing the success route. Color palette: dark navy, amber warnings, cyan success, soft gradients. Clean flat geometric shapes. No brand logos, no readable text beyond the labels 'expired', 'reused', 'wrong domain'.]

Integrators will hit these. We hit them ourselves in testing, more times than we'd like to admit. Here are the four we see most often, and what each one returns.

  • Expired validBefore. The signed authorization had a timestamp in the past. Result: 402 with error: "authorization_expired". The client must re-fetch a fresh 402 and re-sign. Common cause: a stale cached challenge from more than ~10 minutes ago.
  • Reused nonce. EIP-3009 nonces are single-use on the asset contract. A retry that replays the same signed header fails at the contract layer with the standard ERC-20 revert or a USDT0-specific nonce_already_used. Result: 402 with error: "nonce_replayed". Fix: drop the cached signature and request a new challenge.
  • Wrong domain separator. The client signed against the wrong name, version, or chainId in the EIP-712 domain. Result: signature recovery yields a different address than expected, the settler rejects it, and you get 402 with error: "invalid_signature". Fix: re-read the accepts[] array and rebuild the domain from those fields — do not cache them client-side.
  • Insufficient balance. If the signer's USDT0 balance is below the requested amount, the on-chain transfer reverts. The settler catches it and returns 402 with error: "insufficient_funds". Worth noting: the signer key isn't ours — we don't know balances. The chain tells us when we try to settle.

There's a fifth, rarer case: a chain reorg on X Layer that invalidates the settlement tx mid-request. Our settler waits for a small number of confirmations before returning success, and the MCP server treats an aborted settlement as a retryable 402. The EVIDIQ Sentinel docs cover the monitoring side — how we catch these in production and what the alerting looks like.

If you're building a client and the only error you ever see is invalid_signature, the bug is almost always in your domain builder, not in our server. Print the domain, compare it to the accepts[] fields, and the answer shows up in five seconds.

Frequently Asked Questions

The Agent Skill at evidiq.dev/skill.md and the install tools (how_to_install, get_evidiq_skill) on the MCP server are free. The paid tool is verify_agent — billed per call via the x402 pay-per-call MCP server flow, settled on X Layer in USDT0. There are no subscriptions and no monthly minimums, and the canonical report is yours regardless of how many times you re-query it.

Give your agent the trust skill:

curl -s https://evidiq.dev/skill.md
E

EVIDIQ Team

The EVIDIQ team builds the trust layer for the AI agent economy — verifying agent identity and capability, scoring risk, and anchoring every verdict on-chain so agents can decide who to trust before value moves.

More from EVIDIQ Team →
Inside EVIDIQ's x402 Pay-Per-Call MCP Server Protocol — EVIDIQ