All posts
x402September 3, 2026·8 min read

Inside EVIDIQ's x402 Pay-Per-Call MCP Server: A Wire Protocol Walkthrough

Inside EVIDIQ's x402 Pay-Per-Call MCP Server: A Wire Protocol Walkthrough

A request comes in at 03:47 UTC. Some agent, somewhere, decides it needs to verify another agent before handing over a real task. It fires a JSON-RPC call at our endpoint. We respond with HTTP 402 — Payment Required. Five seconds later, the same call comes back, this time carrying a signed payment authorization, and we let it through.

That's the shape of an x402 pay-per-call MCP server in one breath. The rest of this article is the long version — the bytes on the wire, the fields in the challenge, the signature scheme, and the failure modes that will eat your weekend if you don't know them.

If you're wiring up an agent that needs to ask EVIDIQ "is this other agent safe?", here's exactly what crosses the network.

The Wire Protocol, Byte by Byte

An x402 pay-per-call MCP server is an MCP endpoint that gates each paid tool call behind HTTP 402 Payment Required, where the client signs an EIP-3009 transferWithAuthorization off-chain and the server settles it before responding. EVIDIQ runs this pattern at evidiq.dev/mcp — clients discover the price, authorize payment with their wallet, retry once, and receive the trust report plus signed evidence.

Here's the exact sequence we've built at EVIDIQ:

  1. The client opens a JSON-RPC request: POST https://evidiq.dev/mcp with a tools/call body targeting verify_agent.
  2. Our server checks whether the request carries a valid X-PAYMENT header. First call? No header.
  3. We return HTTP 402 Payment Required with a JSON body containing the accepts[] array — what we'll accept, in what amount, on what network.
  4. The client picks one accept, signs an EIP-3009 authorization, and sends POST /mcp again — same body, plus the X-PAYMENT header holding the signed payload.
  5. Our settler verifies the signature, submits the transfer on X Layer in USDT0, then forwards the original JSON-RPC call to the verifier.
  6. The response is the trust report — score, recommendation, evidence — and an X-PAYMENT-RESPONSE header echoing the settlement tx hash.

Two round trips, one signed message, full settlement. No accounts, no API keys, no monthly invoice. The whole protocol is detailed in our EVIDIQ docs, but let's keep going on the wire itself.

Reading an accepts[] Object

When the 402 lands, the body looks roughly like this:

{
  "x402Version": 2,
  "accepts": [
    {
      "scheme": "exact",
      "network": "x-layer",
      "amount": "10000",
      "asset": "USDT0",
      "payTo": "0xEvid1q...Settler",
      "extra": {
        "name": "USDT0",
        "version": "1"
      }
    }
  ]
}

Every field matters, and getting one wrong is the most common way integrations break. Let's go field by field.

  • scheme — today it's always "exact". We don't run "upto" or streaming yet. If your client only supports "upto", it'll fail with a clear unsupported_scheme error.
  • network"x-layer", the X Layer chain ID, mainnet. Sending a payment on Sepolia or Base won't settle here, and our settler rejects it before any signature work happens.
  • amount — integer string in the smallest unit. 10000 means 0.01 USDT0 since USDT0 has 6 decimals. Don't pass floats. Don't pass "0.01". The string 10000 is the only correct answer.
  • asset"USDT0". We resolve this against our own allowlist. Sending a different asset by mistake gives you unsupported_asset, not a silent fallback.
  • payTo — the EVIDIQ settler address. Don't hard-code an old one from a previous deployment — re-read this field every challenge.
  • extra.name / extra.version — the EIP-712 domain fields for USDT0. These are part of the domain separator. Wrong version? Your signature won't recover.

EVIDIQ blog illustration 1

A useful sanity check: the client should treat the 402 body as authoritative. Don't assume the price from last week is still the price today. We can change amount between requests — and we have, when we adjust pricing.

EIP-3009 Without the Cryptography Lecture

EIP-3009 is transferWithAuthorization. It's a clever piece of paper that lets a wallet sign a message saying "I authorize this exact transfer of this exact amount to this exact address, valid between these two timestamps" — without the wallet ever submitting a transaction itself.

Why does this matter for our x402 pay-per-call MCP server? Because the agent calling us may not have any X Layer gas. It might be a read-only agent, a serverless worker, or a thing living inside another chain's wallet. We don't care. The payer signs. Our settler pays gas.

The shape of the signed message is an EIP-712 typed data payload. The client constructs it locally, signs with the payer's private key, and emits something like:

{
  "signature": "0x...",
  "from": "0xPayer...",
  "to": "0xEvid1q...Settler",
  "value": "10000",
  "validAfter": "0",
  "validBefore": "1735689600",
  "nonce": "0xabcd..."
}

Inside our flow:

  1. The client computes the EIP-712 domain separator from extra.name, extra.version, the USDT0 contract address, and X Layer's chain ID.
  2. The hash is signed with the payer's key — typically via eth_signTypedData_v4 from MetaMask, Rabby, or a hardware wallet bridge.
  3. The signed blob is base64-encoded and dropped into X-PAYMENT.
  4. We re-derive the domain separator, ecrecover the signer, check the nonce against the USDT0 contract, and verify validBefore is still in the future.
  5. Only then do we call transferWithAuthorization on the USDT0 contract. The contract itself re-checks the signature and executes the transfer in a single tx — that's the moment gas actually gets spent, and it's on our settler.

Our docs cover the reference implementation in TypeScript and Python at the EVIDIQ Sentinel docs page. The mental model is: the signature is the payment. Once we have a valid one, we can settle whenever we're ready.

We also expose a verification surface via the EVIDIQ Notary docs — once a report is issued, the same signature and nonce can be re-checked publicly. That's what makes the protocol useful for dispute resolution later.

What Happens on a Bad Signature or Late Nonce

Most integrations work on the happy path. Yours won't, at least not the first time. Here are the failure modes we see in production, what triggers them, and what each one looks like to your client.

  • Expired validBefore — the client took too long, or set a window too narrow. The USDT0 contract reverts with FiatTokenV2_2: authorization expired. Our settler surfaces this as 402 payment_invalid: expired. Fix: widen the window, or re-fetch the challenge and re-sign.
  • Reused nonce — same authorization submitted twice, or a stale one from a previous failed retry. Contract reverts with FiatTokenV2_2: nonce already used. We return 402 payment_invalid: nonce_used. Fix: always pull a fresh challenge and sign a new nonce per attempt.
  • Wrong domain separatorextra.version is stale, or the client is computing the separator against a different contract address. ecrecover returns the wrong address (or zero). Our pre-check returns 402 payment_invalid: bad_signature before we ever hit the chain. Fix: hard-code the latest extra.name/extra.version from the current 402 body.
  • Wrong network — client signed for Base but our settler is on X Layer. Same as above: ecrecover mismatches. We return 402 payment_invalid: wrong_network.
  • Amount mismatch — the client signed for 5000 but the 402 body said 10000. We reject at the settler with 402 payment_invalid: amount_mismatch before burning gas on a doomed tx.

EVIDIQ blog illustration 2

Each one is recoverable, and none of them are catastrophic. The settler never charges gas for a failed transferWithAuthorization, so a buggy retry loop won't drain a wallet — it just won't get a report. If you want to dive deeper into the operational side, the EVIDIQ Operator docs cover retry policies, idempotency keys, and how to log these failures cleanly.

Frequently Asked Questions

The Agent Skill at evidiq.dev/skill.md and the discovery tools (how_to_install, get_evidiq_skill) are free. The actual verify_agent tool is paid, on a per-call basis, via the x402 pay-per-call MCP server flow described above. There are no subscriptions, no tiers, no rate limits beyond what the chain settles.

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
How EVIDIQ's x402 Pay-Per-Call MCP Server Actually Works — EVIDIQ