Launched this week

MCP-Billing
OAuth 2.1 + usage-based Stripe billing for MCP servers
114 followers
OAuth 2.1 + usage-based Stripe billing for MCP servers
114 followers
Self-hosted Next.js/TypeScript boilerplate: full OAuth 2.1 + PKCE, API key management with zero-downtime rotation, usage-based Stripe billing, and Redis rate limiting. 7 modules, 300+ tests. One-time €79, no revenue share, no platform lock-in. The metering core is free and open source on npm.








MCP-Billing
The OAuth half of this is the part I would pay for before the billing half. I connect MCP servers to my Claude setup as a user most weeks, and the pattern from that side is blunt, a server whose auth works on the first try gets used the same day, and one that fails sits unauthenticated for weeks. I have one in that exact state right now. Does your OAuth 2.1 flow cover the interactive consent dance the desktop AI clients run, or is it aimed at headless API consumers with keys?
MCP-Billing
@abdullah_javaid3
it covers the real interactive consent flow, not an auto-approve shortcut. when a client kicks off the OAuth 2.1 PKCE authorization code grant, the user lands on an actual consent page in the dashboard to review requested scopes and click "Allow" or "Deny" (backed by TOCTOU protection in the server action and explicit tests for both decisions). so it's definitely built for interactive consent rather than just headless API keys.
that said, to be 100% transparent about a current gap that might affect your exact setup: right now the redirect_uri validation relies on a web-app whitelist checking for https:// or standard http://localhost:port/. if the desktop client you're using relies on RFC 8252 native app patterns like loopbacks with dynamic ports or custom schemes (like claude://), my current validation regex won't cover it — it's a narrow whitelist, easy to extend but not built in yet.
i also haven't tested it end-to-end against a live Claude Desktop client instance yet—the test suite exercises the server actions and handlers directly with mock clients.
curious though, what's the auth setup or custom scheme on the server sitting unauthenticated in your setup right now? would love to know if it's hitting that exact loopback/scheme restriction so i can prioritize it.
@marc_gil1 Honest answer, the stalled one is a hosted server that authenticates through the Claude client itself, browser consent and then a redirect back to a localhost callback the client spins up on a random port. So it is exactly your RFC 8252 case, loopback with a dynamic port, and a fixed localhost whitelist would refuse it. The stall on my side was friction rather than rejection, the flow needs the human at the keyboard at the right moment and that moment kept losing. If desktop AI clients are buyers you care about, the dynamic port loopback looks like the piece to prioritize, and a live end to end run against a real Claude client would tell you more than the mock suite there.
MCP-Billing
@abdullah_javaid3 that's brilliant context, thanks a lot for confirming.
on the loopback validation: you're 100% right. expanding the redirect_uri check to validate standard RFC 8252 dynamic ports instead of exact string matching is a surgical fix (adjusting the URI regex / port validator), and i'm adding that directly to the top of the OAuth backlog.
on the friction point: to be totally clear on how it behaves right now, the consent screen itself actually doesn't time out while sitting open. the request parameters live in the form inputs, and clicking "Allow" re-validates them fresh against Postgres with TOCTOU protection. the 60-second TTL only starts after you click "Allow", which is when the single-use authorization code gets issued for the client to exchange.
so while a timeout isn't kicking the user off the page, you nailed the real UX gap: there's zero client-server orchestration built for when the human isn't sitting at the keyboard at that exact moment. no push notification, no deep-linking polling to wake up the client, nothing. the boilerplate handles the auth primitives, but not the "notify the user when it's time to approve" UX.
and you're completely right about the end-to-end testing against a real Claude Desktop instance. headless mock suites verify the protocol specs, but they completely miss this kind of real-world human-in-the-loop friction. really appreciate you breaking this down!
The OAuth 2.1 + PKCE half is the part I'd have paid for. We ship an MCP server next to a local CLI binary, and the awkward case was authenticating a client that has no redirect target of its own — we ended up binding a loopback listener on 127.0.0.1 and handing back a http://localhost:<port>/ca... redirect URI. That took longer to get right than the billing did.
Does the boilerplate cover that non-browser client path (loopback or device code), or is it aimed at hosted MCP servers where a normal redirect URI already exists? Also curious what led you to one-time €79 with no revenue share when the metering core is already open source — that's a deliberate-looking choice.
The webhook story is the right thing to lead with. I shipped a Stripe integration this month where everything was green in test mode and the first real card 400'd on a currency param test mode never asked for - and separately found receipts failing silently because the send helper never throws and a try/catch was eating the reason. Money bugs don't announce themselves; you find them by walking the path with a real card and reading the logs like a skeptic.
Which is why I'd second Grace's checklist ask, and add one architectural vote: treat metering as a ledger, not a counter. Reserve before the metered call, settle exactly once keyed on the attempt, refund on failure - Gal's retry-dedupe question mostly dissolves when the settle is idempotent by construction. The counter tells you what happened; the ledger makes sure it only happened once.
Publishing mcp-metering free and inspectable is a genuinely good trust move. €79 for the edge cases someone already paid to discover is fair.
the webhook silent-failure story in your maker comment is the one that would actually keep me up at night, not the OAuth stuff everyone's asking about. on the usage-based billing side specifically: if Stripe retries a webhook (which it does on any non-2xx, including your own transient DB hiccups), does mcp-metering dedupe on the event id before incrementing usage, or is double-counting on retry something the integrator has to guard against themselves? that's the kind of bug that doesn't throw an error, it just quietly overcharges someone until they notice their invoice looks wrong
The zero-downtime API key rotation is the detail that would save the most pain in practice — keys usually get replaced when something breaks, not during planned maintenance, and any rotation downtime cascades into support tickets. The question I would ask before building on this: does the usage-based metering support different pricing tiers per API key, or is billing flat across all keys on the account? That matters when you want to give different API keys to different customer tiers without running separate instances.
Hey @marc_gil1 — the webhook silent-failure story in your launch note is a great flag for exactly the kind of bug that doesn't announce itself — appreciated the honesty there.
One thing I didn't see covered in the OAuth thread: how does this handle machine-only auth, where the "user" consenting is an agent acting on someone else's behalf with no human at the keyboard to click Allow? Client-credential / device-code shaped flows with no human in the loop are the case that keeps coming up as agents start initiating their own transactions.
Also curious about the runtime — the stack leans on Postgres + Redis, is this deployable on an edge runtime (Workers, etc.), or does it assume a traditional always-on Node server?