{"slug": "show-hn-mcpay-spend-authorization-and-per-call-billing-for-mcp-tools", "title": "Show HN: MCPay – spend authorization and per-call billing for MCP tools", "summary": "MCPay, a payment layer for AI agents and paid MCP tools, is now in beta with test credits only, as announced on Hacker News. The system provides bounded agent budgets, per-call charging, and settlement for tool creators, but does not handle real funds, Stripe deposits, bank transfers, creator payouts, KYC/AML, sanctions screening, disputes, refunds, tax handling, or regulated custody. The beta includes a Go API, gateway, settlement worker, PostgreSQL migrations, a dashboard, JavaScript and Python SDKs, and a Docker Compose stack, with future work planned for key management, monitoring, backup recovery, reconciliation, incident response, and security review.", "body_md": "**Stripe for AI agents and paid MCP tools.**\n\nMCPay is building a Stripe-like payment layer for MCP: bounded agent budgets, per-call charging, and settlement for tool creators.\n\nMCPay is building a shared payment layer where AI agents receive explicit spending limits, paid MCP calls carry verifiable spend authority, and tool creators can price usage and receive settlement through one integration.\n\nThe goal is to give agents one payment interface across paid MCP tools while regulated payment providers handle deposits, custody, payouts, refunds, and other real-money operations.\n\n**Status as of August 31, 2026: test credits only. No real funds are accepted, held, transferred, or paid out.** Test top-ups create repository-local ledger entries with no cash value. Stripe deposits, bank transfers, creator payouts, KYC/AML, sanctions screening, disputes, refunds, tax handling, and regulated custody are not implemented.\n\nThe repository currently contains:\n\n- a Go API, gateway, settlement worker, and PostgreSQL migrations;\n- a dashboard for beta accounts, wallets, servers, actions, receipts, and test credits;\n- JavaScript and Python SDK source for repository-local development;\n- a Docker Compose stack and integration tests.\n\nThe beta is for controlled development and failure testing. It is not ready to hold customer funds or support financial commitments. See [Known Limitations](/yiaany/MCPay/blob/main/KNOWN_LIMITATIONS.md).\n\nFuture work is expected to include automated key management, operational monitoring, tested backup recovery, reconciliation tooling, incident response, and external security review. Real-money integrations would additionally require legal, compliance, custody, payout, dispute, refund, and tax work. None of those items should be inferred from the current ledger or UI.\n\n| Area | Design goal | Current status |\n|---|---|---|\n| Spend scope | Bind server, environment, actions, prices, budget, expiry, and nonce range into a signed grant | Implemented for the beta; tokens are signed, not encrypted |\n| Replay control | Coordinate claims across gateway instances | PostgreSQL claim state is implemented; this does not provide exactly-once tool delivery |\n| Price stability | Use the price snapshot authorized for the session | Implemented with integer minor units |\n| Usage durability | Retain accepted chargeable usage until upload is acknowledged | A persistent bbolt gateway state file is supported and tested across restart after durable preparation |\n| Settlement | Make repeated usage ingestion and settlement safe to retry | Idempotency is implemented and tested for covered paths; exactly-once charging is not claimed |\n| Money movement | Accept deposits and pay creators | Not implemented; test credits have no real-world value |\n| SDK distribution | Install SDKs from public registries | Not available; npm and PyPI packages are unpublished |\n\n```\nsequenceDiagram\n    participant A as Agent\n    participant C as MCPay API\n    participant G as MCPay Gateway\n    participant P as PostgreSQL\n    participant T as MCP Tool\n    participant W as Settlement Worker\n\n    A->>C: Create spend session\n    C->>P: Reserve test-credit budget and store price snapshot\n    C-->>A: Signed spend token\n    A->>G: tools/call + token + nonce\n    G->>G: Verify signed policy\n    G->>P: Claim nonce and logical call\n    G->>T: Dispatch tool request\n    T-->>G: Return successful result\n    G->>G: Durable PrepareUsage acceptance\n    G-->>A: Attempt response delivery\n    G->>G: Queue prepared usage\n    G->>C: Upload usage batch\n    C->>P: Insert idempotent usage record\n    W->>P: Settle test-credit ledger entries\n```\n\nThe gateway marks a call dispatched before contacting the upstream tool. If the process or network fails after dispatch, the upstream may have executed while the caller receives an error, and the nonce remains unavailable for replay. For a chargeable success, durable `PrepareUsage`\n\nacceptance happens before downstream delivery and is the beta billing boundary. A crash after preparation may therefore settle even when response delivery is partial or uncertain. MCPay does not claim exactly-once delivery or exactly-once charging.\n\nThe beta rejects metered `2xx text/event-stream`\n\nresponses before forwarding upstream success headers or body bytes and creates no usage for them, avoiding indefinite paid SSE buffering. Unmetered MCP traffic can still stream SSE through the gateway.\n\nSpend tokens contain readable claims protected by Ed25519 signatures. They are not encrypted. The API holds the active signing private key; gateways receive a public verification keyring and select keys by the protected JWT `kid`\n\nheader.\n\nThe beta also uses:\n\n`HttpOnly`\n\n,`SameSite=Strict`\n\nbrowser cookies;- bcrypt password hashes;\n- hashed invite and session tokens in PostgreSQL;\n- server-scoped, versioned gateway credentials;\n- HTTPS outside explicit local-development mode;\n- integer minor units and database transactions;\n- redirect blocking, header stripping, and request size/time limits in the gateway.\n\nDatabase rows are not application-level encrypted. Protect PostgreSQL storage, backups, signing keys, gateway secrets, and deployment environment files with operator-controlled encryption and access controls.\n\nRead [Security Policy](/yiaany/MCPay/blob/main/SECURITY.md) and [Threat Model](/yiaany/MCPay/blob/main/docs/threat-model.md) before exposing a deployment.\n\nRequirements: Docker Engine with Compose v2, Go 1.25+, and 4 GB of available memory.\n\n```\ncp deploy/.env.beta.example deploy/.env.beta\ngo run ./cmd/mcpay-keygen --key-id beta-2026-08\n```\n\nPut the generated keys in `deploy/.env.beta`\n\n, replace every `replace-*`\n\nvalue, and start the stack:\n\n```\ndocker compose --env-file deploy/.env.beta -f deploy/compose.beta.yml config\ndocker compose --env-file deploy/.env.beta -f deploy/compose.beta.yml build\ndocker compose --env-file deploy/.env.beta -f deploy/compose.beta.yml up -d\ndocker compose --env-file deploy/.env.beta -f deploy/compose.beta.yml ps\n```\n\nOpen `http://localhost:8080`\n\n. Any top-up is a test credit with no cash value.\n\nVerify the stack:\n\n```\nMCPAY_BETA_URL=http://localhost:8080 ./scripts/verify-central-beta.sh\n./scripts/verify-central-beta.ps1 -BaseUrl http://localhost:8080\n```\n\nSee [Central Beta Runbook](/yiaany/MCPay/blob/main/docs/central-beta-runbook.md), [Deployment](/yiaany/MCPay/blob/main/docs/beta-deployment.md), and [Backup/Restore Drill](/yiaany/MCPay/blob/main/docs/backup-restore-drill.md).\n\nCreate a server and action in the dashboard, issue a server-scoped gateway credential, and run the gateway beside the MCP server. Use persistent local storage for `--state-file`\n\nand do not share one state file between processes.\n\n```\ngo run ./cmd/mcpay-gateway \\\n  --target https://your-mcp-server.example \\\n  --mcp-path /mcp \\\n  --server-id srv_example \\\n  --environment beta \\\n  --token-issuer mcpay.beta \\\n  --control-plane-api https://api.example/v1/gateway/servers/srv_example \\\n  --nonce-claim-api https://api.example/v1/gateway/nonces/claim \\\n  --usage-api https://api.example/v1/usage-records \\\n  --usage-api-token \"$MCPAY_GATEWAY_API_TOKEN\" \\\n  --state-file ./mcpay-gateway.db\n```\n\nPaid requests carry `Authorization: Bearer <spend-token>`\n\nand `X-MCPay-Nonce: <nonce>`\n\n. The gateway removes both headers before forwarding upstream.\n\nThe control-plane gateway configuration supplies `verification_keys`\n\n. For a standalone gateway without `--control-plane-api`\n\n, pass `--verification-keys \"$MCPAY_VERIFICATION_KEYS\"`\n\n.\n\nThe JavaScript and Python SDKs are **not published to npm or PyPI as of August 31, 2026**. Install them from this repository only.\n\n```\nnpm install\nnpm run build --workspace=@mcpay/sdk-js\n```\n\nWorkspace code can then import `@mcpay/sdk-js`\n\n. For use from another local Node project, install the repository path after building:\n\n```\nnpm install ../MCPay/packages/sdk-js\n```\n\nInstall the Python SDK in editable mode from the repository root:\n\n```\npython -m pip install -e ./packages/sdk-python\n```\n\nSee [JavaScript SDK](/yiaany/MCPay/blob/main/packages/sdk-js/README.md) and [Python SDK](/yiaany/MCPay/blob/main/packages/sdk-python/README.md). Direct SDK wrappers use volatile process state in development; the persistent gateway is the supported beta path for crash recovery.\n\n```\ngo test ./...\ngo test -race ./...\ngo vet ./...\ngo build ./cmd/...\nnpm ci\nnpm run build\nnpm run test\npython -m pip install build\npython -m build packages/sdk-python\npython -m unittest discover -s packages/sdk-python/tests\n```\n\nPostgreSQL tests require a disposable migrated database in `MCPAY_TEST_DATABASE_URL`\n\n. They truncate application tables; never point them at retained data.\n\n| Path | Purpose |\n|---|---|\n`apps/api` |\nHTTP control-plane handlers and authentication |\n`apps/dashboard` |\nBeta dashboard |\n`cmd/mcpay-api` |\nAPI process |\n`cmd/mcpay-gateway` |\nMCP and HTTP authorization proxy |\n`cmd/mcpay-worker` |\nSettlement, retry, reconciliation, and expiry loop |\n`internal/controlplane` |\nPostgreSQL ledger and usage transactions |\n`internal/gateway` |\nAuthorization proxy and persistent gateway state |\n`internal/sessions` |\nSpend claims and Ed25519 token code |\n`packages/sdk-js` |\nJavaScript SDK source |\n`packages/sdk-python` |\nPython SDK source |\n`migrations` |\nOrdered PostgreSQL schema changes through `000010` |\n\nMCPay uses the Business Source License 1.1. It is source-available but not OSI-approved open source. The Additional Use Grant and change date are defined in [LICENSE](/yiaany/MCPay/blob/main/LICENSE). The dashboard has a separate MIT license and upstream attribution in [apps/dashboard/LICENSE](/yiaany/MCPay/blob/main/apps/dashboard/LICENSE).", "url": "https://wpnews.pro/news/show-hn-mcpay-spend-authorization-and-per-call-billing-for-mcp-tools", "canonical_source": "https://github.com/yiaany/MCPay", "published_at": "2026-09-02 17:37:35+00:00", "updated_at": "2026-09-02 17:52:53.887901+00:00", "lang": "en", "topics": ["ai-infrastructure", "ai-agents", "developer-tools"], "entities": ["MCPay", "Stripe", "Hacker News", "Go", "PostgreSQL", "Docker Compose"], "alternates": {"html": "https://wpnews.pro/news/show-hn-mcpay-spend-authorization-and-per-call-billing-for-mcp-tools", "markdown": "https://wpnews.pro/news/show-hn-mcpay-spend-authorization-and-per-call-billing-for-mcp-tools.md", "text": "https://wpnews.pro/news/show-hn-mcpay-spend-authorization-and-per-call-billing-for-mcp-tools.txt", "jsonld": "https://wpnews.pro/news/show-hn-mcpay-spend-authorization-and-per-call-billing-for-mcp-tools.jsonld"}}