✦ Cloudflare Workers · Durable Objects · MPP

create-mcpay

Spin up a fully-featured pay-per-call agent API in 2 minutes. Auth, billing, reputation — all in one file.

⚡ Tempo 💳 Stripe ₿ Lightning 🔗 x402
$ npx create-mcpay my-api

click to copy

Built for the
agentic economy

Every design decision optimises for autonomous agents calling your API at scale — zero human in the loop, zero trust violations.

⚛️

Atomic billing, no TOCTOU

All charging happens inside a single Durable Object with blockConcurrencyWhile. Ten concurrent calls on a 100mc balance? Exactly one wins. Every time.

🔑

SHA-256 hashed tokens

Raw bearer tokens are never persisted. A full KV or DO dump exposes zero live keys. The token lives only at mint time and in the holder's memory.

🌐

MPP native — Stripe + crypto

One /v1/signup endpoint accepts Tempo stablecoin, Stripe card, or both simultaneously via Machine Payments Protocol. x402 clients work unchanged.

🚫

Default-deny scopes

A key minted without explicit scopes can call nothing. Every endpoint maps to exactly one scope. No implicit all-access, ever.

🛡️

DO-owned pricing

The Worker never decides cost. It passes call_type to the DO which owns the price table. No split billing authority. No future maintainer footguns.

🤖

Zero human in the loop

Agents pay via MPP → verify on-chain → auto-mint key → start calling. No signup form, no email, no admin needed between deploy and first revenue.

7
versions shipped
1
file to deploy

One Worker. One DO.
Everything atomic.

The Durable Object is the single source of truth for auth, pricing, scoping, and charging. The Worker is a thin router that converts HTTP → DO RPC.

🌍
Agent
sends POST with Bearer token
Worker
validates body shape, no charge yet
🔒
DO Charge
blockConcurrencyWhile — scope, balance, debit
💾
SQLite
hashed key record persisted atomically
Response
result + remaining balance returned

Add a paid endpoint in 30 seconds

src/index.ts
// 1. Validate body first — no charge on bad shape
const body = await parseBody(req);
if (!body.query) return error(400, "no charge");

// 2. Auth + atomic charge via DO
const auth = await authAndCharge(req, env, "search");
if (auth instanceof Response) return auth;

// 3. Do the actual work
const result = await doSearch(body.query);
return json({ ok: true, result,
  balance_mcents: auth.record.balance_mcents });

Pricing table lives in the DO

src/index.ts — DO-owned
// Single source of truth. Worker never touches this.
const PRICE_MCENTS: Record<CallType, number> = {
  example: 100,   // $0.001
  search:  250,   // $0.0025
  read:    0,     // free
};

// One scope per endpoint. Default-deny.
const SCOPE_FOR = {
  example: "example",
  search:  "search",
  read:    "read",
};

Agents self-serve.
No human needed.

Enable /v1/signup with Tempo or Stripe secrets. Agents discover, pay, and call — fully autonomously via Machine Payments Protocol.

The autonomous signup flow

STEP 1
POST /v1/signup

Agent discovers the endpoint, no auth yet.

STEP 2
← 402 WWW-Authenticate: Payment method="tempo"

Server returns MPP challenge. Agent picks Tempo or Stripe.

STEP 3
Agent pays $0.10 on-chain or by card

Sub-second on Tempo. Standard processing on Stripe.

STEP 4
← 200 {"key":"mcp_...","balance_mcents":10000}

Key minted atomically. 100 calls included. Go.

Enable in 3 secrets

$wrangler secret put TEMPO_RECIPIENT
# your wallet address (0x...)
$wrangler secret put TEMPO_CURRENCY
# USDC token on Tempo network
$wrangler secret put MPP_SECRET_KEY
# openssl rand -hex 32

$wrangler deploy
✓ /v1/signup live — agents can self-serve

# also supports Stripe cards:
$wrangler secret put STRIPE_SECRET_KEY
✓ both methods active simultaneously
✓ x402 backwards-compat
✓ MPP native
✓ Separate rate windows
✓ 1000 signups/hr cap

From zero to
charging agents in 2 min

terminal
$npx create-mcpay my-api
✓ Scaffolded my-api/

$cd my-api && npm install

$wrangler secret put ADMIN_KEY
# random 32-hex string

$wrangler deploy
✓ Deployed to workers.dev

$curl -X POST https://my-api.workers.dev/v1/admin/mint \
-H "X-Admin-Key: $ADMIN_KEY" \
-d '{"balance_mcents":10000,"scopes":["example"]}'
{"ok":true,"key":"mcp_...","balance_mcents":10000}

🗂 What you get

  • POST /v1/example — paid endpoint (100mc)
  • POST /v1/admin/mint — key management
  • POST /v1/signup — MPP self-serve (opt-in)
  • GET /v1/pricing — public price list
  • GET /v1/health — liveness check

🔐 Security out of the box

  • ✓ Tokens SHA-256 hashed, never stored raw
  • ✓ Atomic charging — no overdraft under burst
  • ✓ Validate-before-charge on every handler
  • ✓ No CORS on admin routes
  • ✓ Admin mint rate-limited (10/hr in DO)

💡 1 mcent = 1/1000¢

100mc per call = $0.001. Mint 10,000mc for $0.10 of API credit. Set any price you want in the DO's PRICE_MCENTS table.

How much is a mcent?

1 mc = 1/1000th of a cent = $0.00001. No minimums, no subscriptions — agents pay for exactly what they consume.

mc
=
$
mc / call
100 API calls
Quick set →

Reference table

mc / call Cost per call Cost / 1K calls Calls per $1 Calls per $10

Transform your API in seconds

Paste any Cloudflare Worker handler. Claude rewrites it with validate-before-charge, atomic billing, and scoped auth — production-ready.

Your handler
paste your code ↓
mcpay endpoint
// output will appear here as Claude streams it…

Powered by Claude via OpenRouter · no account required · your code is never stored

Ready to charge agents?

One command. One file. No database setup, no auth service, no payment processor boilerplate.