Adding x402 payments to sndev.io
Integrating the x402 micropayment protocol into an MCP server and building a test harness that can run in both bearer token and crypto payment modes.
After launching sndev.io, I needed an auth model. The obvious choice was API keys — hand out bearer tokens, validate against an environment variable, done. But I’d been watching the x402 protocol evolve and wanted to try it in a real production context.
x402 is a payment protocol built on the HTTP 402 status code. When a client hits a protected endpoint without payment credentials, the server responds with a 402 and a machine-readable description of what payment is required. The client can then fulfill the payment on-chain and retry. The whole thing is designed to work without accounts, without dashboards, without any out-of-band coordination — just a private key and a fetch wrapper.
For an MCP server serving AI agents, this felt like a natural fit. Agents already operate autonomously. They don’t have user sessions or login flows. A payment protocol that requires no signup and just works with a wallet is actually the simpler path.
The implementation
The auth layer on sndev.io supports both modes. If you send a valid bearer token, you get through. If you don’t, you get a 402 response with the x402 payment requirements. A properly configured x402 client handles the payment transparently and retries the request — no manual intervention needed.
On the Cloudflare Worker side, adding x402 support was mostly wiring up the right response format for the 402 case and configuring the payment destination address. The worker logs successful payments via a Discord webhook so I have visibility into what’s getting used.
Building the tester
Once both auth modes were live, I needed a way to verify that everything actually worked end to end — not just unit tests, but real requests against the production endpoint, in both payment modes.
I built x402-tester as a standalone script. It runs a suite of seven tests against sndev.io/mcp, covering all three tools (search, search_rest, search_products) plus an error handling case. Each test sends a real MCP request, validates the response structure, and reports pass/fail with timing.
The interesting part is the auth mode switch. Pass --bearer and it uses a bearer token from the environment. Leave it off and it loads a private key, derives an Ethereum account using viem, wraps the fetch function with the x402 payment client, and runs every request through the payment flow. Same test cases, two completely different auth paths:
const client = new x402Client();
registerExactEvmScheme(client, { signer });
fetchFn = wrapFetchWithPayment(fetch, client); Running the tester in payment mode is a good gut check. If every test passes, it means the x402 flow is actually working — payment is happening, the server is accepting it, and the tool responses are correct. If something breaks, the timing output makes it easy to see whether the problem is in the payment layer or the search logic.
What I learned
The x402 client library handles most of the complexity. The wrapFetchWithPayment function intercepts 402 responses, processes the payment, and retries — all transparently. From the test harness perspective, swapping between bearer and x402 mode is a four-line change.
The bigger challenge was making sure the server returned well-formed 402 responses that the client could actually parse. The spec has specific requirements around the payment amount, token, and network, and small deviations cause silent failures. Getting that right required a few iterations.
The end result is an MCP server that accepts payment from any wallet with the right balance — no accounts, no subscriptions, no manual key management. For agents that need to pay for tools programmatically, that’s actually the right model.