# Stevens Keys > License keys, edge validation and usage metering for paid MCP servers and APIs. Sell from your own site instead of a storefront. Preview, TEST MODE: no real charges, checkout is Stripe test mode only (test cards); creators can refund test sales (a full refund revokes the key), payouts via Stripe Connect are planned and not live (planned split 85/15 creator/platform). Accounts are verified for test mode by a Turnstile human check at sign-up (no email). Operated by Canada Site Ops, Ontario, Canada. One call, `POST /v1/validate` with `Authorization: Bearer `, checks and meters a key: 200 allow, 403 deny, 401 missing. Revoked keys deny on the next validation (or within the optional `cache_ttl`, 30s default). ## Docs - [Agent quickstart (Markdown)](https://stevens-keys.pages.dev/agent-quickstart.md): MCP and HTTP quickstart in plain Markdown, no signup - [Creator docs](https://stevens-keys.pages.dev/docs): quickstart, verification, validation, revocation, quotas, API reference - [OpenAPI 3.1 spec](https://stevens-keys.pages.dev/openapi.json): all live API routes (test mode) - [Full text for LLMs](https://stevens-keys.pages.dev/llms-full.txt): docs, guides and every API operation in one file - [API catalog (RFC 9727)](https://stevens-keys.pages.dev/.well-known/api-catalog): machine-readable list of the API's spec, docs and status - [agents.json](https://stevens-keys.pages.dev/.well-known/agents.json): agent flows (demo key, validate, public stats) over the OpenAPI spec - [Hosted MCP server](https://stevens-keys.pages.dev/mcp): Streamable HTTP, no auth, tools create_demo_key, validate_license_key, get_public_stats; resources/list exposes discovery docs (quickstart, llms.txt, OpenAPI, server card, api-catalog, docs.md) (test mode) - [MCP server card](https://stevens-keys.pages.dev/.well-known/mcp/server-card.json): machine-readable description of the hosted MCP server - [server.json](https://stevens-keys.pages.dev/server.json): MCP Registry-format server.json for the hosted MCP server (remote, streamable-http, no auth) - [Agent card](https://stevens-keys.pages.dev/.well-known/agent-card.json): A2A-style agent card (HTTP API + hosted MCP; no A2A JSON-RPC endpoint) - [Agent Skills index](https://stevens-keys.pages.dev/.well-known/agent-skills/index.json): Agent Skills Discovery (v0.2.0) index; skill: [stevens-keys SKILL.md](https://stevens-keys.pages.dev/.well-known/agent-skills/stevens-keys/SKILL.md) - [AGENTS.md](https://stevens-keys.pages.dev/AGENTS.md): standing instructions for AI agents (how to start, machine files, rules) - [Changelog (Atom)](https://stevens-keys.pages.dev/changelog.atom): feed of machine-facing changes; [security.txt](https://stevens-keys.pages.dev/.well-known/security.txt) - [ai.txt](https://stevens-keys.pages.dev/ai.txt): automated-agent usage policy (all welcome); [JSON Feed](https://stevens-keys.pages.dev/feed.json): changelog as JSON Feed 1.1 - [Deprecated A2A agent.json](https://stevens-keys.pages.dev/.well-known/agent.json): same card as agent-card.json for A2A v0.2.x clients; prefer agent-card.json (v0.3+) - [MCP tools catalog](https://stevens-keys.pages.dev/.well-known/mcp/tools.json): static list of the 3 hosted MCP tools with full inputSchema (no handshake required) - [/.well-known/llms.txt](https://stevens-keys.pages.dev/.well-known/llms.txt): identical copy of llms.txt at the well-known path, for crawlers that probe there - [/.well-known/openapi.json](https://stevens-keys.pages.dev/.well-known/openapi.json): identical copy of openapi.json at the well-known path, for scanners that probe there - [ai-plugin.json](https://stevens-keys.pages.dev/.well-known/ai-plugin.json): plugin manifest pointing to the OpenAPI spec (no auth for demo/validate) - [Sell API access with per-key billing in 10 minutes](https://stevens-keys.pages.dev/sell-api-access-per-key-billing): step-by-step guide - [Gate snippet generator](https://stevens-keys.pages.dev/snippets): copy-paste validation code for Workers, Node/Express, Python, curl ## Guides - [License keys for paid MCP servers](https://stevens-keys.pages.dev/mcp-license-keys) - [License keys vs OAuth vs API keys](https://stevens-keys.pages.dev/mcp-license-keys-vs-oauth) - [Keygen alternative: Stevens Keys vs Keygen, Lemon Squeezy, Gumroad](https://stevens-keys.pages.dev/keygen-alternative): sourced comparison (checked Oct 20, 2026), incl. when they are a better fit - [Cryptlex alternative: Stevens Keys vs Cryptlex](https://stevens-keys.pages.dev/cryptlex-alternative): sourced comparison (checked Oct 21, 2026), incl. when Cryptlex is a better fit - [Lemon Squeezy license keys alternative: Stevens Keys vs Lemon Squeezy](https://stevens-keys.pages.dev/lemon-squeezy-license-keys-alternative): sourced comparison (checked Oct 23, 2026), incl. when Lemon Squeezy is a better fit - [MCP monetization FAQ](https://stevens-keys.pages.dev/mcp-monetization-faq) - [Revenue calculator](https://stevens-keys.pages.dev/calculator) ## Markdown versions Every main page has a clean Markdown copy at the same path plus `.md` (also linked from each page's `` and HTTP Link header): - [index.md](https://stevens-keys.pages.dev/index.md) - [docs.md](https://stevens-keys.pages.dev/docs.md) - [demo.md](https://stevens-keys.pages.dev/demo.md) - [mcp-license-keys.md](https://stevens-keys.pages.dev/mcp-license-keys.md) - [mcp-license-keys-vs-oauth.md](https://stevens-keys.pages.dev/mcp-license-keys-vs-oauth.md) - [mcp-monetization-faq.md](https://stevens-keys.pages.dev/mcp-monetization-faq.md) - [mcp-server-pricing-guide.md](https://stevens-keys.pages.dev/mcp-server-pricing-guide.md) - [sell-api-access-per-key-billing.md](https://stevens-keys.pages.dev/sell-api-access-per-key-billing.md) - [keygen-alternative.md](https://stevens-keys.pages.dev/keygen-alternative.md) - [cryptlex-alternative.md](https://stevens-keys.pages.dev/cryptlex-alternative.md) - [lemon-squeezy-license-keys-alternative.md](https://stevens-keys.pages.dev/lemon-squeezy-license-keys-alternative.md) ## Optional - [Live sandbox demo](https://stevens-keys.pages.dev/demo) - [Privacy](https://stevens-keys.pages.dev/privacy) - [Terms](https://stevens-keys.pages.dev/terms) ## Quickstart for agents (no signup) - API base: https://stevens-keys.pages.dev (all /v1/* endpoints; OpenAPI at https://stevens-keys.pages.dev/openapi.json) - Get a 24h sandbox key: POST https://stevens-keys.pages.dev/v1/demo/keys - Validate + meter: POST https://stevens-keys.pages.dev/v1/validate with header "Authorization: Bearer " and JSON body {"units":1} - Agent/bot traffic is welcome and never blocked; optional header "X-Client-Type: agent" labels it. Public aggregate stats: GET https://stevens-keys.pages.dev/v1/public-stats - MCP: connect any MCP client to https://stevens-keys.pages.dev/mcp (Streamable HTTP, no auth). Tools: create_demo_key, validate_license_key, get_public_stats. resources/list returns discovery docs. - Test mode only: no real charges, payouts not live. - [/.well-known/ai.txt](https://stevens-keys.pages.dev/.well-known/ai.txt) and [/.well-known/agents.md](https://stevens-keys.pages.dev/.well-known/agents.md): copies of ai.txt and AGENTS.md at well-known paths, for scanners that probe there --- Full text for LLMs and agents. Generated from the live docs and OpenAPI spec. TEST MODE only. # Creator docs (https://stevens-keys.pages.dev/docs) PREVIEW · TEST MODE — simulated demo sales plus Stripe test sales, no real money. Payouts are not live. Stevens Keys ## Stevens Keys creator docs License keys, edge validation and usage metering for MCP servers. Everything here is test mode: keys start with sk_mcp_test_, revenue shows simulated demo sales plus Stripe test-mode sales (no real money), and payouts aren't live. Contents: Quickstart · Verification · Validating from an MCP server · Revocation · Quotas · Pricing · Stripe checkout · Buy links · Refunds · API reference ### Quickstart - Sign up at /dashboard. Complete the human check (Cloudflare Turnstile) on the sign-up form. - Get verified. Pass the human check at sign-up and your account is verified for test mode immediately; see below. - Create a product for your MCP server (Products tab or POST /v1/products). Pick its Plan in the Plan dropdown: free gives each key a default quota of 3,000 calls/month; one_time (and other paid plans) default to unlimited calls (monthly_quota: null) unless you set a per-key quota. You get a product_id. Unverified accounts can do this. - Set a price (optional, to sell keys): Price in the Products tab is in dollars (CAD); the API field is price_cents. Choose a paid plan (e.g. one_time). - Share the buy link from the Products table (/buy?product=); buyers pay with Stripe test cards and get a key shown once (details). - Or issue a key yourself (Keys tab or POST /v1/keys). The plaintext key is shown once; we store only its SHA-256 hash. - Validate the key on every tool call from your server: curl first, then fetch. - Delete your account any time from the API & SDK tab (password confirmation; revokes all keys). Want to see it work first? The demo lets you issue, validate and revoke a sandbox key without an account. ### Connect via MCP Stevens Keys runs a hosted MCP server at https://stevens-keys.pages.dev/mcp. Agents can create a demo key, validate it and read stats without signing up. # Hosted MCP server (Streamable HTTP, no auth, test mode) https://stevens-keys.pages.dev/mcp # Claude Desktop / Cursor (remote server) - mcp.json / claude_desktop_config.json { "mcpServers": { "stevens-keys": { "url": "https://stevens-keys.pages.dev/mcp" } } } # stdio-only clients: bridge with mcp-remote { "mcpServers": { "stevens-keys": { "command": "npx", "args": ["-y", "mcp-remote", "https://stevens-keys.pages.dev/mcp"] } } } Tools: create_demo_key (free 24h sandbox key, 50 calls), validate_license_key (allow/deny + metering), get_public_stats (aggregate adoption stats). Server card: /.well-known/mcp/server-card.json. ### Verification (no email) We can't send verification emails yet. Instead, sign-up includes a Cloudflare Turnstile human check, verified server-side. Passing it marks your account test verified: you can create products, issue test license keys and API secrets, and run Stripe test checkouts right away. Accounts created before this can pass the same check from the dashboard banner (POST /v1/auth/turnstile-verify). Without it you can create products but not issue keys or secrets (403 email_unverified). Manual early-access review still exists and will be required before anything live; there is no live mode yet. ### Validating from an MCP server #### curl (try this first) curl -X POST https://stevens-keys.pages.dev/v1/validate \ -H "Authorization: Bearer sk_mcp_test_..." \ -H "Content-Type: application/json" \ -d '{"product_id":"prod_...","units":1}' # 200 {"allow":true,"status":"active",...} · 403 {"allow":false,"status":"revoked"} · 401 missing key #### Raw fetch const res = await fetch("https://stevens-keys.pages.dev/v1/validate", { method: "POST", headers: { authorization: `Bearer ${key}`, "content-type": "application/json" }, body: JSON.stringify({ product_id: "prod_...", units: 1 }), }); const r = await res.json(); // 200 allow · 403 deny · 401 missing key if (!r.allow) return deny(r.status); #### TypeScript SDK (not on npm yet) The SDK (stevens-keys) isn't on npm yet. Until it is, use curl or fetch above; this is what it will look like. import { StevensKeys, withLicense } from "stevens-keys"; const keys = new StevensKeys({ baseUrl: "https://stevens-keys.pages.dev", productId: "prod_..." }); // Every request must carry Authorization: Bearer sk_mcp_test_... export default { fetch: withLicense(keys, (req, license) => handleMcp(req)) }; // Or check by hand inside a tool: const r = await keys.validate(userKey, { units: 1 }); if (!r.allow) throw new Error(`license ${r.status}`); Options: failMode: "closed" (default, deny if the API is unreachable) or "open" (allow a recently valid key for failOpenForMs). meter: false checks entitlement without counting usage. The SDK never caches metered calls. ### Selling keys with Stripe Checkout (test mode) Status: live in Stripe test mode. Buyers pay with Stripe test cards (for example 4242 4242 4242 4242); no real money. Live keys and live-mode events are refused. Each test sale appears in your dashboard Revenue tab labelled "Stripe test" (85/15 split shown). Creator payouts (Stripe Connect) are not live. - Set price_cents (CAD, at least 50) on your product. Your account must be verified (the sign-up human check is enough for test mode). - Your buy button calls POST /v1/checkout {"product_id":"prod_..."} and redirects to the returned url. - After payment, Stripe calls our signed webhook (events: checkout.session.completed, checkout.session.async_payment_succeeded, charge.refunded); we issue a license key for that product (stored as a SHA-256 hash). - The buyer lands on /purchase-success, which calls POST /v1/checkout/reveal and shows the key once. Reloading the success page afterwards shows "This key was already shown or the link expired". A second reveal returns 410 already_revealed. ### Revocation behaviour Each key has one Durable Object that every validation goes through. Revoking or suspending a key updates that object before the API responds, so the next validation anywhere is denied (revoked / suspended, cache_ttl: 0). Revocation is terminal; suspend can be resumed. Archiving a product denies all its keys with product_archived. Allowed responses carry a cache_ttl hint (default 30s, per-product, max 300s). If you cache allows for that long, a revoke takes effect within that window. If you don't cache (or use the SDK with metering on), it's immediate. ### Quotas - Per-key monthly quota: set per product (free-plan default 3,000 calls/key/month) or overridden per key. Over the limit, validation returns 403 over_quota. - units (1–1000) lets one call count as more than one unit. - Creator allowance: 50,000 validations/month on the free tier. In preview it's shown in the dashboard but not enforced. - Up to 10 products per creator. ### Pricing: 85/15 and free tier You keep 85% of sales processed through Stevens Keys; the platform fee is 15%. No monthly fee, no compute deduction. Free to sign up with the limits above. Payouts via Stripe Connect are not live yet; until they are, the dashboard shows simulated demo sales plus Stripe test sales (CAD), no real money. ### Refunds (test mode) In the Revenue tab, each Stripe test sale has a Refund button (with a confirmation). The API equivalent is POST /v1/sales/{sale_id}/refund with an optional {"amount_cents": 300} for a partial refund (default: the full remaining amount). Only your own Stripe test sales can be refunded; simulated sales can't. - The API creates the refund in Stripe test mode and returns 202. Our signed charge.refunded webhook does the rest, so refunds made in the Stripe dashboard are handled the same way. - Full refund: the buyer's key is revoked immediately (the next /v1/validate returns allow:false, status revoked). - Partial refund: the key stays active, unless the refunds add up to the full amount. - Ledger: each Stripe refund becomes one negative row (kind refund, linked to the original purchase), splitting gross, platform fee and creator share in proportion. Revenue totals are net of refunds and each sale shows paid / partly refunded / refunded. No real money. ### Stripe checkout & buy links (test mode) Set a price. In the dashboard the Price field is in dollars (CAD, e.g. 9.00). The API takes cents: POST /v1/products with "price_cents": 900. Products priced at CA$0.50 or more can be sold. Buy link. Each priced product in the dashboard Products table has a buy link (with a copy button): /buy?product=. It's a public, noindex page showing the product name, CAD price and a test-mode banner. Its Buy button calls POST /v1/checkout and redirects to Stripe Checkout. Archived, unpriced or unknown products return 404. Product data for the page comes from GET /v1/public/products/{id}. Your own checkout button. Call POST /v1/checkout with {"product_id":"..."} and redirect to the returned url. After payment the buyer lands on /purchase-success, where the license key is revealed once. What you'll see. Checkout runs in Stripe test mode only (use card 4242 4242 4242 4242). Prices stay in CAD; automatic currency conversion (Adaptive Pricing) is turned off. The test checkout page shows the Stripe sandbox's account name ("Labs"), not your product brand. Payouts to creators are not live. ### API reference Base URL https://stevens-keys.pages.dev. Creator endpoints take the session cookie (dashboard) or Authorization: Bearer sk_creator_test_.... JSON in and out. MethodPathAuthNotes POST/v1/validatelicense keyBearer or {key}; body {product_id?, units=1, meter=true}. CORS open. GET/v1/config, /healthznoneRev-share, free tier, test_mode. POST/v1/auth/signup · /login · /logoutnoneRate limited. Signup requires turnstile_token (Cloudflare Turnstile). POST/v1/auth/password-reset/request · /confirmnoneReset emails aren't delivered in preview; the response says so and points to canada.site.ops@gmail.com. POST/v1/auth/turnstile-verifycreator{turnstile_token}: pass the human check to become test verified. DELETE/v1/accountcreator{password}: revokes all keys and deletes all account data. GET/POST/v1/verification-requestcreatorManual early-access review (required before anything live). POST {note?}; 3/hour per creator. GET/v1/mecreatorIncludes email_verified and test_verified. GET/POST/v1/products; GET/PATCH/DELETE /v1/products/:idcreatorDELETE archives. GET/POST/v1/keys (?product_id=); GET /v1/keys/:idcreator (verified to issue)POST {product_id, label?, monthly_quota?, expires_at?} returns key once. POST/v1/keys/:id/revoke · /suspend · /resumecreatorEffective on the next validate. GET/POST/v1/api-secrets; POST /v1/api-secrets/:id/revokecreator (verified to create)Secret shown once. GET/v1/usage?product_id=&days=30, /v1/revenuecreatorDaily usage, top keys, revenue: simulated demo sales plus Stripe test sales (no real money). POST/v1/ledger/simulate-salecreator{product_id, gross_cents, key_id?}, simulated, CAD. POST/v1/demo/keys, /v1/demo/revokenoneSandbox demo product only. Validation statuses: active, invalid, missing_key, suspended, revoked, expired, over_quota, wrong_product, product_archived. Rate-limited calls return 429 with Retry-After. #### More from Stevens Keys - Surface: free MCP server with per-request metering - Usage Lab - Server Track Lab - API Meter Lab # Sell API access with per-key billing (https://stevens-keys.pages.dev/sell-api-access-per-key-billing) PREVIEW · TEST MODE — simulated demo sales plus Stripe test sales, no real money. Payouts are not live. Stevens Keys ## Sell API access with per-key billing in 10 minutes Give each customer their own key, check and count every call with one request, and cut off anyone instantly. This works for any HTTP API, including remote MCP servers. Every endpoint below is live in test mode; the full list is in the OpenAPI spec. Before you start, honestly: Stevens Keys is in preview. Keys, validation, metering and revocation work today. Checkout works in Stripe test mode only (test cards, no real money), and payouts via Stripe Connect are not live, so for real money you collect payment yourself for now, or just meter a free tier. Accounts are verified for test mode by a human check at sign-up (no email). ### 1. Sign up and pass the human check (2 min) Create an account in the dashboard and pass the quick human check. That verifies you for test mode immediately, so you can issue keys right away. You can also try the flow with a sandbox key in the demo. ### 2. Create an API secret and a product (2 min) In the dashboard, create an API secret (sk_creator_test_…, shown once). Then create a product, which holds your quota and cache settings: curl -s -X POST https://stevens-keys.pages.dev/v1/products \ -H "authorization: Bearer sk_creator_test_..." \ -H "content-type: application/json" \ -d '{"name":"My API","monthly_quota":3000,"price_cents":900}' # → 201 { "id": "prod_...", "name": "My API", ... } ### 3. Issue a key per customer (1 min) curl -s -X POST https://stevens-keys.pages.dev/v1/keys \ -H "authorization: Bearer sk_creator_test_..." \ -H "content-type: application/json" \ -d '{"product_id":"prod_...","label":"customer@example.com"}' # → 201 { "id": "key_...", "key": "sk_mcp_test_...", ... } (plaintext shown once) Keys are stored only as SHA-256 hashes, so you can't look the plaintext up later. Give it to your customer; they send it as Authorization: Bearer …. ### 4. Check and meter every call (3 min) Add one validate call in front of your handler. Get code for your stack from the snippet generator; the core is: async function requireLicense(req) { const auth = req.headers.get("authorization") || ""; if (!auth.startsWith("Bearer ")) return { allow: false, status: "missing_key" }; const res = await fetch("https://stevens-keys.pages.dev/v1/validate", { method: "POST", headers: { authorization: auth, "content-type": "application/json" }, body: JSON.stringify({ product_id: "prod_...", units: 1 }), }); return res.json(); // 200 allow · 403 deny · 401 missing key } Each allowed call is counted against the key's monthly quota (send "meter": false for checks that shouldn't count; "units" up to 1000 for heavier calls). Over quota returns 403 over_quota. ### 5. Watch usage, revoke when needed (2 min) The dashboard shows daily usage and top keys (GET /v1/usage). To cut someone off: curl -s -X POST https://stevens-keys.pages.dev/v1/keys/key_.../revoke \ -H "authorization: Bearer sk_creator_test_..." The next validation anywhere is denied. If you cache allows using the cache_ttl hint (30s default), it takes up to that long. ### 6. Price it Per-call or subscription? Model it in the revenue calculator (85/15 is our planned rate; no fees are charged in preview). Background in the monetization FAQ. ### Related Docs · Snippet generator · Calculator · OpenAPI · llms.txt #### More from Stevens Keys - Surface: free MCP server with per-request metering - Usage Lab - Server Track Lab - API Meter Lab # License keys for paid MCP servers (https://stevens-keys.pages.dev/mcp-license-keys) PREVIEW · TEST MODE — simulated demo sales plus Stripe test sales, no real money. Payouts are not live. Stevens Keys ## License keys for paid MCP servers How to gate a paid MCP server with license keys, why revocation speed matters, and whether to sell through a marketplace or from your own site. ### How to gate an MCP server with license keys A remote MCP server is an HTTP endpoint, so gating it works like any paid API: - Give each customer a key. Issue a unique key per customer (or per seat) when they pay. Never share one key across customers; you lose the ability to cut off one without the rest. - Have the client send it. MCP clients that support remote servers let users set headers, so the usual pattern is Authorization: Bearer in the server config. - Check it on every request. Before running a tool, validate the key with your key service. Deny with 401 when it's missing and 403 when it's invalid, revoked, or over quota, and return a message the user can act on. - Meter as you validate. If you charge by usage or cap free plans, count the call in the same check so quota and usage can't drift apart. - Store hashes, not keys. Your database should hold a hash of each key, so a leaked database doesn't leak working keys. Local (stdio) MCP servers are harder: the code runs on the user's machine, so a check can be patched out. Keys still work well for gating a hosted backend that the local server calls. ### Near-instant revocation vs cached keys Many license systems cache validation results, sometimes for hours, to save on lookups. That's fine for desktop software. It's a problem for MCP servers, where a leaked key in a public config or a refunded customer can keep calling paid tools until the cache expires. Some marketplaces document revocation delays of up to 24 hours. The alternative is to route every check for a key through one authoritative place, so a revoke is seen by the next call. Stevens Keys does this with one Durable Object per key, and returns a short cache_ttl hint (default 30 seconds, 0 on deny) for servers that want to cache allows. You choose the trade-off; you can see it in the demo. ### Selling from your own site or GitHub vs a marketplace Marketplaces bring discovery, and typically take 15–20% of revenue. The catch is that the customer relationship lives on their storefront, and moving away later means re-issuing keys to every customer. Selling yourself (your site, your GitHub README, your listing on a directory) keeps the customer relationship and pricing in your hands, but you have to build keys, metering and billing. A billing layer that isn't a storefront sits between the two: you sell wherever you want, and it handles keys, validation, usage and (once live) payouts. MarketplaceYour own site + key service DiscoveryBuilt inYours to drive (directories, GitHub, content) Customer relationshipTheirsYours Typical fee15–20%Stevens Keys: 15%, free to start Switching costHighLow: keys and server stay where they are ### Where Stevens Keys fits Stevens Keys, from the team behind Surface, issues hashed license keys, validates and meters them at the edge, and revokes on the next call. Creators keep 85%. It's in preview: test mode only, payouts via Stripe Connect not live yet, and account verification is manual during early access. Read the docs Try the demo #### More from Stevens Keys - Surface: free MCP server with per-request metering - Usage Lab - Server Track Lab - API Meter Lab # MCP monetization FAQ (https://stevens-keys.pages.dev/mcp-monetization-faq) PREVIEW · TEST MODE — simulated demo sales plus Stripe test sales, no real money. Payouts are not live. Stevens Keys ## MCP monetization FAQ Straight answers for MCP server creators thinking about charging: pricing models, how to gate access, payouts, marketplaces and fees. Stevens Keys is in preview (test mode), and we say below what is and isn't built. - Should my MCP server be free or paid? - License keys, OAuth or API keys: which should I use to gate a paid MCP server? - Should I charge per call or by subscription? - How do payouts work with Stevens Keys? - Should I sell on an MCP marketplace or from my own site? - How fast do revoked keys stop working? - What rev-share do MCP marketplaces typically take? - Is there a free tier? ### Should my MCP server be free or paid? Most MCP servers today are free, and that is a reasonable default while you find users. A common pattern is a free tier that is useful on its own (a monthly call cap, or a subset of tools) plus a paid tier for heavier use or premium tools. Charge when your server costs you real money to run, or when it saves users real time. If you aren't sure anyone will pay, a free tier with a usage cap tells you who your heavy users are before you set a price. ### License keys, OAuth or API keys: which should I use to gate a paid MCP server? License keys are API-style secrets tied to a purchase: one key per customer, checked on every request, revocable, and easy to meter. They suit paid remote servers where the customer pastes a key into their client config (usually Authorization: Bearer ). OAuth is the better fit when your server acts on the user's account in another service, or when you need per-user identity and consent. It is more work to build and not every client handles it the same way. Plain API keys you roll yourself work too, but then you own hashing, revocation, quotas and usage tracking. A license key service is that same idea with those pieces already built. You can also combine them: OAuth for identity, a license key or entitlement check for what the user paid for. ### Should I charge per call or by subscription? Per call (usage-based) matches price to cost and suits expensive tools, but bills are harder for customers to predict and you need accurate metering. Subscriptions are predictable for both sides and simpler to sell; you usually add a monthly call cap so one customer can't run up your costs. Many creators start with a subscription plus a quota, and add overage or per-call pricing later. Whatever you pick, count usage in the same step that checks the key so quotas and usage can't drift apart. ### How do payouts work with Stevens Keys? Plainly: payouts are not live yet. Stevens Keys is in preview, in test mode. No real charges are taken and no money is paid out. Revenue shown in the dashboard is simulated demo sales plus Stripe test sales (CAD), no real money, so you can see how the 85/15 split would work. The plan is payouts through Stripe Connect, where you would connect your own Stripe account and receive 85% of each sale. That is planned, not built or switched on, and there is no launch date yet. Today you can issue, validate, meter and revoke keys in test mode. ### Should I sell on an MCP marketplace or from my own site? Marketplaces bring discovery and handle checkout, but the buyer purchases on their storefront, so the customer relationship is theirs and moving later means re-issuing keys. Selling from your own site, docs or GitHub README keeps the customer and pricing yours, but you have to drive discovery and run keys and billing. A billing layer that isn't a storefront, which is what Stevens Keys is built to be, lets you sell wherever you already are and still list on directories like Smithery or Glama. ### How fast do revoked keys stop working? It depends on caching. At least one marketplace documents that a revoked key can keep working for up to 24 hours because valid results are cached. In Stevens Keys every check for a key goes through one Durable Object, so a revoke is seen by the next validation call. Validate responses include a cache_ttl hint (30 seconds by default, 0 on deny) for servers that choose to cache allows; if you cache, revocation takes up to that long. You can try revoking a key in the demo. ### What rev-share do MCP marketplaces typically take? From published terms we reviewed in October 2026, creators keep between 80% and 85%: - MCP Marketplace: creator 85%, platform 15%. - Apify: creator 80% of user fees minus platform usage costs of the runs. - MCPize: 80/20 for servers monetized since June 10, 2026 (calculated after Stripe fees); earlier servers keep 85/15. - CuratedMCP: creator 80%, platform 20%. - Smithery and Glama: hosting and directories, no creator payouts found. Stevens Keys is set at 85/15 (creator 85%), free to start. Terms change, so check each platform's current pages. ### Is there a free tier? Yes. Sign-up is free with no monthly fee, up to 10 products, and a soft limit of 50K validations per month per creator. Sign-up includes a quick Cloudflare Turnstile human check. Passing it verifies your account for test mode right away (test keys, API secrets, Stripe test checkout); no email needed. Anything live will need manual review. ### Next steps Read the creator docs, try issuing and revoking a key in the demo, or read how to gate a paid MCP server with license keys, or compare license keys vs OAuth vs API keys. Read the docs Try the demo #### More from Stevens Keys - Surface: free MCP server with per-request metering - Usage Lab - Server Track Lab - API Meter Lab # API operations (from https://stevens-keys.pages.dev/openapi.json) Base URL: https://stevens-keys.pages.dev - GET /healthz: Health check (no auth) - GET /v1/public-stats: Public aggregate adoption stats, last 60 days (no auth, CORS *, cached ~60s). Aggregates only: no emails, keys or ids. creators {outside, internal} (internal = demo sandbox, ops/Surface seed, test accounts); signups_by_day [{date, outside}]; api_calls_by_day [{date, agent, human, denied}] (agent/human = metered units, denied = denied calls); products and keys_issued exclude the demo sandbox; revenue_cad {test, live} = Stripe sales net of refunds; pageviews_by_day is [] (no server-side source); days_since_launch from 2026-10-11. (no auth) - GET /v1/config: Public config: rev-share (planned 85/15), free tier, test_mode (no auth) - POST /v1/validate: Validate and meter a license key. 200 allow, 403 deny (status: invalid, revoked, suspended, expired, over_quota, wrong_product, product_archived, activation_limit, instance_required), 401 missing key. Optional instance_id (1-128 chars A-Za-z0-9._:-) identifies a device/installation; required when the product sets max_activations, and new instances beyond the cap get activation_limit. CORS open. - POST /v1/auth/signup: Create a creator account. Requires a passing Cloudflare Turnstile token; passing marks the account test_verified (test keys + test checkout). No email is sent. (no auth) - POST /v1/auth/login: Log in; sets session cookie (no auth) - POST /v1/auth/logout: Log out (no auth) - POST /v1/auth/verify-email: Verify email with a token (no auth) - POST /v1/auth/resend-verification: Resend verification (email sending is currently disabled; returns email_delivery: unavailable) - POST /v1/auth/password-reset/request: Request a password reset (always the same 200 body; while email is unavailable it says so and gives a contact address) (no auth) - POST /v1/auth/password-reset/confirm: Confirm password reset (no auth) - GET /v1/verification-request: Get your manual early-access review request (required before anything live) - POST /v1/verification-request: Request manual early-access review - POST /v1/demo/keys: Issue a sandbox demo key (50 calls, 24h expiry) (no auth) - POST /v1/demo/revoke: Revoke a sandbox demo key (no auth) - GET /v1/public/products/{id}: Public product info for the /buy page (name, description, price_cents, currency CAD, test_mode). 404 unless the product is active, priced (>= 50 cents) and owned by a verified creator. No auth. (no auth) - POST /v1/checkout: Create a Stripe Checkout Session (TEST MODE, mode=payment, CAD, adaptive pricing off) for a priced product of a verified creator. Live in Stripe test mode (test cards only, no real money). Live keys and livemode sessions are refused. (no auth) - POST /v1/checkout/reveal: Single reveal of the license key bought in a Checkout Session (202 pending, 200 key once, 410 already revealed) (no auth) - POST /v1/stripe/webhook: Stripe webhook (Stripe-Signature HMAC-SHA256, 300s tolerance, idempotent on event id). Issues a key on checkout.session.completed / async_payment_succeeded when paid. Livemode events ignored. (no auth) - POST /v1/auth/turnstile-verify: Pass Turnstile to become test_verified (for accounts created before the check) - DELETE /v1/account: Delete your account: re-confirm password; revokes all keys and deletes all creator data - GET /v1/me: Current creator - GET /v1/api-secrets: List creator API secrets - POST /v1/api-secrets: Create a creator API secret (shown once; requires verified account) - POST /v1/api-secrets/{id}/revoke: Revoke a creator API secret - GET /v1/products: List products - POST /v1/products: Create a product - GET /v1/products/{id}: Get a product - PATCH /v1/products/{id}: Update a product - DELETE /v1/products/{id}: Archive a product (its keys then deny with product_archived) - GET /v1/keys: List license keys (optional ?product_id=) - POST /v1/keys: Issue a license key; plaintext returned once (requires verified account) - GET /v1/keys/{id}: Get a key with live counters - GET /v1/keys/{id}/activations: List instances (devices) that activated this key, with the product's max_activations - DELETE /v1/keys/{id}/activations: Reset all activations for this key (frees every slot) - DELETE /v1/keys/{id}/activations/{instance_id}: Deactivate one instance, freeing its slot - POST /v1/keys/{id}/revoke: Revoke a key (terminal; next validation denies) - POST /v1/keys/{id}/suspend: Suspend a key - POST /v1/keys/{id}/resume: Resume a suspended key - GET /v1/usage: Usage rollups (?product_id=&days=30) - GET /v1/revenue: Revenue (test mode, CAD, 85/15): simulated demo sales plus Stripe test sales, net of refunds; no real money - POST /v1/sales/{id}/refund: Refund one of your own Stripe TEST sales (creator session). Body {amount_cents?} (default: remaining amount; partial allowed). Creates a Stripe test refund and returns 202; the charge.refunded webhook then writes a negative refund ledger row (idempotent per refund id) and, when fully refunded, revokes the key immediately. 409 not_refundable for simulated sales, 409 already_refunded. (no auth) - POST /v1/ledger/simulate-sale: Record a simulated demo sale (test mode only; no real money)