MCPay
MCPay sits between an AI agent and an MCP server. The agent receives a short-lived spend token tied to one server, a fixed action list, exact prices, a budget, an expiry time, and a nonce range. The gateway verifies that policy, atomically claims the nonce, calls the upstream tool, then records successfully delivered 2xx usage in a durable outbox.
No subscription per tool. No creator API key inside the agent. No floating-point money.
Beta status: the repository runs a closed, no-real-money beta. Wallet top-ups are test ledger credits; Stripe deposits, creator payouts, KYC/AML, disputes, and tax workflows aren't included yet.
The agent creates a spend session backed by a reserved wallet balance.
MCPay signs the exact server, action prices, budget, expiry, and nonce range.
The gateway verifies the token and claims the nonce in PostgreSQL before dispatch.
A delivered
2xxresponse enters the local bbolt outbox and settles asynchronously.
The repository includes a Go API, gateway, settlement worker, PostgreSQL migrations, a creator dashboard, JavaScript and Python SDKs, browser tests, and a Docker Compose beta stack. Real deposits and payouts remain intentionally disabled.
Product tour
The control plane shows reserved agent budget, creator revenue, paid-call volume, local authorization latency, and recent settlement activity.
Screenshots use a fixed documentation dataset. The figures aren't production metrics.
Related MCP server: MCP Gateway
Why MCPay exists
An agent that calls ten paid tools shouldn't need ten subscriptions, ten billing SDKs, and ten long-lived secrets. A creator shouldn't have to write reservation logic, replay protection, price checks, receipt storage, and settlement workers before charging five cents for web_search.
MCPay makes the spend contract explicit before execution:
Policy | Bound into each spend session |
Where the money can go | One |
What the agent can call | An allowlist of action names |
What each call costs | Immutable |
Maximum exposure | Reserved budget and maximum price per call |
Replay boundary | Nonce start/end range with a distributed atomic claim |
Lifetime | Signed expiry timestamp and online revocation check |
If the claim doesn't match the active session, the gateway stops before the upstream sees the request.
How it compares
MCPay | API keys plus custom billing | Central billing proxy | Per-tool subscriptions | |
Agent gets a bounded spend grant | Yes | You build it | Sometimes | No |
Exact price signed into the session | Yes | You build it | Provider-specific | No |
Cross-gateway replay protection | PostgreSQL atomic claim | Usually missing | Depends on provider | Not applicable |
Tool handler owns payment code | No | Yes | Partly | Yes |
Delivered | bbolt outbox | You build it | Provider-owned | Provider-owned |
Self-hosted control plane | Yes | Yes | Usually no | No |
One wallet across creators | Designed for it | No common contract | Platform-specific | No |
Source can be audited | Yes | Your code only | Usually no | Usually no |
Checkout is the easy part. MCPay handles bounded authorization, duplicate suppression across hosts, immutable prices, revocation ordering, durable delivery of accepted usage, and retry-safe settlement.
Request path
sequenceDiagram
participant A as Agent
participant C as MCPay API
participant G as MCPay Gateway
participant P as PostgreSQL
participant T as MCP Tool
participant W as Settlement Worker
A->>C: Create spend session
C->>P: Reserve budget and store price snapshot
C-->>A: Ed25519-signed spend token
A->>G: tools/call + token + nonce
G->>G: Verify issuer, server, action, price, expiry
G->>P: Atomic nonce claim
P-->>G: Active and unique
G->>P: Mark nonce dispatched
G->>T: Execute tool
T-->>G: Result
G-->>A: Result
G->>G: Persist delivered 2xx usage in bbolt outbox
G->>C: Upload usage batch
C->>P: Insert idempotent usage record
W->>P: Settle creator creditThe control-plane call happens before dispatch because offline-only replay protection can't coordinate two gateway machines or stop a revoked session. Signature checks still happen locally, so malformed or out-of-scope tokens never reach the database claim.
Security model
MCPay doesn't call a signed JWT "encrypted." It isn't. Spend tokens carry readable claims and use Ed25519 signatures so a gateway can detect any modification without holding the signing key.
Boundary | What MCPay does |
Spend tokens | Ed25519 signatures; the API keeps the private key, gateways receive only the public key |
Browser authentication |
|
Password storage | bcrypt hashes, never plaintext passwords |
Invite codes and session tokens | SHA-256 hashes stored in PostgreSQL |
Gateway credentials | HMAC-SHA-256 signed, versioned, and scoped to one server |
Public transport | HTTPS required outside explicit local-development mode |
Internal Docker traffic | Private CA and TLS between Caddy and the API |
Money state | Integer minor units, append-only ledger events, serializable transactions, deterministic idempotency keys |
Replay control | Two-phase PostgreSQL nonce claim with a short pre-dispatch lease, then a non-reusable dispatched state |
Usage delivery | Delivered |
HTTP forwarding | Redirects blocked, hop-by-hop headers removed, forwarding headers stripped, request size and time limits applied |
Agent token injection | HTTPS plus an explicit gateway-origin allowlist; spend headers aren't added to arbitrary URLs |
What encryption at rest means here
MCPay doesn't add application-level field encryption to ledger rows. PostgreSQL credentials, signing keys, gateway secrets, and backups belong in your secret manager and encrypted storage; managed PostgreSQL or encrypted host volumes should protect database files at rest. That distinction matters because claiming "everything is encrypted" would hide the actual trust boundary.
For a beta deployment, keep PostgreSQL and the worker on a private network, terminate public TLS at Caddy, mount secrets at runtime, back up before migrations, and never commit deploy/.env.beta.
Run it locally
Requirements: Docker Engine with Compose v2, Go 1.25+ for key generation, and 4 GB of available memory. Node.js 24 runs inside the dashboard build container.
cp deploy/.env.beta.example deploy/.env.beta
go run ./cmd/mcpay-keygenPaste the generated Ed25519 values into deploy/.env.beta, replace every replace-* value, then start the stack:
docker compose --env-file deploy/.env.beta -f deploy/compose.beta.yml config
docker compose --env-file deploy/.env.beta -f deploy/compose.beta.yml build
docker compose --env-file deploy/.env.beta -f deploy/compose.beta.yml up -d
docker compose --env-file deploy/.env.beta -f deploy/compose.beta.yml psOpen http://localhost:8080. The compose stack starts PostgreSQL, migrations, API, worker, dashboard, Caddy, and internal TLS. Test top-ups remain virtual credits.
Check the running stack:
MCPAY_BETA_URL=http://localhost:8080 ./scripts/verify-central-beta.shPowerShell:
./scripts/verify-central-beta.ps1 -BaseUrl http://localhost:8080Deployment notes, backups, DNS, and the Vercel/Supabase option live in docs/central-beta-runbook.md and docs/beta-deployment.md.
Connect an MCP server
Create a server and action in Creator Studio, issue its server-scoped gateway credential, then run the gateway from the repository beside the MCP process:
go run ./cmd/mcpay-gateway \
--target https://your-mcp-server.example \
--mcp-path /mcp \
--server-id srv_example \
--environment beta \
--token-issuer mcpay.beta \
--public-key "$MCPAY_PUBLIC_KEY" \
--control-plane-api https://api.example/v1/gateway/servers/srv_example \
--nonce-claim-api https://api.example/v1/gateway/nonces/claim \
--usage-api https://api.example/v1/usage-records \
--usage-api-token "$MCPAY_GATEWAY_API_TOKEN" \
--state-file ./mcpay-gateway.dbPaid requests carry two headers:
Authorization: Bearer <spend-token>
X-MCPay-Nonce: <nonce-within-the-signed-range>The gateway removes both headers before forwarding the request upstream.
Connect an agent
MCPayAgentClient creates short-lived sessions and injects payment headers only into allowlisted HTTPS gateway origins:
import {
FileAgentSessionCreationStore,
MCPayAgentClient,
} from "@mcpay/sdk-js";
const paid = new MCPayAgentClient({
apiBaseUrl: "https://pay.example.com/api/mcpay",
accessToken: process.env.MCPAY_ACCESS_TOKEN!,
walletId: process.env.MCPAY_WALLET_ID!,
serverId: process.env.MCPAY_SERVER_ID!,
reservedBudget: 50,
gatewayOrigins: ["https://tools.example.com"],
sessionCreationStore: new FileAgentSessionCreationStore(
"./mcpay-agent-sessions.json",
),
});
const response = await paid.fetch("https://tools.example.com/mcp", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "tools/call",
params: {
name: "web_search",
arguments: { query: "payment rails for MCP" },
},
}),
});Initialization and tool discovery pass through without spend headers. Session creation uses an idempotency key, so a lost response doesn't reserve the budget twice.
Direct SDK wrappers
JavaScript and Python wrappers exist for development and private integrations. Production mode rejects volatile usage; the durable gateway remains the recommended deployment path because it keeps nonce and usage state across process restarts.
import { MCPayClient } from "@mcpay/sdk-js";
const mcpay = new MCPayClient({
publicKey: process.env.MCPAY_PUBLIC_KEY!,
issuer: process.env.MCPAY_TOKEN_ISSUER!,
serverId: process.env.MCPAY_SERVER_ID!,
environment: "development",
allowVolatileUsage: true,
});
export const paidSearch = mcpay.tool({
name: "web_search",
priceMinor: 5,
handler: async (query: string) => search(query),
});import os
from mcpay import MCPayClient
mcpay = MCPayClient(
public_key=os.environ["MCPAY_PUBLIC_KEY"],
issuer=os.environ["MCPAY_TOKEN_ISSUER"],
server_id=os.environ["MCPAY_SERVER_ID"],
environment="development",
allow_volatile_usage=True,
)
@mcpay.tool(name="web_search", price_minor=5)
async def search(query: str):
return await run_search(query)Verification
The main branch checks Go, PostgreSQL integration, migrations, both SDKs, browser tests, package builds, dependency audits, and the Docker Compose configuration.
go test ./...
go test -race ./...
go vet ./...
go build ./cmd/...
npm ci
npm audit --audit-level=high
npm run build
npm run test
python -m pip install build
python -m build packages/sdk-python
python -m unittest discover -s packages/sdk-python/testsFor PostgreSQL tests, point MCPAY_TEST_DATABASE_URL at a disposable migrated database. The tests truncate application tables; never use a production database.
Run the loopback authorization benchmark with:
go run ./cmd/mcpay-benchmark --samples 1000 --warmup 100It reports raw, local SDK, and gateway p50/p95/p99 on your machine. The benchmark excludes session setup, central ledger writes, and asynchronous usage upload, so it isn't a production SLA.
What ships today
Available in the beta | Still required before real-money launch |
Invite-only accounts and virtual USD wallets | Stripe or bank deposit integration |
Server/action catalog with immutable price snapshots | Creator payouts and payout reconciliation |
Signed spend sessions and online revocation | KYC/AML, sanctions, disputes, and tax handling |
Distributed nonce claims across gateway hosts | Signing-key rotation with |
Durable outbox for successfully delivered | Production monitoring, paging, backup drills, and incident runbooks |
Creator receipts, analytics, and test top-ups | Legal review for every launch jurisdiction |
MCPay is ready for a controlled beta with test credits. It isn't ready to hold customer funds.
Repository map
Path | Purpose |
| HTTP control-plane handlers and authentication |
| Creator and agent-budget dashboard |
| Durable Go API process |
| Paid MCP and HTTP reverse proxy |
| Settlement, retry, reconciliation, and expiry loop |
| PostgreSQL money and usage transactions |
| Authorization proxy and bbolt state |
| Spend claims and Ed25519 token code |
| Agent client and JavaScript paid-tool wrapper |
| Python async paid-tool wrapper |
| Ordered PostgreSQL schema changes |
License
MCPay uses the Business Source License 1.1. BSL isn't an OSI-approved open-source license, but it gives everyone access to the source and permits copying, modification, redistribution, and non-production use.
The MCPay Additional Use Grant permits internal production use when the user or organization has no more than $100,000 USD in aggregate gross revenue during the previous 12 months. It doesn't permit a hosted, managed, embedded, or white-label MCPay service for third parties. Production use outside that grant needs a commercial license; open an issue in the official repository to request commercial terms.
On August 13, 2030, this version changes to the Apache License 2.0. BSL also applies its open-source Change License on the fourth anniversary of a version's first public BSL distribution if that date arrives earlier.
Read LICENSE for the binding terms. The dashboard is distributed separately under the MIT license in apps/dashboard/LICENSE, including attribution for its upstream author and MCPay modifications. Have counsel review the BSL parameters before a real-money launch or fundraising diligence.
Security research is welcome. Source access makes review possible; it doesn't prove the absence of vulnerabilities, and BSL supplies the software without a security warranty.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP Gateway: wrap any MCP server with cold-start retries, uptime SLA, and per-execution MPP billing.
Hosted MCP server for LLM cost estimation, model comparison, and budget-aware routing.
- nexusOAuth
Zero-setup MCP gateway securely connecting AI to your tools with authentication and workflows
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
Related MCP Servers
- FlicenseCqualityDmaintenanceA powerful gateway for the Model Context Protocol (MCP) that unifies AI toolchains by federating multiple MCP servers, wrapping REST APIs as MCP tools, and supporting multiple transport methods with an admin dashboard.1
- AlicenseNot gradedqualityDmaintenanceA production-ready unified entry point for AI agents that implements the Model Context Protocol (MCP). It provides a secure gateway with rate limiting, authentication, and observability for managing and proxying requests to multiple downstream APIs.MIT
- AlicenseAqualityBmaintenanceSecurity, cost, and health governance proxy for MCP infrastructure. Enforces YAML-configurable security policies (blocklists, rate limits, token budgets), tracks real token costs via tiktoken, monitors server health with live JSON-RPC probes. Features OAuth 2.1/OIDC with RBAC, web dashboard, payload normalization, semantic shell AST analysis, mTLS, and a formal STRIDE threat model.41933MIT
- FlicenseNot gradedqualityBmaintenanceBridges stdio Model Context Protocol (MCP) servers to MCP Streamable HTTP behind a single gateway, enabling multi-tenant, multi-user deployment with per-tenant environment variables via HTTP headers.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/yiaany/MCPay'
If you have feedback or need assistance with the MCP directory API, please join our Discord server