mpp-mcp-gateway
mpp-mcp-gateway
MCPサーバーを、Tempoブロックチェーン上のMachine Payments Protocol(MPP)によるステーブルコインのマイクロペイメントで収益化します。
AIエージェントに対して、呼び出しごと、セッションごと、またはアクセスキーごとに課金するMCPツールサーバーを構築できます。決済はpathUSDおよびその他のTIP-20ステーブルコインで行われます。また、設定可能な支出上限に基づいて、これらのツールに自動的に支払うAIエージェントクライアントを構築できます。
目次
Related MCP server: MCP Server TypeScript
概要
mpp-mcp-gateway は、MCP(Model Context Protocol)サーバーにステーブルコインのマイクロペイメントゲーティングを追加するTypeScriptライブラリです。AIエージェントが有料ツールを呼び出すと、サーバーは402 Payment Requiredチャレンジを発行します。エージェントのクライアントはTempoブロックチェーン上で支払いトランザクションに署名し、資格情報を付けて呼び出しを再試行します。サーバーはハンドラーを実行してレシート付きで結果を返す前に、決済を検証します。
主な機能:
4つの価格モデル — 従量課金(per-call)、段階的(tiered)、セッション(支払いチャネル)、アクセスキー(サブスクリプション)
マルチカレンシー対応 — ツールごとに複数のTIP-20ステーブルコインを受け付け
正確な収益追跡 — BigInt演算により、数百万件のサブセント支払いでも浮動小数点のずれを防止
プラグ可能なストレージ — インメモリ、Upstash Redis(アトミックCAS)、Cloudflare KV、または独自実装
レート制限 — トークンバケット(インメモリまたはRedisバックエンド)とツールごとの上書き設定
認証ミドルウェア — ベアラートークン、APIキー、HTTP Basic、署名付きURL、CORS — すべてタイミングセーフ
Prometheusメトリクス —
/metricsエンドポイント、依存関係ゼロOpenTelemetryトレーシング — 有料呼び出しごとのオプトインのスパンツリー、無効時はコストゼロ
ウェブフック — HMAC署名付きイベントプッシュ、リトライ、バックオフ、デッドレターフック付き
サービスディスカバリー —
x-payment-info拡張機能を備えたOpenAPI 3.1(mpp.landがクロール)ダッシュボード — ライブ収益と呼び出し監視のためのReact UI + JSON API
グレースフルシャットダウン — 実行中の呼び出しをドレインし、フックを発火し、ウェブフックを決済
ランタイムポータブル — Node.js 20+、Cloudflare Workers、Vercel Edge、Deno、Bunで動作
仕組み
┌─────────────┐ 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 │
└─────────────┘ └──────────────────┘エージェントがMCP経由で有料ツールを呼び出す
サーバーがMPPチャレンジを含むMCPエラーコード
-32042で応答するクライアントが支出上限を適用し、支払いに署名し、資格情報を付けて再試行する
サーバーが
mppx経由でオンチェーン決済を検証するハンドラーが実行され、支払いレシート(txハッシュ、タイムスタンプ)とともに結果が返される
インストール
npm install mpp-mcp-gatewayピア依存関係(使用するものだけをインストール):
# 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-typesクイックスタート
サーバー(ツールプロバイダー)
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()クライアント(AIエージェント)
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()価格モデル
従量課金(Per-Call)
呼び出しごとの固定価格です。1回の呼び出しにつき1つのオンチェーントランザクションが必要です。
pricing: { type: 'per-call', amount: '0.001' }段階的(Tiered)
累計呼び出し回数に応じて価格が下がる(または上がる)方式です。
pricing: {
type: 'tiered',
tiers: [
{ upTo: 100, amount: '0.01' },
{ upTo: 1000, amount: '0.005' },
{ upTo: 'unlimited', amount: '0.001' },
],
}セッション(支払いチャネル)
エージェントはオンチェーンのエスクローチャネルを一度だけ開きます。以降の呼び出しでは、署名済みバウチャーをオフチェーンで送信します。サーバーはチャネルが閉じられたときに最も高いバウチャーを決済します。ストリーミングや高頻度のツールに最適です。
pricing: {
type: 'session',
amount: '0.0005', // per-unit price
unitType: 'request', // informational label
suggestedDeposit: '0.50', // hint for initial channel funding
}クライアント側のセッション管理:
// 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 hashアクセスキー(サブスクリプション)
エージェントは前払いで一度だけ支払い、不透明なトークンを受け取ります。以降の呼び出しではそのトークンを提示します。キーが期限切れになるか使い切られるまで追加の支払いは不要です。「デイパスを購入」や「N回分の呼び出しを購入」といったUXに最適です。
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)
}クライアントはキャッシュを自動的に処理します:
// 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) // falseマルチカレンシー
どの価格モデルでも複数の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
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
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()トランスポート
ゲートウェイは任意のMCPトランスポートで動作します。同梱の例:
トランスポート | ユースケース | 例 |
stdio | CLIツール、サブプロセス起動 |
|
Streamable HTTP | ネットワークサーバー(モダン) |
|
SSE(レガシー) | 旧来のMCPクライアント |
|
In-Memory | テスト、同一プロセス |
|
ストアアダプター
ゲートウェイは、アクセスキーレコードとセッションチャネル状態を永続化するためのプラグ可能な MppMcpStore インターフェースを使用します。
import { Store } from 'mpp-mcp-gateway/stores'アダプター | 原子性 | ユースケース |
| アトミック(プロミスチェーン) | テスト、ローカル開発、単一インスタンス |
| アトミック(Lua CAS) | 本番、複数インスタンス |
| ベストエフォート | エッジアクセスキー(セッション用ではない) |
| ベストエフォート | mppxストアとの後方互換 |
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,
})カスタムストア
4つのメソッドからなるインターフェースを実装します:
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>
}update メソッドはアトミックな読み取り-変更-書き込みを保証する必要があります。競合が発生した場合(CAS方式のバックエンド)、transform コールバックが複数回呼び出される可能性があります。
レート制限
レート制限は支払いおよびハンドラーロジックの前に実行されます。拒否された呼び出しは402を発行せず、ハンドラーも実行されません。
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'}`,
},
})複数インスタンスのデプロイでは、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 },
})認証ミドルウェア
ダッシュボード、メトリクス、ディスカバリーの各エンドポイントを保護するための5つのExpressミドルウェアファクトリー:
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(),
})ダッシュボードとモニタリング
JSON API
import { mountDashboard } from 'mpp-mcp-gateway'
mountDashboard(server, app, { prefix: '/api' })公開エンドポイント:
エンドポイント | レスポンス |
|
|
|
|
|
|
|
|
|
|
Prometheusメトリクス
import { mountMetrics } from 'mpp-mcp-gateway'
mountMetrics(server, app, {
middleware: auth.bearerToken(process.env.METRICS_TOKEN!),
})公開メトリクス:
mppmcp_calls_total{tool}— ツール別カウンターmppmcp_calls_by_mode_total{mode}— paid、free、session、access_key、totalmppmcp_revenue_micro_usd_total{tool}— マイクロUSD単位の累計収益mppmcp_in_flight_calls— 実行中ハンドラーのゲージmppmcp_access_keys_issued_total/expired_totalmppmcp_sessions_opened_total/closed_totalmppmcp_rate_limited_total— レートリミッターによって拒否された呼び出しmppmcp_rejected_shutting_down_total— シャットダウン中に拒否された呼び出しmppmcp_uptime_secondsmppmcp_shutting_down
Reactダッシュボード
ビルド済みのReact + Viteダッシュボードは dashboard/ にあります。JSON APIを2秒ごとにポーリングし、以下を表示します:
収益カウンターと収益順にソートされたツールテーブル
支払いモードごとに色分けされたライブ呼び出しログ
アクセスキーとセッションの統計
cd dashboard
npm install
npm run builddashboard/dist/ をExpressアプリから静的ファイルとして配信します。
サービスディスカバリー
MPPサービスディスカバリーIETFドラフトに従い、x-payment-info 拡張機能を含むOpenAPI 3.1ドキュメントを生成して配信します。mpp.landなどの公開レジストリがこれを自動的にクロールします。
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 toolウェブフック
HMAC-SHA-256署名付きでイベントをURLにプッシュします。配信はファイアアンドフォーゲット(非ブロッキング)で、リトライと指数バックオフ付きです。
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 })
},
},
})イベントタイプ: payment.received、access-key.issued、access-key.expired、session.opened、session.closed、call.failed
受信側の検証:
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トレーシング
オプトイン方式です。トレーサーを渡すと、有料呼び出しごとにスパンツリーが取得できます。無効時はオーバーヘッドゼロです。
import { trace } from '@opentelemetry/api'
const server = createPaidMcpServer({
// ...
tracer: trace.getTracer('mpp-mcp-gateway', '1.0.0'),
})スパンツリー:
mppmcp.tool.call (root)
├── mppmcp.payment.charge (or mppmcp.session.advance, mppmcp.access-key.redeem)
└── mppmcp.handler.run属性: mppmcp.tool.name、mppmcp.pricing.type、mppmcp.amount、mppmcp.payment.mode、mppmcp.payment.tx-hash、mppmcp.session.action、mppmcp.error.code
オペレーターCLI
デプロイ済みゲートウェイをコマンドラインから検査および管理します:
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=admin設定リファレンス
サーバー(PaidMcpServerConfig)
フィールド | 型 | デフォルト | 説明 |
|
| 必須 | クライアントに通知されるサーバー名 |
|
| 必須 | サーバーバージョン |
|
| 必須 | 支払いを受け取るウォレットアドレス |
|
| 必須 | 支払いチャレンジをバインドするためのHMACキー |
|
| 必須 | ハンドラー付きのツール定義 |
|
| pathUSD | TIP-20ステーブルコインのコントラクトアドレス |
|
|
| Tempoネットワーク |
|
| — | サーバー負担のガス(フィーペイヤーの秘密鍵) |
|
| — | セッション決済に必要なオペレーターキー |
|
| ネットワークごとのデフォルト | セッションのエスクローコントラクト |
|
| インメモリ | アクセスキーの永続化 |
|
| インメモリ | セッションチャネルの永続化 |
|
|
| キーを支払いウォレットにバインド |
|
|
| リングバッファ容量(0 = 無効) |
|
| console+redaction | 構造化ロガー |
|
|
| グレースフルシャットダウンのタイムアウト |
|
| — | ドレイン開始時に発火するフック |
| object | 60/min per tool | レート制限の設定 |
|
| — | OpenTelemetryトレーサー(オプトイン) |
|
| — | イベントプッシュの設定 |
クライアント(PaidMcpClientConfig)
フィールド | 型 | デフォルト | 説明 |
|
| required | クライアント名 |
|
| required | クライアントバージョン |
|
| required | エージェントウォレットの秘密鍵 |
|
|
| 1回の呼び出しあたりの最大支出(USD) |
|
|
| 累計最大支出(USD) |
|
|
| チャネル最大預入額(USD) |
|
|
| Tempoネットワーク |
|
| console+redaction | 構造化ロガー |
|
|
| セッション決済トランザクションをオンチェーンで検証 |
例
例 | 料金体系 | トランスポート | デモ内容 |
| 呼び出しごと | InMemory | 単一プロセスでの完全な402ラウンドトリップ |
| 呼び出しごと | stdio | エージェントがサーバーをサブプロセスとして起動 |
| 呼び出しごと | Streamable HTTP | Express上のネットワークサーバー |
| 呼び出しごと | SSE (legacy) | 後方互換のSSEトランスポート |
| 呼び出しごと + アクセスキー | Streamable HTTP | MCP + ダッシュボード + ディスカバリの組み合わせ |
| セッション | stdio | ペイメントチャネル、バウチャー、クローズ |
| アクセスキー | stdio | デイパス、時間限定、コールパック |
| 呼び出しごと | stdio | Peer Cashツールをゲートし、MPP収益を現金化 |
任意の例を実行:
# 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:serverテストウォレットへの資金投入
有料の例では、Tempoテストネット上で資金が入ったウォレットが必要です。Peer Cashの例は例外で、収益ルートがライブのみのためTempoメインネットを使用します。
cast rpc tempo_fundAddress 0xYourAddress --rpc-url https://rpc.moderato.tempo.xyzランタイム互換性
コアライブラリ(サーバー、クライアント、ストア、レート制限、金額、アクセスキー)は、Web Cryptoを介してランタイム間で移植可能です:
ランタイム | サポート |
Node.js 20+ | 完全 |
Cloudflare Workers | 完全 |
Vercel Edge | 完全 |
Deno | 完全 |
Bun | 完全 |
auth.tsミドルウェアモジュールはnode:cryptoを使用し、Node.jsが必要です。エッジデプロイメントでは、代わりにプラットフォームのネイティブルーターと認証プリミティブを使用します。
アーキテクチャ
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 adapterパッケージエクスポート
{
".": "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"
}設計原則
収益の正確性 — すべての金額計算は
bigint基本単位(小数6桁)を使用します。数百万回の操作後も浮動小数点のずれは発生しません。ゼロコストのオプトイン — トレーシング、ウェブフック、レート制限は、設定しない限りノーオペレーションです。トレースしないデプロイメントではスパンは割り当てられません。
すべてプラグ可能 — ストア、ロガー、レートリミッター、認証はインターフェースベースです。ゲートウェイコードに触れることなく実装を交換できます。
フェイルファスト — 設定エラーはリクエスト時ではなく構築時にスローされます。
エラーは値 — 安定したコードを持つ型付きエラークラス。プログラムによる処理には
instanceofまたはerr.codeを使用します。リングバッファコールログ — O(1)で事前割り当てされ、決して増大しません。高スループット下でもGCプレッシャーがありません。
グレースフルライフサイクル — シャットダウンゲートは新しい呼び出しを拒否し、ドレインは進行中の呼び出しを待機し、ウェブフックをフラッシュしてから切断します。
開発
# 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 docsテストスイート
27以上のテストファイルが以下をカバー:
アクセスキーの原子性(Nコールキーの並行リデーム)
アクセスキーフロー(発行 → リデーム → 消費 → 再支払い)
金額計算(BigInt変換、エッジケース)
認証ミドルウェア(全5ファクトリー)
コールログリングバッファ(ラップアラウンド、容量制限)
グレースフルシャットダウンとドレイン
ダッシュボードAPIレスポンス
ディスカバリ / OpenAPI生成
エラータクソノミー
無料ツール(支払い不要パス)
ロガー(構造化出力、リダクション、子ロガー)
Prometheusメトリクスフォーマット
マルチカレンシーディスカバリ
有料フロー(402 → クレデンシャル → レシート)
料金計算(段階的、呼び出しごと)
レート制限(トークンバケット、拒否、retry-after)
収益の正確性(多数の呼び出しにわたるBigInt累積)
ランタイムヘルパー(randomHex、hmacSha256Hex)
セッションライフサイクル(オープン → バウチャー → クローズ → 決済)
支出上限(1回あたり、合計、セッション預入)
OpenTelemetryトレーシング(スパン属性、エラー記録)
ウェブフック(配信、リトライ、HMAC署名、デッドレター)
型テスト(
tsd経由)スループットベンチマーク(
vitest bench経由)
グレースフルシャットダウン
close()をコンテナのシャットダウンシグナルに接続:
process.on('SIGTERM', async () => {
try {
await server.close({ timeoutMs: 25_000 })
process.exit(0)
} catch {
process.exit(1) // drain timed out
}
})構造化ロギング
ライブラリにはプラグ可能なLoggerインターフェースが同梱されています。デフォルト:秘密情報(秘密鍵、クレデンシャル、署名済みトランザクション)を自動的にリダクションしてstderrにJSONで出力します。
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(),
})pino、winston、または任意のロギングライブラリに適合:
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) */,
}ライセンス
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