UCP payment handler specification
Schema: /schemas/payment-handlers/mpp.json
Machine Payments Protocol (MPP), multi-chain. Today AgentScore merchants ship Tempo USDC + Solana USDC via solana/charge; MPP itself reaches Stellar, Lightning, and more.
AgentScore binding for the Machine Payments Protocol (MPP, mpp.dev) in UCP. The agent uses an MPP-aware client (e.g. agentscore-pay, the tempo CLI) to settle in response to a 402 challenge. The merchant's MPP server verifies the signed payment authorization and captures the funds. The `networks` array enumerates which MPP-supported networks the merchant accepts. Today: Tempo USDC + Solana USDC via `solana/charge`. Adding more MPP networks (Stellar, Lightning, etc.) is a config change, not a new handler. Shape is identical to `payment.x402.config` so consumers parse both the same way. The MPP protocol itself is specified at paymentauth.org, with developer docs at mpp.dev.
The schema for the binding's `config` object lives at /schemas/payment-handlers/mpp.json. The wrapper fields (id, version, spec, schema, config) are defined by UCP itself.
Fields:
networks (array of object): Array of MPP networks the merchant accepts. One entry per network. Must contain at least one entry. Same shape as x402.config.networks so consumers parse both handlers identically.networks[].network (string): MPP network identifier. Tempo: `tempo-mainnet` / `tempo-testnet`. Solana via `solana/charge`: `mpp-solana-mainnet` / `mpp-solana-devnet`.networks[].chain_id (integer (optional)): Optional. Numeric chain id for EVM-style chains (e.g. 4217 for Tempo mainnet, 42431 for the Tempo Moderato testnet). Omit for non-EVM networks.networks[].recipient (string (optional)): Optional. Merchant's static settlement address on this network. When present, agents MAY cross-check the 402 challenge's `pay_to` against this declared address as MITM protection. Omit if the merchant uses per-order recipients; the authoritative recipient still ships in the 402 body.Example config:
{
"networks": [
{ "network": "tempo-mainnet", "chain_id": 4217, "recipient": "0xabc..." },
{ "network": "mpp-solana-mainnet", "recipient": "Ata..." }
]
}End-to-end flow from the merchant's 402 challenge to settlement:
accepts[] including one entry per accepted MPP chain. Tempo: { id: "tempo", network: "tempo-mainnet", currency: "USDC", amount, decimals, recipient }; Solana: { id: "solana", network: "mpp-solana-mainnet", currency: "USDC", amount, decimals, recipient }. The 402 body also carries agent_instructions.how_to_pay with the canonical agentscore-pay pay --chain {tempo|solana} commands per chain.did:pkh:eip155:: for Tempo; did:pkh:solana:: for Solana).Authorization: Payment carrying the signed authorization.Merchant-side responsibilities once the agent's payment credential arrives on the retry leg:
mpp.charge() (e.g. via pympp.tempo or mppx) to submit the authorization to Tempo. On confirmation, capture the transaction hash for the order record. The merchant SHOULD attribute the payment to a credential or operator via the source DID (did:pkh:eip155:: ).payload.signed_transaction). Validate the SPL TransferChecked instruction targets the merchant's expected destination ATA, mint (USDC), and amount derived from the 402 challenge. Submit via @solana/mpp/server.charge (or upstream sendTransaction RPC). On confirmation, capture the tx hash. Settlement-Overrides headers (X-Settlement-Overrides) accepted for dynamic-amount finalization.confirmed commitment for low-value payments, finalized for >$100. The reference server uses confirmed by default.did:pkh source OR derived from the on-chain authorization) for AgentScore wallet-attribution writebacks. Required for credential↔wallet linkage on the merchant side.agentscore-pay (npm: @agent-score/pay). See docs.agentscore.com/integrations/pay-cli