mpp-mcp-gateway
mpp-mcp-gateway
Monetarisieren Sie jeden MCP-Server mit Stablecoin-Mikrozahlungen über das Machine Payments Protocol (MPP) auf der Tempo-Blockchain.
Erstellen Sie MCP-Tool-Server, die KI-Agenten pro Aufruf, pro Sitzung oder über Zugriffsschlüssel abrechnen – abgerechnet in pathUSD und anderen TIP-20-Stablecoins. Erstellen Sie KI-Agent-Clients, die für diese Tools automatisch mit konfigurierbaren Ausgabenobergrenzen bezahlen.
Inhaltsverzeichnis
Related MCP server: MCP Server TypeScript
Übersicht
mpp-mcp-gateway ist eine TypeScript-Bibliothek, die MCP-Servern (Model Context Protocol) eine Zugangskontrolle per Stablecoin-Mikrozahlungen hinzufügt. Wenn ein KI-Agent ein kostenpflichtiges Tool aufruft, sendet der Server eine Challenge mit dem Status 402 Payment Required. Der Client des Agenten signiert eine Zahlungstransaktion auf der Tempo-Blockchain, wiederholt den Aufruf mit einem Berechtigungsnachweis, und der Server verifiziert die Abrechnung, bevor er den Handler ausführt und das Ergebnis mit einer Quittung zurückgibt.
Hauptfunktionen:
Vier Preismodelle — pro Aufruf, gestaffelt, Sitzung (Zahlungskanäle) und Zugriffsschlüssel (Abonnements)
Multi-Währungs-Unterstützung — mehrere TIP-20-Stablecoins pro Tool akzeptieren
Exakte Umsatzverfolgung — BigInt-Arithmetik verhindert Float-Drift bei Millionen von Sub-Cent-Zahlungen
Austauschbarer Speicher — In-Memory, Upstash Redis (atomares CAS), Cloudflare KV oder eigener Speicher
Ratenbegrenzung — Token-Bucket (In-Memory oder Redis-gestützt) mit Überschreibungen pro Tool
Auth-Middleware — Bearer-Token, API-Schlüssel, HTTP Basic, signierte URLs, CORS – alles timing-sicher
Prometheus-Metriken —
/metrics-Endpunkt, keine AbhängigkeitenOpenTelemetry-Tracing — optionaler Span-Baum pro kostenpflichtigem Aufruf, keine Kosten, wenn deaktiviert
Webhooks — HMAC-signierter Event-Push mit Wiederholung, Backoff und Dead-Letter-Hooks
Service-Discovery — OpenAPI 3.1 mit
x-payment-info-Erweiterungen (von mpp.land gecrawlt)Dashboard — React-UI + JSON-API für Live-Umsatz- und Aufrufüberwachung
Graceful Shutdown — laufende Aufrufe abwickeln, Hooks auslösen, Webhooks zustellen
Laufzeitportabel — funktioniert auf Node.js 20+, Cloudflare Workers, Vercel Edge, Deno, Bun
So funktioniert es
┌─────────────┐ 402 Challenge ┌──────────────────┐
│ AI Agent │ ────────────────────────────── │ Paid MCP Server │
│ (Client) │ │ (Gateway) │
│ │ ◄── Payment Required (-32042) │ │
│ │ │ │
│ Signs tx │ ── Credential (signed payment) │ Verifies on │
│ via mppx │ ──► │ Tempo chain │
│ │ │ │
│ │ ◄── Tool Result + Receipt │ Runs handler │
└─────────────┘ └──────────────────┘Der Agent ruft ein kostenpflichtiges Tool über MCP auf
Der Server antwortet mit dem MCP-Fehlercode
-32042, der eine MPP-Challenge enthältDer Client setzt Ausgabenobergrenzen durch, signiert die Zahlung und wiederholt den Aufruf mit einem Berechtigungsnachweis
Der Server verifiziert die On-Chain-Abrechnung über
mppxDer Handler wird ausgeführt, das Ergebnis wird mit einer Zahlungsquittung (Transaktions-Hash, Zeitstempel) zurückgegeben
Installation
npm install mpp-mcp-gatewayPeer-Abhängigkeiten (nur installieren, was Sie verwenden):
# For HTTP/Express transports and dashboard
npm install express
# For Upstash Redis stores / rate limiting
npm install @upstash/redis
# For OpenTelemetry tracing
npm install @opentelemetry/api
# For Cloudflare Workers KV store
npm install @cloudflare/workers-typesSchnellstart
Server (Tool-Anbieter)
import { createPaidMcpServer } from 'mpp-mcp-gateway/server'
import { z } from 'zod'
const server = createPaidMcpServer({
name: 'my-api',
version: '1.0.0',
recipient: '0xYourWalletAddress',
secretKey: process.env.PAYMENT_SECRET_KEY!,
network: 'testnet',
tools: [
{
name: 'get_weather',
description: 'Get weather for a city. $0.001 per call.',
inputSchema: { city: z.string() },
pricing: { type: 'per-call', amount: '0.001' },
handler: async ({ city }) => ({
content: [{ type: 'text', text: `Weather in ${city}: 72°F, sunny` }],
}),
},
{
name: 'ping',
description: 'Free liveness check.',
inputSchema: {},
// No pricing = free tool
handler: async () => ({
content: [{ type: 'text', text: 'pong' }],
}),
},
],
})
await server.startStdio()Client (KI-Agent)
import { createPaidMcpClient } from 'mpp-mcp-gateway/client'
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
const client = createPaidMcpClient({
name: 'my-agent',
version: '1.0.0',
privateKey: process.env.AGENT_PRIVATE_KEY! as `0x${string}`,
maxPerCall: '0.10', // safety cap: max $0.10 per single call
maxTotal: '10.00', // safety cap: max $10.00 total spend
network: 'testnet',
})
const transport = new StdioClientTransport({
command: 'node',
args: ['server.js'],
})
await client.connect(transport)
// Free call — no payment required
const ping = await client.callTool('ping')
console.log(ping.content[0].text) // "pong"
console.log(ping.paid) // false
// Paid call — automatic 402 → sign → retry
const weather = await client.callTool('get_weather', { city: 'Tokyo' })
console.log(weather.content[0].text) // "Weather in Tokyo: 72°F, sunny"
console.log(weather.paid) // true
console.log(weather.receipt?.reference) // "0xabc...def" (tx hash)
await client.close()Preismodelle
Pro Aufruf
Fester Preis pro Aufruf. Eine On-Chain-Transaktion pro Aufruf.
pricing: { type: 'per-call', amount: '0.001' }Gestaffelt
Der Preis sinkt (oder steigt) basierend auf der kumulierten Anzahl der Aufrufe.
pricing: {
type: 'tiered',
tiers: [
{ upTo: 100, amount: '0.01' },
{ upTo: 1000, amount: '0.005' },
{ upTo: 'unlimited', amount: '0.001' },
],
}Sitzung (Zahlungskanäle)
Der Agent öffnet einmalig einen On-Chain-Escrow-Kanal. Nachfolgende Aufrufe übermitteln signierte Vouchers off-chain. Der Server begleicht den höchsten Voucher, wenn der Kanal geschlossen wird. Am besten geeignet für Streaming- oder hochfrequente Tools.
pricing: {
type: 'session',
amount: '0.0005', // per-unit price
unitType: 'request', // informational label
suggestedDeposit: '0.50', // hint for initial channel funding
}Clientseitige Sitzungsverwaltung:
// Make multiple calls against the same channel
await client.callTool('think', { topic: 'AI alignment' })
await client.callTool('think', { topic: 'quantum computing' })
// Cooperatively close and settle on-chain
const result = await client.closeSession('think')
console.log(result.receipt.reference) // settlement tx hashZugriffsschlüssel (Abonnements)
Der Agent zahlt einmalig im Voraus und erhält einen undurchsichtigen Token. Nachfolgende Aufrufe präsentieren den Token – keine weitere Zahlung, bis der Schlüssel abläuft oder aufgebraucht ist. Am besten geeignet für die UX „Tagespass kaufen“ oder „N Aufrufe kaufen“.
pricing: {
type: 'access-key',
amount: '0.01', // upfront cost
validFor: '1d', // time limit (supports: 60s, 30m, 4h, 7d)
maxCalls: 100, // call limit (at least one of validFor/maxCalls required)
}Der Client übernimmt das Caching automatisch:
// First call: pays $0.01, receives access key
const r1 = await client.callTool('premium_data', { query: 'foo' })
console.log(r1.paid) // true
console.log(r1.accessKey?.justIssued) // true
console.log(r1.accessKey?.remainingCalls) // 99
// Subsequent calls: free (key presented in _meta)
const r2 = await client.callTool('premium_data', { query: 'bar' })
console.log(r2.paid) // falseMulti-Währung
Jedes Preismodell kann mehrere TIP-20-Stablecoins akzeptieren:
pricing: {
type: 'per-call',
amount: '0.001',
accept: [
{ currency: '0x20c0...0000', amount: '0.001' }, // pathUSD
{ currency: '0x20c0...0001', amount: '0.001' }, // alphaUSD
],
}Server-API
import { createPaidMcpServer, PaidMcpServer } from 'mpp-mcp-gateway/server'
const server = createPaidMcpServer(config)
// Start on stdio (for CLI / subprocess use)
await server.startStdio()
// Or access the underlying McpServer for custom transports
const mcpServer = server.server
await mcpServer.connect(someTransport)
// Runtime inspection
server.getStats() // GatewayStats (calls, revenue, sessions, keys)
server.listTools() // tool names, descriptions, current prices
server.getRecentCalls(100) // last N calls from the ring buffer
server.getInFlightCount() // currently active handlers
server.isShuttingDown() // true after close() begins
server.describe() // full descriptor for discovery/OpenAPI
// Access-key management
await server.listAccessKeys() // live keys issued by this instance
await server.revokeAccessKey(token) // { revoked: boolean }
// Graceful shutdown
await server.close({ timeoutMs: 25_000 })Client-API
import { createPaidMcpClient, PaidMcpClient } from 'mpp-mcp-gateway/client'
const client = createPaidMcpClient(config)
await client.connect(transport)
await client.listTools()
const result = await client.callTool('tool_name', { arg: 'value' })
// Spending state
client.getSpending() // { totalSpent, remaining, maxTotal, maxPerCall, ... }
client.resetSpending() // reset cumulative counter (for tests)
// Access key management
client.getAccessKeys() // cached keys by tool name
client.clearAccessKey('tool') // force re-payment on next call
client.clearAccessKeys() // drop all cached keys
// Session management
client.getOpenSessions() // open channels by tool name
await client.closeSession('tool') // settle channel on-chain
await client.close()Transports
Das Gateway funktioniert mit jedem MCP-Transport. Beispiele sind enthalten:
Transport | Anwendungsfall | Beispiel |
stdio | CLI-Tools, Subprozess-Spawning |
|
Streamable HTTP | Netzwerkserver (modern) |
|
SSE (veraltet) | Ältere MCP-Clients |
|
In-Memory | Tests, gleicher Prozess |
|
Store-Adapter
Das Gateway verwendet eine austauschbare MppMcpStore-Schnittstelle zum Speichern von Zugriffsschlüssel-Datensätzen und Sitzungskanal-Zuständen.
import { Store } from 'mpp-mcp-gateway/stores'Adapter | Atomarität | Anwendungsfall |
| Atomar (Promise-Kette) | Tests, lokale Entwicklung, Einzelinstanz |
| Atomar (Lua-CAS) | Produktion, Multi-Instanz |
| Best-effort | Edge-Zugriffsschlüssel (nicht für Sitzungen) |
| Best-effort | Abwärtskompatibilität mit mppx-Stores |
Upstash-Beispiel
import { Redis } from '@upstash/redis'
import { createUpstashStore } from 'mpp-mcp-gateway/stores'
const store = createUpstashStore(
new Redis({ url: process.env.UPSTASH_URL!, token: process.env.UPSTASH_TOKEN! }),
{ keyPrefix: 'mppmcp:', ttlSeconds: 30 * 24 * 3600 }
)
const server = createPaidMcpServer({
// ...
accessKeyStore: store,
sessionStore: store,
})Eigener Store
Implementieren Sie die Schnittstelle mit vier Methoden:
interface MppMcpStore {
get<T>(key: string): Promise<T | null>
put(key: string, value: unknown): Promise<void>
delete(key: string): Promise<void>
update<T>(key: string, transform: (current: T | null) => T | null): Promise<T | null>
}Die update-Methode muss ein atomares Read-Modify-Write garantieren. Der transform-Callback kann bei Konflikten mehrfach aufgerufen werden (CAS-basierte Backends).
Ratenbegrenzung
Die Ratenbegrenzung greift vor der Zahlungs- und Handler-Logik – abgelehnte Aufrufe lösen niemals eine 402 aus und führen Ihren Handler nicht aus.
const server = createPaidMcpServer({
// ...
rateLimit: {
refillPerMinute: 60, // sustained rate
capacity: 10, // burst capacity
perTool: {
expensive_ai: { refillPerMinute: 5, capacity: 2 },
cheap_lookup: { refillPerMinute: 600, capacity: 100 },
},
// Custom bucketing (e.g. per-session on HTTP transports)
keyExtractor: (toolName, extra) => `${toolName}:${extra.sessionId ?? 'default'}`,
},
})Für Multi-Instanz-Bereitstellungen verwenden Sie den Upstash-gestützten Limiter:
import { upstashTokenBucketLimiter } from 'mpp-mcp-gateway/rate-limit'
const limiter = upstashTokenBucketLimiter(redis, {
keyPrefix: 'mppmcp:rl:',
refillPerMinute: 120,
capacity: 20,
})
const server = createPaidMcpServer({
// ...
rateLimit: { limiter },
})Authentifizierungs-Middleware
Fünf Express-Middleware-Fabriken zum Schutz von Dashboard-, Metrik- und Discovery-Endpunkten:
import { auth } from 'mpp-mcp-gateway'
// Bearer token (constant-time comparison)
mountDashboard(server, app, {
middleware: auth.bearerToken(process.env.DASHBOARD_TOKEN!, { realm: 'admin' }),
})
// API key in custom header
mountMetrics(server, app, {
middleware: auth.apiKey({ header: 'x-api-key', value: process.env.METRICS_KEY! }),
})
// HTTP Basic Auth (multi-user)
mountDashboard(server, app, {
middleware: auth.basicAuth({ users: { admin: 'secret' }, realm: 'gateway' }),
})
// HMAC-signed URLs with TTL
mountDashboard(server, app, {
middleware: auth.signedQuery({ secret: process.env.URL_SECRET!, ttlSeconds: 300 }),
})
// Public CORS for registry crawlers
mountDiscovery(server, app, {
middleware: auth.publicCors(),
})Dashboard & Monitoring
JSON-API
import { mountDashboard } from 'mpp-mcp-gateway'
mountDashboard(server, app, { prefix: '/api' })Bietet:
Endpunkt | Antwort |
|
|
|
|
|
|
|
|
|
|
Prometheus-Metriken
import { mountMetrics } from 'mpp-mcp-gateway'
mountMetrics(server, app, {
middleware: auth.bearerToken(process.env.METRICS_TOKEN!),
})Bereitgestellte Metriken:
mppmcp_calls_total{tool}— Zähler nach Toolmppmcp_calls_by_mode_total{mode}— paid, free, session, access_key, totalmppmcp_revenue_micro_usd_total{tool}— kumulativer Umsatz in micro-USDmppmcp_in_flight_calls— Messgröße (Gauge) für aktive Handlermppmcp_access_keys_issued_total/expired_totalmppmcp_sessions_opened_total/closed_totalmppmcp_rate_limited_total— Aufrufe, die von der Ratenbegrenzung abgelehnt wurdenmppmcp_rejected_shutting_down_total— Aufrufe, die während des Herunterfahrens abgelehnt wurdenmppmcp_uptime_secondsmppmcp_shutting_down
React-Dashboard
Ein vorgefertigtes React- + Vite-Dashboard befindet sich in dashboard/. Es fragt die JSON-API alle 2 Sekunden ab und zeigt:
Umsatzzähler und Tool-Tabelle, sortiert nach Umsatz
Live-Aufrufprotokoll, farbcodiert nach Zahlungsmodus
Zugriffsschlüssel- und Sitzungsstatistiken
cd dashboard
npm install
npm run buildStellen Sie dashboard/dist/ als statische Dateien über Ihre Express-App bereit.
Service-Discovery
Generieren und stellen Sie ein OpenAPI-3.1-Dokument mit x-payment-info-Erweiterungen gemäß dem MPP-Service-Discovery-IETF-Entwurf bereit. Öffentliche Registries wie mpp.land crawlen dies automatisch.
import { mountDiscovery } from 'mpp-mcp-gateway'
mountDiscovery(server, app, {
baseUrl: 'https://api.example.com',
categories: ['data', 'search'],
docs: { homepage: 'https://example.com/docs' },
})
// GET /openapi.json → OpenAPI 3.1 with x-payment-info per toolWebhooks
Senden Sie Ereignisse mit HMAC-SHA-256-Signaturen an eine URL. Die Zustellung erfolgt fire-and-forget (nicht blockierend), mit Wiederholung und exponentiellem Backoff.
const server = createPaidMcpServer({
// ...
webhooks: {
url: 'https://example.com/webhook',
secret: process.env.WEBHOOK_SECRET!,
events: ['payment.received', 'session.closed'], // or omit for all
maxAttempts: 3,
onDrop: async (event, lastError) => {
// Dead-letter: persist to DB for replay
await db.insert('webhook_dlq', { event, error: lastError })
},
},
})Ereignistypen: payment.received, access-key.issued, access-key.expired, session.opened, session.closed, call.failed
Empfängerverifizierung:
import { createHmac } from 'node:crypto'
function verify(req) {
const expected = 'sha256=' + createHmac('sha256', WEBHOOK_SECRET)
.update(`${req.headers['x-mppmcp-timestamp']}.${req.body}`)
.digest('hex')
return timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers['x-mppmcp-signature']))
}OpenTelemetry-Tracing
Opt-in. Übergeben Sie einen Tracer, um einen Span-Baum pro kostenpflichtigem Aufruf zu erhalten. Kein Overhead, wenn deaktiviert.
import { trace } from '@opentelemetry/api'
const server = createPaidMcpServer({
// ...
tracer: trace.getTracer('mpp-mcp-gateway', '1.0.0'),
})Span-Baum:
mppmcp.tool.call (root)
├── mppmcp.payment.charge (or mppmcp.session.advance, mppmcp.access-key.redeem)
└── mppmcp.handler.runAttribute: mppmcp.tool.name, mppmcp.pricing.type, mppmcp.amount, mppmcp.payment.mode, mppmcp.payment.tx-hash, mppmcp.session.action, mppmcp.error.code
Operator-CLI
Bereitgestellte Gateways über die Befehlszeile inspizieren und verwalten:
npx mpp-mcp inspect https://my-gateway.fly.dev --token=secret123
npx mpp-mcp stats https://api.example.com
npx mpp-mcp tools https://api.example.com
npx mpp-mcp calls https://api.example.com --limit=50
npx mpp-mcp keys list https://api.example.com --token=admin
npx mpp-mcp keys revoke mppmcp_abc123... https://api.example.com --token=adminKonfigurationsreferenz
Server (PaidMcpServerConfig)
Feld | Typ | Standard | Beschreibung |
|
| required | Server-Name, der Clients angezeigt wird |
|
| required | Serverversion |
|
| required | Wallet-Adresse, die Zahlungen empfängt |
|
| required | HMAC-Schlüssel zum Binden von Zahlungs-Challenges |
|
| required | Tool-Definitionen mit Handlern |
|
| pathUSD | TIP-20-Stablecoin-Vertragsadresse |
|
|
| Tempo-Netzwerk |
|
| — | Vom Server übernommene Gasgebühren (privater Schlüssel des Fee Payers) |
|
| — | Operator-Schlüssel, der für die Sitzungsabrechnung erforderlich ist |
|
| netzwerkabhängiger Standard | Escrow-Vertrag für Sitzungen |
|
| in-memory | Persistenz für Zugriffsschlüssel |
|
| in-memory | Persistenz für Sitzungskanäle |
|
|
| Schlüssel an die zahlende Wallet binden |
|
|
| Ringpufferkapazität (0 = deaktiviert) |
|
| console+redaction | Strukturierter Logger |
|
|
| Timeout für Graceful Shutdown |
|
| — | Hook, der ausgelöst wird, wenn das Abdrainen beginnt |
| object | 60/min pro Tool | Konfiguration der Ratenbegrenzung |
|
| — | OpenTelemetry-Tracer (Opt-in) |
|
| — | Konfiguration für Event-Push |
Client (PaidMcpClientConfig)
Feld | Typ | Standard | Beschreibung |
|
| erforderlich | Client-Name |
|
| erforderlich | Client-Version |
|
| erforderlich | Privater Schlüssel der Agent-Wallet |
|
|
| Maximale Ausgabe pro einzelnem Aufruf (USD) |
|
|
| Maximale kumulative Ausgabe (USD) |
|
|
| Maximale Kanaleinzahlung (USD) |
|
|
| Tempo-Netzwerk |
|
| console+redaction | Strukturierter Logger |
|
|
| Sitzungsabrechnungstransaktion on-chain verifizieren |
Beispiele
Beispiel | Preisgestaltung | Transport | Was es demonstriert |
| pro Aufruf | InMemory | Vollständiger 402-Roundtrip in einem Prozess |
| pro Aufruf | stdio | Agent startet Server als Unterprozess |
| pro Aufruf | Streamable HTTP | Netzwerkserver auf Express |
| pro Aufruf | SSE (Legacy) | Abwärtskompatibler SSE-Transport |
| pro Aufruf + Zugriffsschlüssel | Streamable HTTP | Kombiniertes MCP + Dashboard + Discovery |
| Sitzung | stdio | Zahlungskanäle, Gutscheine, Schließen |
| Zugriffsschlüssel | stdio | Tagespass, nur Zeit, Anrufpakete |
| pro Aufruf | stdio | Peer-Cash-Tools absichern, dann MPP-Einnahmen auszahlen |
Führen Sie ein beliebiges Beispiel aus:
# In-memory demo (no wallet needed)
npm run example:demo
# Server + client pairs
npm run example:server # then in another terminal:
npm run example:client
npm run example:http:server
npm run example:http:client
npm run example:streaming:server
npm run example:streaming:client
npm run example:subscription:server
npm run example:subscription:client
# Node.js 22+, Tempo mainnet
npm run example:peer-cash:server
# Dashboard (with all endpoints)
npm run example:dashboard:serverTest-Wallet aufladen
Bezahlte Beispiele erfordern eine finanzierte Wallet im Tempo-Testnetz. Das Peer-Cash-Beispiel ist die Ausnahme: Es verwendet das Tempo-Mainnet, da die Einnahmenroute nur live verfügbar ist.
cast rpc tempo_fundAddress 0xYourAddress --rpc-url https://rpc.moderato.tempo.xyzLaufzeitkompatibilität
Die Kernbibliothek (Server, Client, Stores, Rate-Limit, Beträge, Zugriffsschlüssel) ist über Web Crypto laufzeitportabel:
Laufzeit | Unterstützung |
Node.js 20+ | Voll |
Cloudflare Workers | Voll |
Vercel Edge | Voll |
Deno | Voll |
Bun | Voll |
Das Middleware-Modul auth.ts verwendet node:crypto und erfordert Node.js. Edge-Bereitstellungen verwenden stattdessen den nativen Router und die nativen Auth-Primitive ihrer Plattform.
Architektur
src/
├── server.ts PaidMcpServer — payment gating, stats, shutdown, webhooks
├── client.ts PaidMcpClient — auto-payment, caps, key caching, sessions
├── types.ts Core interfaces (PricingModel, configs, stats, results)
├── index.ts Barrel exports (11 subpath entry points)
├── access-keys.ts Issue, redeem (atomic), validate, duration parsing
├── amounts.ts BigInt <-> USD string conversion (exact arithmetic)
├── auth.ts 5 Express middleware factories (timing-safe)
├── cli.ts Operator CLI (inspect, stats, tools, calls, keys)
├── constants.ts Tempo networks, token addresses, escrow contracts
├── dashboard.ts JSON API: /api/stats, /api/tools, /api/calls
├── discovery.ts OpenAPI 3.1 generation with x-payment-info
├── errors.ts 9 typed error classes with stable codes
├── logger.ts Logger interface + 4 implementations + redaction
├── metrics.ts Prometheus /metrics (hand-formatted, zero deps)
├── rate-limit.ts RateLimiter interface + 3 implementations
├── runtime.ts Cross-runtime: randomHex, writeLogLine, hmacSha256Hex
├── tracing.ts OTel span helpers (no-op when disabled)
├── webhooks.ts HMAC-signed event push with retry + dead-letter
└── stores/
├── types.ts MppMcpStore interface
├── index.ts Store namespace + re-exports
├── memory.ts In-memory (atomic via promise chains)
├── upstash.ts Upstash Redis (atomic via Lua CAS)
├── cloudflare-kv.ts Cloudflare KV (best-effort)
└── bridge.ts Legacy 3-method store adapterPaket-Exporte
{
".": "Main barrel (everything)",
"./server": "PaidMcpServer",
"./client": "PaidMcpClient",
"./dashboard": "mountDashboard",
"./discovery": "mountDiscovery, buildOpenApi",
"./stores": "Store adapters",
"./rate-limit": "Rate limiter implementations",
"./auth": "Auth middleware factories",
"./metrics": "mountMetrics, formatMetrics",
"./tracing": "startSpan, withSpan, TRACE_ATTRS",
"./webhooks": "WebhookDispatcher, event types"
}Design-Prinzipien
Umsatzgenauigkeit — Die gesamte Geldmathematik verwendet
bigint-Basiseinheiten (6 Dezimalstellen). Kein Float-Drift nach Millionen von Operationen.Null-Kosten-Opt-in — Tracing, Webhooks und Ratenbegrenzung sind No-ops, sofern nicht konfiguriert. Nicht getracete Bereitstellungen allozieren keine Spans.
Alles austauschbar — Stores, Logger, Ratenbegrenzer und Auth sind schnittstellenbasiert. Implementierungen austauschen, ohne Gateway-Code anzufassen.
Fail fast — Konfigurationsfehler werden zur Konstruktionszeit geworfen, nicht zur Anfragezeit.
Fehler sind Werte — Typisierte Fehlerklassen mit stabilen Codes. Verwenden Sie
instanceofodererr.codefür die programmatische Behandlung.Ringpuffer-Anrufprotokoll — O(1) vorab allokiert, wächst nie. Kein GC-Druck bei hohem Durchsatz.
Sanfter Lebenszyklus — Das Shutdown-Gate lehnt neue Aufrufe ab, Drain wartet auf laufende, Webhook-Flush, dann Trennen.
Entwicklung
# Install dependencies
npm install
# Build
npm run build
# Type check
npm run typecheck
# Run tests
npm run test
# Run tests in watch mode
npm run test:watch
# Type tests (tsd)
npm run test:types
# Benchmarks
npm run bench
# Generate docs
npm run docsTest-Suite
27+ Testdateien, die Folgendes abdecken:
Access-Key-Atomizität (gleichzeitige Einlösungen von N-Call-Keys)
Access-Key-Abläufe (Ausstellung → Einlösung → Erschöpfung → erneute Zahlung)
Betragsmathematik (BigInt-Konvertierungen, Randfälle)
Auth-Middleware (alle 5 Factories)
Call-Log-Ringpuffer (Überlauf, Kapazitätsgrenzen)
Sanftes Herunterfahren & Drain
Dashboard-API-Antworten
Discovery / OpenAPI-Generierung
Fehlertaxonomie
Kostenlose Tools (Pfad ohne Zahlung)
Logger (strukturierte Ausgabe, Schwärzung, Child-Logger)
Prometheus-Metrikenformatierung
Multi-Währungs-Discovery
Bezahlter Ablauf (402 → Credential → Quittung)
Preisberechnungen (gestaffelt, pro Aufruf)
Ratenbegrenzung (Token-Bucket, Ablehnung, Retry-After)
Umsatzgenauigkeit (BigInt-Akkumulation über viele Aufrufe)
Laufzeit-Helfer (randomHex, hmacSha256Hex)
Sitzungslebenszyklus (öffnen → Gutschein → schließen → abrechnen)
Ausgabengrenzen (pro Aufruf, gesamt, Sitzungseinzahlung)
OpenTelemetry-Tracing (Span-Attribute, Fehleraufzeichnung)
Webhooks (Zustellung, Wiederholung, HMAC-Signatur, Dead-Letter)
Typtests (über
tsd)Durchsatz-Benchmarks (über
vitest bench)
Sanftes Herunterfahren
Binden Sie close() an das Herunterfahrsignal Ihres Containers:
process.on('SIGTERM', async () => {
try {
await server.close({ timeoutMs: 25_000 })
process.exit(0)
} catch {
process.exit(1) // drain timed out
}
})Strukturierte Protokollierung
Die Bibliothek enthält eine austauschbare Logger-Schnittstelle. Standard: JSON nach stderr mit automatischer Schwärzung von Geheimnissen (private Schlüssel, Anmeldedaten, signierte Transaktionen).
import { consoleLogger, silentLogger, withRedaction } from 'mpp-mcp-gateway'
// Custom logger
const server = createPaidMcpServer({
// ...
logger: withRedaction(consoleLogger({ level: 'debug', pretty: true })),
})
// Silence for tests
const server = createPaidMcpServer({
// ...
logger: silentLogger(),
})Passen Sie es an pino, winston oder eine beliebige Logging-Bibliothek an:
const adapter: Logger = {
debug: (m, c) => pino.debug(c, m),
info: (m, c) => pino.info(c, m),
warn: (m, c) => pino.warn(c, m),
error: (m, c) => pino.error(c, m),
child: (bindings) => /* wrap pino.child(bindings) */,
}Lizenz
MIT — Gaurav Pant
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA TypeScript implementation of the MCP Agent framework, providing tools for building context-aware agents with advanced workflow management, logging, and execution capabilities.18
- -licenseNot gradedqualityNot gradedmaintenanceA production-ready TypeScript MCP server providing basic tools (add, echo, timestamp), resources (server info, greetings, data access), and prompt templates (analyze, code-review, summarize). Serves as a foundation for building custom MCP servers with extensible architecture.225
- AlicenseNot gradedqualityCmaintenanceMCP server for AgentPay — the payment gateway for autonomous AI agents. Fund a wallet once, give your agent the key, and it discovers, provisions, and pays for tool APIs on its own. One key, every tool.1121MIT
- AlicenseNot gradedqualityCmaintenanceSimplifies creating MCP servers in TypeScript with an Express-like API and experimental decorators, enabling quick definition of tools, resources, and prompts.26196MIT
Related MCP Connectors
Monetize any MCP server: x402 paywall, pay-per-call billing in USDC on Base, agent marketplace.
A paid remote MCP for OpenAI Codex agent coordination MCP, built to return verdicts, receipts, usage
A paid remote MCP for AI SDK MCP gateway registry, built to return verdicts, receipts, usage logs, a
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/aspiring-100x/mpp-mcp-gateway'
If you have feedback or need assistance with the MCP directory API, please join our Discord server