paygate-mcp
v10.24.0
Published
Pay-per-tool-call gating proxy for MCP servers. Wrap any MCP server with API key auth, per-tool pricing, rate limiting, and usage metering.
Maintainers
Readme
paygate-mcp
Monetize any MCP server with one command. Add API key auth, per-tool pricing, rate limiting, and usage metering to any Model Context Protocol server. Zero dependencies. Zero config. Zero code changes.
Table of Contents
- Quick Start
- What It Does
- Usage — Local stdio, remote HTTP, multi-server, client SDK
- API Reference — All 199+ endpoints
- CLI Options
- Deployment — Docker, docker-compose, systemd, PM2
- Load Testing — k6 benchmarking for production
- Error Codes — Complete error code reference
- Feature Reference — Detailed docs for every feature
- Programmatic API
- Security
- Tested With — Verified against popular MCP servers
- Current Limitations
- Roadmap
- Requirements
- License
Quick Start
# Interactive setup wizard (generates paygate.json)
npx paygate-mcp init
# Or wrap directly with CLI flags
npx paygate-mcp wrap --server "npx @modelcontextprotocol/server-filesystem /tmp"
# Gate a remote MCP server (Streamable HTTP transport)
npx paygate-mcp wrap --remote-url "https://my-server.example.com/mcp" --price 5That's it. Your MCP server is now gated behind API keys with credit-based billing.
What It Does
PayGate sits between AI agents and your MCP server:
Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)- API Key Auth — Clients need a valid
X-API-Keyto call tools - Credit Billing — Each tool call costs credits (configurable per-tool)
- Rate Limiting — Sliding window per-key rate limits + per-tool rate limits
- Usage Metering — Track who called what, when, and how much they spent
- Multi-Server Mode — Wrap N MCP servers behind one PayGate with tool prefix routing
- Client SDK —
PayGateClientwith auto 402 retry, balance tracking, and typed errors - Two Transports — Wrap local servers via stdio or remote servers via Streamable HTTP
- Per-Tool ACL — Whitelist/blacklist tools per API key (enterprise access control)
- Per-Tool Rate Limits — Independent rate limits per tool, not just global
- Key Expiry (TTL) — Auto-expire API keys after a set time
- Spending Limits — Cap total spend per API key to prevent runaway costs
- Usage Quotas — Daily/monthly call and credit limits per key (with UTC auto-reset)
- Dynamic Pricing — Charge extra credits based on input size (
creditsPerKbInput) - OAuth 2.1 — Full authorization server with PKCE, client registration, Bearer tokens
- SSE Streaming — Full MCP Streamable HTTP transport (POST SSE, GET notifications, DELETE sessions)
- Audit Log — Structured audit trail with retention policies, query API, CSV/JSON export
- Registry/Discovery — Agent-discoverable pricing via
/.well-known/mcp-payment,/pricing, and/.well-known/mcp.jsonidentity card - OpenAPI 3.1 + Interactive Docs — Auto-generated spec at
/openapi.json, Swagger UI at/docs— all 199+ endpoints documented - Public Endpoint Rate Limiting — Configurable per-IP rate limit (default 300/min) on
/health,/info,/pricing,/docs,/openapi.json,/.well-known/*,/robots.txt,/— 429 with Retry-After header - Robots.txt + HEAD Support — Standard
/robots.txt(allow public, disallow admin/keys), HEAD method on all public endpoints for uptime monitoring - Prometheus Metrics —
/metricsendpoint with counters, gauges, and uptime in standard text format - Key Rotation — Rotate API keys without losing credits, ACLs, or quotas
- Rate Limit Headers —
X-RateLimit-*andX-Credits-Remainingon every/mcpresponse - Webhook Signatures — HMAC-SHA256 signed webhook payloads (
X-PayGate-Signature) for tamper-proof delivery - Admin Lifecycle Events — Webhook notifications for key.created, key.revoked, key.rotated, key.topup
- IP Allowlisting — Restrict API keys to specific IPs or CIDR ranges (IPv4)
- Key Tags/Metadata — Attach arbitrary key-value tags to API keys for external system integration
- Usage Analytics — Time-series analytics API with tool breakdown, top consumers, and trend comparison
- Alert Webhooks — Configurable alerts for spending thresholds, low credits, quota warnings, key expiry, rate limit spikes
- Team Management — Group API keys into teams with shared budgets, quotas, and usage tracking
- Horizontal Scaling (Redis) — Redis-backed state for multi-process deployments with atomic credit deduction, distributed rate limiting, persistent usage audit trail, real-time pub/sub notifications, and admin API sync
- Webhook Retry Queue — Exponential backoff retry (1s, 2s, 4s...) with dead letter queue for permanently failed deliveries, admin API for monitoring, clearing, and replaying
- Admin Dashboard v2 — Tabbed web dashboard at
/dashboardwith overview, keys management (create/suspend/resume/revoke/top-up), analytics (credit flow, deny reasons, top consumers, webhook health), and system status — all data via safe DOM methods, 30s auto-refresh - Self-Service Portal — API key holder portal at
/portal— check credits, usage, rate limits, available tools, and recent activity without admin access; includes Buy Credits UI, credit history with spending velocity, usage alerts, and self-service key rotation - Stripe Checkout — Self-service credit purchases via Stripe Checkout Sessions —
POST /stripe/checkoutcreates a session,GET /stripe/packageslists available packages; zero-dependency implementation using Node.jshttps, auto-tops-up credits via webhook - State Backup & Restore —
GET /admin/backupexports full server state (keys, teams, groups, webhooks) as versioned JSON with SHA-256 checksum;POST /admin/restoreimports with merge/overwrite/full modes and integrity verification - API Version Header —
X-PayGate-Versionheader on every HTTP response for client version tracking, exposed via CORS - Readiness Probe —
GET /readyreturns 200/503 based on operational state (not draining, not maintenance, backend connected) — separate from/healthliveness probe, ideal for Kubernetes - Health Check + Graceful Shutdown —
GET /healthpublic endpoint with status, uptime, version, in-flight requests, Redis & webhook stats;gracefulStop()drains in-flight requests before teardown - Config Validation + Dry Run —
paygate-mcp validate --config paygate.jsoncatches misconfigurations before starting;--dry-rundiscovers tools, prints pricing table, then exits - Batch Tool Calls —
tools/call_batchmethod for calling multiple tools in one request with all-or-nothing billing, aggregate credit checks, and parallel execution - Multi-Tenant Namespaces — Isolate API keys and usage data by tenant with namespace-filtered admin endpoints, analytics, and usage export
- Scoped Tokens — Issue short-lived
pgt_tokens scoped to specific tools with auto-expiry (max 24h), HMAC-SHA256 signed, zero server-side state - Token Revocation List — Revoke scoped tokens before expiry with O(1) lookup, auto-cleanup, Redis cross-instance sync, and admin API
- Usage-Based Auto-Topup — Automatically add credits when balance drops below a threshold with configurable daily limits, audit trail, webhook events, and Redis sync
- Admin API Key Management — Multiple admin keys with role-based permissions (super_admin, admin, viewer), file persistence, audit trail, and safety guards
- Plugin System — Extensible middleware hooks for custom billing logic, request/response transformation, custom endpoints, and lifecycle management
- Key Groups — Policy templates that apply shared ACL, rate limits, pricing overrides, IP allowlists, and quotas to groups of API keys with automatic inheritance and key-level override support
- Refund on Failure — Automatically refund credits when downstream tool calls fail
- Credit Transfers — Atomically transfer credits between API keys with validation, audit trail, and webhook events
- Bulk Key Operations — Execute multiple key operations (create, topup, revoke, suspend, resume) in a single request with per-operation error handling and index tracking
- Key Import/Export — Export all API keys for backup/migration (JSON or CSV) and import with conflict resolution (skip, overwrite, error modes)
- Webhook Filters — Route webhook events to different destinations based on event type and API key prefix with per-filter secrets, independent retry queues, and admin CRUD API
- Key Cloning —
POST /keys/clonecreates a new API key with the same config (ACL, quotas, tags, IP, namespace, group, spending limit, expiry, auto-topup) but fresh counters — ideal for provisioning similar keys - Key Suspension — Temporarily disable API keys without revoking them — suspended keys are denied at the gate but can be resumed, and admin operations (topup, ACL, etc.) still work on suspended keys
- Per-Key Usage —
GET /keys/usage?key=...returns detailed usage breakdown for a specific key: per-tool stats, hourly time-series, deny reasons, recent events, and key metadata - Webhook Test —
POST /webhooks/testsends a test event to your configured webhook URL with synchronous response including status code, response time, and delivery success/failure — verifies webhook connectivity without generating real events - Webhook Delivery Log —
GET /webhooks/logreturns a queryable log of all webhook delivery attempts with timestamps, HTTP status codes, response times, success/failure, retry attempts, event counts, and event types — filter by success status, time range, and limit - Webhook Pause/Resume —
POST /webhooks/pauseandPOST /webhooks/resumetemporarily halt webhook delivery during maintenance — events are buffered (not lost) and flushed on resume, with pause state visible in/webhooks/stats - Key Aliases —
POST /keys/aliasassigns human-readable aliases (e.g.my-service,prod-backend) to API keys — use aliases in any admin endpoint (topup, revoke, suspend, resume, clone, transfer, usage) instead of opaque key IDs, with uniqueness enforcement, format validation, state file persistence, and audit trail - Key Expiry Scanner — Proactive background scanner that detects expiring API keys before they expire — configurable scan interval and notification thresholds (default: 7d, 24h, 1h), de-duplicated
key.expiry_warningwebhook events, audit trail,GET /keys/expiring?within=86400query endpoint, and graceful shutdown - Key Templates — Named templates for API key creation — define reusable presets (credits, ACL, quotas, IP, tags, namespace, expiry TTL, spending limit, auto-topup) and create keys with
template: "free-tier"— explicit params override template defaults, CRUD admin API, Prometheus gauge, file persistence, max 100 templates - Environment Variables Config — Configure everything via
PAYGATE_*env vars for Docker/K8s deployments — 18 env vars covering all CLI flags, with priority: CLI flags > env vars > config file > defaults,PAYGATE_CONFIGloads config file path, help text with Docker examples - Request ID Tracking — Every HTTP response includes
X-Request-Idheader (auto-generatedreq_prefix + 16 hex chars) for distributed tracing — propagates incomingX-Request-Idfrom load balancers/proxies, included in gate audit log metadata, CORS-exposed, available viagetRequestId(req)helper - Server Info Endpoint —
GET /inforeturns server capabilities, enabled features, auth methods, pricing summary, rate limits, and available endpoints — public, no admin key required, ideal for agent auto-discovery and debugging - Configurable CORS — Control which origins can access your server: single origin, multiple origins, or wildcard (
*default), with credentials support, configurable preflight max-age, andVary: Originfor proper caching — set via config filecorsobject,--cors-originCLI flag, orPAYGATE_CORS_ORIGINenv var - Custom Response Headers — Add security headers (
X-Frame-Options,X-Content-Type-Options, etc.), cache control, or any custom headers to all HTTP responses — set via config filecustomHeadersobject,--headerCLI flag, orPAYGATE_CUSTOM_HEADERSenv var - Config Export —
GET /configreturns the running server configuration with sensitive values masked (webhook secrets →***, server commands →***, webhook URLs → scheme+host only) — admin auth required, includes audit trail - Trusted Proxies — Configure trusted proxy IPs/CIDRs for accurate
X-Forwarded-Forextraction — walks the header right-to-left, skipping trusted proxies to find the real client IP, supports exact IPs and CIDR ranges (IPv4), backward compatible (first IP) when not configured - Key Listing Pagination — Enhanced
GET /keyswith cursor-based pagination (limit/offset), sorting (sortBy/order), and filtering by namespace, group, active/suspended/expired status, name prefix, and credit range — backward compatible (returns flat array when no pagination params used) - Key Statistics —
GET /keys/statsreturns aggregate statistics across all keys — total/active/suspended/expired/revoked counts, credit aggregates (allocated/spent/remaining), total calls, namespace and group breakdowns, optional?namespace=filter - Rate Limit Status —
GET /keys/rate-limit-status?key=...returns the current rate limit window state for any key — global calls used/remaining/reset time, per-tool rate limits with individual usage, read-only (doesn't consume a call) - Quota Status —
GET /keys/quota-status?key=...returns daily/monthly quota usage for any key — calls and credits used/remaining/limits, reset periods, quota source (per-key vs global vs none) - Credit History —
GET /keys/credit-history?key=...returns per-key credit mutation log — tracks initial allocation, topups, transfers (in/out), auto-topups, with type/limit/since filters, balance-before/after on every entry, newest-first ordering, capped at 100 entries per key - Spending Velocity —
GET /keys/spending-velocity?key=...returns credit burn rate and depletion forecast — credits/calls per hour/day, estimated depletion date, top tools by spend, configurable analysis window (1h–30d) - Key Comparison —
GET /keys/compare?keys=pg_a,pg_breturns side-by-side comparison of 2–10 keys — credits, usage, velocity, rate limits, status, metadata (namespace/group/tags) — with not-found key reporting - Key Health Score —
GET /keys/health?key=...returns composite health score (0–100) with weighted component breakdown: balance health (30%), quota utilization (25%), rate limit pressure (20%), error rate (25%) — status levels (healthy/good/caution/warning/critical), key issue detection (revoked/suspended/expired/expiring/zero credits), alias support - Maintenance Mode —
POST /maintenanceenables/disables maintenance mode with custom message —/mcpreturns 503 to clients while admin endpoints stay operational,GET /maintenancechecks status,GET /healthreflects maintenance state, full audit trail - Admin Event Stream —
GET /admin/eventsSSE endpoint streams real-time audit events to admin clients — tool calls, denials, key operations, maintenance changes, all with optional?types=filter for event type filtering, keepalive pings, multi-client support - Key Notes —
POST /keys/notesadds timestamped notes to API keys,GET /keys/notes?key=...lists notes,DELETE /keys/notes?key=...&index=Nremoves notes — max 50 per key, 1000 char limit, works on suspended/revoked keys, alias support, audit trail - Scheduled Actions —
POST /keys/schedulecreates future-dated actions (revoke/suspend/topup) on API keys,GET /keys/schedulelists pending schedules with optional?key=filter,DELETE /keys/schedule?id=...cancels a schedule — max 20 per key, alias support, background execution timer, audit trail - Key Activity Timeline —
GET /keys/activity?key=...returns a unified chronological feed of audit events and usage events for a specific key — newest first, optional?since=and?limit=filters, alias support - Credit Reservations —
POST /keys/reserveholds credits,POST /keys/reserve/commitdeducts held credits,POST /keys/reserve/releasefrees the hold,GET /keys/reservelists active reservations — prevents overcommit, configurable TTL (10s–1h), max 50 per key, auto-expiry, audit trail - Request Log —
GET /requestsqueryable log of every tool call with timing, credits charged, status (allowed/denied), deny reason, key, and request ID — filter by key/tool/status/since, pagination, summary statistics (totals + avg duration), 5000-entry ring buffer - Tool Stats —
GET /tools/statsper-tool analytics: call counts, success rate, avg/p95 latency, credits consumed, deny reason breakdown, top 10 consumers — optional?tool=for detailed single-tool view,?since=filter - Request Log Export —
GET /requests/exportexports the full request log as JSON or CSV with Content-Disposition headers — filter by key/tool/status/since/until, combined time-window queries, no pagination limit - Tool Call Dry Run —
POST /requests/dry-runsimulates a tool call without executing — checks key validity, ACL, rate limits, credits, and spending limits, returns predicted outcome with credits-after calculation and rate limit status - Batch Dry Run —
POST /requests/dry-run/batchsimulates multiple tool calls at once — aggregate credit check, per-tool ACL validation, spending limit, returns per-tool results with total credits required and credits-after - Tool Availability —
GET /tools/available?key=...returns per-key tool availability with pricing, affordability (canAfford), ACL enforcement (accessible/denyReason), and per-tool + global rate limit status - Key Dashboard —
GET /keys/dashboard?key=...consolidated single-endpoint view with metadata, balance, health score, spending velocity, rate limits, quotas, usage summary, and recent activity timeline - Admin Notifications —
GET /admin/notificationsscans all keys for actionable issues: expired/expiring keys, zero credits, credit depletion velocity, suspended keys, high error rates, and rate limit pressure — with severity filtering and priority sorting - System Dashboard —
GET /admin/dashboardsystem-wide overview with key counts (active/suspended/revoked/expired), credit summary (allocated/spent/remaining), usage breakdown with deny reasons, top consumers, top tools, notification counts, and uptime - Key Lifecycle Report —
GET /admin/lifecycleaggregated lifecycle trends with daily creation/revocation/suspension buckets, average key lifetime, and at-risk keys (expiring, expired, zero credits) - Cost Analysis —
GET /admin/costscost-centric view with per-tool and per-namespace cost breakdowns, hourly spending trends, top spenders, average cost per call, and namespace filtering - Rate Limit Analysis —
GET /admin/rate-limitsrate limit utilization analysis with per-key and per-tool breakdown, denial trends, most throttled keys, and current window utilization - Quota Analysis —
GET /admin/quotasquota utilization analysis with per-key daily/monthly usage vs limits, per-tool denial breakdown, most constrained keys, and global/per-key quota source tracking - Denial Analysis —
GET /admin/denialscomprehensive denial breakdown by reason type (insufficient_credits, rate_limited, quota_exceeded, key_suspended, etc.) with per-key and per-tool stats, hourly trends, and most denied keys - Traffic Analysis —
GET /admin/trafficrequest volume analysis with tool popularity, hourly volume, top consumers by call count, namespace breakdown, peak hour identification, and success rates - Response Caching — SHA-256 keyed response cache for identical tool calls — skips backend invocation and credit deduction on cache hit, LRU eviction, per-tool or global TTL,
X-Cache: HIT/MISSheader, admin management (GET/DELETE /admin/cache), Prometheus gauge - Circuit Breaker — Three-state circuit breaker (closed → open → half_open) for backend failure detection — opens after N consecutive failures, auto-recovers after cooldown, error code
-32003, admin management (GET/POST /admin/circuit) - Configurable Timeouts — Per-tool and global timeout for tool calls — returns error code
-32004on timeout, per-tool override viatoolPricing[tool].timeoutMs, triggers circuit breaker failure recording - Outcome-Based Pricing — Charge extra credits based on response output size —
creditsPerKbOutputper-tool config, post-response billing,X-Output-Surchargeheader, complementscreditsPerKbInputfor complete size-based pricing - Compliance Audit Export — Framework-specific compliance reports for SOC 2, GDPR, HIPAA —
GET /admin/compliance/export, event classification into access control/data processing/config changes/security, JSON or CSV export, configurable time periods - Per-Key Webhook URLs — Key-level webhook routing — events for a specific key sent to key's webhook URL alongside global webhook, SSRF-protected, HMAC-SHA256 signed, lazy emitter management via
POST/GET/DELETE /keys/webhook - Security Audit —
GET /admin/securitysecurity posture analysis identifying keys without IP allowlists, quotas, ACL restrictions, spending limits, or expiry dates, flagging high-credit keys, and computing a composite security score - Revenue Analysis —
GET /admin/revenuerevenue metrics with per-tool revenue breakdown, per-key spending, hourly revenue trends, credit flow summary (allocated/spent/remaining), and average revenue per call - Key Portfolio Health —
GET /admin/key-portfolioportfolio-wide key health with active/inactive/suspended counts, stale keys, expiring-soon keys, age distribution, credit utilization, and namespace breakdown - Content Guardrails — Regex-based PII detection and redaction for tool call inputs/outputs — 8 built-in rules (credit card, SSN, email, phone, AWS key, API secret, IBAN, passport), 4 actions (log/warn/block/redact), scope filtering (input/output/both), per-tool targeting, violation tracking with query API, admin CRUD endpoints (
/admin/guardrails,/admin/guardrails/violations) - IP Country Restrictions — Per-key geographic access control with allow/deny country lists (ISO 3166-1 alpha-2) — country code from reverse-proxy headers (
X-Country,CF-IPCountry, configurable), CRUD via/keys/geo, enforced at gate evaluation, zero-dependency geo-fencing - Bulk Suspend/Resume — Added
suspendandresumeactions toPOST /keys/bulk— temporarily disable or re-activate multiple keys in one request with per-operation error handling - Concurrency Limiter — Per-key and per-tool inflight request caps — distinct from rate limiting, limits simultaneous active requests to protect backends from burst parallelism, error code
-32005withRetry-Afterheader, runtime-adjustable viaGET/POST /admin/concurrency - Traffic Mirroring — Fire-and-forget request duplication to a shadow backend for A/B testing MCP server versions — percentage-based sampling, configurable timeout, zero impact on primary response path, stats/management via
GET/POST/DELETE /admin/mirror - Tool Aliasing + Deprecation — Tool renaming with RFC 8594 compliance — map old tool names to new ones with
Deprecation,Sunset, andLinkheaders, chain prevention, per-alias call counts, CRUD viaGET/POST/DELETE /admin/tool-aliases - Usage Plans — Tiered key policies (free/pro/enterprise) — bundle rate limits, quotas, credit multipliers, and tool ACL into reusable templates, assign keys to plans via
POST /admin/keys/plan, denied tools rejected with error code-32403, CRUD viaGET/POST/DELETE /admin/plans - Tool Input Schema Validation — Per-tool JSON Schema validation at the gateway — register schemas to reject invalid payloads before they reach downstream, zero-dependency JSON Schema subset (type, required, enum, minLength, pattern, items), error code
-32602with detailed errors, manage viaGET/POST/DELETE /admin/tools/schema - Canary Routing — Weighted traffic splitting between primary and canary MCP servers — enable zero-downtime upgrades with percentage-based routing (0-100%), unbiased
crypto.randomIntdecisions, per-backend call/error tracking, weight updates without restart, manage viaGET/POST/DELETE /admin/canary - Request/Response Transforms — Declarative rewriting of tool call arguments and responses — inject defaults, strip fields, rename keys, and template
{{variables}}from context, wildcard tool matching, priority ordering, deep clone on apply, import/export for backup, manage viaGET/POST/PUT/DELETE /admin/transforms - Backend Retry Policy — Automatic retry with exponential backoff for transient failures — configurable max retries, base/max backoff, full jitter, retry budget (max % of traffic as retries with cold-start grace), per-tool stats, retryable error pattern matching, manage via
GET/POST /admin/retry-policy - Adaptive Rate Limiting — Dynamic rate adjustment based on key behavior — auto-tighten for high error rates, auto-boost for good actors, cooldown periods, configurable thresholds, per-key behavior tracking, LRU eviction, batch evaluation, manage via
GET/POST /admin/adaptive-rates - Request Deduplication — Idempotency layer preventing duplicate billing from agent retries —
X-Idempotency-Keyheader with auto-generation fallback (SHA-256), in-flight request coalescing, configurable TTL window, LRU eviction, credits-saved tracking, manage viaGET/POST/DELETE /admin/dedup - Priority Queue — Tiered request prioritization (critical/high/normal/low/background) with fair scheduling — per-key priority assignment, configurable max wait times per tier, starvation prevention via automatic promotion, max queue depth limiting, manage via
GET/POST /admin/priority-queue - Cost Allocation Tags — Per-request cost attribution via
X-Cost-Tagsheader (JSON) for enterprise chargeback — aggregated reports by any tag dimension, cross-tabulation, CSV export, required tag enforcement per key, cardinality limits, manage viaGET/POST/DELETE /admin/cost-tags - IP Access Control — Fine-grained IP-based access control with CIDR notation support — global allow/deny lists, per-key IP binding, automatic blocking after configurable violation thresholds, X-Forwarded-For/X-Real-IP trusted proxy depth, IPv6-mapped IPv4 normalization, manage via
GET/POST/DELETE /admin/ip-access - Request Signing (HMAC-SHA256) — Cryptographic request authentication with replay protection —
X-Signature: t=<ts>,n=<nonce>,s=<sig>header, timestamp tolerance with nonce dedup, per-key signing secrets with rotation, timing-safe comparison, manage viaGET/POST/DELETE /admin/signing - Multi-Tenant Isolation — Full tenant isolation for platform operators — per-tenant rate limits, credit pools, usage tracking, API key binding, tenant suspension/activation, cross-tenant reporting, configurable limits (10K tenants, 1K keys/tenant), manage via
GET/POST/DELETE /admin/tenants - Request Tracing — End-to-end structured tracing with span recording at gate, backend, and transform stages — trace/request ID lookup, timing breakdown (gateMs/backendMs/transformMs), configurable sample rate, retention limits, P95 latency tracking, JSON export, manage via
GET/POST/DELETE /admin/tracing - Budget Policy Engine — Burn rate monitoring with progressive throttling — daily/monthly budget enforcement, credits/minute burn rate tracking over configurable windows, three actions (alert/throttle/deny), per-namespace and per-key targeting, budget remaining forecast, automatic daily/monthly reset, manage via
GET/POST/DELETE /admin/budget-policies - Tool Dependency Graph — DAG-based workflow validation — register tool dependencies, enforce execution order, failure propagation (upstream failure blocks downstream), topological sort, cycle detection, per-workflow execution tracking, hard vs soft dependencies, group scoping, manage via
GET/POST/DELETE /admin/tool-deps - Quota Management — Granular daily/weekly/monthly hard caps per API key — per-tool or global quotas, calls or credits metric, burst allowance (temporary over-limit percentage), three overage actions (deny/warn/throttle), UTC-based period boundaries (daily midnight, weekly Monday, monthly 1st), automatic period rollover, manage via
GET/POST/DELETE /admin/quota-rules - Webhook Replay (DLQ) — Dead letter queue management for failed webhook deliveries — record failures with full request context (URL, headers, body, HMAC signature), replay individual or bulk failed deliveries, status tracking (pending → retrying → succeeded/exhausted), configurable max retries with timeout, purge by ID or status, age-based expiry, manage via
GET/POST/DELETE /admin/webhook-replay - Config Profiles — Named configuration presets with save/activate/rollback — profile inheritance chains (base → child merging), SHA-256 checksums, flat-key diffing for comparison (onlyInA/onlyInB/changed/unchanged), import/export as JSON with merge or replace mode, activation history, circular inheritance detection, manage via
GET/POST/DELETE /admin/config-profiles - Scheduled Reports — Automated periodic usage, billing, compliance, and security reports delivered via webhook — daily/weekly/monthly frequency with UTC period bounds, HMAC-SHA256 signed payloads, namespace/group/tool/key filters, report generation with delivery tracking, configurable timeouts, manage via
POST /admin/scheduled-reports - Approval Workflows — Pre-execution approval gates for high-cost or sensitive tool calls — three conditions (cost_threshold, tool_match with glob, key_match with prefix), pending requests with configurable TTL (default 1h), approve/deny/expire lifecycle, trigger counting, manage via
POST /admin/approval-workflows - Gateway Hooks — Pre/post request lifecycle hooks for custom logic — three stages (pre_gate, pre_backend, post_backend), four types (log, header_inject, metadata_tag, reject), priority-based execution pipeline, tool/key glob filtering, reject short-circuits processing, execution counting, manage via
POST /admin/gateway-hooks - Anomaly Detection —
GET /admin/anomaliesidentifies unusual patterns: keys with high denial rates, rapid credit depletion, low remaining credits, with severity ratings and detailed descriptions - Usage Forecasting —
GET /admin/forecastpredicts future credit consumption with per-key depletion estimates, calls remaining, at-risk key identification, system-wide consumption aggregates, and per-tool cost breakdown - Compliance Report —
GET /admin/compliancegenerates compliance-ready report with key governance (expiry coverage), access control (ACL/IP/spending limit coverage), audit trail completeness, weighted overall score, and actionable recommendations - SLA Monitoring —
GET /admin/slatracks service level metrics: success rates, denial breakdowns by reason, per-tool availability and error rates, uptime tracking, sorted by call volume - Capacity Planning —
GET /admin/capacitysystem capacity analysis with credit burn rates, utilization percentages, top consumers, per-namespace breakdown, and scaling recommendations - Key Dependency Map —
GET /admin/dependenciestool-to-key relationship map with tool usage popularity, unique key counts per tool, per-key tool lists, and used/unused tool identification - Tool Latency Analysis —
GET /admin/latencyper-tool response time metrics with avg/p95/min/max durations, slowest tools ranking, and per-key latency breakdown - Error Rate Trends —
GET /admin/error-trendsdenial rate trends with per-tool error rates, denial reason breakdown, worst-performing tools, and trend direction - Credit Flow Analysis —
GET /admin/credit-flowcredit inflow/outflow analysis with utilization percentage, top spenders, and per-tool spend breakdown - Key Age Analysis —
GET /admin/key-agekey age distribution with oldest/newest keys, age buckets (24h/7d/30d/older), and recently created list - Namespace Usage Summary —
GET /admin/namespace-usageper-namespace usage metrics with credit allocation, spending, call counts, and cross-namespace comparison - Audit Summary —
GET /admin/audit-summaryaudit event analytics with type breakdown, top actors, recent events, and activity summary - Group Performance —
GET /admin/group-performanceper-group analytics with key counts, credit allocation/spending, call volume, utilization, and policy summary - Request Volume Trends —
GET /admin/request-trendshourly time-series of request volume, success/failure counts, credit spend, avg duration, and peak hour identification - Key Status Overview —
GET /admin/key-statuskey status dashboard with active/suspended/revoked/expired counts and keys needing attention (low credits, near expiry) - Webhook Health —
GET /admin/webhook-healthwebhook delivery health overview with success rate, pending retries, dead letter count, pause status, and buffered events - Consumer Insights —
GET /admin/consumer-insightsper-key behavioral analytics with top spenders, most active callers, tool diversity, and spending patterns - System Health Score —
GET /admin/system-healthcomposite 0-100 health score with weighted component breakdowns for key health, error rates, and credit utilization - Tool Adoption —
GET /admin/tool-adoptionper-tool adoption metrics with unique consumers, adoption rate, first/last seen timestamps, and usage ranking - Credit Efficiency —
GET /admin/credit-efficiencycredit allocation efficiency with burn efficiency, waste ratio, over-provisioned and under-provisioned key detection - Access Heatmap —
GET /admin/access-heatmaphourly access patterns with tool breakdown, unique consumers, and peak hour identification - Key Churn Analysis —
GET /admin/key-churnkey churn metrics with creation/revocation rates, churn and retention percentages, and never-used key detection - Tool Correlation —
GET /admin/tool-correlationtool co-occurrence analysis showing which tools are commonly used together by the same consumers - Consumer Segmentation —
GET /admin/consumer-segmentationclassifies API key consumers into power/regular/casual/dormant segments with per-segment metrics - Credit Distribution —
GET /admin/credit-distributionhistogram of credit balances across active keys with bucket ranges and median calculation - Response Time Distribution —
GET /admin/response-time-distributionhistogram of response times with latency buckets and p50/p95/p99 percentiles - Consumer Lifetime Value —
GET /admin/consumer-lifetime-valueper-consumer spend analysis with value tiers, tool diversity, and top spender rankings - Tool Revenue Ranking —
GET /admin/tool-revenueranks tools by total credits consumed with call counts, unique consumers, and percentage breakdown - Consumer Retention Cohorts —
GET /admin/consumer-retentiongroups consumers by creation date with retention rates and avg spend per cohort - Error Breakdown —
GET /admin/error-breakdowncategorizes denied requests by reason with counts, percentages, affected consumers, and error rate - Credit Utilization Rate —
GET /admin/credit-utilizationshows utilization percentage across active keys with utilization bands and over-provisioning detection - Namespace Revenue —
GET /admin/namespace-revenuerevenue breakdown by namespace with spend, call counts, key counts, and percentage breakdown - Group Revenue —
GET /admin/group-revenuerevenue breakdown by key group with spend, call counts, key counts, and percentage breakdown - Peak Usage Times —
GET /admin/peak-usagetraffic patterns by hour-of-day with request counts, credits, unique consumers, and peak hour identification - Consumer Activity —
GET /admin/consumer-activityper-consumer activity metrics with calls, spend, credits remaining, last active time, and active/inactive status - Tool Popularity —
GET /admin/tool-popularitytool usage popularity with call counts, credits, unique consumers, percentage, and most popular tool identification - Credit Allocation Summary —
GET /admin/credit-allocationcredit allocation across active keys with tier breakdown (1-100, 101-500, 501+), totals, and average allocation - Daily Summary —
GET /admin/daily-summarydaily rollup of requests, credits spent, new keys, errors, unique consumers and tools for trend analysis - Key Ranking —
GET /admin/key-rankingleaderboard of active keys ranked by spend, calls, or credits remaining with configurable sorting - Hourly Traffic —
GET /admin/hourly-trafficgranular per-hour request counts with allowed/denied breakdown, credits, consumers, tools, and busiest hour - Tool Error Rate —
GET /admin/tool-error-rateper-tool error rates with denied/allowed counts, error percentage, and overall reliability metrics - Consumer Spend Velocity —
GET /admin/consumer-spend-velocityper-consumer spend rate with credits/hour, depletion forecast, and velocity ranking - Namespace Activity —
GET /admin/namespace-activityper-namespace activity metrics with key counts, spend, calls, credits remaining for multi-tenant visibility - Credit Burn Rate —
GET /admin/credit-burn-ratesystem-wide credit burn rate with credits/hour, utilization percentage, depletion forecast - Consumer Risk Score —
GET /admin/consumer-risk-scoreper-consumer risk scoring based on utilization with risk levels (low/medium/high/critical) - Revenue Forecast —
GET /admin/revenue-forecastprojected revenue with hourly/daily/weekly/monthly forecasts capped by remaining credits - System Overview —
GET /admin/system-overviewexecutive summary with key counts, credit totals, utilization, activity metrics - Key Health Overview —
GET /admin/key-health-overviewholistic per-key health check with utilization, status levels, health distribution - Namespace Comparison —
GET /admin/namespace-comparisonside-by-side namespace comparison with allocation, spend, utilization, leader - Consumer Growth —
GET /admin/consumer-growthconsumer growth metrics with age, spend rate, credits allocated, new consumer count - Tool Profitability —
GET /admin/tool-profitabilityper-tool profitability analysis with revenue, calls, avg revenue per call, unique callers - Credit Waste Analysis —
GET /admin/credit-wasteper-key credit waste analysis with utilization metrics and waste percentage - Group Activity —
GET /admin/group-activityper-group activity metrics with key counts, spend, calls, credits remaining for policy-template analytics - Config Hot Reload —
POST /config/reloadreloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart - Webhook Events — POST batched usage events to any URL for external billing/alerting
- Config File Mode — Load all settings from a JSON file (
--config) - Shadow Mode — Log everything without enforcing payment (for testing)
- Persistent Storage — Keys, credits, admin keys, and groups survive restarts with
--state-file - Zero Dependencies — No external npm packages. Uses only Node.js built-ins.
Usage
Wrap a Local MCP Server (stdio)
# Default: 1 credit per call, 60 calls/min, port 3402
npx paygate-mcp wrap --server "npx @modelcontextprotocol/server-filesystem /tmp"
# Custom pricing and limits
npx paygate-mcp wrap \
--server "python my-server.py" \
--price 2 \
--rate-limit 30 \
--port 8080
# Per-tool pricing
npx paygate-mcp wrap \
--server "node server.js" \
--tool-price "search:1,generate:5,premium_analyze:20"
# Shadow mode (observe without enforcing)
npx paygate-mcp wrap --server "node server.js" --shadowGate a Remote MCP Server (Streamable HTTP)
Gate any remote MCP server that supports the Streamable HTTP transport (MCP spec 2025-03-26):
npx paygate-mcp wrap --remote-url "https://my-mcp-server.example.com/mcp"
# With custom pricing
npx paygate-mcp wrap \
--remote-url "https://api.example.com/mcp" \
--price 5 \
--tool-price "gpt4:20,search:2"The proxy handles:
- JSON-RPC forwarding via HTTP POST
- SSE (text/event-stream) response parsing
Mcp-Session-Idsession management- Graceful session cleanup (HTTP DELETE on shutdown)
When started, you'll see your admin key in the console. Save it.
Multi-Server Mode
Wrap multiple MCP servers behind a single PayGate instance. Tools are prefixed with the server name:
npx paygate-mcp wrap --config multi-server.jsonExample multi-server.json:
{
"port": 3402,
"defaultCreditsPerCall": 1,
"servers": [
{
"prefix": "fs",
"serverCommand": "npx",
"serverArgs": ["@modelcontextprotocol/server-filesystem", "/tmp"]
},
{
"prefix": "github",
"remoteUrl": "https://github-mcp.example.com/mcp"
}
]
}Tools are exposed with prefixes: fs:read_file, fs:write_file, github:search_repos, etc. Pricing and ACLs work on the prefixed names:
{
"toolPricing": {
"github:search_repos": { "creditsPerCall": 5 },
"fs:read_file": { "creditsPerCall": 1 }
}
}Credits are shared across all backends — one API key works for all servers.
Client SDK
Use PayGateClient to call tools from TypeScript/Node.js with auto 402 retry:
import { PayGateClient, PayGateError } from 'paygate-mcp/client';
const client = new PayGateClient({
url: 'http://localhost:3402',
apiKey: 'pg_abc123...',
autoRetry: true,
onCreditsNeeded: async (info) => {
// Called when credits run out — add credits and return true to retry
await topUpCredits(info.creditsRequired);
return true;
},
});
const tools = await client.listTools();
const result = await client.callTool('search', { query: 'hello' });
const balance = await client.getBalance();Features:
- Auto 402 retry: When a tool call returns payment-required, calls
onCreditsNeededand retries - Balance tracking:
client.lastKnownBalancetracks credits fromgetBalance()calls - Typed errors:
PayGateErrorwith.isPaymentRequired,.isRateLimited,.isExpiredhelpers - Zero dependencies: Uses Node.js built-in
http/https
Create API Keys
curl -X POST http://localhost:3402/keys \
-H "Content-Type: application/json" \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-d '{"name": "my-client", "credits": 100}'Call Tools
curl -X POST http://localhost:3402/mcp \
-H "Content-Type: application/json" \
-H "X-API-Key: CLIENT_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "read_file",
"arguments": {"path": "/tmp/test.txt"}
}
}'Top Up Credits
curl -X POST http://localhost:3402/topup \
-H "Content-Type: application/json" \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-d '{"key": "CLIENT_API_KEY", "credits": 500}'Check Balance (Client Self-Service)
curl http://localhost:3402/balance \
-H "X-API-Key: CLIENT_API_KEY"Returns credits, total spent, call count, and last used timestamp. Clients can check their own balance without needing admin access.
Export Usage Data (Admin)
# JSON export
curl http://localhost:3402/usage \
-H "X-Admin-Key: YOUR_ADMIN_KEY"
# CSV export (for spreadsheet/billing import)
curl "http://localhost:3402/usage?format=csv" \
-H "X-Admin-Key: YOUR_ADMIN_KEY"
# Filter by date
curl "http://localhost:3402/usage?since=2025-01-01T00:00:00Z" \
-H "X-Admin-Key: YOUR_ADMIN_KEY"Returns per-call usage events with tool name, credits charged, and timestamps. API keys are masked in output.
Check Status
curl http://localhost:3402/status \
-H "X-Admin-Key: YOUR_ADMIN_KEY"Returns active keys, usage stats, per-tool breakdown, and deny reasons.
Admin Dashboard
Open the web dashboard in your browser:
http://localhost:3402/dashboardA real-time admin UI for managing keys, viewing usage, and monitoring tool calls. Enter your admin key to authenticate. Features auto-refresh every 30s, top tools chart, activity feed, and key creation/management.
API Reference
| Endpoint | Method | Auth | Description |
|----------|--------|------|-------------|
| /mcp | POST | X-API-Key or Bearer | JSON-RPC 2.0 proxy (returns JSON or SSE) |
| /mcp | GET | X-API-Key or Bearer | SSE notification stream (Streamable HTTP) |
| /mcp | DELETE | Mcp-Session-Id | Terminate an MCP session |
| /balance | GET | X-API-Key | Client self-service — check credits, quota, ACL, expiry |
| /keys | POST | X-Admin-Key | Create API key (with ACL, expiry, quota, credits) |
| /keys | GET | X-Admin-Key | List all keys (masked, with expiry status) |
| /topup | POST | X-Admin-Key | Add credits to an existing key |
| /keys/transfer | POST | X-Admin-Key | Transfer credits between API keys |
| /keys/bulk | POST | X-Admin-Key | Execute multiple key operations (create, topup, revoke) in one request |
| /keys/export | GET | X-Admin-Key | Export all API keys for backup/migration (JSON or CSV) |
| /keys/import | POST | X-Admin-Key | Import API keys from backup with conflict resolution |
| /keys/revoke | POST | X-Admin-Key | Permanently revoke an API key |
| /keys/suspend | POST | X-Admin-Key | Temporarily suspend a key (reversible) |
| /keys/resume | POST | X-Admin-Key | Resume a suspended key |
| /keys/clone | POST | X-Admin-Key | Clone a key (new key, same config, fresh counters) |
| /keys/usage | GET | X-Admin-Key | Per-key usage breakdown (per-tool, time-series, deny reasons) |
| /keys/rotate | POST | X-Admin-Key | Rotate key (new key, same credits/ACL/quotas) |
| /keys/acl | POST | X-Admin-Key | Set tool ACL (whitelist/blacklist) on a key |
| /keys/expiry | POST | X-Admin-Key | Set or remove key expiry (TTL) |
| /keys/quota | POST | X-Admin-Key | Set usage quota (daily/monthly limits) |
| /keys/tags | POST | X-Admin-Key | Set key tags/metadata (merge semantics) |
| /keys/ip | POST | X-Admin-Key | Set IP allowlist (CIDR + exact match) |
| /keys/search | POST | X-Admin-Key | Search keys by tag values |
| /keys/auto-topup | POST | X-Admin-Key | Configure or disable auto-topup for a key |
| /admin/keys | GET | X-Admin-Key (super_admin) | List all admin keys (masked) |
| /admin/keys | POST | X-Admin-Key (super_admin) | Create a new admin key with role |
| /admin/keys/revoke | POST | X-Admin-Key (super_admin) | Revoke an admin key |
| /limits | POST | X-Admin-Key | Set spending limit on a key |
| /usage | GET | X-Admin-Key | Export usage data (JSON or CSV) |
| /status | GET | X-Admin-Key | Full dashboard with usage stats |
| /dashboard | GET | None (admin key in-browser) | Real-time admin web dashboard |
| /stripe/checkout | POST | X-API-Key | Create Stripe Checkout Session for credit purchase |
| /stripe/packages | GET | None | List available credit packages (public, rate-limited) |
| /stripe/webhook | POST | Stripe Signature | Auto-top-up credits on payment |
| /admin/backup | GET | X-Admin-Key | Export full server state as versioned JSON snapshot |
| /admin/restore | POST | X-Admin-Key | Import state from backup (merge/overwrite/full modes) |
| /admin/cache | GET | X-Admin-Key | Response cache stats (entries, hits, misses, hit rate) |
| /admin/cache | DELETE | X-Admin-Key | Clear cache (all or ?tool= filter) |
| /admin/circuit | GET | X-Admin-Key | Circuit breaker status (state, failures, rejections) |
| /admin/circuit | POST | X-Admin-Key | Reset circuit breaker to closed state |
| /admin/compliance/export | GET | X-Admin-Key | Compliance audit export (SOC 2/GDPR/HIPAA, JSON/CSV) |
| /keys/webhook | POST | X-Admin-Key | Set per-key webhook URL |
| /keys/webhook | GET | X-Admin-Key | Get per-key webhook status |
| /keys/webhook | DELETE | X-Admin-Key | Remove per-key webhook URL |
| /.well-known/oauth-authorization-server | GET | None | OAuth 2.1 server metadata |
| /oauth/register | POST | None | Dynamic Client Registration (RFC 7591) |
| /oauth/authorize | GET | None | Authorization endpoint (PKCE required) |
| /oauth/token | POST | None | Token endpoint (code exchange + refresh) |
| /oauth/revoke | POST | None | Token revocation (RFC 7009) |
| /oauth/clients | GET | X-Admin-Key | List registered OAuth clients |
| /.well-known/mcp-payment | GET | None | Server payment metadata (SEP-2007) |
| /.well-known/mcp.json | GET | None | MCP Server Identity card (discovery) |
| /pricing | GET | None | Full per-tool pricing breakdown |
| /openapi.json | GET | None | OpenAPI 3.1 spec (all 199+ endpoints) |
| /docs | GET | None | Interactive API docs (Swagger UI) |
| /robots.txt | GET | None | Crawler directives (allow public, disallow admin/keys) |
| /portal | GET | None | Self-service API key portal (browser UI, auth via X-API-Key prompt) |
| /ready | GET | None | Readiness probe (200 when ready, 503 when draining/maintenance) |
| /metrics | GET | None | Prometheus metrics (counters, gauges, uptime) |
| /analytics | GET | X-Admin-Key | Usage analytics (time-series, tool breakdown, trends) |
| /alerts | GET | X-Admin-Key | Consume pending alerts |
| /alerts | POST | X-Admin-Key | Configure alert rules |
| /teams | GET | X-Admin-Key | List all teams |
| /teams | POST | X-Admin-Key | Create a team (name, budget, quota, tags) |
| /teams/update | POST | X-Admin-Key | Update team settings |
| /teams/delete | POST | X-Admin-Key | Delete (deactivate) a team |
| /teams/assign | POST | X-Admin-Key | Assign an API key to a team |
| /teams/remove | POST | X-Admin-Key | Remove an API key from a team |
| /teams/usage | GET | X-Admin-Key | Team usage summary with member breakdown |
| /tokens | POST | X-Admin-Key | Create a scoped token (short-lived, tool-restricted) |
| /tokens/revoke | POST | X-Admin-Key | Revoke a scoped token (by full token string) |
| /tokens/revoked | GET | X-Admin-Key | List all revoked token entries |
| /namespaces | GET | X-Admin-Key | List all namespaces with key/credit/spending stats |
| /audit | GET | X-Admin-Key | Query audit log (filter by type, actor, time) |
| /audit/export | GET | X-Admin-Key | Export full audit log (JSON or CSV) |
| /audit/stats | GET | X-Admin-Key | Audit log statistics |
| /plugins | GET | X-Admin-Key | List registered plugins with hook info |
| /groups | GET | X-Admin-Key | List all key groups (policy templates) |
| /groups | POST | X-Admin-Key | Create a key group with shared policies |
| /groups/update | POST | X-Admin-Key | Update group policies |
| /groups/delete | POST | X-Admin-Key | Delete (deactivate) a group |
| /groups/assign | POST | X-Admin-Key | Assign an API key to a group |
| /groups/remove | POST | X-Admin-Key | Remove an API key from a group |
| /webhooks/filters | GET | X-Admin-Key | List all webhook filter rules |
| /webhooks/filters | POST | X-Admin-Key | Create a webhook filter rule |
| /webhooks/filters/update | POST | X-Admin-Key | Update a webhook filter rule |
| /webhooks/filters/delete | POST | X-Admin-Key | Delete a webhook filter rule |
| /webhooks/replay | POST | X-Admin-Key | Replay dead letter webhook events (all or by index) |
| /webhooks/test | POST | X-Admin-Key | Send test event to configured webhook URL (synchronous) |
| /webhooks/log | GET | X-Admin-Key | Webhook delivery log with status, timing, and filters |
| /webhooks/pause | POST | X-Admin-Key | Pause webhook delivery (events buffered until resumed) |
| /webhooks/resume | POST | X-Admin-Key | Resume webhook delivery and flush buffered events |
| /keys/alias | POST | X-Admin-Key | Set or clear a human-readable alias for an API key |
| /keys/expiring | GET | X-Admin-Key | List keys expiring within a time window (?within=86400 seconds) |
| /keys/templates | GET | X-Admin-Key | List all key templates |
| /keys/templates | POST | X-Admin-Key | Create or update a key template |
| /keys/templates/delete | POST | X-Admin-Key | Delete a key template |
| /config/reload | POST | X-Admin-Key | Hot-reload config file (pricing, rate limits, webhooks, quotas) |
| /health | GET | None | Health check (status, uptime, version, in-flight, Redis/webhook status) |
| / | GET | None | Root endpoint (endpoint list) |
Free Methods
These MCP methods pass through without auth or billing:
initialize, initialized, ping, tools/list, resources/list, prompts/list
Gated methods: tools/call (single), tools/call_batch (batch — all-or-nothing billing, parallel execution). See Batch Tool Calls.
CLI Commands
paygate-mcp wrap [options] # Start a payment-gated MCP proxy
paygate-mcp init [--output] [--force] # Interactive setup wizard
paygate-mcp validate --config <path> # Validate config without starting
paygate-mcp completions <bash|zsh|fish> # Generate shell completions
paygate-mcp version [--json] # Print versionShell Completions
# Bash
paygate-mcp completions bash > ~/.local/share/bash-completion/completions/paygate-mcp
# Zsh
paygate-mcp completions zsh > ~/.zfunc/_paygate-mcp
# Add to .zshrc: fpath=(~/.zfunc $fpath) && compinit
# Fish
paygate-mcp completions fish > ~/.config/fish/completions/paygate-mcp.fishMachine-Readable Output
# Version as JSON (for CI/CD)
paygate-mcp version --json
# → {"version":"10.3.0"}
# Validate config with structured output
paygate-mcp validate --config paygate.json --json
# → {"valid":true,"diagnostics":[...],"errors":0,"warnings":0}CLI Options
--server <cmd> MCP server command to wrap via stdio
--remote-url <url> Remote MCP server URL (Streamable HTTP transport)
--port <n> HTTP port (default: 3402)
--price <n> Default credits per tool call (default: 1)
--rate-limit <n> Max calls/min per key (default: 60, 0=unlimited)
--name <s> Server display name
--shadow Shadow mode — log without enforcing payment
--admin-key <s> Set admin key (default: auto-generated)
--tool-price <t:n> Per-tool price (e.g. "search:5,generate:10")
--import-key <k:c> Import existing key with credits (e.g. "pg_abc:100")
--state-file <path> Persist keys/credits to a JSON file (survives restarts)
--stripe-secret <s> Stripe webhook signing secret (enables /stripe/webhook)
--webhook-url <url> POST batched usage events to this URL
--webhook-secret <s> HMAC-SHA256 secret for signing webhook payloads
--refund-on-failure Refund credits when downstream tool call fails
--redis-url <url> Redis URL for distributed state (e.g. "redis://localhost:6379")
--config <path> Load settings from a JSON config file
--discovery <mode> Tool discovery mode: static (default) or dynamic
--json Machine-readable JSON outputNote: Use
--serverOR--remote-urlfor single-server mode. Useserversin a config file for multi-server mode.
Dynamic Tool Discovery
For servers with many tools, dynamic discovery mode reduces agent context window bloat by exposing 3 meta-tools instead of the full tool list:
npx paygate-mcp wrap --server "your-server" --discovery dynamicAgents see 3 tools: paygate_list_tools (paginated listing), paygate_search_tools (keyword search), and paygate_call_tool (proxy any tool). This reduces N tools to 3 in the context window while preserving full functionality.
Persistent Storage
Add --state-file to save API keys and credits to disk. Data survives server restarts.
npx paygate-mcp wrap --server "your-mcp-server" --state-file ~/.paygate/state.jsonStripe Integration
Connect Stripe to automatically top up credits when customers pay:
npx paygate-mcp wrap \
--server "your-mcp-server" \
--state-file ~/.paygate/state.json \
--stripe-secret "whsec_your_stripe_webhook_secret"Setup:
- Create a Stripe Checkout Session with metadata:
paygate_api_key— the customer's API key (e.g.pg_abc123...)paygate_credits— credits to add on payment (e.g.500)
- Point your Stripe webhook to
https://your-server/stripe/webhook - Subscribe to
checkout.session.completedandinvoice.payment_succeededevents
When a customer completes payment, credits are automatically added to their API key. Subscriptions auto-renew credits on each billing cycle.
Security:
- HMAC-SHA256 signature verification (Stripe's v1 scheme)
- Timing-safe comparison to prevent timing attacks
- 5-minute timestamp tolerance to prevent replay attacks
- Payment status verification (only
paidtriggers credits) - Zero dependencies — uses Node.js built-in
crypto
Per-Tool ACL (Access Control)
Control which tools each API key can access:
# Create a key that can only access search and read tools
curl -X POST http://localhost:3402/keys \
-H "Content-Type: application/json" \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-d '{"name": "limited-client", "credits": 100, "allowedTools": ["search", "read_file"]}'
# Create a key with specific tools blocked
curl -X POST http://localhost:3402/keys \
-H "Content-Type: application/json" \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-d '{"name": "safe-client", "credits": 100, "deniedTools": ["delete_file", "admin_reset"]}'
# Update ACL on an existing key
curl -X POST http://localhost:3402/keys/acl \
-H "Content-Type: application/json" \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-d '{"key": "CLIENT_API_KEY", "allowedTools": ["search"], "deniedTools": ["admin"]}'- allowedTools (whitelist): Only these tools are accessible. Empty = all tools.
- deniedTools (blacklist): These tools are always denied. Applied after allowedTools.
- ACL also filters
tools/list— clients only see their permitted tools.
Per-Tool Rate Limits
Set independent rate limits per tool (on top of the global limit):
{
"toolPricing": {
"expensive_analyze": { "creditsPerCall": 10, "rateLimitPerMin": 5 },
"search": { "creditsPerCall": 1, "rateLimitPerMin": 30 },
"cheap_read": { "creditsPerCall": 1 }
}
}Per-tool limits are enforced independently per API key. A key can be rate-limited on one tool while still accessing others. The global --rate-limit applies across all tools.
Key Expiry (TTL)
Create API keys that auto-expire:
# Create a key that expires in 1 hour (3600 seconds)
curl -X POST http://localhost:3402/keys \
-H "Content-Type: application/json" \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-d '{"name": "trial-user", "credits": 50, "expiresIn": 3600}'
# Create a key with a specific expiry date
curl -X POST http://localhost:3402/keys \
-H "Content-Type: application/json" \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-d '{"name": "quarterly", "credits": 1000, "expiresAt": "2026-06-01T00:00:00Z"}'
# Set or extend expiry on an existing key
curl -X POST http://localhost:3402/keys/expiry \
-H "Content-Type: application/json" \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-d '{"key": "CLIENT_API_KEY", "expiresIn": 86400}'
# Remove expiry (key never expires)
curl -X POST http://localhost:3402/keys/expiry \
-H "Content-Type: application/json" \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-d '{"key": "CLIENT_API_KEY", "expiresAt": null}'Expired keys return a clear api_key_expired error. Admins can extend or remove expiry at any time.
Credit Transfers
Atomically transfer credits between API keys:
curl -X POST http://localhost:3402/keys/transfer \
-H "X-Admin-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{ "from": "pg_source_key", "to": "pg_dest_key", "credits": 500, "memo": "Monthly allocation" }'Response:
{
"transferred": 500,
"from": { "keyMasked": "pg_sour...key1", "balance": 500 },
"to": { "keyMasked": "pg_dest...key2", "balance": 700 },
"memo": "Monthly allocation",
"message": "Transferred 500 credits"
}Validation: Both keys must exist, be active (not revoked/expired), and the source must have sufficient credits. Fractional credits are floored to integers. Self-transfers are rejected.
Audit trail: Every transfer logs a key.credits_transferred audit event with masked keys, amount, balances, and memo.
Bulk Key Operations
Execute multiple key operations (create, topup, revoke) in a single request. Failed operations don't stop subsequent ones — each result includes success status and index for easy correlation.
curl -X POST http://localhost:3402/keys/bulk \
-H "X-Admin-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"operations": [
{ "action": "create", "name": "api-key-1", "credits": 500, "tags": { "env": "prod" } },
{ "action": "create", "name": "api-key-2", "credits": 200 },
{ "action": "topup", "key": "pg_existing_key", "credits": 1000 },
{ "action": "revoke", "key": "pg_old_key" }
]
}'Response:
{
"total": 4,
"succeeded": 4,
"failed": 0,
"results": [
{ "index": 0, "action": "create", "success": true, "result": { "key": "pg_abc...", "name": "api-key-1", "credits": 500 } },
{ "index": 1, "action": "create", "success": true, "result": { "key": "pg_def...", "name": "api-key-2", "credits": 200 } },
{ "index": 2, "action": "topup", "success": true, "result": { "creditsAdded": 1000, "newBalance": 1500 } },
{ "index": 3, "action": "revoke", "success": true, "result": { "message": "Key revoked" } }
]
}Actions: create (with optional name, credits, tags, namespace, allowedTools, deniedTools), topup (key + credits), revoke (key). Unknown actions return an error result without stopping the batch.
Limits: Maximum 100 operations per request. Empty operations array returns 400.
Audit trail: Each successful operation logs an individual audit event with "(bulk)" suffix.
Key Import/Export
Export all API keys for backup or migration between PayGate instances:
# Export as JSON (includes full key secrets)
curl http://localhost:3402/keys/export \
-H "X-Admin-Key: $ADMIN_KEY" \
-o paygate-keys-backup.json
# Export as CSV
curl "http://localhost:3402/keys/export?format=csv" \
-H "X-Admin-Key: $ADMIN_KEY" \
-o paygate-keys-backup.csv
# Export only active keys in a specific namespace
curl "http://localhost:3402/keys/export?activeOnly=true&namespace=production" \
-H "X-Admin-Key: $ADMIN_KEY"Import keys into a PayGate instance:
curl -X POST http://localhost:3402/keys/import \
-H "X-Admin-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"keys": [{ "key": "pg_abc123...", "name": "my-key", "credits": 500, "active": true, "tags": {} }],
"mode": "skip"
}'Response:
{
"total": 1,
"imported": 1,
"overwritten": 0,
"skipped": 0,
"errors": 0,
"mode": "skip",
"results": [{ "key": "pg_abc123...", "name": "my-key", "status": "imported" }]
}Conflict modes: skip (default) — skip keys that already exist, overwrite — replace existing keys, error — fail on duplicate keys.
Limits: Maximum 1000 keys per import request. Keys must start with pg_ prefix.
Export formats: JSON (full records with all fields) or CSV (key subset for spreadsheet use).
Spending Limits
Cap the total credits any API key can spend:
# Set a spending limit on a key (admin only)
curl -X POST http://localhost:3402/limits \
-H "Content-Type: application/json" \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-d '{"key": "CLIENT_API_KEY", "spendingLimit": 500}'
# Check remaining budget
curl http://localhost:3402/balance -H "X-API-Key: CLIENT_API_KEY"
# → { "spendingLimit": 500, "remainingBudget": 350, ... }Set spendingLimit to 0 for un
