DEV Community

Roman V
Roman V

Posted on

How to Monetize Your MCP Server in 10 Minutes

You built an MCP server. It works. Agents call your tools, get results, everybody's happy — except you're paying for compute and API calls out of pocket.

You want to charge for it. But now you're looking at building: payment verification, usage tracking, API key management, subscription tiers, credit balances, revenue splits, Stripe integration, webhook handling. That's 2–4 weeks of work that has nothing to do with the tool you actually built.

This is the billing problem every MCP server operator hits. You can build tools in a weekend, but monetizing them takes weeks. Most operators choose "not monetizing" and either burn money or shut down.

mcp-billing-gateway solves this. It's a reverse proxy that sits in front of your MCP server and handles all billing — Stripe subscriptions, per-call credits, and x402 crypto payments. Your server stays unchanged. You register it, set pricing, and start earning.

Architecture: How It Works

AI Agent (caller)
    │
    ├─ Authorization: Bearer cgwcl_...
    │
    ▼
┌──────────────────────────┐
│   mcp-billing-gateway    │
│                          │
│  1. Authenticate caller  │
│  2. Check credits/sub    │
│  3. Debit payment        │
│  4. Forward JSON-RPC     │
│  5. Record usage         │
│  6. Return response      │
└──────────┬───────────────┘
           │
           ▼
┌──────────────────────────┐
│  Your MCP Server         │
│  (unchanged, untouched)  │
└──────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Your MCP server never sees billing logic. The gateway proxies JSON-RPC requests, handling authentication, payment verification, and usage metering transparently. If a caller doesn't have credits or a valid subscription, they get a 402 Payment Required before your server is even contacted.

Step 1: Register as an Operator

curl -X POST https://mcp-billing-gateway-production.up.railway.app/api/v1/operator/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "you@yourcompany.com",
    "name": "Your Company"
  }'
Enter fullscreen mode Exit fullscreen mode

Response:

{
  "operator_id": "op_01jvz...",
  "api_key": "cgwop_abcd1234...",
  "stripe_onboard_url": "https://connect.stripe.com/setup/abc123..."
}
Enter fullscreen mode Exit fullscreen mode

Save that API key — it's shown once. Visit the stripe_onboard_url to connect your Stripe account (business info + bank account for payouts). This uses Stripe Connect Express, so you get a managed account without handling PCI compliance yourself.

Step 2: Register Your MCP Server

Point the gateway at your upstream server:

curl -X POST https://mcp-billing-gateway-production.up.railway.app/api/v1/operator/servers \
  -H "Authorization: Bearer cgwop_abcd1234..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weather MCP",
    "description": "Real-time weather data for AI agents",
    "upstream_url": "https://your-mcp-server.com/mcp",
    "proxy_slug": "weather",
    "auth_mode": "header",
    "upstream_auth_token": "your-server-secret",
    "transport": "http",
    "is_public": true
  }'
Enter fullscreen mode Exit fullscreen mode

Your server is now proxied at:

https://mcp-billing-gateway-production.up.railway.app/proxy/weather
Enter fullscreen mode Exit fullscreen mode

The auth_mode field controls how the gateway authenticates to your upstream: header injects a Bearer token, query appends it as a query parameter, none sends requests unauthenticated. The upstream_auth_token is your server's own auth — callers never see it.

Step 3: Set Pricing

The gateway supports three billing models. You can have multiple plans per server.

Per-call (pay-as-you-go):

curl -X POST https://mcp-billing-gateway-production.up.railway.app/api/v1/operator/servers/srv_01jvz.../plans \
  -H "Authorization: Bearer cgwop_abcd1234..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Pay-as-you-go",
    "billing_model": "per_call",
    "price_per_call_usd_micro": 10000,
    "free_calls_per_month": 100,
    "is_default": true
  }'
Enter fullscreen mode Exit fullscreen mode

That's $0.01 per call (prices are in micro-units: 10,000 micro = $0.01) with 100 free calls per month. The free tier resets monthly.

Monthly subscription:

curl -X POST https://mcp-billing-gateway-production.up.railway.app/api/v1/operator/servers/srv_01jvz.../plans \
  -H "Authorization: Bearer cgwop_abcd1234..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Pro",
    "billing_model": "subscription",
    "subscription_price_usd_cents": 999,
    "subscription_interval": "monthly",
    "subscription_call_limit": 10000,
    "is_default": false
  }'
Enter fullscreen mode Exit fullscreen mode

$9.99/month for up to 10,000 calls. Managed via Stripe, with automatic period tracking and cancellation handling.

Tiered pricing:

curl -X POST https://mcp-billing-gateway-production.up.railway.app/api/v1/operator/servers/srv_01jvz.../plans \
  -H "Authorization: Bearer cgwop_abcd1234..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Volume",
    "billing_model": "tiered",
    "tiers": [
      {"up_to": 1000, "price_usd_micro": 0},
      {"up_to": 10000, "price_usd_micro": 5000},
      {"up_to": null, "price_usd_micro": 10000}
    ],
    "is_default": false
  }'
Enter fullscreen mode Exit fullscreen mode

First 1,000 calls free, next 9,000 at $0.005 each, everything above at $0.01.

Step 4: Callers Start Using Your Server

From the caller's perspective, the integration is straightforward. Using the TypeScript SDK:

import { GatewayCallerSDK } from '@mcp-billing-gateway/caller-sdk';

const client = new GatewayCallerSDK({
  baseUrl: 'https://mcp-billing-gateway-production.up.railway.app'
});

// Register (one-time)
const { api_key } = await client.register('bot@myapp.com', 'My Agent');
client.setApiKey(api_key);

// Add credits ($10.00)
await client.topupCredits(1000, 'pm_stripe_payment_method_id');

// Call your tool — billing happens automatically
const result = await client.callTool('weather', 'get_weather', {
  city: 'Berlin'
});
console.log(result);
Enter fullscreen mode Exit fullscreen mode

Or with plain curl:

curl -X POST https://mcp-billing-gateway-production.up.railway.app/proxy/weather \
  -H "Authorization: Bearer cgwcl_caller_key..." \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": "req-1",
    "method": "tools/call",
    "params": {
      "name": "get_weather",
      "arguments": {"city": "Berlin"}
    }
  }'
Enter fullscreen mode Exit fullscreen mode

The gateway authenticates the caller, checks their credit balance, debits the call cost, forwards the JSON-RPC request to your server, and returns the response. If the upstream returns an error, credits are automatically refunded.

x402 Crypto Payments

For agent-to-agent transactions where callers have crypto wallets, the gateway supports x402 payments — USDC on Base chain. No API key needed. The caller sends a payment claim header:

curl -X POST https://mcp-billing-gateway-production.up.railway.app/proxy/weather \
  -H "X-402-Payment: <base64-encoded-payment-claim>" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": "req-1",
    "method": "tools/call",
    "params": {"name": "get_weather", "arguments": {"city": "Berlin"}}
  }'
Enter fullscreen mode Exit fullscreen mode

If a caller sends a request without valid payment, they get a structured 402 response with pricing info:

{
  "jsonrpc": "2.0",
  "id": "req-1",
  "error": {
    "code": 402,
    "message": "Payment Required",
    "data": {
      "price_usd_micro": 10000,
      "x402_address": "0x...",
      "chain": "base"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This means your single server can accept both fiat (Stripe) and crypto (USDC) payments simultaneously, depending on what the caller supports.

Revenue and Analytics

Track how your server is being used and how much you're earning:

# Usage analytics
curl "https://mcp-billing-gateway-production.up.railway.app/api/v1/operator/servers/srv_01jvz.../usage?from=2026-04-01&to=2026-04-15" \
  -H "Authorization: Bearer cgwop_abcd1234..."
Enter fullscreen mode Exit fullscreen mode

The response includes usage broken down by day, by tool name, by billing rail (fiat vs. x402), and top callers. You see exactly which tools are popular and which pricing model callers prefer.

# Revenue and payouts
curl https://mcp-billing-gateway-production.up.railway.app/api/v1/operator/revenue \
  -H "Authorization: Bearer cgwop_abcd1234..."
Enter fullscreen mode Exit fullscreen mode

The default revenue split is 85/15 — you keep 85% of each call's revenue, the platform takes 15%. When you're ready to collect:

curl -X POST https://mcp-billing-gateway-production.up.railway.app/api/v1/operator/payouts/request \
  -H "Authorization: Bearer cgwop_abcd1234..."
Enter fullscreen mode Exit fullscreen mode

Funds transfer to your linked Stripe account within 1–2 business days. Minimum payout: $1.00.

Self-Hosting

The gateway is open for self-hosting if you want full control:

docker run -p 3000:3000 \
  -e DB_PATH=/data/billing.db \
  -e STRIPE_SECRET_KEY=sk_test_... \
  -e STRIPE_WEBHOOK_SECRET=whsec_... \
  -e PLATFORM_URL=https://your-domain.com \
  -v billing-data:/data \
  mcp-billing-gateway
Enter fullscreen mode Exit fullscreen mode

SQLite for storage (no Postgres dependency), Stripe for payment processing, and the full operator + caller API available at your own domain. Set DEFAULT_TAKE_RATE_BPS to adjust the revenue split (default 1500 = 15%).

What You Don't Have to Build

Here's what the gateway handles so you don't have to:

Concern Without Gateway With Gateway
API key management Build auth system Built-in (hashed, scoped, revocable)
Payment processing Integrate Stripe SDK Pre-integrated via Stripe Connect
Usage metering Build tracking system Per-call metering with breakdown
Subscription management Handle Stripe webhooks Automatic period tracking + cancellation
Credit system Build ledger + balance tracking Prepaid credits with auto-refund on errors
x402 crypto payments Implement payment verification Built-in x402 validation + anti-replay
Revenue analytics Build dashboard Usage by day, tool, billing rail, caller
Payouts Manual Stripe transfers One API call, automatic splits

Getting Started

  1. Register as an operator (30 seconds)
  2. Complete Stripe onboarding (2 minutes)
  3. Register your server with a proxy slug (1 minute)
  4. Create a pricing plan (1 minute)
  5. Share the proxy URL with your users

Your MCP server is now monetized. No code changes to your server, no new dependencies, no payment infrastructure to maintain.

Live gateway: mcp-billing-gateway-production.up.railway.app
SDK docs: sapph1re/mcp-billing-gateway-sdk
Glama listing: glama.ai/mcp/servers/sapph1re/mcp-billing-gateway-sdk

Top comments (0)