Skip to main content

What is MPP

The Method Payment Protocol is an IETF-flavoured spec for attaching prices to JSON-RPC methods and MCP tools. Where x402 paywalls HTTP endpoints, MPP paywalls methods. That makes it the natural fit for Model Context Protocol servers and structured RPC services. AlgoVoi is registered in the public MPP services catalogue at mpp.dev and can be discovered programmatically by MPP clients. The live server entry is also indexed on MPPScan.

When to use MPP

Monetised MCP tools

Sell access to a database.query or web.scrape tool inside an MCP server.

JSON-RPC paywalls

Charge per eth_call shadow on your archive node, per getBlock on your indexer.

Method-level pricing

Different prices for read versus write methods on the same service.

Agent-discoverable services

AI agents browsing the MPP registry and paying to use any service that fits.

How MPP differs from x402

x402MPP
GranularityPer HTTP endpointPer method (RPC or MCP tool)
DiscoveryWalk endpointsPublic registry at mpp.dev
Auth headerAuthorization: Payment …Authorization: Payment …
Challenge formatpayment_requirements JSONChallenge object with method name
Best forREST APIs and content paywallsRPC services and MCP tools
Both protocols speak the same Authorization: Payment scheme on the wire. AlgoVoi accepts either on the same gateway.

AgentCash

AgentCash is the reference CLI client for MPP over Tempo mainnet. It holds a USDCe wallet, handles the full challenge-pay-retry loop, and needs no API key or configuration to call any AlgoVoi-hosted MPP resource.

Discover and call with one command

# Discover what's available at the gateway
npx agentcash try https://api.algovoi.co.uk

# Pay a specific tenant resource (no API key needed)
npx agentcash fetch https://api.algovoi.co.uk/mpp/{tenant_short_id}/{resource_id} -m GET

Deposit funds

npx agentcash deposit
# Deposits USDCe to your AgentCash wallet address on Tempo mainnet
A successful payment returns a signed JWT receipt in the response body:
{
  "verified": true,
  "resource_id": "mpp-test-tempo",
  "access_token": "eyJhbGci...",
  "network": "tempo"
}

Per-tenant discovery spec

Each tenant that has enabled public MPP access exposes a machine-readable resource list:
GET https://api.algovoi.co.uk/openapi-mpp/{tenant_short_id}.json
AgentCash and MPPScan can use this to enumerate all payable resources for that merchant.

Keyless public route

AlgoVoi supports a keyless public MPP route — no X-Tenant-Id or X-API-Key required. The payment proof is the auth.
GET /mpp/{tenant_short_id}/{resource_id}
Tenants must opt in to this route (operators set mpp_public_enabled in the dashboard). When a tenant is not enabled or a resource doesn’t exist, the response is a cloaked 404 regardless of the reason.
RouteAuth
GET /mpp/{resource_id}X-Tenant-Id + X-API-Key (server-to-server)
GET /mpp/{tenant_short_id}/{resource_id}Authorization: Payment proof only — no API key

Quickstart

1. Register your service

Define a service entry that points at your MPP-paywalled methods. AlgoVoi can register the entry on mpp.dev for you, or you can self-publish. Service definitions live in schemas/services.ts upstream. AlgoVoi’s own entry is published there as the canonical reference. See PR #556.

2. Issue a challenge

Client calls a paid method without payment. Server returns a Challenge:
{
  "version": 1,
  "method": "database.query",
  "credentials": [
    {
      "scheme": "exact",
      "network": "base:mainnet",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "amount": "5000",
      "payTo": "0xMerchant…",
      "validUntil": 1777200300
    }
  ]
}

3. Pay and present credential

Client pays on-chain, builds a Credential referencing the tx, and retries:
POST /jsonrpc HTTP/1.1
Authorization: Payment <base64-credential>
Content-Type: application/json

{ "jsonrpc": "2.0", "method": "database.query", "params": {...}, "id": 1 }
AlgoVoi verifies the credential, marks the payment consumed, and forwards the call.

Per-method pricing

A single MPP service can charge different prices for different methods:
{
  "id": "your-service",
  "methods": {
    "data.read":  { "price_microunits": "100",   "asset": "USDC" },
    "data.write": { "price_microunits": "10000", "asset": "USDC" }
  }
}

Chain support

All 7 chains are supported. Each chain maps to a specific MPP method string and methodDetails shape per the paymentauth.org draft specifications. Configure the chain per-tenant in the dashboard; the gateway emits the correct challenge automatically.

Network reference

ChainNetworkMethodSpecmethodDetails
Tempomainnettempodraft-tempo-charge-00none — flat request object
Solanamainnetsolanadraft-solana-charge-00network: "mainnet", decimals: 6
Solanadevnetsolanadraft-solana-charge-00network: "devnet", decimals: 6
Stellarmainnetstellardraft-stellar-charge-00network: "stellar:pubnet"
Stellartestnetstellardraft-stellar-charge-00network: "stellar:testnet"
Basemainnetevmdraft-evm-charge-00chainId: 8453, credentialTypes: ["hash","permit2"]
Basesepoliaevmdraft-evm-charge-00chainId: 84532, credentialTypes: ["hash","permit2"]
AlgorandmainnetalgorandAlgoVoi extensionnetwork: "algorand:mainnet"
AlgorandtestnetalgorandAlgoVoi extensionnetwork: "algorand:testnet"
VOImainnetvoiAlgoVoi extensionnetwork: "voi:mainnet"
VOItestnetvoiAlgoVoi extensionnetwork: "voi:testnet"
HederamainnethederaAlgoVoi extensionnetwork: "hedera:mainnet"
HederatestnethederaAlgoVoi extensionnetwork: "hedera:testnet"
Algorand, VOI, and Hedera are not yet in the paymentauth.org catalogue. AlgoVoi implements custom methods for each, following the same request/credential shape as stellar (CAIP-2 methodDetails.network, push-mode txId credential).

Challenge example — Solana

HTTP/1.1 402 Payment Required
WWW-Authenticate: Payment realm="api.algovoi.co.uk", id="...", method="solana",
  intent="charge", expires="...", request="<base64url>"
Decoded request object:
{
  "amount": "1000000",
  "currency": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
  "recipient": "<payout_wallet>",
  "methodDetails": {
    "network": "mainnet",
    "decimals": 6
  }
}

Credential shapes by method

MethodPush credentialPull credential
tempopayload.hash (EVM tx hash)payload.transaction (RLP signed tx)
solanapayload.signature (base58 tx sig)payload.transaction (base64 serialised tx)
stellarpayload.hash (64-char hex tx hash)payload.transaction (base64 XDR)
evmpayload.hash (0x tx hash) or payload permit2 objectpayload.transaction (RLP signed tx)
algorandpayload.txId (base64 tx ID)
voipayload.txId (base64 tx ID)
hederapayload.txId (Hedera tx ID)
For AgentCash (Tempo mainnet), the CLI handles the full challenge-pay-retry loop automatically — see AgentCash above.

Subscriptions — intent="subscription"

In addition to per-call charges (intent="charge"), MPP supports subscription intent — a one-time authority tx that grants AlgoVoi standing permission to pull a fixed amount each period.

How it differs from per-call charges

intent="charge"intent="subscription"
Payment per callYes — agent pays each timeNo — authority is granted once
Agent involvement after setupEvery callNone — AlgoVoi pulls autonomously
On-chain txPayment txAuthority (approve/allowance) tx
Use caseMetered API callsPeriodic tool access, data feeds

Subscription challenge

When a resource is configured for subscription billing, the gateway returns a 402 with subscription fields:
HTTP/1.1 402 Payment Required
WWW-Authenticate: Payment realm="api.algovoi.co.uk" method="algorand"
  intent="subscription"
  periodCount="1" periodUnit="month"
  subscriptionExpires="2027-05-12T00:00:00Z"
  amount="5000000" asset="31566704"
  receiver="ALGOVOI_WALLET"
  nonce="..." expires="..." request="<base64url>"
The agent signs an on-chain authority tx, then re-submits with Authorization: Payment. AlgoVoi verifies the authority tx inline and executes the first-period charge on chain before returning (draft-payment-intent-subscription-00 §Activation L396-407). Activation succeeds only when the first pull is broadcast-accepted; the response carries status: "active", a base64url subscriptionId, a first_pull_tx_id, and a Payment-Receipt header. Clients may include an Idempotency-Key header on retries to get the cached response instead of a replay rejection — see Recurring payments — Idempotency. On successful activation the gateway returns:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: private
Payment-Receipt: subscriptionId="gIom4-F_S4qDyD7Hq9EFjw", intent="subscription",
                 periodCount="1", periodUnit="month"

{
  "subscriptionId": "gIom4-F_S4qDyD7Hq9EFjw",
  "status": "active",
  "periodCount": 1,
  "periodUnit": "month",
  "nextDueAt": "2026-06-12T12:00:00Z",
  "expiresAt": "2027-05-12T00:00:00Z",
  "first_pull_tx_id": "0xabc..."
}
The subscriptionId is base64url-no-padding per draft-payment-intent-subscription-00 §Subscription Identifier; internally it remains a 16-byte UUID, so it round-trips losslessly. first_pull_tx_id is the on-chain tx that collected the first period; a background finality monitor watches it until per-chain confirmation depth is reached and flips the subscription to status: "revoked" if the tx is orphaned before finality. If the first-period charge can’t be collected (insufficient allowance, wallet balance, etc.) the gateway returns 402 Payment Required rather than activating — the agent retries with a fresh challenge after resolving the cause. A facilitator-side timeout returns 504.

Subscription routes

RouteAuthPurpose
GET /mpp/sub/{resource_id}X-Tenant-Id + X-API-KeyServer-to-server subscription setup
GET /mpp/sub/{tenant_short_id}/{resource_id}Authorization: Payment onlyKeyless agent subscription setup

Lifecycle

(synchronous activation, atomic with first-period charge)
  authority verify  →  first-pull broadcast-accepted  →  active
                                                       →  402 (pull failed)

(post-activation, async)
  active  →  revoked   (first-pull dropped pre-finality)
          →  cancelled (operator or agent request)
          →  expired   (sub_expires_at reached)
Once active, AlgoVoi’s pull reaper fires every 120 seconds and executes each subsequent period’s pull autonomously (the first period was already charged at activation). The agent receives no further prompts. See Recurring payments — MPP subscriptions for the full lifecycle, wire format, and resource setup details.

Audit trail & B2 retention

Every MPP payment — regardless of which route or client is used — is recorded in the payment_ledger table and shipped to Backblaze B2 Object Lock storage. Both paths converge on the same internal function before any response is returned.
RouteClientStorage path
GET /mpp/{resource_id} with X-Tenant-Id + X-API-KeyServer-to-server (native code, SDK)payment_ledger → dashboard Payments tab → B2
GET /mpp/{tenant_short_id}/{resource_id} with Authorization: PaymentAgentCash, MPP clients (no API key)payment_ledger → dashboard Payments tab → B2

Hash chain

Each PaymentLedgerEntry row receives three tamper-evidence fields at insert time:
FieldDescription
chain_positionMonotonically increasing sequence across all MPP payments
content_hashSHA-256 of the RFC-8785 canonical JSON of the row’s immutable fields
prev_hashcontent_hash of the previous row (64 zeros for the first row)
The canonical payload locked into each hash includes: tenant_id, resource_id, tx_id, chain, asset_id, amount_microunits, verified_at, payer_address, and status. These fields cannot be altered post-insert without breaking the chain.

B2 Object Lock shipping

A background reaper (running every ~5 minutes) batches new chained rows and ships them to B2:
payment_ledger/000000001-000000250-<batch-sha256>.ndjson
Each .ndjson file contains the full canonical payload for every row in the batch, including content_hash and prev_hash, so external auditors can independently recompute and verify the chain. Files are written in COMPLIANCE mode Object Lock — immutable and undeletable for 7 years.

What this means for your integration

  • Keyless (AgentCash) payments: the payer_address of the AgentCash wallet is captured in the B2 record at the moment of payment. GDPR erasure after 90 days applies to the live database copy; the WORM copy is permanent per UK MLRs Reg 40.
  • Key-authenticated payments: same guarantee — the calling tenant and the on-chain tx_id are cryptographically bound to the tenant’s tenant_id in the chain.
  • Dispute resolution: tenants can request the B2 batch files for any time range from security@algovoi.co.uk. The batch SHA-256 is recorded in audit_chain_shipments for cross-reference.
  • Regulatory retention: minimum 5 years per UK MLRs Reg 40; AlgoVoi retains for 7 years (aligned with HMRC standard).

See also

  • x402 for HTTP endpoints
  • AP2 for Google’s mandate-based agent commerce
  • A2A for x402 over the Agent-to-Agent transport
  • Tempo chain for USDCe TIP-20 details
  • AlgoVoi on MPPScan — live server entry and resource index