npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

create-mcpay

v0.7.1

Published

Cloudflare Worker template for pay-per-call agent gateways: x402 signup, mcent pricing, scoped keys, XP leaderboard, MCP server, Agent Readiness.

Readme

create-mcpay

A reusable Cloudflare Worker template for pay-per-call agent gateways. Spin up a fully-featured agent API — auth, billing, reputation — in ~2 minutes.

mcpay — because every call costs a few mcents (1 mcent = 1/1000¢). Agents pay in crypto via x402, you keep the revenue.

Quickstart

npx create-mcpay my-api
cd my-api
npm install
wrangler secret put ADMIN_KEY       # random 32-hex; required for /v1/admin/mint
wrangler deploy                     # Durable Object migration runs automatically

Mint your first key:

curl -X POST https://<your-worker>.workers.dev/v1/admin/mint \
  -H "X-Admin-Key: $ADMIN_KEY" \
  -H "Content-Type: application/json" \
  -d '{"balance_mcents": 10000, "scopes": ["example","read"]}'
# → {"ok":true,"key":"mcp_...","balance_mcents":10000,"scopes":["example","read"]}

Use it:

curl -X POST https://<your-worker>.workers.dev/v1/example \
  -H "Authorization: Bearer mcp_..." \
  -H "Content-Type: application/json" \
  -d '{"message":"hello"}'

Security posture

  • Bearer tokens stored HASHED (SHA-256). Raw tokens live only at mint time + in the holder's memory. A KV/DO dump exposes no live keys.
  • Atomic charging via Durable Object with blockConcurrencyWhile — no TOCTOU overdraft under burst traffic.
  • Default-deny scopes — a key minted without an explicit scopes array cannot call any paid endpoint. No implicit all-access.
  • Admin mint: timingSafeEqual on the admin key, crypto.getRandomValues for the token, required scopes, MAX_MINT_MCENTS ceiling ($1,000 default).
  • Validate-before-charge — handlers parse and shape-check the body before debiting. Malformed requests return 400 with "note":"no charge applied".
  • No CORS on /v1/admin/* — a compromised browser tab can't mint keys even with a leaked admin key.
  • Bounded body reads (16 KB default) to prevent memory DoS.

See src/template.ts header comment for the full list.

Architecture

┌──────────────┐    Bearer mcp_<hex>    ┌────────────────────────────────┐
│  External    │───────────────────────▶│ Cloudflare Worker (this repo)  │
│  Agent       │                        │   /v1/example  (paid, 100mc)   │
└──────────────┘                        │   /v1/admin/mint (admin-only)  │
                                         │                                │
                                         │   ┌────────────────────────┐   │
                                         │   │ LeaderboardDO          │   │
                                         │   │  - atomic charging     │   │
                                         │   │  - stores hashed keys  │   │
                                         │   │  - blockConcurrency…   │   │
                                         │   └────────────────────────┘   │
                                         └────────────────────────────────┘

Extending with your own paid endpoint

async function handleMyTool(req: Request, env: Env): Promise<Response> {
  // 1. Validate body first — no charge on malformed requests.
  const raw = await req.text();
  if (raw.length > 16 * 1024) return error(413, "body too large");
  let body: any;
  try { body = JSON.parse(raw); } catch { body = null; }
  if (!body || typeof body.query !== "string") {
    return error(400, 'missing "query"', { note: "no charge applied" });
  }

  // 2. Auth + charge. Atomic via the Durable Object.
  const auth = await authAndCharge(req, env, 250, "mytool");
  if (auth instanceof Response) return auth;

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

Register it in the router:

if (p === "/v1/mytool" && req.method === "POST") return handleMyTool(req, env);

Add to CallType, PRICE_MCENTS, XP_AWARD, SCOPE_FOR, plus a scope string. The template's SCOPE_FOR table is the single source of truth — every paid handler routes through it.

What's NOT in the template (by design)

  • x402 signup, leaderboard UI, MCP server, Agent Readiness .well-known routes — these are product-specific; see data-label-factory's agent-gateway/ for a reference that bolts them on.
  • Refund policy — depends on your failure modes. DLF's reference has a 5xx + rate-capped refund policy you can adapt.
  • Rate limiting on /v1/admin/mint — use Cloudflare's [[unsafe.bindings]] rate-limiter or a DO counter. The template assumes admin is trusted.

MPP signup — autonomous key minting

Enable /v1/signup so agents self-serve keys without a human admin. Set at least one payment method's secrets:

# Tempo (stablecoin, sub-second settlement)
wrangler secret put TEMPO_RECIPIENT   # wallet to receive USDC
wrangler secret put TEMPO_CURRENCY    # USDC token address on Tempo network
wrangler secret put MPP_SECRET_KEY    # openssl rand -hex 32

# Stripe (card/wallet — Machine Payments must be enabled on your Stripe account)
wrangler secret put STRIPE_RECIPIENT
wrangler secret put STRIPE_NETWORK_ID
wrangler secret put STRIPE_SECRET_KEY

# Optional tuning (defaults shown)
wrangler secret put SIGNUP_PRICE_CENTS             # 10  ($0.10)
wrangler secret put DEFAULT_SIGNUP_BALANCE_MCENTS  # 10000 (100 calls at 100mc each)
wrangler secret put DEFAULT_SIGNUP_SCOPES          # example

The signup flow (MPP charge intent, x402-compatible):

Agent POST /v1/signup
→ 402  WWW-Authenticate: Payment ...   (one header per configured method)

Agent pays (Tempo USDC or Stripe card), retries:
→ POST /v1/signup  Authorization: Payment <credential>
→ 200  {"ok":true,"key":"mcp_...","balance_mcents":10000,"scopes":["example"]}
        Payment-Receipt: ...

Both methods can be active simultaneously — the agent picks whichever it supports. x402 clients work unchanged (MPP is backwards-compatible with x402).

Changelog

  • 0.7.0 — 5 correctness fixes: (1) Non-200 mppx responses no longer fall through to mint — only explicit 200 triggers key creation. (2) Amount formula corrected: mppx expects whole token units ("0.1" for $0.10), not base units. (3) Separate DO rate-limit windows for admin (10/hr) vs signup (1000/hr) — paid signups can't DoS the operator's admin mint. (4) compose() entries use correct ["method/intent", options] tuple format. (5) nodejs_compat flag added to generated wrangler.toml — mppx requires Node.js built-ins.
  • 0.6.0 — MPP signup via /v1/signup: agents self-serve keys by paying with Tempo (stablecoin), Stripe (card), or both. Uses mppx SDK (official MPP TypeScript SDK). x402 backwards-compatible. Opt-in via secrets — no signup endpoint if neither method is configured. Strict type check on balance_mcents at mint: string/boolean inputs now rejected with 400 instead of being silently coerced via Number().
  • 0.3.0 — SHA-256-hashed token storage (was: raw bearer as KV key), atomic charging via Durable Object (was: TOCTOU-prone KV rmw), admin mint balance ceiling, bounded body reads, mcp_ service-namespaced key prefix, 503 on admin when unset (no timing oracle), no CORS on admin paths.
  • 0.2.0 — default-deny scopes, opinionated admin mint route, validate-before-charge in example, hoisted projectName in scaffolder, flat 404, X-Admin-Key removed from CORS preflight.
  • 0.1.0 — initial release.

License

MIT. Fork, remix, commercialize.