Index / Table of Contents Jump to Section
mcpaid(1)
— Comprehensive Documentation
Zero-friction edge micropayment gateway for the Model Context Protocol (MCP). Standardizing machine-to-machine commerce using HTTP 402 Payment Required, EIP-712 typed signature permits, and Base L2 settlement.
Wrap existing MCP tools with a reverse proxy, embed our TypeScript SDK, or deploy via edge portal. 97% net split.
Setup an autonomous Base L2 wallet, fund with $1-$5 USDC, and connect Claude Desktop, Cursor, or Python agents.
Sample test MCP setup, reverse proxying, Cloudflare Tunnels (public exposure), FastMCP & Agent Swarms.
Download or stream the complete, unformatted documentation in clean Markdown for Cursor, Windsurf, Claude Desktop, or autonomous agent context windows.
curl -s https://mcpaid.dev/docs.md > DOCS.md
0. Get started in 5 minutes
Two paths — pick one. Everything below this section is reference material.
Paste JSON-RPC on stdin (initialize → tools/list → tools/call). Your key loads automatically from
.env (written by step 1) — override per-command with
--key 0x... if needed. Free tools just work; paid tools sign a
gasless EIP-712 permit and settle on Base L2 — or draw from your pre-funded session (step 3) with signed
spends and no per-call permits. Prefer Claude Desktop? Point an MCP entry at the bridge with
AGENT_PRIVATE_KEY in env — full config in §3 below.
Verify with Track A against your own gateway URL, then watch earnings accrue — withdraw 97% (minus a small Base L2 network fee) to your payout wallet once you reach the $1.00 minimum (§5 below).
1. Protocol Architecture & The x402 Flow
Traditional API payment flows require humans: entering a 16-digit credit card, passing 3D Secure SMS codes, or negotiating monthly subscriptions with Stripe.
Autonomous AI agents (Claude, Cursor, AutoGPT, CrewAI) cannot do this.
MCPaid solves this by reviving the standard HTTP status code 402 Payment Required and coupling it with EIP-712 typed signature permits on Base L2.
AI Agent / Harness Edge Gateway (mcpaid.dev) Upstream MCP Server
│ │ │
[0] │── Session deposit (one-time) ──────►│ │
│ USDC transfer → treasury ($1 min) │ Full amount credited │
│ POST /v1/sessions/deposit │ to session balance │
│ │ │
[1] │── tools/call (Unauthenticated) ────►│ │
│ │ │
[2] │◄── HTTP 402 Payment Required ───────│ │
│ • Price: 0.01 USDC │ │
│ • Nonce: 0x7f19b2... │ │
│ • EIP-712 Typed Domain │ │
│ │ │
[3] │── Sign Permit Voucher Off-Chain ──┐ │ │
│ (Zero on-chain gas; or draw │ │ │
│ from pre-funded session [0]) │ │ │
│◄──────────────────────────────────┘ │ │
│ │ │
[4] │── tools/call + Permit in Auth ─────►│ │
│ Authorization: Bearer <voucher> │── [5] Verify Nonce & Sig ────┐ │
│ │ Split 97% dev / 3% protocol │ │
│ │ in ledger (no chain tx) │ │
│ │◄─────────────────────────────┘ │
│ │ │
│ │── [6] Forward JSON-RPC call ──►│
│ │ │
│ │◄── [7] Return Tool Result ─────│
│ │ │
[8] │◄── HTTP 200 OK (Tool Output) ───────│ │
│ Total roundtrip latency: < 5ms │ │
│ Developer withdraws 97% (min $1, │ │
│ minus ~$0.02 gas) via relayer [§5] │ │
# 1.2 Why HTTP 402 + EIP-712 Permits?
Traditional web payment APIs require human interactive input (browser redirects, credit card forms, SMS 2FA codes). Autonomous AI agents operating inside continuous reasoning loops cannot use these interfaces. MCPaid establishes autonomous machine-to-machine commerce using HTTP 402 and Base L2:
Agents sign cryptographic permits off-chain using their private key. No gas is spent per tool call.
97% of every call accrues immediately to the developer's internal ledger balance (3% protocol fee). Withdraw to your Base EVM wallet from $1.00 — see §2.8.
Every challenge contains a cryptographically unique, single-use nonce with 5-minute expiry and sliding circuit breakers.
2. For MCP Developers: Monetizing Your Servers
# 2.1 Prerequisites & CLI Installation
You only need two things to start monetizing:
- Node.js 18+ installed on your machine or server.
- An EVM Wallet Address on Base L2 (MetaMask, Coinbase Wallet, Rabby, or hardware wallet) where USDC earnings will accumulate.
Run npx @mcpaid/sdk wallet new --developer --save to generate a dedicated EVM keypair specifically for receiving your 97% revenue cuts on Base L2 (saved to ./.env), or paste your existing Coinbase / MetaMask / hardware wallet address.
# Global install npm install -g @mcpaid/sdk # Or run zero-install on demand via npx npx @mcpaid/sdk --help
# 2.2 Option 1: Terminal CLI Edge Deployment (Fastest & Recommended)
Prefer deploying directly from your terminal or CI/CD pipelines without ever opening a browser?
The @mcpaid/sdk CLI provides a complete end-to-end workflow to generate your payout wallet, initialize configuration, and publish your MCP servers to MCPaid Edge servers globally.
$ npx @mcpaid/sdk wallet new --developer --save Generating dedicated MCPaid developer payout keypair on Base L2... ====================================================== 🔑 Developer Payout Keypair Generated ====================================================== • Address: 0x49E9fEc4e08310Fb106de24711aBCe51028ECbad • Private Key: 0x**************************************************************** • Network: Base L2 (EVM Chain ID 8453) • Token: Circle Native USDC ====================================================== 💡 Address + key saved to ./.env (PAYOUT_ADDRESS, PAYOUT_PRIVATE_KEY). Use this address as "payoutWallet" in your config.
You can also use an existing EVM wallet from Coinbase, MetaMask, Rabby, or a hardware wallet.
$ npx @mcpaid/sdk login Enter your developer email: dev@example.com A 6-digit verification code was sent to dev@example.com Enter 6-digit verification code: 849201 ✅ Successfully authenticated as dev@example.com! Session saved to ~/.mcpaid/credentials.json
Credentials are saved locally in ~/.mcpaid/credentials.json with restrictive file permissions. You can verify your active session anytime using npx @mcpaid/sdk whoami or revoke it with npx @mcpaid/sdk logout.
$ npx @mcpaid/sdk init ✅ Created sample MCPaid configuration at: ./mcpaid.config.json
Edit mcpaid.config.json to specify your serverId, upstreamUrl, payoutWallet, and per-tool prices.
$ npx @mcpaid/sdk validate mcpaid.config.json ✅ Configuration is valid! (Server: financial-intel-mcp, 3 tools, payout: 0x49E9...ECbad)
Deploy your server configuration directly to Cloudflare's global edge network:
$ npx @mcpaid/sdk publish mcpaid.config.json ====================================================== 🚀 Deploying Server to MCPaid Edge Gateway ====================================================== • Authenticated: dev@example.com • Server ID: financial-intel-mcp • Server Name: Market Intelligence & Stock MCP • Upstream Target: https://mcp.yourdomain.com/sse • Payout Wallet: 0xYourBaseL2PayoutAddress • Tools: 3 configured (1 free, 2 paid) ====================================================== Registering server financial-intel-mcp... ✅ Server "financial-intel-mcp" registered on Edge! Configuring tool "ping" (free)... Configuring tool "get_quote" ($0.0100)... Configuring tool "run_backtest" ($0.1000)... 🎉 MCP Server published and monetized successfully! Public Edge URL: https://mcpaid.dev/mcp/financial-intel-mcp Upstream Target: https://mcp.yourdomain.com/sse
$ npx @mcpaid/sdk server list ====================================================== 📡 Registered MCP Servers (dev@example.com) ====================================================== • financial-intel-mcp: Name: Market Intelligence & Stock MCP Gateway: https://mcpaid.dev/mcp/financial-intel-mcp Upstream: https://mcp.yourdomain.com/sse Payout: 0x49E9fEc4e08310Fb106de24711aBCe51028ECbad Tools: ping (free), get_quote ($0.01), run_backtest ($0.10)
To decommission an MCP server, purge its tool pricing rules, and wipe it from your account records:
$ npx @mcpaid/sdk server remove financial-intel-mcp ⚠️ Are you sure you want to disconnect and permanently remove "financial-intel-mcp" from the MCPaid network? (y/N): y ====================================================== 🗑️ MCP Server Disconnected & Removed ====================================================== • Server ID: financial-intel-mcp • Status: Removed from MCPaid network & account records • Gateway: https://mcpaid.dev/mcp/financial-intel-mcp (Deactivated) ======================================================
# 2.3 Option 2: Zero-Code Reverse Proxy (Local & Self-Hosted)
If you already have an MCP server running (in Python, Node.js, Go, or Docker), you do not need to modify a single line of your code. The MCPaid reverse proxy sits in front of your upstream endpoint and handles the 402 gatekeeping, permit verification, and rate limiting.
$ npx @mcpaid/sdk init ✅ Created sample MCPaid configuration at: ./mcpaid.config.json
mcpaid.config.json:
{
"version": "1.0",
"server": {
"id": "financial-intel-mcp",
"name": "Market Intelligence & Stock MCP",
"upstreamUrl": "https://mcp.yourcompany.com/mcp",
"payoutWallet": "0xYourBaseL2WalletAddressHere",
"network": "base",
"currency": "USDC",
"platformFeeBps": 300
},
"tools": [
{
"name": "ping",
"type": "free",
"description": "Server latency and connectivity check"
},
{
"name": "get_quote",
"type": "fixed",
"priceUsd": "0.01",
"description": "Real-time NASDAQ/NYSE quote ($0.01 / call)"
},
{
"name": "run_backtest",
"type": "fixed",
"priceUsd": "0.10",
"description": "Historical algorithmic backtest ($0.10 / call)",
"circuitBreaker": {
"maxCallsPerMinute": 10,
"maxSessionSpendUsd": "2.00",
"preventDuplicateLoops": true
}
}
]
}
• Cloud Production (Public Domain): When publishing to the global edge gateway (https://mcpaid.dev) via npx @mcpaid/sdk publish or the Web Dashboard, Cloudflare edge isolates must be able to route requests to your server. Your upstreamUrl must be an externally reachable public URL (e.g. https://api.yourcompany.com/mcp or https://app.railway.app/sse). Private/loopback addresses (localhost, 127.0.0.1, 10.x.x.x, 192.168.x.x) are blocked by Cloudflare SSRF protection.
• Local Hardware (Zero Cloud Deploy): If your MCP server is running locally on your computer at http://127.0.0.1:3000/mcp, you do not need a public domain or cloud hosting! Simply run npx @mcpaid/sdk dev. The CLI establishes an encrypted edge tunnel from Cloudflare to your local hardware port automatically.
• Local Offline Gateway: If running a local proxy directly on your machine with npx @mcpaid/sdk start --port 8080, local addresses like http://localhost:3000/mcp work directly because both the proxy and your server share the local network interface.
$ npx @mcpaid/sdk validate ✅ Configuration valid! - Server ID: financial-intel-mcp - Upstream Target: https://mcp.yourcompany.com/mcp - Payout Wallet: 0xYourBaseL2WalletAddressHere - Tools Configured: 3 (1 free, 2 paid)
# Choice A: Local hardware tunnel (for localhost:3000 MCP servers) $ npx @mcpaid/sdk dev # Choice B: Global edge deployment (for cloud-hosted MCP servers) $ npx @mcpaid/sdk publish # Choice C: Local offline proxy daemon $ npx @mcpaid/sdk start mcpaid.config.json --port 8080
# 2.4 Option 3: Native TypeScript / Node.js Server SDK
If you are developing a new MCP server in Node.js, Express, Hono, or Cloudflare Workers, you can embed MCPaid directly as middleware.
import { McpaidServer } from '@mcpaid/sdk'; import express from 'express'; const app = express(); app.use(express.json()); // Initialize MCPaid Server Engine const mcpaid = new McpaidServer({ serverId: 'custom-analytics-mcp', payoutWallet: '0xYourBaseL2WalletAddress', network: 'base', tools: { 'fast_ping': { type: 'free' }, 'deep_audit': { priceUsd: '0.05' } } }); // Intercept MCP JSON-RPC Endpoint app.post('/mcp', async (req, res) => { const result = await mcpaid.handleRequest(req.body, { headers: req.headers }); res.status(result.statusCode).json(result.body); }); app.listen(3000, () => console.log('Server listening on port 3000'));
# 2.5 Option 4: Cloudflare Edge Web Dashboard (mcpaid.dev/dashboard)
Prefer a browser UI? The MCPaid Developer Web Dashboard is served directly from Cloudflare V8 edge isolates with zero cold starts, real-time D1 database replication, and an interactive command interface.
Authenticate with zero passwords or seed phrases. Enter your developer email and verify with a 6-digit confirmation or login OTP.
Check "Remember this terminal" for a 30-day sliding session with secure HttpOnly cookies that auto-refresh upon activity.
Register, configure, and monitor MCP servers and tool catalogs across Cloudflare's global edge spanning 310+ cities.
Enter your developer email at /dashboard. An email with a 6-digit code will be dispatched instantly via Cloudflare's edge mail pipeline. Leave Remember this terminal checked to maintain a 30-day session across browser restarts.
Click [ EDIT ] next to your payout wallet address in the dashboard header. Enter any standard Base EVM address (0x... from Coinbase, MetaMask, Rabby, or hardware wallet). All 97% net earnings from your monetized tools accrue to this wallet — request a withdrawal (minimum $1.00) to receive them on-chain.
Click >_ Publish MCP Server to open the Dynamic Multi-Tool Pricing Builder. Provide a unique Server ID, your public upstream URL, and add as many tools as you want (Fixed Price ($) or Free). Upon saving, your server is immediately active at https://mcpaid.dev/mcp/:serverId.
To decommission an MCP server, click the red >_ Disconnect Server button on the server card. Confirmed removal purges the edge reverse proxy, deletes all tool pricing rules, and frees the Server ID cleanly.
Click >_ Withdraw to Base L2 to cash out your available USDC. The edge locks your balance and queues the ticket. Within 60 seconds, the automated network relayer executes the native ERC-20 transfer on Base L2, transitioning status to SETTLED with a direct, clickable BaseScan transaction link.
#
2.6 Option 5: Zero-Config Live Development Tunnel (npx @mcpaid/sdk dev)
Have an MCP server running locally on your hardware (http://127.0.0.1:3000/mcp) that has not yet been deployed to a public cloud VPS?
With MCPaid's built-in Zero-Config Live Development Tunnel, you don't need to rent cloud servers or purchase domain names to monetize your tools.
Incoming agent calls hit mcpaid.dev/mcp/:id. MCPaid enforces the x402 payment challenge, verifies signatures, and settles USDC on Base L2.
Once payment is verified, the call is securely dispatched through an encrypted Cloudflare Tunnel (TLS 1.3 / QUIC) directly to your local hardware.
The local MCPaid Security Shield ensures incoming traffic strictly originates from the MCPaid Edge Gateway. Any direct unmonetized calls to the tunnel are dropped with 403 Forbidden.
Ensure your local MCP server is running (e.g. on port 3000), then execute:
$ npx @mcpaid/sdk dev ============================================================ ⚡ MCPaid Live Development Tunnel (Connected & Protected) ============================================================ • Local MCP Target: http://127.0.0.1:3000/mcp • Edge Gateway URL: https://mcpaid.dev/mcp/dummy-mcp • Cloudflare Tunnel: https://swift-whale-tunnel.trycloudflare.com [TLS 1.3 Encrypted] • Security Shield: ACTIVE (Direct tunnel bypasses blocked) • Payout Wallet: 0x16D365427B4958579adC3593C4C6E8C0aD6EB759 (Base L2) • Monitored Tools (2): • health_ping -> FREE • get_market_intel -> $0.01 USDC / call 📋 Agent / Client Connection: npx @mcpaid/sdk bridge --gateway https://mcpaid.dev/mcp/dummy-mcp Ready! Agents can now invoke monetized tools. Press Ctrl+C to stop. ============================================================ ⚡ [CALL #1] get_market_intel | Agent: 0x16D365... | Status: 200 (38ms) ⚡ [CALL #2] get_market_intel | Agent: 0x892a41... | Status: 200 (42ms)
- No Direct Bypass: The built-in Security Shield verifies that every incoming tool invocation bears the cryptographic MCPaid Edge Gateway signature. Anyone who discovers your temporary tunnel URL cannot bypass 402 payment challenges.
- End-to-End Encryption: Traffic between Cloudflare's global edge and your machine is wrapped in TLS 1.3 over QUIC.
- Zero Port Forwarding: Outbound connection only—no open router ports, public IP addresses, or firewall changes required.
- No Hosting Costs: Because your computer provides the execution compute, MCPaid incurs zero container costs, keeping the platform fee at a flat 3% on earnings with no recurring subscription fees.
# 2.7 Simulating & Testing HTTP 402 with cURL
You can test that your monetization gate is active by sending an unauthenticated tool invocation using standard curl:
curl -i -X POST https://mcpaid.dev/mcp/dummy-mcp -H "Content-Type: application/json" -d '{
"jsonrpc": "2.0",
"id": 100,
"method": "tools/call",
"params": {
"name": "analyze_sentiment",
"arguments": { "text": "Base L2 is fast and cheap!" }
}
}'
HTTP/1.1 402 Payment Required
Content-Type: application/json
X-ToolPay-Status: 402_CHALLENGE_ISSUED
X-Payment-Amount: 0.0100
X-Payment-Currency: USDC
X-Payment-Network: base
X-Payment-Nonce: nonce_8a12f6...
{
"jsonrpc": "2.0",
"id": 100,
"error": {
"code": 402,
"message": "Payment Required: Tool "analyze_sentiment" costs 0.0100 USDC on Base.",
"data": {
"priceUsd": "0.0100",
"currency": "USDC",
"network": "base",
"challengeNonce": "nonce_8a12f6...",
"developerCut": "$0.0097 (97%)",
"instructions": {
"summary": "Tool is monetized. Set AGENT_PRIVATE_KEY to authorize gasless payments.",
"steps": [
"Fund agent EVM address with USDC on Base.",
"Run via npx @mcpaid/sdk bridge or pass private key in harness."
]
}
}
}
}
# 2.8 Earnings, Settlements & Withdrawals
Payments are calculated atomically on every request:
Tools with freemium.freeCallsPerDay grant their free quota
only to wallets holding a $1.00+ MCPaid session balance
(key ownership was proven when the stake was deposited). Unfunded or unidentified callers skip
the free tier and go straight to 402 payment. Quota is consumed atomically in D1, so
"X free calls per day" holds globally across edge isolates.
Withdrawing Earnings to Base L2
When autonomous agents call your paid tools via EIP-712 permits or session wallets, earnings accrue to your developer balance in real time. Once you reach the $1.00 minimum withdrawal, withdraw to your verified Base EVM wallet via the Web Dashboard or CLI. Every withdrawal deducts a flat Base L2 network fee (default ~$0.02) from your payout — you receive gross minus gas on-chain, and the retained fee offsets the ETH gas the relayer fronts:
Navigate to mcpaid.dev/dashboard and click >_ Withdraw to Base L2. Your balance is atomically locked, registered in D1, and queued for the next 60-second settlement batch.
Withdraw directly from your terminal or script:
$ npx @mcpaid/sdk withdrawals
MCPaid uses a high-throughput hybrid architecture: micro-calls are authorized instantly and gaslessly off-chain via EIP-712 permits, while payouts are settled on-chain via an automated 60-second cron relayer:
When requested (minimum $1.00), the edge locks your gross balance, retains the flat Base L2 network fee (~$0.02), and registers a withdrawal ticket for the net amount in D1. The dashboard displays QUEUED FOR BATCH.
Every minute, Cloudflare Workers' isolated cron scheduler invokes the relayer. The relayer broadcasts native ERC-20 transfers for the net amount on Base L2 directly to your payout wallet.
Upon block confirmation, the status updates to SETTLED and stamps the verified BaseScan transaction hash directly into your history.
npx @mcpaid/sdk relayer --run
Edge Receipts: Downstream Payment Enforcement
# The Multi-Hop Trust Boundary Problem
When an AI agent calls a monetized tool, MCPaid's edge reverse proxy challenges the agent with HTTP 402, verifies the EIP-712 permit, and credits your ledger. But in real-world applications, your upstream MCP server often triggers state changes on downstream systems: committing a database write (e.g. Cloudflare D1, PostgreSQL, DynamoDB), enqueueing background compute jobs, or calling paid third-party APIs.
That downstream hop is a separate trust domain. A rogue user could fork the client or bypass the edge gateway entirely to hit your internal backend directly. Checking static headers like X-MCPaid-Gateway: true is not enough because static secrets can leak or be extracted from binaries.
Edge Receipts provide end-to-end cryptographic enforcement. When a paid call settles, the edge mints a tamper-proof HMAC-SHA256 receipt bound to the settled challenge nonce, server ID, tool name, and price, and injects it as X-MCPaid-Receipt. Your downstream backend verifies it in 5 lines of code.
[ Autonomous AI Agent ]
│
│ 1. POST /mcp/:serverId (JSON-RPC tools/call)
▼
[ MCPaid Edge Gateway (mcpaid.dev) ]
│
│ 2. HTTP 402 Challenge (Price: 0.01 USDC, Nonce, EIP-712 Domain)
▼
[ AI Agent Pays ]
│
│ 3. Signs gasless EIP-712 permit off-chain & replays request
▼
[ MCPaid Edge Gateway ]
│
│ 4. Settles micropayment on Base L2 ledger (97% Dev / 3% Platform)
│ 5. Mints HMAC-SHA256 Edge Receipt (canonical JSON, exp: now + 300s)
│ 6. Injects X-MCPaid-Receipt: <base64url> and proxies upstream
▼
[ Developer Upstream MCP Server ]
│
│ 7. Forwards X-MCPaid-Receipt header to internal microservice/backend
▼
[ Downstream Backend / Database Worker ]
│
│ 8. Verifies HMAC-SHA256 signature in 5 lines
│ 9. Atomically claims challengeNonce in NonceClaimStore (anti-replay)
▼
[ Executes state change, commits DB transaction, returns response ]
# Edge Receipt Payload Schema (v1)
Receipts are serialized to canonical JSON (recursively sorted keys without whitespace) and signed using HMAC-SHA256 with your server-scoped secret:
{
"v": 1, // Receipt protocol version
"serverId": "stock-oracle", // Unique server identifier
"toolName": "get_quote", // Specific authorized tool
"challengeNonce": "rcpt_...",// Settled 402 challenge nonce (single-use)
"amountMicro": "10000", // Settled amount (10000 = 0.01 USDC)
"recipient": "0x16d3...", // Developer payout address
"treasury": "0x49e9...", // Platform treasury address
"feeBps": 300, // Protocol fee (3.00%)
"chainId": 8453, // EVM Chain ID (8453 = Base Mainnet)
"settledAt": 1758120000, // Settlement epoch timestamp (seconds)
"exp": 1758120300, // Expiry epoch timestamp (default: +300s)
"agentWallet": "0x9876...", // Paying agent's wallet address
"sig": "b2f5c9e4..." // 64-char HMAC-SHA256 signature hex
}
# Retrieving & Rotating Receipt Secrets via CLI
Secrets are deterministically derived per server using HKDF-SHA256 from the edge master secret. When rotated, the edge supports zero-downtime rollover by honoring the previous secret for a 1-hour grace window:
# Display the receipt secret for your server $ npx @mcpaid/sdk server receipt-secret <serverId> # Rotate secret (previous secret remains valid for 1-hour grace window) $ npx @mcpaid/sdk server receipt-secret <serverId> --rotate # Automatically append or update MCPAID_RECEIPT_SECRET in your local .env $ npx @mcpaid/sdk server receipt-secret <serverId> --env
# Downstream Verification Snippets
import { verifyEdgeReceipt, D1ReceiptStore } from '@mcpaid/sdk';
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// 5-line payment verification & atomic anti-replay
const err = await verifyEdgeReceipt(
{
secret: env.MCPAID_RECEIPT_SECRET,
previousSecret: env.MCPAID_PREVIOUS_RECEIPT_SECRET, // 1-hr grace key
store: new D1ReceiptStore(env.DB), // Atomic SQLite claim
},
{
receipt: request.headers.get('X-MCPaid-Receipt'),
expectedTool: 'cloud_sync_push',
expectedServer: 'my-server-id',
maxAgeSeconds: 300,
}
);
if (err) {
return new Response(JSON.stringify({ error: 'payment_required', message: err }), {
status: 402,
headers: { 'Content-Type': 'application/json' },
});
}
// Safely execute downstream database write or heavy job
return new Response(JSON.stringify({ status: 'committed' }), { status: 200 });
},
};
import express from 'express';
import { createReceiptMiddleware, MemoryReceiptStore } from '@mcpaid/sdk';
const app = express();
app.use(express.json());
// Protect downstream route in 5 lines
app.post(
'/api/v1/heavy-compute',
createReceiptMiddleware({
secret: process.env.MCPAID_RECEIPT_SECRET!,
expectedTool: 'heavy_compute',
expectedServer: 'my-server-id',
store: new MemoryReceiptStore(), // Prevents replay attacks
}),
(req: any, res) => {
// req.mcpaidReceipt contains verified settlement metadata
const { amountMicro, agentWallet } = req.mcpaidReceipt;
res.json({ success: true, payer: agentWallet, microPaid: amountMicro });
}
);
app.listen(3000);
import base64, hashlib, hmac, json, os, time
from fastapi import FastAPI, Header, HTTPException
app = FastAPI()
SECRET = os.environ.get("MCPAID_RECEIPT_SECRET", "")
claimed_nonces = set()
def verify_mcpaid_receipt(receipt_header: str, expected_tool: str) -> dict:
if not receipt_header:
raise HTTPException(status_code=402, detail="Missing X-MCPaid-Receipt header")
# Base64url decode with padding
padded = receipt_header + "=" * ((4 - len(receipt_header) % 4) % 4)
receipt = json.loads(base64.urlsafe_b64decode(padded.encode()).decode("utf-8"))
if receipt.get("v") != 1 or receipt.get("toolName") != expected_tool:
raise HTTPException(status_code=402, detail="Invalid receipt tool or version")
if time.time() > receipt.get("exp", 0) + 60:
raise HTTPException(status_code=402, detail="Receipt expired")
# Recompute HMAC-SHA256 signature on canonical JSON (sorted keys without 'sig')
sig = receipt.pop("sig", None)
canonical = json.dumps(receipt, sort_keys=True, separators=(",", ":"))
computed = hmac.new(SECRET.encode(), canonical.encode(), hashlib.sha256).hexdigest()
if not hmac.compare_digest(sig, computed):
raise HTTPException(status_code=402, detail="Cryptographic signature mismatch")
nonce = receipt.get("challengeNonce")
if nonce in claimed_nonces:
raise HTTPException(status_code=402, detail="Receipt replay attack detected")
claimed_nonces.add(nonce)
return receipt
@app.post("/v1/db-commit")
def commit_action(x_mcpaid_receipt: str = Header(None)):
verified = verify_mcpaid_receipt(x_mcpaid_receipt, expected_tool="db_commit")
return {"status": "ok", "paid_micro": verified["amountMicro"], "payer": verified.get("agentWallet")}
3. For Users & AI Agents: Calling Monetized Tools
If an MCP tool requires a payment (e.g. $0.01 / query), you don't have to manually approve every single request. By setting up an autonomous agent wallet with a spend ceiling, your agent signs permits off-chain and executes tools seamlessly.
# 3.1 Step 1: Generate an Agent Wallet
Run our CLI command with the --agent flag to generate a dedicated EVM keypair for your AI agent — add --save to write it straight to .env:
$ npx @mcpaid/sdk wallet new --agent --save ====================================================== 🔑 New MCPaid Agent Wallet Generated ====================================================== • Role: Autonomous Agent (Spending Keypair) • Public Address: 0x9B1671fBcf648aB361BFFb9bC92A76c2A0c9c7e3 • Private Key: 0x8f2d5a9... (ALSO SAVED TO ./.env) ====================================================== 💡 Next Steps: 1. .env now holds AGENT_ADDRESS + AGENT_PRIVATE_KEY — every command below picks the key up automatically (override with --key 0x... when needed). 2. Fund this address with Base USDC (e.g. $1.00 - $5.00).
Creates a spending keypair. Save the private key into your agent's environment (AGENT_PRIVATE_KEY) to sign EIP-712 permits for 402 challenges.
Generates a receiving wallet for developers. Only the public address is needed to receive 97% cuts from monetized MCP servers.
Never put your primary personal wallet's private key into an AI agent environment.
Generate a separate, throwaway wallet using npx @mcpaid/sdk wallet new --agent --save and only fund it with the small amount of USDC you want the agent to spend (e.g. $2.00 - $5.00).
# 3.2 Step 2: Fund the Agent with USDC on Base L2
Depending on whether you are running in testnet or production, fund the agent's public address:
Get 100% free test USDC to test your agents without spending real money:
Deposit $1 - $5 USDC to power hundreds of live tool executions:
Per-call permits work fine, but each 402 round-trip costs a turn. Instead, deposit once into a
session wallet: one on-chain USDC transfer to the MCPaid treasury
(minimum $1.00), verified by the edge and credited in full to your
session. Every spend after that is a gasless signed deduction — no per-call permits, no ETH needed.
Sessions expire after 24h by default (--ttl up to 30d), deduct
atomically, and refund automatically if the upstream call fails. The 3% protocol cut is split per
paid call, never taken at deposit.
$ npx @mcpaid/sdk deposit 2.00
# → transfers $2.00 USDC to the treasury, edge verifies it,
# → prints your session id + balance. Then spend it from the SDK:
# new ToolPayClientAgent({ sessionId: 'sess_...' }) with AGENT_PRIVATE_KEY set.
The deposit transfer itself needs a little ETH for gas (~$0.01, one time). Top up later with
--session-id sess_.... Permit deposits are rejected by policy —
a signature moves no funds, so sessions only credit verified on-chain transfers.
# 3.3 Connecting Claude Desktop (Stdio Bridge)
Claude Desktop communicates with MCP tools via standard I/O (stdio).
The mcpaid bridge translates Claude's local stdio calls to the remote HTTPS edge gateway and automatically handles 402 signing.
{
"mcpServers": {
"paid-stock-intel": {
"command": "npx",
"args": [
"@mcpaid/sdk",
"bridge",
"--gateway",
"https://mcpaid.dev/mcp/dummy-mcp"
],
"env": {
"AGENT_PRIVATE_KEY": "0xYourAgentPrivateKeyGeneratedInStep1",
"AGENT_MAX_PRICE_USD": "0.50"
}
}
}
}
Restart Claude Desktop. The paid tools appear in Claude's tool picker with an icon.
When Claude uses a tool, the bridge intercepts the 402 challenge, verifies the price is under $0.50, signs an EIP-712 permit voucher, and returns the result.
Claude never sees an error!
# 3.4 Cursor, Windsurf & Antigravity IDE Setup
To connect AI coding environments (Cursor, Windsurf, Google Antigravity) to paid remote tools:
- Navigate to your IDE's Settings > Features > MCP.
- Click Add New MCP Server.
- Set Type to
command. - Set Command:
npx @mcpaid/sdk bridge --gateway https://mcpaid.dev/mcp/<serverId> - Add Environment Variables:
•
AGENT_PRIVATE_KEY=0x...•AGENT_MAX_PRICE_USD=0.25
# 3.5 Autonomous Python Agent (LangChain / CrewAI / AutoGPT)
Building a custom agent in Python? Here is the complete code to autonomously handle HTTP 402 challenges using eth_account and requests:
import os, json, requests from eth_account import Account from eth_account.messages import encode_typed_data # 1. Load agent key & define spend budget agent_account = Account.from_key(os.environ["AGENT_PRIVATE_KEY"]) MAX_ALLOWABLE_PRICE_USD = 0.50 GATEWAY_URL = "https://mcpaid.dev/mcp/financial-intel-mcp" tool_payload = { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "get_quote", "arguments": { "symbol": "NVDA" } } } # 2. Call tool (expecting 402 if paid) resp = requests.post(GATEWAY_URL, json=tool_payload) if resp.status_code == 402: challenge = resp.json()["error"]["data"] price_usd = float(challenge["priceUsd"]) nonce = challenge["challengeNonce"] # 3. Guardrail: Enforce spend limit if price_usd > MAX_ALLOWABLE_PRICE_USD: raise PermissionError(f"Tool price ${price_usd} exceeds ceiling") # 4. Sign EIP-712 Permit Voucher domain = challenge["domain"] types = challenge["types"] message = challenge["message"] signable = encode_typed_data(domain, types, message) signed = agent_account.sign_message(signable) # 5. Replay with voucher in Authorization header voucher = { "scheme": "eip-712-permit", "challengeNonce": nonce, "signerWallet": agent_account.address, "signature": signed.signature.hex() } headers = { "Authorization": f"Bearer {json.dumps(voucher)}" } resp = requests.post(GATEWAY_URL, json=tool_payload, headers=headers) print("Tool Output:", resp.json()["result"])
# 3.6 Programmatic TypeScript Client SDK
import { ToolPayClientAgent } from '@mcpaid/sdk'; const agent = new ToolPayClientAgent({ privateKey: process.env.AGENT_PRIVATE_KEY as `0x${string}`, spendPolicy: { autoApprove: true, maxPricePerCallUsd: '0.10', maxSessionSpendUsd: '5.00' } }); const response = await agent.executeToolCall({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name: 'get_quote', arguments: { symbol: 'AAPL' } } }, async (req, proof) => { return fetch('https://mcpaid.dev/mcp/stock-mcp', { method: 'POST', headers: { 'Authorization': `Bearer ${JSON.stringify(proof)}` }, body: JSON.stringify(req) }); });
# 3.7 Safety Guardrails, Nonces & Replay Protection
MCPaid implements military-grade cryptographic safeguards to protect agents and developers:
Every 402 challenge generates a cryptographically random 32-byte nonce that expires after 5 minutes and is permanently invalidated upon first use.
Permits are cryptographically bound to the specific serverId, toolName, and amount. A voucher signed for a $0.01 tool cannot be intercepted to pay for a $5.00 tool.
4. Practical Cookbooks & Real-World Examples
Sample MCP Server: Reverse Proxy & Exposing Beyond Localhost
Step-by-step recipe: Build a minimal test MCP server from scratch, wrap it with the MCPaid reverse proxy, and securely expose it to the public internet using a Cloudflare Tunnel so any remote agent in the world can call and pay for it.
test-mcp-server.js)
Create a simple script using standard Node.js that implements standard Model Context Protocol JSON-RPC.
It provides one free tool (health_ping) and one paid tool (code_analyzer):
import { createServer } from 'node:http'; const server = createServer((req, res) => { if (req.method !== 'POST') { res.writeHead(405).end('Method Not Allowed'); return; } let body = ''; req.on('data', chunk => { body += chunk; }); req.on('end', () => { const rpc = JSON.parse(body); // 1. Handle tools/list if (rpc.method === 'tools/list') { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ jsonrpc: '2.0', id: rpc.id, result: { tools: [ { name: 'health_ping', description: 'Free server latency and health check' }, { name: 'code_analyzer', description: 'Deep security and syntax audit ($0.02 / call)' } ] } })); return; } // 2. Handle tools/call if (rpc.method === 'tools/call') { const toolName = rpc.params?.name; let toolResult = {}; if (toolName === 'health_ping') { toolResult = { status: 'ok', timestamp: Date.now() }; } else if (toolName === 'code_analyzer') { const codeSnippet = rpc.params?.arguments?.code || ''; toolResult = { auditPassed: true, linesAudited: codeSnippet.split('\n').length, vulnerabilitiesFound: 0, summary: 'Code analysis complete: Zero critical vulnerabilities.' }; } res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ jsonrpc: '2.0', id: rpc.id, result: toolResult })); return; } }); }); server.listen(3000, () => { console.log('✅ Upstream Test MCP Server running on http://127.0.0.1:3000/mcp'); });
Start the upstream server in your terminal: node test-mcp-server.js
mcpaid.config.json)
{
"version": "1.0",
"server": {
"id": "my-code-auditor-mcp",
"name": "Production Code Auditor MCP",
"upstreamUrl": "http://127.0.0.1:3000/mcp",
"payoutWallet": "0xYourBaseL2PayoutAddress",
"network": "base",
"currency": "USDC",
"platformFeeBps": 300
},
"tools": [
{
"name": "health_ping",
"type": "free",
"description": "Free latency check"
},
{
"name": "code_analyzer",
"type": "fixed",
"priceUsd": "0.02",
"description": "Deep security & syntax audit ($0.02 / call)",
"circuitBreaker": {
"maxCallsPerMinute": 30,
"maxSessionSpendUsd": "5.00",
"preventDuplicateLoops": true
}
}
]
}
$ npx @mcpaid/sdk start mcpaid.config.json --port 8080 🚀 MCPaid Gateway running on http://localhost:8080 • Monitored Server: my-code-auditor-mcp • Upstream Target: http://127.0.0.1:3000/mcp • Payout Wallet: 0xYourBaseL2PayoutAddress • Platform Cut: 3% (Developer Net: 97%)
To allow remote agents (like Claude Desktop on a colleague's laptop or an autonomous agent on AWS) to call your MCP tool, you need a secure public HTTPS endpoint. Here are the 3 best options:
Cloudflare Tunnel connects your local port 8080 directly to Cloudflare's global edge without opening any router ports or port forwarding.
# Install cloudflared (macOS) brew install cloudflared # Run instant zero-config tunnel pointing to MCPaid proxy: cloudflared tunnel --url http://localhost:8080
Tip: If you own a domain on Cloudflare, you can bind it permanently: cloudflared tunnel route dns my-tunnel mcp.mycompany.com
ngrok http 8080 # Forwarding -> https://a48b-71-218-12-3.ngrok-free.app
# Dockerfile FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 8080 CMD ["sh", "-c", "node test-mcp-server.js & npx @mcpaid/sdk start mcpaid.config.json --port 8080"]
From any laptop or server in the world, test the public tunnel URL using curl:
curl -i -X POST https://swift-whale-tunnel.trycloudflare.com -H "Content-Type: application/json" -d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "code_analyzer",
"arguments": { "code": "function run() { return 42; }" }
}
}'
< HTTP/1.1 402 Payment Required (Challenge issued from your public tunnel to the remote caller!)
Now give your public tunnel URL to your users or agents. In their claude_desktop_config.json:
{
"mcpServers": {
"public-code-auditor": {
"command": "npx",
"args": [
"@mcpaid/sdk",
"bridge",
"--gateway",
"https://swift-whale-tunnel.trycloudflare.com"
],
"env": {
"AGENT_PRIVATE_KEY": "0xRemoteUserAgentPrivateKey...",
"AGENT_MAX_PRICE_USD": "0.10"
}
}
}
}
Earnings accrue per call — nothing is auto-pushed. Once your balance reaches the $1.00 minimum, request a payout. The 1-minute relayer settles the net amount (gross minus a ~$0.02 Base L2 network fee you pay via deduction) to your payout wallet:
$ npx @mcpaid/sdk withdraw $ npx @mcpaid/sdk withdrawals # watch QUEUED → SETTLED + BaseScan receipt
Monetizing a Python FastMCP Server
How to monetize a native Python MCP server built with the official mcp package and FastMCP.
from mcp.server.fastmcp import FastMCP mcp = FastMCP("QuantAnalytics") # Free health ping @mcp.tool() def health_ping() -> str: return "pong" # Monetized Tool ($0.05 / execution) @mcp.tool() def generate_quant_forecast(ticker: str, horizon_days: int = 30) -> dict: """Proprietary quantitative pricing model""" return { "ticker": ticker, "horizon_days": horizon_days, "expected_sharpe": 2.14, "target_price": 184.50, "confidence_interval": [178.20, 191.00] } if __name__ == "__main__": # Run with standard SSE or Stream transport mcp.run(transport="sse", port=8000)
In your mcpaid.config.json, simply set "upstreamUrl": "http://127.0.0.1:8000/sse"
and assign "priceUsd": "0.05" to generate_quant_forecast.
LangChain / CrewAI Swarm with Spending Caps & Nonce Signing
How to integrate monetized MCP tools into multi-agent loops with automated budget tracking and session ceilings.
import os, json, requests from eth_account import Account from eth_account.messages import encode_typed_data class PaidMcpToolWrapper: def __init__(self, gateway_url: str, private_key: str, max_budget_usd: float = 5.00): self.gateway_url = gateway_url self.account = Account.from_key(private_key) self.max_budget = max_budget_usd self.cumulative_spent = 0.0 def call_tool(self, tool_name: str, arguments: dict) -> dict: payload = { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": tool_name, "arguments": arguments } } # 1. Initial attempt res = requests.post(self.gateway_url, json=payload) if res.status_code == 200: return res.json()["result"] # 2. Handle HTTP 402 if res.status_code == 402: data = res.json()["error"]["data"] price = float(data["priceUsd"]) if self.cumulative_spent + price > self.max_budget: raise RuntimeError(f"Budget exhausted! Cumulative: ${self.cumulative_spent:.2f}") # 3. Sign EIP-712 Permit Voucher signable = encode_typed_data(data["domain"], data["types"], data["message"]) sig = self.account.sign_message(signable).signature.hex() # 4. Replay with voucher in Authorization header voucher = { "scheme": "eip-712-permit", "challengeNonce": data["challengeNonce"], "signerWallet": self.account.address, "signature": sig } auth_res = requests.post( self.gateway_url, json=payload, headers={ "Authorization": f"Bearer {json.dumps(voucher)}" } ) self.cumulative_spent += price return auth_res.json()["result"] raise RuntimeError(f"Tool call failed with status: {res.status_code}")
Deploying Monetized MCP Directly on Cloudflare Workers (No Localhost)
Want to avoid running a local computer, VPS, or tunnel altogether? Deploy your MCP tool logic directly on Cloudflare Workers edge using the MCPaid engine with sub-5ms cold starts across 310+ cities. Running a full production edge clone (own Worker + D1 + router) requires an operator agreement — see OPERATOR-LICENSE.md. EIP-712 vouchers are bound to the official router (0x406240a9af02596a20ef9779aa214143c794ecee); official clients warn on non-official routers.
import { McpaidServer } from '@mcpaid/sdk'; export default { async fetch(request: Request, env: any): Promise<Response> { if (request.method !== 'POST') { return new Response('MCP Edge Endpoint', { status: 200 }); } const mcpaid = new McpaidServer({ serverId: 'global-crypto-oracle', payoutWallet: env.DEVELOPER_BASE_WALLET, network: 'base', tools: { 'get_oracle_price': { priceUsd: '0.01' } } }); const rpcReq = await request.json(); const res = await mcpaid.handleRequest(rpcReq, { headers: Object.fromEntries(request.headers.entries()) }); return new Response(JSON.stringify(res.body), { status: res.statusCode, headers: { 'Content-Type': 'application/json' } }); } };
5. Technical Specifications & Reference
# 5.1 Base L2 Network & Settlement Contracts
| NETWORK | CHAIN ID | USDC TOKEN CONTRACT | TOOLPAY ROUTER CONTRACT |
|---|---|---|---|
| Base Mainnet | 8453 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | Deployed via Factory |
| Base Sepolia | 84532 | 0x036CbD53842c5426634e7929541eC2318f3dCF7e | 0x406240a9af02596a20ef9779aa214143c794ecee |
#
5.2 CLI Command Manual (mcpaid)
| COMMAND | ARGUMENTS & FLAGS | DESCRIPTION |
|---|---|---|
| mcpaid init | — | Scaffolds a sample mcpaid.config.json in the working directory. |
| mcpaid validate | [config-path] | Validates JSON syntax, schema rules, and upstream URL reachability. |
| mcpaid start | [config] [--port <num>] | Launches local embedded gateway on your own machine (your fees/ops — not the hosted edge). |
| mcpaid dev | [config-path] [--gateway <url>] | Launches zero-config encrypted Cloudflare tunnel with local Security Shield to monetize localhost MCP servers. |
| mcpaid tunnel | [port] | Spawns a zero-config Cloudflare tunnel forwarding to a local port (default: 3000). |
| mcpaid bridge | --gateway <url> [--key <k>] [--max-price <$>] | Pipes local stdio from Claude Desktop or IDEs to remote gateway with auto-signing. (agent-proxy --url alias also works.) |
| mcpaid publish | [config-path] [--gateway <url>] [--tunnel] | Publishes and monetizes an MCP server on MCPaid Edge Gateway directly from terminal. |
| mcpaid server list | — | Lists all MCP servers, upstream URLs, and tool pricing registered under your account. |
| mcpaid server remove | <server-id> [--force] | Disconnects and permanently removes an MCP server and its tool pricing from MCPaid. |
| mcpaid server receipt-secret | <server-id> [--rotate] [--env] | Retrieves or rotates the HMAC-SHA256 Edge Receipt secret for backend payment verification. |
| mcpaid login | [--email <addr>] [--code <otp>] | Signs into your developer account with 2FA OTP and persists credentials in ~/.mcpaid. |
| mcpaid whoami | — | Displays authenticated developer profile, email verification status, and default payout wallet. |
| mcpaid logout | — | Revokes session and deletes local credential tokens. |
| mcpaid withdraw | [amount] | Requests an on-chain withdrawal of accrued USDC earnings (minimum $1.00; you receive gross minus a ~$0.02 network fee). |
| mcpaid withdrawals | — | Lists all withdrawal requests, live batch processing statuses, and confirmed BaseScan receipts. |
| mcpaid relayer | [--run] | Inspects automated 1-minute cron relayer status or runs a manual operator settlement cycle. |
| mcpaid wallet new | [--developer | --agent] [--save] | Generates a fresh EVM keypair with tailored guidance for Developer Payouts or Agent Spending. --save writes address + key to ./.env. |
| mcpaid wallet status | — | Inspects currently configured environment wallet and network links. |
| mcpaid deposit | <amount-usd> [--key <k>] [--network base|base-sepolia] [--session-id <id>] [--ttl <s>] | Transfers USDC to the treasury on-chain (min $1.00) and credits a gasless session wallet. Key auto-loads from .env. Top up with --session-id. |
# 5.3 mcpaid.config.json Specification & Schema
The reverse proxy and local gateway read configuration from mcpaid.config.json in the project root.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "MCPaidConfig",
"type": "object",
"required": ["serverId", "payoutWallet", "tools"],
"properties": {
"serverId": {
"type": "string",
"description": "Unique URL-safe identifier for your MCP server (e.g. 'stock-intel')"
},
"name": {
"type": "string",
"description": "Human-readable name for dashboard and discovery listings"
},
"upstreamUrl": {
"type": "string",
"format": "uri",
"description": "Internal HTTP or SSE URL where your raw MCP server is listening"
},
"payoutWallet": {
"type": "string",
"pattern": "^0x[a-fA-F0-9]{40}$",
"description": "Base EVM address receiving 97% USDC payouts (e.g. 0xYourWallet)"
},
"tools": {
"type": "array",
"items": {
"type": "object",
"required": ["toolName", "type"],
"properties": {
"toolName": { "type": "string" },
"type": { "type": "string", "enum": ["free", "paid"] },
"priceUsd": { "type": "string", "pattern": "^[0-9]+(\.[0-9]{1,4})?$" },
"description": { "type": "string" }
}
}
},
"platformFee": {
"type": "object",
"properties": {
"platformFeeBasisPoints": { "type": "number", "default": 300 },
"platformTreasuryWallet": { "type": "string" }
}
}
}
}
# 5.4 HTTP 402 Challenge & Payment Response Schema
When an agent requests a monetized tool without valid payment authorization, the gateway halts execution and issues an RFC 9110 compliant 402 challenge.
{
"status": 402,
"headers": {
"X-ToolPay-Status": "402_CHALLENGE_ISSUED",
"X-Payment-Amount": "0.0100",
"X-Payment-Currency": "USDC",
"X-Payment-Network": "base",
"X-Payment-Nonce": "0x7f19b2c8..."
},
"body": {
"jsonrpc": "2.0",
"id": 100,
"error": {
"code": 402,
"message": "Payment Required: Tool "analyze_sentiment" costs 0.0100 USDC on Base.",
"data": {
"priceUsd": "0.0100",
"currency": "USDC",
"network": "base",
"chainId": 8453,
"tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"challengeNonce": "0x7f19b2c8...",
"developerCut": "$0.0097 (97%)",
"instructions": {
"summary": "Tool is monetized. Sign EIP-712 permit voucher with agent key.",
"steps": [
"Sign permit off-chain for amount 0.0100 USDC and nonce 0x7f19b2c8...",
"Attach voucher in Authorization: Bearer <voucher> or X-Payment-Proof header",
"Re-issue tools/call POST request"
]
}
}
}
}
}
# 5.5 Gateway HTTP & RPC Status Codes
| STATUS CODE | CONDITION | ACTION REQUIRED |
|---|---|---|
| 200 OK | Tool call authorized and executed successfully. | Consume JSON-RPC result in res.body.result. |
| 402 Payment Required | Unauthenticated or insufficient permit proof provided. | Parse nonce & price, sign EIP-712 permit voucher, and replay with Authorization header. |
| 403 Forbidden | Invalid cryptographic signature, expired nonce, or tool mismatch. | Request fresh challenge nonce and re-sign with correct agent private key. |
| 404 Not Found | Server ID not registered or tool name does not exist. | Verify server slug and tool name registered in config or dashboard. |
| 405 Method Not Allowed | Request method was not POST (MCP tools requires JSON-RPC POST). | Switch client HTTP method to POST with Content-Type: application/json. |
| 413 Payload Too Large | Request body exceeds the 2MB isolate limit. | Trim arguments or compress large embedded text/binary context. |
| 429 Rate Limit | Per-IP rate limits exceeded (anti-abuse throttle). | Back off request frequency using exponential retry. |
| 503 Circuit Breaker | Upstream MCP server is unreachable, crashing, or timed out. | Check upstream health and connectivity. Gateway auto-resets when upstream recovers. |
# 5.6 Edge REST Endpoints: Deposits & Withdrawals
Money movement outside JSON-RPC uses two REST endpoints. Amounts are integer micro-USDC strings.
// Request: the txHash must be a CONFIRMED on-chain USDC transfer
// to the treasury (0x49E9…bad on Base) from agentWallet, ≥ $1.00.
// Permit signatures are rejected here — only funded transfers credit.
POST https://mcpaid.dev/v1/sessions/deposit
{
"agentWallet": "0xAgent...",
"amountMicro": "2000000",
"txHash": "0xDepositTx...",
"sessionId": "sess_... (optional: top up instead of opening)",
"ttlSeconds": 86400
}
// → 200 { success, sessionId, agentWallet, balanceMicro,
// totalDepositedMicro, totalSpentMicro, expiresAt }
// → 400 below-minimum / already-claimed / permit-scheme
// → 402 transfer verification failed (wrong recipient, token, or amount)
// Policy env: MIN_SESSION_DEPOSIT_MICRO (default 1000000 = $1.00)
// Auth: developer session cookie. Gross is locked from your balance;
// the ticket settles the NET (gross − ~$0.02 network fee) on Base L2.
POST https://mcpaid.dev/v1/developer/withdraw
{ "developerWallet": "0xPayout...", "amountMicro": 5000000 } // amount optional = full balance
// → 200 { success, withdrawal: { id, amountMicro (net), gasFeeMicro,
// status: 'processing', ... },
// message: "… You receive $X net after a $Y network fee …" }
// → 400 balance or request below the $1.00 minimum
// Ticket lifecycle: processing → settling (relayer lease) → completed (+txHash)
// or failed. The 1-minute cron only settles tickets you create.
// Policy env: MIN_WITHDRAWAL_MICRO (default 1000000 = $1.00),
// WITHDRAWAL_GAS_FEE_MICRO (default 20000 = ~$0.02)
Support & Business Inquiries
We provide direct communication channels for developers integrating Model Context Protocol servers, agent framework builders, security researchers, and enterprise partners.
Troubleshooting MCP server proxies, local tunnels (mcpaid dev), Claude Desktop stdio bridge, Base L2 USDC settlements, or reporting bugs.
High-throughput agent clusters, custom gateway RPC endpoints, enterprise revenue settlement agreements, ecosystem integrations, and media inquiries.