Watch an AI Agent Try to Spend Money It Shouldn't Engineers Prakash Rao and Marco Gonzalez built a live demonstration of an AI agent paying for MCP tool calls over the x402 payment protocol on a test network, including the failure path where the agent attempts to spend on something it was not approved for. The pair argue that while x402 v2 and the MCP 2026-07-28 revision moved pricing and routing metadata into HTTP headers, making paid agent traffic cheaper to meter, neither spec defines who holds the authority to approve spending — a decision they place with a budget authority the agent cannot reach. Their architecture treats the agent process and all its inputs as hostile, routing every request through an enforcement gateway, authorization service and signing service. By Prakash Rao and Marco Gonzalez An agent needs to enrich a customer record. The tool that does it costs money. Nothing in x402 v2 says who is allowed to approve that. Nothing in MCP 2026-07-28 says it either. Both specs moved price and routing metadata into HTTP headers, which means your gateway can now see what a tool call costs. Seeing a price is not the same as having the authority to approve one. We wrote about where that authority should sit in 402 Payment Required: What Enterprise MCP Servers Owe the Agents That Pay Them https://aaif.io/blog/402-payment-required-what-enterprise-mcp-servers-owe-the-agents-that-pay-them , with the Agentic AI Foundation. Then we took it to AGNTCon / MCPCon Japan in Tokyo and let an agent actually do it, live, on a test network. If you missed either the post or the session, here is everything you need before we start. What x402 is. HTTP has had a 402 Payment Required status code sitting unused since 1997, reserved but never specified. x402 finally gave it a meaning: a server answers 402 with the terms it wants, the client retries with a signed payment authorization, and the server returns the result plus evidence of settlement. v2 December 2025 moved all of that into headers : PAYMENT-REQUIRED , PAYMENT-SIGNATURE and PAYMENT-RESPONSE , instead of burying it in bodies. What MCP is. The Model Context Protocol is how an AI agent discovers and calls tools. The 2026-07-28 revision removed sessions and the Mcp-Session-Id header, added Mcp-Method and Mcp-Name as headers, and hardened authorization with issuer validation per RFC 9207. Why those two releases matter together. Both moved the interesting metadata out of request bodies and into headers . Your gateway, rate limiter and WAF can now see who is calling, which tool, and what it costs, without parsing a single JSON-RPC body. Metering and routing for paid agent traffic got dramatically cheaper. And that is exactly where the problem starts. Header visibility is not authority. The moment your infrastructure can see the price, it has to decide something about it, and neither spec tells you who gets to make that call. That was the argument in our AAIF post https://aaif.io/blog/402-payment-required-what-enterprise-mcp-servers-owe-the-agents-that-pay-them : the spending decision belongs to a budget authority the agent cannot reach, and where you put it is the part that will still matter after the protocol details have moved on. What we did in Tokyo. Stopped arguing and ran it: a live agent paying for MCP tool calls on a test network, including the path where it tries to spend on something it was not approved for. Five moving parts appear throughout. You do not need to memorize these; they are here so the diagrams read cleanly. | Component | Its one job | |---|---| | Agent | Decides what work to do. Treated as hostile throughout. Holds no private key. | | Enforcement gateway | The only permitted route out. Sees every request twice and can refuse at the boundary. | | Authorization service | Decides whether spending is permitted, and reserves the budget. The agent cannot influence it. | | Signing service | Produces signatures. Reads what it signs, and can refuse. | | Protected resource | The tool that costs money, behind a paid server. | Our threat model, so you know what is and is not being defended: the agent process and every input to it are hostile . The gateway, the services and their policies are honest but fallible . Compromised binaries, malicious operators, key extraction from hardware and chain-level attacks are out of scope . Different problem, different post. Now follow one request all the way through. It gets interesting about two-thirds of the way down, when the request that arrives at the boundary turns out not to be the request that was approved. Our agent has a task stated in business terms: enrich record 42 . It does not know what that costs, and it does not know which provider will do it. So the first problem is immediate: how do you let a hostile thing shop around, without handing it a wallet first? It asks, and gets refused on purpose: GET /tools/enrich?record=42 HTTP/1.1 Host: resource.example HTTP/1.1 402 Payment Required PAYMENT-REQUIRED: eyJ2IjoyLCJhY2NlcHRzIjpbey... That header is base64 JSON. Decoded, it is an offer: { "v": 2, "accepts": { "scheme": "exact", "network": "