Skip to main content
Glama

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.

  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.

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

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

1Releases (12mo)
Commit activity

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.

View all MCP Connectors

Related MCP Servers

  • F
    license
    C
    quality
    D
    maintenance
    A 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
  • A
    license
    Not graded
    quality
    D
    maintenance
    A 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
  • A
    license
    A
    quality
    B
    maintenance
    Security, 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.
    4
    193
    3
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Bridges 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.

View all related MCP servers

Latest Blog Posts

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