MCPay

MCPay

High-performance Go gateway and reverse proxy for Model Context Protocol servers with rate-limiting, authorization, and pay-per-result metering.

Category
访问服务器

README

<p align="center"> <img src="docs/assets/mcpay-mark.svg" alt="MCPay" width="132" height="132"> </p>

<h1 align="center">MCPay</h1>

<p align="center"> <strong>Stripe for AI agents.</strong> The spend authorization layer for paid AI tools.<br> Give agents a hard budget. Charge per execution. Keep payment code out of the tool handler. </p>

<p align="center"> <a href="https://github.com/yiaany/MCPay/actions/workflows/ci.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/yiaany/MCPay/ci.yml?branch=main&style=flat-square&label=CI"></a> <img alt="Go 1.25+" src="https://img.shields.io/badge/Go-1.25%2B-00ADD8?style=flat-square&logo=go&logoColor=white"> <img alt="Node.js 24+" src="https://img.shields.io/badge/Node.js-24%2B-5FA04E?style=flat-square&logo=nodedotjs&logoColor=white"> <img alt="Python 3.11+" src="https://img.shields.io/badge/Python-3.11%2B-3776AB?style=flat-square&logo=python&logoColor=white"> <img alt="PostgreSQL 16+" src="https://img.shields.io/badge/PostgreSQL-16%2B-4169E1?style=flat-square&logo=postgresql&logoColor=white"> <a href="https://github.com/yiaany/MCPay/releases/tag/v0.1.0-beta.1"><img alt="MCPay beta release" src="https://img.shields.io/badge/release-v0.1.0--beta.1-B7FF64?style=flat-square&labelColor=111827"></a> <a href="#license"><img alt="Business Source License 1.1" src="https://img.shields.io/badge/license-BSL%201.1-111827?style=flat-square"></a> </p>

<p align="center"> <a href="#run-it-locally"><strong>Run the beta</strong></a>  ·  <a href="#request-path"><strong>See the protocol</strong></a>  ·  <a href="#security-model"><strong>Inspect security</strong></a>  ·  <a href="#connect-an-mcp-server"><strong>Connect a tool</strong></a> </p>

<p align="center"> <code>signed spend sessions</code>   <code>atomic nonce claims</code>   <code>immutable prices</code>   <code>durable settlement</code> </p>

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.

<details> <summary><strong>What happens on one paid call?</strong></summary>

  1. The agent creates a spend session backed by a reserved wallet balance.
  2. MCPay signs the exact server, action prices, budget, expiry, and nonce range.
  3. The gateway verifies the token and claims the nonce in PostgreSQL before dispatch.
  4. A delivered 2xx response enters the local bbolt outbox and settles asynchronously.

</details>

<details> <summary><strong>What can I run today?</strong></summary>

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.

</details>

Product tour

<p align="center"> <img src="docs/assets/control-plane.png" alt="MCPay control plane in dark mode" width="100%"> </p>

The control plane shows reserved agent budget, creator revenue, paid-call volume, local authorization latency, and recent settlement activity.

<table> <tr> <td width="50%"><img src="docs/assets/creator-studio.png" alt="MCPay Creator Studio in dark mode"></td> <td width="50%"><img src="docs/assets/settled-ledger.png" alt="MCPay settled ledger in dark mode"></td> </tr> <tr> <td><strong>Creator Studio</strong><br>Map each MCP action to an integer price and copy a configured gateway command.</td> <td><strong>Settled Ledger</strong><br>Trace every accepted call by receipt, nonce, action, price, status, and measured authorization time.</td> </tr> </table>

Screenshots use a fixed documentation dataset. The figures aren't production metrics.

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 server_id and environment
What the agent can call An allowlist of action names
What each call costs Immutable action -> price_minor snapshots
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 2xx usage survives gateway restart 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 credit

The 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 HttpOnly, SameSite=Strict cookie; Secure is set on HTTPS requests
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 2xx calls enter a bounded bbolt outbox with at-least-once upload, idempotent ingestion, and idempotent settlement
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-keygen

Paste 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 ps

Open 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.sh

PowerShell:

./scripts/verify-central-beta.ps1 -BaseUrl http://localhost:8080

Deployment 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.db

Paid 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/tests

For 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 100

It 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 kid rollout procedures
Durable outbox for successfully delivered 2xx usage and retry-safe settlement 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
apps/api HTTP control-plane handlers and authentication
apps/dashboard Creator and agent-budget dashboard
cmd/mcpay-api Durable Go API process
cmd/mcpay-gateway Paid MCP and HTTP reverse proxy
cmd/mcpay-worker Settlement, retry, reconciliation, and expiry loop
internal/controlplane PostgreSQL money and usage transactions
internal/gateway Authorization proxy and bbolt state
internal/sessions Spend claims and Ed25519 token code
packages/sdk-js Agent client and JavaScript paid-tool wrapper
packages/sdk-python Python async paid-tool wrapper
migrations 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.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选