← Blog
August 10, 2026 · 15 min

MPP: Stripe and Tempo's Answer to x402, Audited From the Spec Up

There are now two production protocols that turn HTTP 402 into a payment rail for machines. One of them we have covered for months. The other one is co-signed by Stripe, runs on a purpose-built L1, and just kept shipping specs through last week. We cloned the repo and read all of it.

The Machine Payments Protocol (MPP) is an open standard for machine-to-machine payments co-authored by Tempo — the payments L1 incubated by Stripe and Paradigm — and Stripe itself. It launched on March 18, 2026, the same day Tempo's mainnet went live, and the same day version 01 of its core spec landed at the IETF. Since then it has appeared in our coverage only in passing: AWS listed Stripe and MPP as "coming soon" facilitator options in its WAF monetization launch, and OSL AgentPay shipped x402, AP2 and MPP side by side. That is not enough for a protocol this positioned. This is the full read.

For this audit we cloned tempoxyz/mpp-specs on August 10, 2026 (HEAD f9506cd, committed August 7). The repo holds 23 specification documents totaling roughly 125,000 words: one core spec, two intents, eighteen method documents across ten payment families, and two extensions. The specs are dedicated to the public domain under CC0 1.0. First commit: January 5, 2026. Public launch: March 18. It is a young document set, and it reads like one — in ways that matter, as we will show.

An authentication scheme, not a header pair

The single most important design decision in MPP is where it lives in HTTP. x402 v2 defines its own header family — PAYMENT-REQUIRED, PAYMENT-SIGNATURE, PAYMENT-RESPONSE — that travels alongside the status code but outside HTTP's authentication machinery. MPP instead registers Payment as an HTTP authentication scheme, next to Basic and Bearer in the IANA registry. The challenge arrives in WWW-Authenticate; the proof goes back in Authorization.

HTTP/1.1 402 Payment Required
Cache-Control: no-store
WWW-Authenticate: Payment id="x7Tg2pLqR9mKvNwY3hBcZa",
    realm="api.example.com",
    method="tempo",
    intent="charge",
    expires="2026-08-10T12:05:00Z",
    request="eyJhbW91bnQiOiIxMDAwIi4uLg"

// client fulfills the payment, then retries:
GET /resource HTTP/1.1
Authorization: Payment eyJjaGFsbGVuZ2UiOnsuLi59LCJwYXlsb2FkIjp7Li4ufX0

The request parameter is base64url-encoded JSON, canonicalized with JCS (RFC 8785) so that every implementation produces identical bytes. The credential echoes the entire challenge plus a method-specific payload and an optional source field for payer identity, where the spec recommends W3C DIDs. Success responses carry a Payment-Receipt header. Errors use RFC 9457 Problem Details with a registered vocabulary (payment-insufficient, verification-failed, invalid-challenge). The status code semantics are spelled out: 402 for any payment barrier including failed verification, 401 reserved for non-payment authentication, 403 when payment succeeded but policy denies access.

Two details deserve attention because x402 lacks both. First, challenge binding: the spec recommends computing the challenge id as an HMAC-SHA256 over seven fixed positional slots (realm, method, intent, request, expires, digest, opaque), which gives servers stateless, tamper-proof challenges without a database lookup — the same trick Cloudflare's batch binding uses, but normatively specified with a slot layout designed to survive future extension. Second, Accept-Payment: a client request header with full content-negotiation semantics — q-values, wildcards like tempo/*, and q=0 exclusions — that lets an agent declare which method and intent combinations it can pay with before the server chooses which challenges to emit. x402 has nothing comparable; the buyer just receives whatever accepts array the seller configured. For a client that holds one wallet and one card, pre-negotiation removes a round trip and an entire class of unfulfillable challenges.

Also notable: the core spec mandates Cache-Control: no-store on every 402 and Cache-Control: private on responses carrying receipts. When we audited x402's edge deployments in early August, we found the x402 specs contained zero occurrences of Cache-Control while the SDKs converged on exactly this behavior through patch PRs. MPP had it as a MUST in the core document from the start. That is what writing at the HTTP layer, in IETF style, buys you.

Intents and methods instead of schemes and networks

MPP's modularity slices differently than x402's. Where x402 has schemes (exact, upto, batch-settlement) crossed with network bindings, MPP separates intents — what kind of payment: charge (one-time), session (streaming), subscription (recurring, merged July 29 with Stripe and Tempo implementations) — from methods, the concrete rails. The methods directory currently covers ten families: tempo, stripe, card, usdc, evm, solana, lightning, nearintents, stellar, and hedera. The last additions are dated August 7: a Hedera session intent, support for Solana confidential transfers in the charge flow, and a tightening of the Solana session's operator-signed mode.

Read that list again. Card. Lightning. Stripe. This is the deepest philosophical split with x402, which is stablecoin-only by construction. MPP's core is aggressively payment-method agnostic — its stated design principle is "no implicit advantages for any currency or asset" — and the same 402 challenge array can offer a Tempo stablecoin transfer next to a card charge next to a Lightning invoice, letting the client pick. The Agentic Commerce Protocol solved fiat-for-agents at the checkout layer; MPP solves it at the HTTP layer, per request.

The other structural difference: MPP has no facilitator. x402 externalizes verification and settlement to a dedicated API role that spawned a market of hosted providers. In MPP the server settles directly — against the Stripe API, against a Tempo RPC, against a Lightning node. That removes a trust intermediary and a metadata choke point, but it also means every seller integrates every rail it wants to accept. The facilitator market is x402's answer to that integration burden; MPP's answer, for now, is SDKs in TypeScript, Python, Rust, Go and Ruby, plus official Stripe samples.

Sessions: payment channels as a first-class primitive

The most technically interesting document in the repo is the Tempo session spec. It defines unidirectional streaming payment channels: the client deposits into an on-chain escrow, then signs off-chain EIP-712 vouchers with monotonically increasing cumulative amounts as it consumes service. The server verifies each voucher over HTTP — no chain interaction — and settles periodically or at close, receiving cumulativeAmount − settled in a single transaction. The spec's own leading use case is an LLM inference API charging per output token, with a price unit of llm_token in the challenge.

// challenge request for a session (decoded)
{
  "amount": "25",              // price per unit, base units
  "unitType": "llm_token",
  "suggestedDeposit": "10000000",
  "currency": "0x20c0…",        // TIP-20 token
  "recipient": "0x742d…",
  "methodDetails": { "escrowContract": "0x1234…", "chainId": 4217, "sessionProtocol": "v2" }
}

The lifecycle runs through four payload actions — open, topUp, voucher, close — all submitted to the same resource URI, so no dedicated payment control plane routes exist. Channels have no expiry; the client's exit is a forced close with a 15-minute grace period that lets the server land its last voucher. There are two backends: v1 contract-backed escrow (EIP-712 domain "Tempo Stream Channel", uint128 amounts) and v2 on a TIP-20 channel precompile (domain "TIP20 Channel Reserve", uint96), with fee sponsorship where the server co-signs the client's funding transaction using Tempo's dual-signature transaction format. For streaming responses the spec even defines an SSE event, payment-need-voucher, that pauses delivery mid-stream until the client signs a higher voucher — metered inference with in-band flow control.

Compare this to what x402 offers for the same problem. The upto scheme authorizes a maximum and settles actual usage via Permit2 — one authorization, one settlement, per request cycle. Circle's Nanopayments batch thousands of off-chain signatures against a shared Gateway balance, with Circle's TEE as the batching operator. MPP sessions are the third architecture: per-relationship escrow, cumulative vouchers, no operator between payer and payee. It is capital-backed like Circle's design — funds are locked before service — but bilateral and operator-free like a classic state channel. The cost is capital fragmentation (every payer-payee pair needs its own funded channel) and the accounting burden the spec honestly documents: servers MUST persist voucher state and spent counters to durable storage before delivering service, or crash-lose funds.

The fiat rail: Shared Payment Tokens

The Stripe method is where MPP stops looking like a crypto protocol. The client creates a single-use Shared Payment Token (spt_…) via the Stripe API, with usage limits on currency, maximum amount and expiry. The credential carries the SPT id; the server redeems it by creating a PaymentIntent with shared_payment_granted_token and confirm: true, and returns 200 once the intent status is succeeded. Cards, Link, and by extension BNPL — everything Stripe processes — flows through the same 402 exchange as a stablecoin transfer, and lands in the merchant's existing Stripe dashboard and payout schedule. Both sides need Stripe accounts, and the spec supports Stripe Connect settlement (platform fees, transfer destinations) as server-side policy that MUST NOT appear in the challenge.

This is the same custodial-tokenized pattern as ACP's Delegated Payment Spec — an allowance-scoped token standing in for a card — but stripped of the checkout-session machinery and embedded at the request level. For agent operators the implication is real: an MPP-paying agent does not need to hold crypto at all. It needs a Stripe account and a payment method. That widens the addressable base enormously, at the price of accounts, KYC, and reversibility — everything the walk-up x402 model was designed to avoid.

Discovery, written by the x402scan team

The discovery extension is short and pragmatic: services publish an OpenAPI 3.x document at /openapi.json annotated with x-service-info (categories, docs links, llms.txt) and per-operation x-payment-info offer arrays — intent, method, amount (with null for dynamic pricing), currency. The 402 challenge remains authoritative; discovery is advisory. An informative appendix specifies registry behavior: re-crawl at least every 24 hours, delist after 7 consecutive failures, 64 KB size limits.

The authorship is the interesting part. Alongside two Tempo authors, the spec is co-authored by Ryan Sproule and Sam Ragsdale of Merit Systems — the team behind x402scan, the largest independent x402 explorer. The document explicitly credits x402scan's OpenAPI-first approach as prior art, and x402 accounts for 8 of the repo's citations. The people who built x402's de facto discovery layer wrote MPP's official one. Contrast with x402's own answer, the Bazaar, which ranks by observed settlement activity: MPP discovery is self-declared and crawled, Bazaar is settlement-evidenced. The Sybil-resistance argument favors x402; the works-without-a-facilitator argument favors MPP.

MCP transport: error −32042

MPP also specifies how the Payment scheme travels over JSON-RPC and MCP. A paid tool call fails with error code -32042 ("Payment Required") carrying a challenges array in error.data — as native JSON, not base64url, with JCS canonicalization and hashing preserving the challenge binding. The client retries with the credential under _meta["org.paymentauth/credential"], and the receipt returns under _meta["org.paymentauth/receipt"]. Verification failure is -32043 with a fresh challenge. Tool calls, resource reads and prompt fetches are all covered, and payment-gated notifications are explicitly dropped.

This is a cleaner in-band design than x402's MCP story, which threads payment through _meta on otherwise-successful responses. But it is also where the spec shows its age, as the audit section explains.

What the audit found

We read the specs the way we read x402-rs and Visa's TAP repo: assuming nothing, decoding everything. Three findings survived verification.

Finding 1 — the core spec's wire examples contradict its own prose. We decoded every base64url request blob in the core document. Three of them decode to "currency":"USD" — uppercase — while the charge intent spec requires lowercase ISO 4217 codes and the prose "decoded" JSON printed directly beneath each example shows "usd". Worse, the "Signed Authorization" example's actual bytes contain "asset":"USD" and a top-level "nonce" — a field name that appears in no schema — while the prose rendering shows "currency" and tucks the nonce inside methodDetails. In a protocol whose challenge binding is an HMAC computed over the base64url request exactly as it appears on the wire, examples that do not match their own decoding are broken test vectors waiting to propagate into implementations.
Finding 2 — the appendix credential example is missing a REQUIRED field. The core spec's own credential table marks challenge as required, and every parser section depends on the echoed challenge for verification. But the one-time charge example in the appendix ships an Authorization header whose bytes decode to {"id":"…","payload":{…}} — no challenge object at all, with the challenge id floated to the top level in a structure defined nowhere in the document. The prose below it, again, shows the correct shape. Anyone implementing from the examples rather than the tables builds an incompatible client.
Finding 3 — the MCP transport is pinned to a superseded revision. The transport document normatively references MCP 2025-11-25 and advertises payment support under capabilities.experimental.payment. MCP 2026-07-28 has been final since late July, and its extension framework — the mechanism that gave us Tasks, Apps and enterprise authorization as first-class extensions — is precisely where a payment capability belongs. As of HEAD f9506cd there is no reference to the 2026-07-28 spec anywhere in the repo. MPP's MCP story is one protocol revision behind the ecosystem it targets.

None of these are architectural flaws. They are the fingerprints of a spec written fast by a small group: the git history shows 68 commits from 17 human contributors, with a single Tempo engineer (Brendan Ryan) authoring 20 of them. Compare the numbers: mpp-specs has 87 stars, 52 forks and 17 open issues; the x402 repo we audited last week is at over a thousand commits with SDKs at 2.20.0. Maturity gap, not quality ceiling.

Governance: two companies and an individual draft

The IETF posture deserves precision, because "IETF draft" is doing marketing work in most MPP coverage. draft-ryan-httpauth-payment is an individual submission — five authors, three from Tempo Labs and two from Stripe — with intended status Standards Track, no working group adoption, no IETF stream, and an expiry of September 19, 2026. That is a legitimate first step on a standards path, the same one Web Bot Auth walked before its working group formed. But today it has exactly the standing of any expired-in-six-months personal draft, and the specification's normative home remains a repo governed by two companies. x402 chose the opposite trade: custom headers with no IANA blessing, but a Linux Foundation home with 40 member organizations. One protocol is standards-shaped without neutral governance; the other is neutrally governed without standards-body form.

Adoption reflects the age difference. Stripe's launch post names early adopters — Browserbase charging per headless browser session, Parallel Web Systems selling web access per API call — and Tempo brings unusual institutional weight: a $500 million Series A at a reported $5 billion valuation before mainnet, sub-second deterministic finality, no native gas token (fees paid in stablecoins through a protocol AMM), and Stripe, Visa and Zodia Custody as its first external validators on a still-permissioned network. But x402's throughput numbers — hundreds of millions of cumulative transactions, whatever fraction is organic — remain an order of magnitude beyond anything MPP has reported. The realistic 2026 reading: x402 owns the crypto-native agent economy; MPP is the first credible bridge from that economy to the card networks' installed base, and Stripe supports both.

What it means for LLM4Agents

LLM4Agents sells inference through an OpenAI-compatible gateway settled per call over x402 and EIP-3009. MPP touches that position three ways.

First, the session intent is aimed at exactly our workload. Per-token streaming billing with in-band voucher flow control is a better mechanical fit for LLM inference than per-request exact settlement, and the spec's flagship example is an LLM API. If MPP sessions get traction among inference sellers, "pay per output token over a channel" becomes a pricing shape buyers expect, and our reserve-then-settle billing — which already meters actual usage — maps onto it more naturally than onto x402's upto. Second, Accept-Payment and multi-method challenges mean a single 402 can offer stablecoin and card rails simultaneously. A gateway that answered with both an x402 challenge and an MPP challenge would be payable by any agent, funded or carded. Nothing in either protocol forbids emitting both header families on one response. Third, the threat: MPP with Stripe rails re-introduces accounts, KYC and chargebacks into machine payments. If enterprise buyers standardize on carded agents, the walk-up, no-account model that differentiates us becomes a niche rather than the default. The bearer-versus-walk-up decision tree gains a third branch, and it is owned by the largest payments processor on the internet.

Staying on the frontier

Concrete moves, in order. First, prototype dual-challenge responses: emit our existing x402 PAYMENT-REQUIRED header and an MPP WWW-Authenticate: Payment challenge on the same 402 for one test route, and measure what breaks in real clients. Second, implement the MPP charge intent as a receiver using the Tempo method on testnet — the credential verification is simpler than x402's facilitator round trip, and the SDK surface (TypeScript via mppx) is small. Third, map our reserve-proxy-settle pipeline onto the session intent's accounting model (acceptedCumulative / spent / settled) and publish the comparison; if we ever ship channel-based billing, that document becomes the design. Fourth, upstream the three findings above — decoded-example mismatches and the MCP revision pin are exactly the issues a young spec repo wants reported, and contributor standing in a two-company spec is cheap now and expensive later. Fifth, watch two dates: September 19, when the current IETF draft expires and either gets refreshed or adopted, and whatever moment the MCP transport moves to the 2026-07-28 extension framework — because the first payment extension blessed into the official MCP registry, whether it descends from MPP's -32042 or from x402's _meta flow, will set the default for every agent host that follows.

Settlement per call, no account required

LLM4Agents meters real usage across 345+ models and settles in stablecoins over x402 — the walk-up model MPP is now competing with.

Register your agent