{"id":"59da7aa0-21f9-4ba6-84ff-bdf713c8b126","shortId":"dXU9Vb","kind":"skill","title":"mpp","tagline":"Build with MPP (Machine Payments Protocol) - the open protocol for machine-to-machine payments over HTTP 402. Use when developing paid APIs, payment-gated content, AI agent payment flows, MCP tool payments, pay-per-token streaming, or any service using HTTP 402 Payment Required. ","description":"# MPP - Machine Payments Protocol\n\nMPP is an open protocol (co-authored by Tempo and Stripe) that standardizes HTTP `402 Payment Required` for machine-to-machine payments. Clients pay in the same HTTP request - no accounts, API keys, or checkout flows needed.\n\nThe core protocol spec is submitted to the IETF as the [Payment HTTP Authentication Scheme](https://datatracker.ietf.org/doc/draft-ryan-httpauth-payment/).\n\n## When to Use\n\n- Building a **paid API** that charges per request\n- Adding a **paywall** to endpoints or content\n- Enabling **AI agents** to pay for services autonomously\n- **MCP tool calls** that require payment\n- **Pay-per-token streaming** (LLM inference, content generation)\n- **Session-based metered billing** (pay-as-you-go)\n- Accepting **stablecoins** (Tempo), **cards** (Stripe), or **Bitcoin** (Lightning) for API access\n- Building a **payments proxy** to gate existing APIs (OpenAI, Anthropic, etc.)\n\n## Core Architecture\n\nThree primitives power every MPP payment:\n\n1. **Challenge** - server-issued payment requirement (in `WWW-Authenticate: Payment` header)\n2. **Credential** - client-submitted payment proof (in `Authorization: Payment` header)\n3. **Receipt** - server confirmation of successful payment (in `Payment-Receipt` header)\n\n```\nClient                                          Server\n  │  (1) GET /resource                            │\n  ├──────────────────────────────────────────────>│\n  │         (2) 402 + WWW-Authenticate: Payment   │\n  │<──────────────────────────────────────────────┤\n  │  (3) Sign payment proof                       │\n  │  (4) GET /resource + Authorization: Payment   │\n  ├──────────────────────────────────────────────>│\n  │         (5) Verify + settle                   │\n  │         (6) 200 OK + Payment-Receipt          │\n  │<──────────────────────────────────────────────┤\n```\n\n## Payment Methods & Intents\n\nMPP is payment-method agnostic. Each method defines its own settlement rail:\n\n| Method | Rail | SDK Package | Status |\n|--------|------|-------------|--------|\n| [Tempo](/payment-methods/tempo) | TIP-20 stablecoins on Tempo chain | `mppx` (built-in) | Production |\n| [Stripe](/payment-methods/stripe) | Cards, wallets via Shared Payment Tokens | `mppx` (built-in) | Production |\n| [Lightning](/payment-methods/lightning) | Bitcoin over Lightning Network | `@buildonspark/lightning-mpp-sdk` | Production |\n| [Stellar](/payment-methods/stellar) | SEP-41 tokens on Stellar | `@stellar/mpp` | Production |\n| [Card](/payment-methods/card) | Encrypted network tokens (Visa) | `mpp-card` | Production |\n| Custom | Any rail | `Method.from()` + `Method.toClient/toServer` | Extensible |\n\nTwo payment intents:\n\n| Intent | Pattern | Best For |\n|--------|---------|----------|\n| **charge** | One-time payment per request | API calls, content access, fixed-price endpoints |\n| **session** | Pay-as-you-go over payment channels | LLM streaming, metered billing, high-frequency APIs |\n\n## Quick Start: Server (TypeScript)\n\n```typescript\nimport { Mppx, tempo } from 'mppx/server'\n\nconst mppx = Mppx.create({\n  methods: [tempo({\n    currency: '0x20c0000000000000000000000000000000000000', // pathUSD\n    recipient: '0xYourAddress',\n  })],\n})\n\nexport async function handler(request: Request) {\n  const result = await mppx.charge({ amount: '0.01' })(request)\n  if (result.status === 402) return result.challenge\n  return result.withReceipt(Response.json({ data: '...' }))\n}\n```\n\nInstall: `npm install mppx viem`\n\n## Quick Start: Client (TypeScript)\n\n```typescript\nimport { privateKeyToAccount } from 'viem/accounts'\nimport { Mppx, tempo } from 'mppx/client'\n\n// Polyfills globalThis.fetch to handle 402 automatically\nMppx.create({\n  methods: [tempo({ account: privateKeyToAccount('0x...') })],\n})\n\nconst res = await fetch('https://api.example.com/paid')\n// Payment happens transparently when server returns 402\n```\n\n## Quick Start: Server (Python)\n\n```python\nfrom fastapi import FastAPI, Request\nfrom mpp.server import Mpp\nfrom mpp.methods.tempo import tempo, ChargeIntent\n\napp = FastAPI()\nmpp = Mpp.create(method=tempo(\n    currency=\"0x20c0000000000000000000000000000000000000\",\n    recipient=\"0xYourAddress\", intents={\"charge\": ChargeIntent()},\n))\n\n@app.get(\"/resource\")\nasync def get_resource(request: Request):\n    result = await mpp.charge(authorization=request.headers.get(\"Authorization\"), amount=\"0.50\")\n    if isinstance(result, Challenge):\n        return JSONResponse(status_code=402, content={\"error\": \"Payment required\"},\n            headers={\"WWW-Authenticate\": result.to_www_authenticate(mpp.realm)})\n    return {\"data\": \"paid content\"}\n```\n\nInstall: `pip install \"pympp[tempo]\"`. See `references/python-sdk.md` for full patterns.\n\n## Quick Start: Server (Rust)\n\nInstall: `cargo add mpp --features tempo,server`. See `references/rust-sdk.md` for full patterns.\n\n## Framework Middleware (TypeScript)\n\nEach framework has its own import (`mppx/nextjs`, `mppx/hono`, `mppx/express`, `mppx/elysia`):\n\n```typescript\n// Next.js\nimport { Mppx, tempo } from 'mppx/nextjs'\nconst mppx = Mppx.create({ methods: [tempo({ currency: '0x20c0...', recipient: '0x...' })] })\nexport const GET = mppx.charge({ amount: '0.1' })(() => Response.json({ data: '...' }))\n\n// Hono\nimport { Mppx, tempo } from 'mppx/hono'\napp.get('/resource', mppx.charge({ amount: '0.1' }), (c) => c.json({ data: '...' }))\n```\n\nSee `references/typescript-sdk.md` for Express and Elysia examples.\n\n## Sessions: Pay-as-You-Go Streaming\n\nSessions open a payment channel once, then use off-chain vouchers for each request - no blockchain transaction per request. Sub-100ms latency, near-zero per-request fees.\n\n```typescript\n// Server - session endpoint\nconst result = await mppx.session({\n  amount: '0.001',\n  unitType: 'token',\n})(request)\nif (result.status === 402) return result.challenge\nreturn result.withReceipt(Response.json({ data: '...' }))\n\n// Server - SSE streaming with per-word billing\nconst mppx = Mppx.create({\n  methods: [tempo({ currency: '0x20c0...', recipient: '0x...', sse: true })],\n})\nexport const GET = mppx.session({ amount: '0.001', unitType: 'word' })(\n  async () => {\n    const words = ['hello', 'world']\n    return async function* (stream) {\n      for (const word of words) {\n        await stream.charge()\n        yield word\n      }\n    }\n  }\n)\n\n// Client - session with auto-managed channel\nimport { Mppx, tempo } from 'mppx/client'\nMppx.create({\n  methods: [tempo({ account, maxDeposit: '1' })], // Lock up to 1 pathUSD\n})\nconst res = await fetch('http://localhost:3000/api/resource')\n// 1st request: opens channel on-chain\n// 2nd+ requests: off-chain vouchers (no on-chain tx)\n```\n\n**WebSocket transport**: Sessions also support WebSocket streaming via `Ws.serve()`. The WebSocket protocol uses typed messages (`mpp: 'authorization'`, `mpp: 'message'`, `mpp: 'payment-close-request'`, etc.) for payment negotiation alongside data delivery. See `references/sessions.md` for the full session lifecycle, escrow contracts, SSE patterns, and WebSocket integration.\n\n## Multi-Method Support\n\nAccept Tempo stablecoins, Stripe cards, and Lightning Bitcoin on a single endpoint:\n\n```typescript\nimport Stripe from 'stripe'\nimport { Mppx, tempo, stripe } from 'mppx/server'\nimport { spark } from '@buildonspark/lightning-mpp-sdk/server'\n\nconst mppx = Mppx.create({\n  methods: [\n    tempo({ currency: '0x20c0...', recipient: '0x...' }),\n    stripe.charge({ client: new Stripe(key), networkId: 'internal', paymentMethodTypes: ['card'] }),\n    spark.charge({ mnemonic: process.env.MNEMONIC! }),\n  ],\n})\n```\n\nUse `compose()` to present multiple methods in a single 402 response with per-route pricing. See `references/typescript-sdk.md` for compose patterns.\n\n## Payment Links (HTML)\n\nPayment links render a browser-friendly payment UI when a 402 endpoint is visited in a browser. Set `html: true` on the payment method config. Supports theming, multi-method compose (Tempo + Stripe tabs), and Solana wallets.\n\n```typescript\nimport { Mppx, tempo } from 'mppx/nextjs'\n\nconst mppx = Mppx.create({\n  methods: [tempo.charge({\n    currency: '0x20c0...', recipient: '0x...',\n    html: true, // auto-renders payment page for browsers\n  })],\n})\nexport const GET = mppx.charge({ amount: '0.1' })(() => Response.json({ data: '...' }))\n```\n\nCustomize via `mppx/html` exports (`Config`, `Text`, `Theme`). Service workers handle credential submission - the page reloads with the paid response. For multi-method compose, tabs auto-switch between payment options.\n\n## Zero-Dollar Auth (Proof Credentials)\n\nAuthenticate agent identity without payment. Clients sign an EIP-712 proof over the challenge ID instead of creating a transaction - no gas burned, no funds transferred.\n\n```typescript\n// Server - zero-dollar charge (amount: '0')\nconst result = await mppx.charge({ amount: '0' })(request)\n\n// Enable replay protection (makes each proof single-use)\nconst mppx = Mppx.create({\n  methods: [tempo.charge({ currency: '0x20c0...', recipient: '0x...', store: Store.memory() })],\n})\n```\n\nUse cases: identity verification, long-running job polling (prove identity once, poll freely), paid unlock with free subsequent access, multi-step agent pipelines. See mpp.dev/advanced/identity for full patterns.\n\n## Payments Proxy\n\nGate existing APIs behind MPP payments:\n\n```typescript\nimport { openai, Proxy } from 'mppx/proxy'\nimport { Mppx, tempo } from 'mppx/server'\n\nconst mppx = Mppx.create({ methods: [tempo()] })\nconst proxy = Proxy.create({\n  title: 'My API Gateway',\n  description: 'Paid access to AI APIs',\n  services: [\n    openai({\n      apiKey: 'sk-...', // pragma: allowlist secret\n      routes: {\n        'POST /v1/chat/completions': mppx.charge({ amount: '0.05' }),\n        'GET /v1/models': mppx.free(), // mppx.free() marks a route as free (no payment)\n      },\n    }),\n  ],\n})\n// Discovery: GET /openapi.json (canonical), GET /llms.txt (legacy /discover* returns 410)\n```\n\n## MCP Transport\n\nMCP tool calls can require payment using JSON-RPC error code `-32042`:\n\n```typescript\n// Server - MCP with payment (import tempo from mppx/server, NOT mppx/tempo)\nimport { McpServer } from 'mppx/mcp-sdk/server'\nimport { tempo } from 'mppx/server'\nconst server = McpServer.wrap(baseServer, {\n  methods: [tempo.charge({ ... })],\n  secretKey: '...',\n})\n\n// Client - payment-aware MCP client (import tempo from mppx/client)\nimport { McpClient } from 'mppx/mcp-sdk/client'\nimport { tempo } from 'mppx/client'\nconst mcp = McpClient.wrap(client, { methods: [tempo({ account })] })\nconst result = await mcp.callTool({ name: 'premium_tool', arguments: {} })\n```\n\nSee `references/transports.md` for the full MCP encoding (challenge in error.data.challenges, credential in _meta).\n\n## Privy Server Wallets\n\nUse [Privy](https://docs.privy.io) server wallets as MPP signers for agentic payment flows. The pattern: create a custom viem `Account` via `toAccount()` that delegates `signMessage`, `signTransaction`, and `signTypedData` to Privy's API (`@privy-io/node`), then pass it to `tempo({ account })`. Tempo's custom serializer requires using `signSecp256k1` (raw hash signing) for transactions instead of Privy's higher-level `signTransaction`.\n\nInstall: `npm install @privy-io/node mppx viem`. See `references/typescript-sdk.md` for the full implementation, [Privy agentic wallets docs](https://docs.privy.io/recipes/agent-integrations/agentic-wallets), and the [demo app](https://github.com/privy-io/examples/tree/main/privy-next-mpp-agent-demo).\n\n## Testing & CLI\n\n```bash\n# Create an account (stored in keychain, auto-funded on testnet)\nnpx mppx account create\n\n# Make a paid request\nnpx mppx http://localhost:3000/resource\n\n# Inspect challenge without paying\nnpx mppx --inspect http://localhost:3000/resource\n```\n\n**CLI config file**: Extend the CLI with custom payment methods via `mppx.config.(js|mjs|ts)`:\n```typescript\n// mppx.config.ts\nimport { defineConfig } from 'mppx/cli'\nexport default defineConfig({ plugins: [myCustomMethod()] })\n```\n\n## SDK Packages\n\n| Language | Package | Install |\n|----------|---------|---------|\n| TypeScript | [`mppx`](https://github.com/wevm/mppx) | `npm install mppx` |\n| Python | [`pympp`](https://github.com/tempoxyz/pympp) | `pip install pympp` or `pip install \"pympp[tempo]\"` |\n| Rust | [`mpp`](https://github.com/tempoxyz/mpp-rs) | `cargo add mpp --features tempo,client,server` |\n| Go | [`mppx`](https://github.com/cp0x-org/mppx) (community) | `go get github.com/cp0x-org/mppx` |\n| Stellar | [`@stellar/mpp`](https://github.com/stellar/stellar-mpp-sdk) | `npm install @stellar/mpp` |\n\nTypeScript subpath exports:\n- Server: `mppx/server` (generic), `mppx/hono`, `mppx/express`, `mppx/nextjs`, `mppx/elysia` (framework middleware)\n- Client: `mppx/client`\n- Proxy: `mppx/proxy`\n- MCP: `mppx/mcp-sdk/server`, `mppx/mcp-sdk/client`\n- HTML: `mppx/html` (exports `Config`, `Text`, `Theme` types and `init()` for payment link customization)\n- Discovery: `mppx/discovery` (OpenAPI-first discovery tooling)\n- SSE utilities: `mppx/tempo` (exports `Session` with `Session.Sse.iterateData` for SSE stream parsing)\n\nAlways import `Mppx` and `tempo` from the appropriate subpath for your context (e.g. `mppx/hono` for Hono, `mppx/server` for generic/MCP server, `mppx/client` for client). Note: `Mppx` and `tempo` are NOT exported from `mppx/tempo` - that subpath only exports `Session`.\n\n## Key Concepts\n\n- **Challenge/Credential/Receipt**: The three protocol primitives. Challenge IDs are HMAC-SHA256 bound to prevent tampering. See `references/protocol-spec.md`\n- **Payment methods**: Tempo (stablecoins), Stripe (cards), Lightning (Bitcoin), Card (network tokens), or custom. See method-specific references\n- **Intents**: `charge` (one-time) and `session` (streaming). See `references/sessions.md` for session details\n- **Payment links**: Browser-rendered 402 payment pages with `html: true`. Supports theming and multi-method compose tabs\n- **Zero-dollar auth**: `proof` credential type for identity without payment. Amount `'0'` triggers EIP-712 proof signing. Add `store` for replay protection\n- **Split payments**: Distribute a charge across multiple recipients in a single transaction (Tempo charge, 0.4.12+)\n- **Transports**: HTTP (headers), MCP (JSON-RPC), and WebSocket (streaming). See `references/transports.md`\n- **Tempo gas model**: Tempo has **no native gas token** (no ETH equivalent). All transaction fees are paid in stablecoins (USDC, pathUSD) via the `feeToken` transaction field. Accounts must either set `feeToken` per-transaction or call `setUserToken` on the FeeManager precompile to set a default. Without this, transactions fail with `gas_limit: 0`. See `references/tempo-method.md`\n- **Fee sponsorship**: Server pays gas fees on behalf of clients (Tempo). See `references/tempo-method.md`\n- **Push/pull modes**: Client broadcasts tx (push) or server broadcasts (pull). See `references/tempo-method.md`\n- **Custom methods**: Implement any payment rail with `Method.from()`. See `references/custom-methods.md`\n\n## Production Gotchas\n\n### Tempo Gas (CRITICAL)\n\n**Tempo has no native gas token.** Unlike Ethereum (ETH for gas) or Solana (SOL for fees), Tempo charges transaction fees in stablecoins. Every transaction must specify which stablecoin pays for gas. There are two ways:\n\n1. **Per-transaction `feeToken`** - set in the transaction itself:\n```typescript\nconst prepared = await prepareTransactionRequest(client, {\n  account,\n  calls: [{ to, data }],\n  feeToken: '0x20C000000000000000000000b9537d11c60E8b50', // USDC mainnet\n} as never)\n```\n\n2. **Account-level default via `setUserToken`** - one-time setup, applies to all future transactions:\n```typescript\nimport { setUserToken } from 'viem/tempo'\nawait client.fee.setUserTokenSync({\n  token: '0x20C000000000000000000000b9537d11c60E8b50', // USDC mainnet\n})\n```\n\n**Without either, transactions fail silently with `gas_limit: 0`.** The mppx SDK handles this internally for payment transactions, but any direct on-chain calls (settle, close, custom contract interactions) must set `feeToken` explicitly or ensure `setUserToken` was called for the account.\n\n**Fee token addresses:**\n| Network | Token | Address |\n|---------|-------|---------|\n| Mainnet | USDC.e (Bridged USDC) | `0x20C000000000000000000000b9537d11c60E8b50` |\n| Testnet | pathUSD | `0x20c0000000000000000000000000000000000000` |\n\n### Setup\n\n**Self-payment trap**: The payer and recipient cannot be the same wallet address. When testing with `npx mppx`, create a separate client account (`npx mppx account create -a client`) and fund it separately.\n\n**Recipient wallet initialization**: TIP-20 token accounts on Tempo must be initialized before they can receive tokens (similar to Solana ATAs). Send a tiny amount (e.g. 0.01 USDC) to the recipient address first: `tempo wallet transfer 0.01 0x20C000000000000000000000b9537d11c60E8b50 <recipient>`.\n\n### Server\n\n**Set `realm` explicitly for mppscan attribution.** The `realm` value is hashed into Tempo's attribution memo (bytes 5-14 of the 32-byte `transferWithMemo` data) and is how mppscan correlates on-chain transactions to registered servers. `Mppx.create()` auto-detects `realm` from env vars (`MPP_REALM`, `FLY_APP_NAME`, `HEROKU_APP_NAME`, `HOST`, `HOSTNAME`, `RAILWAY_PUBLIC_DOMAIN`, `RENDER_EXTERNAL_HOSTNAME`, `VERCEL_URL`, `WEBSITE_HOSTNAME`). On PaaS platforms (Vercel, Railway, Heroku) these are stable app names and work fine. **In Kubernetes, `HOSTNAME` is the pod name** (e.g. `web-69d986c8d8-6dtdx`) which rotates on every deploy - causing a new server fingerprint each time, so mppscan can't track your transactions. Fix by setting `MPP_REALM` env var to your stable public domain or passing `realm` directly:\n```typescript\nMppx.create({\n  methods: [tempo({ ... })],\n  realm: 'web.surf.cascade.fyi', // or process.env.MPP_REALM\n  secretKey,\n})\n```\n\n**`tempo()` vs explicit registration**: `tempo({ ... })` registers both `charge` and `session` intents with shared config. When you need different config per intent (e.g. session needs `store` and `sse: { poll: true }` but charge doesn't), register them explicitly:\n```typescript\nimport { Mppx, Store, tempo } from 'mppx/server'\nMppx.create({\n  methods: [\n    tempo.charge({ currency, recipient }),\n    tempo.session({ currency, recipient, store: Store.memory(), sse: { poll: true } }),\n  ],\n  secretKey,\n})\n```\n\n**Hono multiple headers**: `c.header(name, value)` replaces by default. When emitting multiple `WWW-Authenticate` values (e.g. charge + session intents), the second call silently overwrites the first. Prefer using `mppx.compose()` which handles multi-header emission correctly. If composing manually, use `{ append: true }`:\n```typescript\nc.header('WWW-Authenticate', chargeWwwAuth)\nc.header('WWW-Authenticate', sessionWwwAuth, { append: true })\n```\n\n**CORS headers**: `WWW-Authenticate` and `Payment-Receipt` must be listed in `access-control-expose-headers` or browsers/clients won't see them.\n\n**SSE utilities import path**: `Session.Sse.iterateData` is exported from `mppx/tempo`, NOT `mppx/server`:\n```typescript\nimport { Mppx, Store, tempo } from 'mppx/server'\nimport { Session } from 'mppx/tempo'\nconst iterateSseData = Session.Sse.iterateData\n```\n\n### Stores\n\n**Never use `Store.memory()` in production.** It loses all channel state on server restart/redeploy. When state is lost, the server can't close channels or settle funds - client deposits stay locked in escrow indefinitely. Use a persistent store.\n\nBuilt-in store adapters (all handle BigInt serialization via `ox`'s `Json` module):\n```typescript\nimport { Store } from 'mppx/server'\n\nStore.memory()              // development only\nStore.redis(redisClient)    // ioredis, node-redis, Valkey (added in 0.4.9)\nStore.upstash(upstashClient) // Upstash Redis / Vercel KV\nStore.cloudflare(kvNamespace) // Cloudflare KV\nStore.from({ get, put, delete }) // custom adapter\n```\n\n**AtomicStore** (0.5.7+): Extends `Store` with an `update(key, fn)` method for safe concurrent read-modify-write. Used internally for replay protection and channel state. All built-in adapters (redis, upstash, cloudflare) support atomic updates. Custom adapters via `Store.from()` get an optimistic-retry implementation automatically.\n\n**Polling mode**: If your store doesn't implement the optional `waitForUpdate()` method (e.g. custom adapters via `Store.from()`), pass `sse: { poll: true }` to `tempo.session()`. Otherwise SSE streams will hang waiting for event-driven wakeups that never come.\n\n### Channel Recovery After Restarts\n\nPass `channelId` to `mppx.session()` so returning clients recover existing on-chain channels instead of opening new ones (which locks more funds in escrow). See `references/sessions.md` for the full pattern with `Credential.fromRequest()` and `tryRecoverChannel()`.\n\n### Request Handling\n\n**Session voucher POSTs have no body.** Mid-stream voucher POSTs carry only `Authorization: Payment` - no JSON body. If your middleware decides charge vs session based on `body.stream`, vouchers will hit the charge path. Check the **credential's intent** instead. As of mppx 0.4.9, the SDK skips route amount/currency/recipient validation for topUp and voucher credentials (the on-chain voucher signature is the real validation), so body-derived pricing mismatches no longer cause spurious 402 rejections.\n\n**Clone the request before reading the body.** `request.json()` consumes the Request body. If you parse the body first and then pass the original request to `mppx.session()` or `mppx.charge()`, the mppx handler gets an empty body and returns 402. Clone before reading.\n\n### Pricing & Streaming\n\n**Cheap model zero-charge floor**: Tempo USDC has 6-decimal precision. For very cheap models, per-token cost like `(0.10 / 1_000_000) * 1.3 = 0.00000013` rounds to `\"0.000000\"` via `toFixed(6)` - effectively zero. Add a minimum tick cost floor:\n```typescript\nconst MIN_TICK_COST = 0.000001 // smallest Tempo USDC unit (6 decimals)\nconst tickCost = Math.max((outputRate / 1_000_000) * margin, MIN_TICK_COST)\n```\n\n**SSE chunks != tokens**: Per-SSE-event `stream.charge()` is an acceptable approximation. `stream.charge()` is serial (Redis GET + SET per call, per-channelId mutex) - no bulk API exists yet.\n\n**Add upstream timeouts**: Always use `AbortSignal.timeout()` on upstream fetches. A stalled upstream holds the payment channel open, locking client funds.\n\n### Infrastructure\n\n**Nginx proxy buffer overflow**: Large 402 headers can exceed nginx's default 4k `proxy_buffer_size`, causing **502 Bad Gateway**. Fix: `nginx.ingress.kubernetes.io/proxy-buffer-size: \"16k\"`. Debug: port-forward directly to the pod - if you get 402, the issue is in the ingress layer.\n\n### Client / Tempo CLI\n\n**CLI defaults to mainnet** (0.5.4+): The `mppx` CLI now defaults to Tempo mainnet when `--rpc-url` is omitted. Previously it defaulted to testnet. Use `--rpc-url` or set `MPPX_RPC_URL`/`RPC_URL` env vars for testnet.\n\n**Stale sessions after redeploy**: When the server redeploys and loses in-memory session state, clients get `\"Session invalidation claim for channel 0x... was not confirmed on-chain\"`. Fix: `tempo wallet sessions close` or `tempo wallet sessions sync`. Dispute window is 4-15 min.\n\n## References\n\n| File | Content |\n|------|---------|\n| `references/protocol-spec.md` | Core protocol: Challenge/Credential/Receipt structure, status codes, error handling, security, caching, extensibility |\n| `references/typescript-sdk.md` | mppx TypeScript SDK: server/client/middleware, proxy, MCP SDK, CLI, AtomicStore, Privy wallets |\n| `references/tempo-method.md` | Tempo: charge + session, fee sponsorship, push/pull, auto-swap, split payments, config |\n| `references/stripe-method.md` | Stripe payment method: SPT flow, server/client config, Stripe Elements, createToken proxy, metadata |\n| `references/sessions.md` | Sessions: payment channels, vouchers, SSE/WebSocket streaming, escrow, channel recovery |\n| `references/transports.md` | HTTP, MCP, and WebSocket transport bindings: header/message encoding, comparison |\n| `references/python-sdk.md` | pympp Python SDK: FastAPI/server patterns, async client, streaming sessions |\n| `references/rust-sdk.md` | mpp Rust SDK: server/client, feature flags, reqwest middleware |\n| `references/lightning-method.md` | Lightning payment method: charge (BOLT11), session (bearer tokens), Spark SDK |\n| `references/custom-methods.md` | Custom payment methods: Method.from, Method.toClient, Method.toServer patterns |\n\n## Official Resources\n\n- Website: https://mpp.dev\n- GitHub: https://github.com/wevm/mppx (TypeScript SDK)\n- Protocol spec: https://paymentauth.org\n- Stripe docs: https://docs.stripe.com/payments/machine/mpp\n- Tempo docs: https://docs.tempo.xyz\n- Privy MPP guide: https://docs.privy.io (search \"MPP\" or see agentic wallets recipes)\n- x402 migration: https://mpp.dev/guides/upgrade-x402\n- LLM docs: https://mpp.dev/llms-full.txt","tags":["mpp","skills","tenequm","agent-skills","ai-agents","claude-code","claude-skills","clawhub","erc-8004","openclaw","solana","x402"],"capabilities":["skill","source-tenequm","skill-mpp","topic-agent-skills","topic-ai-agents","topic-claude-code","topic-claude-skills","topic-clawhub","topic-erc-8004","topic-mpp","topic-openclaw","topic-skills","topic-solana","topic-x402"],"categories":["skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/tenequm/skills/mpp","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add tenequm/skills","source_repo":"https://github.com/tenequm/skills","install_from":"skills.sh"}},"qualityScore":"0.461","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 23 github stars · SKILL.md body (24,879 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T01:01:39.897Z","embedding":null,"createdAt":"2026-04-18T23:05:18.775Z","updatedAt":"2026-04-22T01:01:39.897Z","lastSeenAt":"2026-04-22T01:01:39.897Z","tsv":"'-14':2000 '-15':2853 '-20':280,1947 '-32042':1179 '-41':314 '-712':1010,1634 '/advanced/identity':1090 '/cp0x-org/mppx':1454 '/cp0x-org/mppx)':1448 '/discover':1162 '/doc/draft-ryan-httpauth-payment/).':109 '/guides/upgrade-x402':3002 '/llms-full.txt':3007 '/llms.txt':1160 '/node':1289,1322 '/openapi.json':1157 '/paid'')':456 '/payment-methods/card':321 '/payment-methods/lightning':304 '/payment-methods/stellar':312 '/payment-methods/stripe':291 '/payment-methods/tempo':278 '/payments/machine/mpp':2983 '/privy-io/examples/tree/main/privy-next-mpp-agent-demo).':1344 '/proxy-buffer-size:':2747 '/recipes/agent-integrations/agentic-wallets),':1337 '/resource':231,244,497,607 '/stellar/stellar-mpp-sdk)':1459 '/tempoxyz/mpp-rs)':1436 '/tempoxyz/pympp)':1423 '/toserver':336 '/v1/chat/completions':1140 '/v1/models':1145 '/wevm/mppx':2973 '/wevm/mppx)':1415 '0':1034,1040,1631,1721,1860 '0.000000':2639 '0.00000013':2636 '0.000001':2656 '0.001':668,705 '0.01':408,1969,1979 '0.05':1143 '0.1':597,610,961 '0.10':2631 '0.4.12':1656 '0.4.9':2349,2533 '0.5.4':2775 '0.5.7':2367 '0.50':511 '000':2633,2634,2668,2669 '0x':449,591,697,857,946,1059,2832 '0x20c0':589,695,855,944,1057 '0x20c0000000000000000000000000000000000000':393,490,1907 '0x20c000000000000000000000b9537d11c60e8b50':1820,1849,1904,1980 '0xyouraddress':396,492 '1':191,229,743,747,1799,2632,2667 '1.3':2635 '100ms':650 '16k':2748 '1st':755 '2':204,232,1825 '200':251 '2nd':762 '3':215,238 '3000/api/resource':754 '3000/resource':1370,1379 '32':2003 '4':242,2852 '402':19,46,68,233,412,442,463,520,674,879,905,1605,2565,2604,2729,2760 '410':1164 '4k':2736 '5':247,1999 '502':2741 '6':250,2619,2642,2661 '69d986c8d8':2071 '6dtdx':2072 'abortsignal.timeout':2708 'accept':161,822,2684 'access':171,355,1081,1127,2245 'access-control-expose-head':2244 'account':85,447,741,1230,1273,1295,1350,1361,1695,1815,1827,1893,1932,1935,1949 'account-level':1826 'across':1647 'ad':121,2347 'adapt':2322,2365,2395,2403,2427 'add':553,1438,1637,2645,2703 'address':1896,1899,1922,1974 'agent':30,130,1002,1085,1264,1332,2995 'agnost':264 'ai':29,129,1129 'allowlist':1136 'alongsid':801 'also':776 'alway':1513,2706 'amount':407,510,596,609,667,704,960,1033,1039,1142,1630,1967 'amount/currency/recipient':2538 'anthrop':181 'api':24,86,116,170,179,352,376,1098,1123,1130,1285,2700 'api.example.com':455 'api.example.com/paid'')':454 'apikey':1133 'app':483,1341,2030,2033,2056 'app.get':496,606 'append':2216,2229 'appli':1836 'appropri':1520 'approxim':2685 'architectur':184 'argument':1238 'async':398,498,708,714,2934 'ata':1963 'atom':2400 'atomicstor':2366,2879 'attribut':1987,1996 'auth':998,1622 'authent':105,201,236,528,531,1001,2189,2222,2227,2235 'author':60,212,245,507,509,789,2503 'auto':730,950,990,1355,2021,2890 'auto-detect':2020 'auto-fund':1354 'auto-manag':729 'auto-rend':949 'auto-swap':2889 'auto-switch':989 'automat':443,2412 'autonom':135 'await':405,452,505,665,722,751,1037,1233,1812,1846 'awar':1209 'bad':2742 'base':153,2515 'baseserv':1202 'bash':1347 'bearer':2954 'behalf':1731 'behind':1099 'best':343 'bigint':2325 'bill':155,372,688 'bind':2924 'bitcoin':167,305,829,1576 'blockchain':644 'bodi':2495,2507,2557,2573,2578,2583,2601 'body-deriv':2556 'body.stream':2517 'bolt11':2952 'bound':1563 'bridg':1902 'broadcast':1740,1745 'browser':899,911,955,1603 'browser-friend':898 'browser-rend':1602 'browsers/clients':2250 'buffer':2726,2738 'build':2,113,172 'buildonspark/lightning-mpp-sdk':309 'buildonspark/lightning-mpp-sdk/server':848 'built':287,300,2319,2393 'built-in':286,299,2318,2392 'bulk':2699 'burn':1023 'byte':1998,2004 'c':611 'c.header':2178,2219,2224 'c.json':612 'cach':2868 'call':138,353,1169,1704,1816,1876,1890,2197,2693 'cannot':1917 'canon':1158 'card':164,292,320,328,826,866,1574,1577 'cargo':552,1437 'carri':2501 'case':1063 'caus':2078,2563,2740 'chain':284,638,761,766,771,1875,2014,2465,2548,2838 'challeng':192,515,1014,1246,1372,1557 'challenge/credential/receipt':1552,2861 'channel':368,632,732,758,2289,2303,2389,2450,2466,2718,2831,2911,2916 'channelid':2455,2696 'charg':118,345,494,1032,1588,1646,1655,1781,2125,2148,2192,2512,2522,2614,2884,2951 'chargeint':482,495 'chargewwwauth':2223 'cheap':2610,2624 'check':2524 'checkout':89 'chunk':2675 'claim':2829 'cli':1346,1380,1385,2770,2771,2778,2878 'client':77,207,227,426,726,859,1006,1206,1211,1227,1442,1475,1535,1733,1739,1814,1931,1938,2307,2460,2721,2768,2825,2935 'client-submit':206 'client.fee.setusertokensync':1847 'clone':2567,2605 'close':795,1878,2302,2843 'cloudflar':2358,2398 'co':59 'co-author':58 'code':519,1178,2864 'come':2449 'communiti':1449 'comparison':2927 'compos':871,889,925,987,1617,2213 'concept':1551 'concurr':2378 'config':919,968,1381,1485,2131,2136,2894,2902 'confirm':218,2835 'const':387,403,450,583,593,663,689,701,709,718,749,849,938,957,1035,1051,1113,1118,1199,1224,1231,1810,2277,2652,2663 'consum':2575 'content':28,127,149,354,521,536,2857 'context':1524 'contract':812,1880 'control':2246 'cor':2231 'core':93,183,2859 'correct':2211 'correl':2011 'cost':2629,2649,2655,2673 'creat':1018,1269,1348,1362,1928,1936 'createtoken':2905 'credenti':205,974,1000,1249,1624,2526,2544 'credential.fromrequest':2485 'critic':1763 'currenc':392,489,588,694,854,943,1056,2164,2167 'custom':330,964,1271,1298,1387,1494,1581,1749,1879,2364,2402,2426,2959 'data':418,534,599,613,680,802,963,1818,2006 'datatracker.ietf.org':108 'datatracker.ietf.org/doc/draft-ryan-httpauth-payment/).':107 'debug':2749 'decid':2511 'decim':2620,2662 'def':499 'default':1402,1713,1829,2183,2735,2772,2780,2792 'defin':267 'defineconfig':1398,1403 'deleg':1277 'delet':2363 'deliveri':803 'demo':1340 'deploy':2077 'deposit':2308 'deriv':2558 'descript':1125 'detail':1599 'detect':2022 'develop':22,2338 'differ':2135 'direct':1872,2107,2753 'discoveri':1155,1495,1500 'disput':2849 'distribut':1644 'doc':1334,2980,2985,3004 'docs.privy.io':1257,1336,2990 'docs.privy.io/recipes/agent-integrations/agentic-wallets),':1335 'docs.stripe.com':2982 'docs.stripe.com/payments/machine/mpp':2981 'docs.tempo.xyz':2986 'doesn':2149,2418 'dollar':997,1031,1621 'domain':2039,2103 'driven':2445 'e.g':1525,1968,2068,2139,2191,2425 'effect':2643 'eip':1009,1633 'either':1697,1853 'element':2904 'elysia':619 'emiss':2210 'emit':2185 'empti':2600 'enabl':128,1042 'encod':1245,2926 'encrypt':322 'endpoint':125,359,662,833,906 'ensur':1887 'env':2025,2097,2806 'equival':1680 'error':522,1177,2865 'error.data.challenges':1248 'escrow':811,2312,2477,2915 'etc':182,797 'eth':1679,1772 'ethereum':1771 'event':2444,2680 'event-driven':2443 'everi':188,1786,2076 'exampl':620 'exceed':2732 'exist':178,1097,2462,2701 'explicit':1885,1984,2120,2153 'export':397,592,700,956,967,1401,1465,1484,1505,1542,1548,2261 'expos':2247 'express':617 'extend':1383,2368 'extens':337,2869 'extern':2041 'fail':1717,1855 'fastapi':470,472,484 'fastapi/server':2932 'featur':555,1440,2943 'fee':658,1683,1724,1729,1779,1783,1894,2886 'feemanag':1708 'feetoken':1692,1699,1803,1819,1884 'fetch':453,752,2711 'field':1694 'file':1382,2856 'fine':2060 'fingerprint':2082 'first':1499,1975,2201,2584 'fix':357,2092,2744,2839 'fixed-pric':356 'flag':2944 'fli':2029 'floor':2615,2650 'flow':32,90,1266,2900 'fn':2374 'forward':2752 'framework':563,567,1473 'free':1079,1152 'freeli':1075 'frequenc':375 'friend':900 'full':545,561,808,1092,1243,1329,2482 'function':399,715 'fund':1025,1356,1940,2306,2475,2722 'futur':1839 'gas':1022,1670,1676,1719,1728,1762,1768,1774,1794,1858 'gate':27,177,1096 'gateway':1124,2743 'generat':150 'generic':1468 'generic/mcp':1531 'get':230,243,500,594,702,958,1144,1156,1159,1451,2361,2406,2598,2690,2759,2826 'github':2970 'github.com':1343,1414,1422,1435,1447,1453,1458,2972 'github.com/cp0x-org/mppx':1452 'github.com/cp0x-org/mppx)':1446 'github.com/privy-io/examples/tree/main/privy-next-mpp-agent-demo).':1342 'github.com/stellar/stellar-mpp-sdk)':1457 'github.com/tempoxyz/mpp-rs)':1434 'github.com/tempoxyz/pympp)':1421 'github.com/wevm/mppx':2971 'github.com/wevm/mppx)':1413 'globalthis.fetch':439 'go':160,365,626,1444,1450 'gotcha':1760 'guid':2989 'handl':441,973,1864,2206,2324,2489,2866 'handler':400,2597 'hang':2440 'happen':458 'hash':1304,1992 'header':203,214,226,525,1659,2177,2209,2232,2248,2730 'header/message':2925 'hello':711 'heroku':2032,2052 'high':374 'high-frequ':373 'higher':1313 'higher-level':1312 'hit':2520 'hmac':1561 'hmac-sha256':1560 'hold':2715 'hono':600,1528,2175 'host':2035 'hostnam':2036,2042,2046,2063 'html':893,913,947,1482,1609 'http':18,45,67,82,104,1658,2919 'id':1015,1558 'ident':1003,1064,1072,1627 'ietf':100 'implement':1330,1751,2411,2420 'import':382,429,433,471,476,480,571,578,601,733,835,839,845,933,1103,1108,1185,1191,1195,1212,1216,1220,1397,1514,1842,2155,2257,2267,2273,2333 'in-memori':2820 'indefinit':2313 'infer':148 'infrastructur':2723 'ingress':2766 'init':1490 'initi':1945,1954 'inspect':1371,1377 'instal':419,421,537,539,551,1316,1318,1410,1417,1425,1429,1461 'instead':1016,1308,2467,2529 'integr':817 'intent':258,340,341,493,1587,2128,2138,2194,2528 'interact':1881 'intern':864,1866,2384 'invalid':2828 'io':1288,1321 'ioredi':2342 'isinst':513 'issu':195,2762 'iteratessedata':2278 'job':1069 'js':1392 'json':1175,1662,2330,2506 'json-rpc':1174,1661 'jsonrespons':517 'key':87,862,1550,2373 'keychain':1353 'kubernet':2062 'kv':2355,2359 'kvnamespac':2357 'languag':1408 'larg':2728 'latenc':651 'layer':2767 'legaci':1161 'level':1314,1828 'lifecycl':810 'lightn':168,303,307,828,1575,2948 'like':2630 'limit':1720,1859 'link':892,895,1493,1601 'list':2242 'llm':147,369,3003 'localhost':753,1369,1378 'lock':744,2310,2473,2720 'long':1067 'long-run':1066 'longer':2562 'lose':2287,2819 'lost':2297 'machin':5,13,15,50,73,75 'machine-to-machin':12,72 'mainnet':1822,1851,1900,2774,2783 'make':1045,1363 'manag':731 'manual':2214 'margin':2670 'mark':1148 'math.max':2665 'maxdeposit':742 'mcp':33,136,1165,1167,1182,1210,1225,1244,1479,1660,2876,2920 'mcp.calltool':1234 'mcpclient':1217 'mcpclient.wrap':1226 'mcpserver':1192 'mcpserver.wrap':1201 'memo':1997 'memori':2822 'messag':787,791 'meta':1251 'metadata':2907 'meter':154,371 'method':257,263,266,272,390,445,487,586,692,739,820,852,875,918,924,941,986,1054,1116,1203,1228,1389,1570,1584,1616,1750,2110,2162,2375,2424,2898,2950,2961 'method-specif':1583 'method.from':333,1756,2962 'method.toclient':335,2963 'method.toclient/toserver':334 'method.toserver':2964 'mid':2497 'mid-stream':2496 'middlewar':564,1474,2510,2946 'migrat':2999 'min':2653,2671,2854 'minimum':2647 'mismatch':2560 'mjs':1393 'mnemon':868 'mode':1738,2414 'model':1671,2611,2625 'modifi':2381 'modul':2331 'mpp':1,4,49,53,189,259,327,477,485,554,788,790,792,1100,1261,1433,1439,2027,2095,2939,2988,2992 'mpp-card':326 'mpp.charge':506 'mpp.create':486 'mpp.dev':1089,2969,3001,3006 'mpp.dev/advanced/identity':1088 'mpp.dev/guides/upgrade-x402':3000 'mpp.dev/llms-full.txt':3005 'mpp.methods.tempo':479 'mpp.realm':532 'mpp.server':475 'mppscan':1986,2010,2086 'mppx':285,298,383,388,422,434,579,584,602,690,734,840,850,934,939,1052,1109,1114,1323,1360,1368,1376,1412,1418,1445,1515,1537,1862,1927,1934,2156,2268,2532,2596,2777,2801,2871 'mppx.charge':406,595,608,959,1038,1141,2594 'mppx.compose':2204 'mppx.config':1391 'mppx.config.ts':1396 'mppx.create':389,444,585,691,738,851,940,1053,1115,2019,2109,2161 'mppx.free':1146,1147 'mppx.session':666,703,2457,2592 'mppx/cli':1400 'mppx/client':437,737,1215,1223,1476,1533 'mppx/discovery':1496 'mppx/elysia':575,1472 'mppx/express':574,1470 'mppx/hono':573,605,1469,1526 'mppx/html':966,1483 'mppx/mcp-sdk/client':1219,1481 'mppx/mcp-sdk/server':1194,1480 'mppx/nextjs':572,582,937,1471 'mppx/proxy':1107,1478 'mppx/server':386,844,1112,1188,1198,1467,1529,2160,2265,2272,2336 'mppx/tempo':1190,1504,1544,2263,2276 'multi':819,923,985,1083,1615,2208 'multi-head':2207 'multi-method':818,922,984,1614 'multi-step':1082 'multipl':874,1648,2176,2186 'must':1696,1788,1882,1952,2240 'mutex':2697 'mycustommethod':1405 'name':1235,2031,2034,2057,2067,2179 'nativ':1675,1767 'near':653 'near-zero':652 'need':91,2134,2141 'negoti':800 'network':308,323,1578,1897 'networkid':863 'never':1824,2281,2448 'new':860,2080,2470 'next.js':577 'nginx':2724,2733 'nginx.ingress.kubernetes.io':2746 'nginx.ingress.kubernetes.io/proxy-buffer-size:':2745 'node':2344 'node-redi':2343 'note':1536 'npm':420,1317,1416,1460 'npx':1359,1367,1375,1926,1933 'off-chain':636,764 'offici':2966 'ok':252 'omit':2789 'on-chain':759,769,1873,2012,2463,2546,2836 'one':347,1590,1833,2471 'one-tim':346,1589,1832 'open':9,56,629,757,2469,2719 'openai':180,1104,1132 'openapi':1498 'openapi-first':1497 'optimist':2409 'optimistic-retri':2408 'option':994,2422 'origin':2589 'otherwis':2436 'outputr':2666 'overflow':2727 'overwrit':2199 'ox':2328 'paa':2048 'packag':275,1407,1409 'page':953,977,1607 'paid':23,115,535,981,1076,1126,1365,1685 'pars':1512,2581 'pass':1291,2105,2430,2454,2587 'path':2258,2523 'pathusd':394,748,1689,1906 'pattern':342,546,562,814,890,1093,1268,2483,2933,2965 'pay':37,78,132,143,157,362,623,1374,1727,1792 'pay-as-you-go':156,361,622 'pay-per-token':36,142 'payer':1914 'payment':6,16,26,31,35,47,51,69,76,103,141,174,190,196,202,209,213,221,224,237,240,246,254,256,262,296,339,349,367,457,523,631,794,799,891,894,901,917,952,993,1005,1094,1101,1154,1172,1184,1208,1265,1388,1492,1569,1600,1606,1629,1643,1753,1868,1911,2238,2504,2717,2893,2897,2910,2949,2960 'payment-awar':1207 'payment-close-request':793 'payment-g':25 'payment-method':261 'payment-receipt':223,253,2237 'paymentauth.org':2978 'paymentmethodtyp':865 'paywal':123 'per':38,119,144,350,646,656,686,883,1701,1801,2137,2627,2678,2692,2695 'per-channelid':2694 'per-request':655 'per-rout':882 'per-sse-ev':2677 'per-token':2626 'per-transact':1700,1800 'per-word':685 'persist':2316 'pip':538,1424,1428 'pipelin':1086 'platform':2049 'plugin':1404 'pod':2066,2756 'poll':1070,1074,2145,2172,2413,2432 'polyfil':438 'port':2751 'port-forward':2750 'post':1139,2492,2500 'power':187 'pragma':1135 'precis':2621 'precompil':1709 'prefer':2202 'premium':1236 'prepar':1811 'preparetransactionrequest':1813 'present':873 'prevent':1565 'previous':2790 'price':358,885,2559,2608 'primit':186,1556 'privatekeytoaccount':430,448 'privi':1252,1256,1283,1287,1310,1320,1331,2880,2987 'privy-io':1286,1319 'process.env.mnemonic':869 'process.env.mpp':2115 'product':289,302,310,319,329,1759,2285 'proof':210,241,999,1011,1047,1623,1635 'protect':1044,1641,2387 'protocol':7,10,52,57,94,784,1555,2860,2976 'prove':1071 'proxi':175,1095,1105,1119,1477,2725,2737,2875,2906 'proxy.create':1120 'public':2038,2102 'pull':1746 'push':1742 'push/pull':1737,2888 'put':2362 'pympp':540,1420,1426,1430,2929 'python':467,468,1419,2930 'quick':377,424,464,547 'rail':271,273,332,1754 'railway':2037,2051 'raw':1303 'read':2380,2571,2607 'read-modify-writ':2379 'real':2553 'realm':1983,1989,2023,2028,2096,2106,2112,2116 'receipt':216,225,255,2239 'receiv':1958 'recip':2997 'recipi':395,491,590,696,856,945,1058,1649,1916,1943,1973,2165,2168 'recov':2461 'recoveri':2451,2917 'redeploy':2813,2817 'redi':2345,2353,2396,2689 'rediscli':2341 'refer':1586,2855 'references/custom-methods.md':1758,2958 'references/lightning-method.md':2947 'references/protocol-spec.md':1568,2858 'references/python-sdk.md':543,2928 'references/rust-sdk.md':559,2938 'references/sessions.md':805,1596,2479,2908 'references/stripe-method.md':2895 'references/tempo-method.md':1723,1736,1748,2882 'references/transports.md':1240,1668,2918 'references/typescript-sdk.md':615,887,1326,2870 'regist':2017,2123,2151 'registr':2121 'reject':2566 'reload':978 'render':896,951,1604,2040 'replac':2181 'replay':1043,1640,2386 'request':83,120,351,401,402,409,473,502,503,642,647,657,671,756,763,796,1041,1366,2488,2569,2577,2590 'request.headers.get':508 'request.json':2574 'requir':48,70,140,197,524,1171,1300 'reqwest':2945 'res':451,750 'resourc':501,2967 'respons':880,982 'response.json':417,598,679,962 'restart':2453 'restart/redeploy':2293 'result':404,504,514,664,1036,1232 'result.challenge':414,676 'result.status':411,673 'result.to':529 'result.withreceipt':416,678 'retri':2410 'return':413,415,462,516,533,675,677,713,1163,2459,2603 'rotat':2074 'round':2637 'rout':884,1138,1150,2537 'rpc':1176,1663,2786,2797,2802,2804 'rpc-url':2785,2796 'run':1068 'rust':550,1432,2940 'safe':2377 'scheme':106 'sdk':274,1406,1863,2535,2873,2877,2931,2941,2957,2975 'search':2991 'second':2196 'secret':1137 'secretkey':1205,2117,2174 'secur':2867 'see':542,558,614,804,886,1087,1239,1325,1567,1582,1595,1667,1722,1735,1747,1757,2253,2478,2994 'self':1910 'self-pay':1909 'send':1964 'sep':313 'separ':1930,1942 'serial':1299,2326,2688 'server':194,217,228,379,461,466,549,557,660,681,1028,1181,1200,1253,1258,1443,1466,1532,1726,1744,1981,2018,2081,2292,2299,2816 'server-issu':193 'server/client':2901,2942 'server/client/middleware':2874 'servic':43,134,971,1131 'session':152,360,621,628,661,727,775,809,1506,1549,1593,1598,2127,2140,2193,2274,2490,2514,2811,2823,2827,2842,2847,2885,2909,2937,2953 'session-bas':151 'session.sse.iteratedata':1508,2259,2279 'sessionwwwauth':2228 'set':912,1698,1711,1804,1883,1982,2094,2691,2800 'settl':249,1877,2305 'settlement':270 'setup':1835,1908 'setusertoken':1705,1831,1843,1888 'sha256':1562 'share':295,2130 'sign':239,1007,1305,1636 'signatur':2550 'signer':1262 'signmessag':1278 'signsecp256k1':1302 'signtransact':1279,1315 'signtypeddata':1281 'silent':1856,2198 'similar':1960 'singl':832,878,1049,1652 'single-us':1048 'size':2739 'sk':1134 'skill' 'skill-mpp' 'skip':2536 'smallest':2657 'sol':1777 'solana':930,1776,1962 'source-tenequm' 'spark':846,2956 'spark.charge':867 'spec':95,2977 'specif':1585 'specifi':1789 'split':1642,2892 'sponsorship':1725,2887 'spt':2899 'spurious':2564 'sse':682,698,813,1502,1510,2144,2171,2255,2431,2437,2674,2679 'sse/websocket':2913 'stabl':2055,2101 'stablecoin':162,281,824,1572,1687,1785,1791 'stale':2810 'stall':2713 'standard':66 'start':378,425,465,548 'state':2290,2295,2390,2824 'status':276,518,2863 'stay':2309 'stellar':311,317,1455 'stellar/mpp':318,1456,1462 'step':1084 'store':1060,1351,1638,2142,2157,2169,2269,2280,2317,2321,2334,2369,2417 'store.cloudflare':2356 'store.from':2360,2405,2429 'store.memory':1061,2170,2283,2337 'store.redis':2340 'store.upstash':2350 'stream':40,146,370,627,683,716,779,1511,1594,1666,2438,2498,2609,2914,2936 'stream.charge':723,2681,2686 'stripe':64,165,290,825,836,838,842,861,927,1573,2896,2903,2979 'stripe.charge':858 'structur':2862 'sub':649 'sub-100ms':648 'submiss':975 'submit':97,208 'subpath':1464,1521,1546 'subsequ':1080 'success':220 'support':777,821,920,1611,2399 'swap':2891 'switch':991 'sync':2848 'tab':928,988,1618 'tamper':1566 'tempo':62,163,277,283,384,391,435,446,481,488,541,556,580,587,603,693,735,740,823,841,853,926,935,1110,1117,1186,1196,1213,1221,1229,1294,1296,1431,1441,1517,1539,1571,1654,1669,1672,1734,1761,1764,1780,1951,1976,1994,2111,2118,2122,2158,2270,2616,2658,2769,2782,2840,2845,2883,2984 'tempo.charge':942,1055,1204,2163 'tempo.session':2166,2435 'test':1345,1924 'testnet':1358,1905,2794,2809 'text':969,1486 'theme':921,970,1487,1612 'three':185,1554 'tick':2648,2654,2672 'tickcost':2664 'time':348,1591,1834,2084 'timeout':2705 'tini':1966 'tip':279,1946 'titl':1121 'toaccount':1275 'tofix':2641 'token':39,145,297,315,324,670,1579,1677,1769,1848,1895,1898,1948,1959,2628,2676,2955 'tool':34,137,1168,1237,1501 'topic-agent-skills' 'topic-ai-agents' 'topic-claude-code' 'topic-claude-skills' 'topic-clawhub' 'topic-erc-8004' 'topic-mpp' 'topic-openclaw' 'topic-skills' 'topic-solana' 'topic-x402' 'topup':2541 'track':2089 'transact':645,1020,1307,1653,1682,1693,1702,1716,1782,1787,1802,1807,1840,1854,1869,2015,2091 'transfer':1026,1978 'transferwithmemo':2005 'transpar':459 'transport':774,1166,1657,2923 'trap':1912 'trigger':1632 'true':699,914,948,1610,2146,2173,2217,2230,2433 'tryrecoverchannel':2487 'ts':1394 'two':338,1797 'tx':772,1741 'type':786,1488,1625 'typescript':380,381,427,428,565,576,659,834,932,1027,1102,1180,1395,1411,1463,1809,1841,2108,2154,2218,2266,2332,2651,2872,2974 'ui':902 'unit':2660 'unittyp':669,706 'unlik':1770 'unlock':1077 'updat':2372,2401 'upstash':2352,2397 'upstashcli':2351 'upstream':2704,2710,2714 'url':2044,2787,2798,2803,2805 'usdc':1688,1821,1850,1903,1970,2617,2659 'usdc.e':1901 'use':20,44,112,635,785,870,1050,1062,1173,1255,1301,2203,2215,2282,2314,2383,2707,2795 'util':1503,2256 'valid':2539,2554 'valkey':2346 'valu':1990,2180,2190 'var':2026,2098,2807 'vercel':2043,2050,2354 'verif':1065 'verifi':248 'via':294,780,965,1274,1390,1690,1830,2327,2404,2428,2640 'viem':423,1272,1324 'viem/accounts':432 'viem/tempo':1845 'visa':325 'visit':908 'voucher':639,767,2491,2499,2518,2543,2549,2912 'vs':2119,2513 'wait':2441 'waitforupd':2423 'wakeup':2446 'wallet':293,931,1254,1259,1333,1921,1944,1977,2841,2846,2881,2996 'way':1798 'web':2070 'web-69d986c8d8-6dtdx':2069 'web.surf.cascade.fyi':2113 'websit':2045,2968 'websocket':773,778,783,816,1665,2922 'window':2850 'without':1004,1373,1628,1714,1852 'won':2251 'word':687,707,710,719,721,725 'work':2059 'worker':972 'world':712 'write':2382 'ws.serve':781 'www':200,235,527,530,2188,2221,2226,2234 'www-authent':199,234,526,2187,2220,2225,2233 'x402':2998 'yet':2702 'yield':724 'zero':654,996,1030,1620,2613,2644 'zero-charg':2612 'zero-dollar':995,1029,1619","prices":[{"id":"6219987a-bf67-4ef8-b19b-9829244caa00","listingId":"59da7aa0-21f9-4ba6-84ff-bdf713c8b126","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"tenequm","category":"skills","install_from":"skills.sh"},"createdAt":"2026-04-18T23:05:18.775Z"}],"sources":[{"listingId":"59da7aa0-21f9-4ba6-84ff-bdf713c8b126","source":"github","sourceId":"tenequm/skills/mpp","sourceUrl":"https://github.com/tenequm/skills/tree/main/skills/mpp","isPrimary":false,"firstSeenAt":"2026-04-18T23:05:18.775Z","lastSeenAt":"2026-04-22T01:01:39.897Z"}],"details":{"listingId":"59da7aa0-21f9-4ba6-84ff-bdf713c8b126","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"tenequm","slug":"mpp","github":{"repo":"tenequm/skills","stars":23,"topics":["agent-skills","ai-agents","claude-code","claude-skills","clawhub","erc-8004","mpp","openclaw","skills","solana","x402"],"license":"mit","html_url":"https://github.com/tenequm/skills","pushed_at":"2026-04-14T16:24:57Z","description":"Agent skills for building, shipping, and growing software products","skill_md_sha":"05a6af3d51dfd6db65036434957dbcd2ddfb383a","skill_md_path":"skills/mpp/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/tenequm/skills/tree/main/skills/mpp"},"layout":"multi","source":"github","category":"skills","frontmatter":{"name":"mpp","description":"Build with MPP (Machine Payments Protocol) - the open protocol for machine-to-machine payments over HTTP 402. Use when developing paid APIs, payment-gated content, AI agent payment flows, MCP tool payments, pay-per-token streaming, or any service using HTTP 402 Payment Required. Covers the mppx TypeScript SDK with Hono/Express/Next.js/Elysia middleware, pympp Python SDK, and mpp Rust SDK. Supports Tempo stablecoins, Stripe cards, Lightning Bitcoin, and custom payment methods. Includes charge (one-time) and session (streaming pay-as-you-go) intents. Make sure to use this skill whenever the user mentions mpp, mppx, machine payments, HTTP 402 payments, Tempo payments, payment channels, pay-per-token, paid API endpoints, or payment-gated services."},"skills_sh_url":"https://skills.sh/tenequm/skills/mpp"},"updatedAt":"2026-04-22T01:01:39.897Z"}}