mpp-mcp-gateway
mpp-mcp-gateway
Monetiza cualquier servidor MCP con micropagos en stablecoins a través del Machine Payments Protocol (MPP) en la cadena de bloques Tempo.
Crea servidores de herramientas MCP que cobren a los agentes de IA por llamada, por sesión o mediante claves de acceso, con liquidación en pathUSD y otros stablecoins TIP-20. Crea clientes de agente de IA que paguen por esas herramientas automáticamente con límites de gasto configurables.
Tabla de contenidos
Related MCP server: MCP Server TypeScript
Descripción general
mpp-mcp-gateway es una biblioteca de TypeScript que añade control de micropagos en stablecoins a los servidores MCP (Model Context Protocol). Cuando un agente de IA llama a una herramienta de pago, el servidor emite un desafío 402 Payment Required. El cliente del agente firma una transacción de pago en la cadena de bloques Tempo, reintenta la llamada con una credencial, y el servidor verifica la liquidación antes de ejecutar el handler y devolver el resultado con un recibo.
Características principales:
Cuatro modelos de precios — por llamada, por niveles, por sesión (canales de pago) y por clave de acceso (suscripciones)
Soporte multimoneda — acepta múltiples stablecoins TIP-20 por herramienta
Seguimiento exacto de ingresos — la aritmética con BigInt evita la deriva de coma flotante en millones de pagos de menos de un céntimo
Almacenamiento conectable — en memoria, Upstash Redis (CAS atómico), Cloudflare KV, o trae el tuyo propio
Limitación de velocidad — token bucket (en memoria o respaldado por Redis) con anulaciones por herramienta
Middleware de autenticación — token bearer, clave de API, HTTP Basic, URLs firmadas, CORS — todo seguro frente a ataques de temporización
Métricas de Prometheus — endpoint
/metrics, cero dependenciasTrazado con OpenTelemetry — árbol de spans opcional por llamada de pago, coste cero cuando está desactivado
Webhooks — envío de eventos firmados con HMAC con reintentos, backoff y hooks de dead-letter
Descubrimiento de servicios — OpenAPI 3.1 con extensiones
x-payment-info(rastreadas por mpp.land)Panel de control — interfaz React + API JSON para la monitorización en vivo de ingresos y llamadas
Apagado ordenado — drena las llamadas en curso, dispara hooks, liquida webhooks
Portátil entre entornos de ejecución — funciona en Node.js 20+, Cloudflare Workers, Vercel Edge, Deno, Bun
Cómo funciona
┌─────────────┐ 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 │
└─────────────┘ └──────────────────┘El agente llama a una herramienta de pago a través de MCP
El servidor responde con el código de error MCP
-32042que contiene un desafío MPPEl cliente aplica los límites de gasto, firma el pago y reintenta con una credencial
El servidor verifica la liquidación en cadena mediante
mppxSe ejecuta el handler y se devuelve el resultado con un recibo de pago (hash de la transacción, marca de tiempo)
Instalación
npm install mpp-mcp-gatewayDependencias entre pares (instala solo lo que uses):
# 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-typesInicio rápido
Servidor (proveedor de herramientas)
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()Cliente (agente de IA)
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()Modelos de precios
Por llamada
Precio fijo por invocación. Una transacción en cadena por llamada.
pricing: { type: 'per-call', amount: '0.001' }Por niveles
El precio disminuye (o aumenta) según el número acumulado de llamadas.
pricing: {
type: 'tiered',
tiers: [
{ upTo: 100, amount: '0.01' },
{ upTo: 1000, amount: '0.005' },
{ upTo: 'unlimited', amount: '0.001' },
],
}Sesión (canales de pago)
El agente abre un canal de depósito en garantía (escrow) en cadena una sola vez. Las llamadas posteriores envían vales firmados fuera de cadena. El servidor liquida el vale más alto cuando el canal se cierra. Ideal para herramientas de streaming o de alta frecuencia.
pricing: {
type: 'session',
amount: '0.0005', // per-unit price
unitType: 'request', // informational label
suggestedDeposit: '0.50', // hint for initial channel funding
}Gestión de sesión en el cliente:
// 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 hashClave de acceso (suscripciones)
El agente paga una vez por adelantado y recibe un token opaco. Las llamadas posteriores presentan el token; no hay más pagos hasta que la clave caduque o se agote. Ideal para experiencias de «comprar un pase de un día» o «comprar N llamadas».
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)
}El cliente gestiona el caché automáticamente:
// 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) // falseMultimoneda
Cualquier modelo de precios puede aceptar múltiples stablecoins TIP-20:
pricing: {
type: 'per-call',
amount: '0.001',
accept: [
{ currency: '0x20c0...0000', amount: '0.001' }, // pathUSD
{ currency: '0x20c0...0001', amount: '0.001' }, // alphaUSD
],
}API del servidor
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 })API del cliente
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()Transportes
La pasarela funciona con cualquier transporte MCP. Se incluyen ejemplos:
Transporte | Caso de uso | Ejemplo |
stdio | Herramientas CLI, lanzamiento de subprocesos |
|
Streamable HTTP | Servidores de red (modernos) |
|
SSE (heredado) | Clientes MCP antiguos |
|
In-Memory | Pruebas, mismo proceso |
|
Adaptadores de almacenamiento
La pasarela utiliza una interfaz conectable MppMcpStore para persistir los registros de claves de acceso y el estado de los canales de sesión.
import { Store } from 'mpp-mcp-gateway/stores'Adaptador | Atomicidad | Caso de uso |
| Atómico (cadena de promesas) | Pruebas, desarrollo local, una sola instancia |
| Atómico (CAS con Lua) | Producción, múltiples instancias |
| Mejor esfuerzo | Claves de acceso en el edge (no para sesiones) |
| Mejor esfuerzo | Compatibilidad hacia atrás con los stores de mppx |
Ejemplo con Upstash
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,
})Store personalizado
Implementa la interfaz de cuatro métodos:
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>
}El método update debe garantizar una lectura-modificación-escritura atómica. La devolución de llamada transform puede invocarse varias veces en condiciones de contención (backends de estilo CAS).
Limitación de velocidad
La limitación de velocidad se aplica antes de la lógica de pago y del handler; las llamadas denegadas nunca emiten un 402 ni ejecutan tu handler.
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'}`,
},
})Para despliegues de múltiples instancias, usa el limitador respaldado por Upstash:
import { upstashTokenBucketLimiter } from 'mpp-mcp-gateway/rate-limit'
const limiter = upstashTokenBucketLimiter(redis, {
keyPrefix: 'mppmcp:rl:',
refillPerMinute: 120,
capacity: 20,
})
const server = createPaidMcpServer({
// ...
rateLimit: { limiter },
})Middleware de autenticación
Cinco fábricas de middleware de Express para proteger los endpoints del panel, las métricas y el descubrimiento:
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(),
})Panel y monitorización
API JSON
import { mountDashboard } from 'mpp-mcp-gateway'
mountDashboard(server, app, { prefix: '/api' })Expone:
Endpoint | Respuesta |
|
|
|
|
|
|
|
|
|
|
Métricas de Prometheus
import { mountMetrics } from 'mpp-mcp-gateway'
mountMetrics(server, app, {
middleware: auth.bearerToken(process.env.METRICS_TOKEN!),
})Métricas expuestas:
mppmcp_calls_total{tool}— contador por herramientamppmcp_calls_by_mode_total{mode}— de pago, gratuitas, sesión, access_key, totalmppmcp_revenue_micro_usd_total{tool}— ingresos acumulados en micro-USDmppmcp_in_flight_calls— medidor de handlers activosmppmcp_access_keys_issued_total/expired_totalmppmcp_sessions_opened_total/closed_totalmppmcp_rate_limited_total— llamadas rechazadas por el limitador de velocidadmppmcp_rejected_shutting_down_total— llamadas rechazadas durante el apagadomppmcp_uptime_secondsmppmcp_shutting_down
Panel de React
Hay un panel prefabricado de React + Vite en dashboard/. Consulta la API JSON cada 2 segundos y muestra:
Contadores de ingresos y tabla de herramientas ordenada por ingresos
Registro de llamadas en vivo codificado por colores según el modo de pago
Estadísticas de claves de acceso y sesiones
cd dashboard
npm install
npm run buildSirve dashboard/dist/ como archivos estáticos desde tu aplicación Express.
Descubrimiento de servicios
Genera y sirve un documento OpenAPI 3.1 con extensiones x-payment-info según el borrador IETF de descubrimiento de servicios de MPP. Los registros públicos como mpp.land lo rastrean automáticamente.
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
Envía eventos a una URL con firmas HMAC-SHA-256. La entrega es de tipo fire-and-forget (no bloqueante), con reintentos y backoff exponencial.
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 })
},
},
})Tipos de evento: payment.received, access-key.issued, access-key.expired, session.opened, session.closed, call.failed
Verificación por parte del receptor:
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']))
}Trazado con OpenTelemetry
Opcional. Pasa un tracer para obtener un árbol de spans por llamada de pago. Cero sobrecarga cuando está desactivado.
import { trace } from '@opentelemetry/api'
const server = createPaidMcpServer({
// ...
tracer: trace.getTracer('mpp-mcp-gateway', '1.0.0'),
})Árbol de spans:
mppmcp.tool.call (root)
├── mppmcp.payment.charge (or mppmcp.session.advance, mppmcp.access-key.redeem)
└── mppmcp.handler.runAtributos: mppmcp.tool.name, mppmcp.pricing.type, mppmcp.amount, mppmcp.payment.mode, mppmcp.payment.tx-hash, mppmcp.session.action, mppmcp.error.code
CLI del operador
Inspecciona y gestiona pasarelas desplegadas desde la línea de comandos:
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=adminReferencia de configuración
Servidor (PaidMcpServerConfig)
Campo | Tipo | Predeterminado | Descripción |
|
| obligatorio | Nombre del servidor anunciado a los clientes |
|
| obligatorio | Versión del servidor |
|
| obligatorio | Dirección de wallet que recibe los pagos |
|
| obligatorio | Clave HMAC para vincular los desafíos de pago |
|
| obligatorio | Definiciones de herramientas con sus handlers |
|
| pathUSD | Dirección del contrato del stablecoin TIP-20 |
|
|
| Red de Tempo |
|
| — | Gas patrocinado por el servidor (clave privada del pagador de comisiones) |
|
| — | Clave de operador necesaria para la liquidación de sesiones |
|
| predeterminado por red | Contrato de depósito en garantía de sesión |
|
| en memoria | Persistencia para las claves de acceso |
|
| en memoria | Persistencia para los canales de sesión |
|
|
| Vincular las claves a la wallet que paga |
|
|
| Capacidad del búfer circular (0 = desactivado) |
|
| console+redaction | Registrador estructurado |
|
|
| Tiempo de espera de apagado ordenado |
|
| — | Hook que se dispara cuando comienza el drenaje |
| object | 60/min por herramienta | Configuración del límite de velocidad |
|
| — | Tracer de OpenTelemetry (opcional) |
|
| — | Configuración del envío de eventos |
Cliente (PaidMcpClientConfig)
Campo | Tipo | Por defecto | Descripción |
|
| obligatorio | Nombre del cliente |
|
| obligatorio | Versión del cliente |
|
| obligatorio | Clave privada de la cartera del agente |
|
|
| Gasto máximo por llamada individual (USD) |
|
|
| Gasto máximo acumulado (USD) |
|
|
| Depósito máximo del canal (USD) |
|
|
| Red Tempo |
|
| console+redaction | Registrador estructurado |
|
|
| Verificar la transacción de liquidación de la sesión en la cadena |
Ejemplos
Ejemplo | Precio | Transporte | Qué demuestra |
| por llamada | InMemory | Recorrido completo 402 en un solo proceso |
| por llamada | stdio | El agente lanza el servidor como subproceso |
| por llamada | Streamable HTTP | Servidor de red en Express |
| por llamada | SSE (legacy) | Transporte SSE compatible con versiones anteriores |
| por llamada + access-key | Streamable HTTP | MCP combinado + panel + descubrimiento |
| sesión | stdio | Canales de pago, vales, cierre |
| access-key | stdio | Pase diario, solo tiempo, paquetes de llamadas |
| por llamada | stdio | Controla el acceso a las herramientas de Peer Cash y luego retira los ingresos de MPP |
Ejecuta cualquier ejemplo:
# 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:serverFinanciación de una cartera de prueba
Los ejemplos de pago requieren una cartera financiada en la red de prueba de Tempo. El ejemplo de Peer Cash es la excepción: usa la red principal de Tempo porque la ruta de ingresos solo está disponible en vivo.
cast rpc tempo_fundAddress 0xYourAddress --rpc-url https://rpc.moderato.tempo.xyzCompatibilidad en tiempo de ejecución
La biblioteca principal (servidor, cliente, almacenes, límite de tasa, importes, claves de acceso) es portable entre entornos de ejecución mediante Web Crypto:
Runtime | Soporte |
Node.js 20+ | Completo |
Cloudflare Workers | Completo |
Vercel Edge | Completo |
Deno | Completo |
Bun | Completo |
El módulo de middleware auth.ts usa node:crypto y requiere Node.js. Los despliegues Edge usan en su lugar el enrutador nativo y las primitivas de autenticación de su plataforma.
Arquitectura
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 adapterExportaciones del paquete
{
".": "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"
}Principios de diseño
Exactitud de ingresos — todas las operaciones monetarias usan unidades base
bigint(6 decimales). Sin desviación de coma flotante después de millones de operaciones.Adopción opcional sin coste — el trazado, los webhooks y el límite de tasa son operaciones nulas salvo que se configuren. Los despliegues sin trazado no asignan spans.
Todo es conectable — los almacenes, registradores, limitadores de tasa y la autenticación se basan en interfaces. Intercambia implementaciones sin tocar el código de la puerta de enlace.
Fallar rápido — los errores de configuración se lanzan en el momento de la construcción, no en el de la petición.
Los errores son valores — clases de error tipadas con códigos estables. Usa
instanceofoerr.codepara el manejo programático.Registro de llamadas en búfer circular — preasignado O(1), nunca crece. Sin presión del recolector de basura bajo alto rendimiento.
Ciclo de vida elegante — la compuerta de apagado rechaza nuevas llamadas, el drenaje espera a las que están en curso, vacía los webhooks y luego se desconecta.
Desarrollo
# 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 docsSuite de pruebas
27+ archivos de prueba que cubren:
Atomicidad de las claves de acceso (canjes concurrentes de claves de N llamadas)
Flujos de claves de acceso (emisión → canje → agotamiento → nuevo pago)
Matemática de importes (conversiones BigInt, casos límite)
Middleware de autenticación (las 5 fábricas)
Búfer circular de registro de llamadas (envoltura, límites de capacidad)
Apagado elegante y drenaje
Respuestas de la API del panel
Descubrimiento / generación de OpenAPI
Taxonomía de errores
Herramientas gratuitas (ruta sin pago)
Registrador (salida estructurada, redacción, registradores secundarios)
Formato de métricas de Prometheus
Descubrimiento multidivisa
Flujo de pago (402 → credencial → recibo)
Cálculos de precios (por niveles, por llamada)
Límite de tasa (cubo de tokens, denegación, retry-after)
Exactitud de ingresos (acumulación BigInt en muchas llamadas)
Utilidades de tiempo de ejecución (randomHex, hmacSha256Hex)
Ciclo de vida de la sesión (abrir → vale → cerrar → liquidar)
Límites de gasto (por llamada, total, depósito de sesión)
Trazado OpenTelemetry (atributos de span, registro de errores)
Webhooks (entrega, reintento, firma HMAC, mensajes fallidos)
Pruebas de tipos (mediante
tsd)Pruebas de rendimiento (mediante
vitest bench)
Apagado elegante
Conecta close() a la señal de apagado de tu contenedor:
process.on('SIGTERM', async () => {
try {
await server.close({ timeoutMs: 25_000 })
process.exit(0)
} catch {
process.exit(1) // drain timed out
}
})Registro estructurado
La biblioteca incluye una interfaz Logger conectable. Por defecto: JSON a stderr con redacción automática de secretos (claves privadas, credenciales, transacciones firmadas).
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(),
})Adáptalo a pino, winston o cualquier biblioteca de registro:
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) */,
}Licencia
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