Usage billing for MCP servers
Tollgate meters every tools/call, hands out API keys with 200 free credits, and answers "out of credits" with a checkout link the calling agent can follow. One wrapper around your fetch handler — your tools stay yours.
TypeScript SDK · MIT · zero runtime deps · Workers, Node 18+, Deno, Bun
import { Tollgate, D1Store } from "@tollgate/sdk"; export default { async fetch(req: Request, env: Env) { const tollgate = new Tollgate({ store: new D1Store(env.DB), signupUrl: "https://your.dev/signup", checkoutUrl: "https://your.dev/buy", }); return tollgate.protect( req, ({ message, ctx }) => yourMcpHandler(message, ctx), // unchanged ); }, };
The 402 MCP never had
MCP has no payment primitive, so Tollgate answers in the protocol's own language: structured JSON-RPC errors with the URL that fixes them. Agents read the message; tooling reads the data.
{
"code": -31401,
"message": "This method requires an
API key. Get one free at
tollgate.dev/signup — 200
credits included.",
"data": {
"signup_url": "…/signup"
}
}
{
"code": -31402,
"message": "Out of credits
(0 remaining). Buy more at
tollgate.dev/dashboard
($9 per 1,000 credits)",
"data": {
"checkout_url": "…/dashboard",
"credits_remaining": 0
}
}
{
"code": -31429,
"message": "Rate limit exceeded
(120 requests/minute).
Retry shortly.",
"data": {
"retry_after_seconds": 30
}
}
Codes are HTTP-mnemonic (401 / 402 / 429) and sit outside the JSON-RPC reserved range and the codes the MCP spec uses — they can't be misread. Discovery stays free: initialize, tools/list, ping never cost a credit.
Proof, not promises
This site is an MCP server: live AI-ecosystem data — LLM prices, the official MCP registry, AI tool changelogs. Every record carries source_url and collected_at. It bills through the same SDK you just read about.
| tool | what it answers | cost |
|---|---|---|
| ai_ecosystem_overview | what's inside, how fresh | free |
| llm_pricing | prices & limits, 8 providers, 142 models | 1 |
| llm_price_compare | your workload costed across models | 1 |
| mcp_servers_search | official registry, 329 servers | 1 |
| mcp_server_info | remotes, packages, install | 1 |
| ai_changelog | releases of 6 AI tools + MCP spec | 1 |
Bulk reads via MCP resources cost 5 credits per dataset. Counts are from the snapshot collected 2026-06-11; refresh with one command.
# streamable HTTP + bearer key { "url": "https://tollgate.example.dev/mcp", "headers": { "Authorization": "Bearer tg_…" } }
{
"workload": { "input_tokens": 50000, "output_tokens": 5000, "calls": 1000 },
"cheapest": "deepseek-chat",
"comparison": [
{ "model_id": "deepseek-chat", "total_usd": 8.40 },
{ "model_id": "gpt-5-mini", "total_usd": 22.50 },
{ "model_id": "gemini-2.5-flash", "total_usd": 27.50 },
{ "model_id": "claude-haiku-4-5", "total_usd": 75.00 }
],
"note": "Vendor list prices per 1M tokens;
caching/batch discounts not applied."
}
models.dev (vendor list prices) cross-checked against the OpenRouter API — 75 agreements, 12 disagreements, both numbers kept when they differ. Registry: registry.modelcontextprotocol.io. Changelogs: GitHub Releases. If a source is down, the collector fails loudly — it never invents a row.
Built like billing, not like a demo
A charge is one conditional UPDATE — free credits first, then paid, guarded by WHERE free + paid >= cost. Concurrent calls can race; the balance can't go negative.
Raw keys are shown once. Only SHA-256 hashes are stored; dashboards see tg_a1b2c3d8…. Rotation revokes the old key in the same transaction.
Lemon Squeezy and Stripe signatures are verified before any state changes, and fulfillment is idempotent on the provider's reference — retries and replays are no-ops.
Pricing
Free
200 credits
On signup, no card. 1 credit = 1 tool call. Discovery and the overview tool are always free.
Start freePay as you go
$9 per 1,000 credits
Blocks never expire. Checkout via Lemon Squeezy or Stripe — or the built-in mock driver while you develop.
Buy creditsThe SDK itself is MIT — self-host the whole thing for free. Hosted data + billing is the product.
For server authors
The quickstart takes a fresh project to a metered, billable MCP server in under 15 minutes — memory store first, D1 and live checkout when you're ready. We timed it.
$ npm install @tollgate/sdk $ wrangler d1 execute DB \ --file=node_modules/@tollgate/sdk/schema.sql # wrap your handler, deploy, done