paygate-mcp 7.9.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +189 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -106,6 +106,7 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
106
106
|
- **Tool Call Dry Run** — `POST /requests/dry-run` simulates 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
|
|
107
107
|
- **Batch Dry Run** — `POST /requests/dry-run/batch` simulates 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
|
|
108
108
|
- **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
|
|
109
|
+
- **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
|
|
109
110
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
110
111
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
111
112
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -2330,6 +2331,35 @@ curl "http://localhost:3402/tools/available?key=pg_..." \
|
|
|
2330
2331
|
|
|
2331
2332
|
Returns every discovered tool with: `accessible` (ACL check), `denyReason` (if blocked), `creditsPerCall`, `canAfford` (credits vs price), and per-tool `rateLimit` when configured. Includes global rate limit info. Supports alias keys. Works on suspended keys (informational). Read-only — does not deduct credits or increment rate counters.
|
|
2332
2333
|
|
|
2334
|
+
### Key Dashboard
|
|
2335
|
+
|
|
2336
|
+
Get a consolidated overview of any API key in a single request:
|
|
2337
|
+
|
|
2338
|
+
```bash
|
|
2339
|
+
curl "http://localhost:3402/keys/dashboard?key=pg_..." \
|
|
2340
|
+
-H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
2341
|
+
```
|
|
2342
|
+
|
|
2343
|
+
**Response:**
|
|
2344
|
+
|
|
2345
|
+
```json
|
|
2346
|
+
{
|
|
2347
|
+
"key": "pg_c815...09a6",
|
|
2348
|
+
"name": "production-agent",
|
|
2349
|
+
"status": "active",
|
|
2350
|
+
"namespace": "prod",
|
|
2351
|
+
"balance": { "credits": 850, "totalSpent": 150, "totalAllocated": 1000, "spendingLimit": 500 },
|
|
2352
|
+
"health": { "score": 92, "status": "good" },
|
|
2353
|
+
"velocity": { "creditsPerHour": 6.2, "creditsPerDay": 149, "estimatedDepletionDate": "2025-02-03T..." },
|
|
2354
|
+
"rateLimits": { "global": { "limit": 60, "used": 12, "remaining": 48, "resetInMs": 35000 } },
|
|
2355
|
+
"quotas": { "source": "global", "daily": { "callsUsed": 24, "callsLimit": 100 }, "monthly": { "callsUsed": 340, "callsLimit": 5000 } },
|
|
2356
|
+
"usage": { "totalCalls": 340, "totalAllowed": 330, "totalDenied": 10, "totalCredits": 150 },
|
|
2357
|
+
"recentActivity": [{ "timestamp": "...", "event": "gate.allowed", "tool": "search", "credits": 5 }]
|
|
2358
|
+
}
|
|
2359
|
+
```
|
|
2360
|
+
|
|
2361
|
+
Combines metadata (status/namespace/group/tags), balance (credits/spent/allocated/spendingLimit), health score (0-100 composite), spending velocity with depletion forecast, rate limit and quota status, usage summary, and last 10 audit events. Supports alias keys. Works on suspended/revoked/expired keys. Read-only.
|
|
2362
|
+
|
|
2333
2363
|
### IP Allowlisting
|
|
2334
2364
|
|
|
2335
2365
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
package/dist/server.d.ts
CHANGED
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -638,6 +638,12 @@ class PayGateServer {
|
|
|
638
638
|
return this.handleKeyComparison(req, res);
|
|
639
639
|
case '/keys/health':
|
|
640
640
|
return this.handleKeyHealth(req, res);
|
|
641
|
+
case '/keys/dashboard':
|
|
642
|
+
if (req.method === 'GET')
|
|
643
|
+
return this.handleKeyDashboard(req, res);
|
|
644
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
645
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
646
|
+
return;
|
|
641
647
|
case '/keys/templates':
|
|
642
648
|
if (req.method === 'GET')
|
|
643
649
|
return this.handleListTemplates(req, res);
|
|
@@ -1331,6 +1337,7 @@ class PayGateServer {
|
|
|
1331
1337
|
requestDryRunBatch: 'POST /requests/dry-run/batch — Simulate multiple tool calls without executing (requires X-Admin-Key)',
|
|
1332
1338
|
toolStats: 'GET /tools/stats — Per-tool call counts, success rates, latency, credits, and top consumers (requires X-Admin-Key)',
|
|
1333
1339
|
toolAvailability: 'GET /tools/available?key=... — Per-key tool availability with pricing, affordability, and rate limit status (requires X-Admin-Key)',
|
|
1340
|
+
keyDashboard: 'GET /keys/dashboard?key=... — Consolidated key overview with metadata, balance, health, velocity, rate limits, quotas, and recent activity (requires X-Admin-Key)',
|
|
1334
1341
|
...(this.oauth ? {
|
|
1335
1342
|
oauthMetadata: 'GET /.well-known/oauth-authorization-server — OAuth 2.1 server metadata',
|
|
1336
1343
|
oauthRegister: 'POST /oauth/register — Register OAuth client',
|
|
@@ -3289,6 +3296,188 @@ class PayGateServer {
|
|
|
3289
3296
|
},
|
|
3290
3297
|
}));
|
|
3291
3298
|
}
|
|
3299
|
+
// ─── /keys/dashboard — Consolidated key overview ──────────────────────────────
|
|
3300
|
+
handleKeyDashboard(req, res) {
|
|
3301
|
+
if (!this.checkAdmin(req, res))
|
|
3302
|
+
return;
|
|
3303
|
+
const urlParts = req.url?.split('?') || [];
|
|
3304
|
+
const params = new URLSearchParams(urlParts[1] || '');
|
|
3305
|
+
const keyParam = params.get('key');
|
|
3306
|
+
if (!keyParam) {
|
|
3307
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3308
|
+
res.end(JSON.stringify({ error: 'Missing required parameter: key' }));
|
|
3309
|
+
return;
|
|
3310
|
+
}
|
|
3311
|
+
const record = this.gate.store.resolveKeyRaw(keyParam);
|
|
3312
|
+
if (!record) {
|
|
3313
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
3314
|
+
res.end(JSON.stringify({ error: 'Key not found' }));
|
|
3315
|
+
return;
|
|
3316
|
+
}
|
|
3317
|
+
const actualKey = record.key;
|
|
3318
|
+
const maskedKey = actualKey.slice(0, 7) + '...' + actualKey.slice(-4);
|
|
3319
|
+
// ── Metadata ──
|
|
3320
|
+
const isExpired = record.expiresAt ? new Date(record.expiresAt).getTime() < Date.now() : false;
|
|
3321
|
+
let status = 'active';
|
|
3322
|
+
if (!record.active)
|
|
3323
|
+
status = 'revoked';
|
|
3324
|
+
else if (record.suspended)
|
|
3325
|
+
status = 'suspended';
|
|
3326
|
+
else if (isExpired)
|
|
3327
|
+
status = 'expired';
|
|
3328
|
+
const metadata = {
|
|
3329
|
+
key: maskedKey,
|
|
3330
|
+
name: record.name || null,
|
|
3331
|
+
status,
|
|
3332
|
+
namespace: record.namespace || null,
|
|
3333
|
+
group: record.group || null,
|
|
3334
|
+
createdAt: record.createdAt || null,
|
|
3335
|
+
...(record.expiresAt ? { expiresAt: record.expiresAt } : {}),
|
|
3336
|
+
tags: record.tags && Object.keys(record.tags).length > 0 ? record.tags : undefined,
|
|
3337
|
+
};
|
|
3338
|
+
// ── Balance ──
|
|
3339
|
+
const balance = {
|
|
3340
|
+
credits: record.credits,
|
|
3341
|
+
totalSpent: record.totalSpent || 0,
|
|
3342
|
+
totalAllocated: record.credits + (record.totalSpent || 0),
|
|
3343
|
+
...(record.spendingLimit ? { spendingLimit: record.spendingLimit } : {}),
|
|
3344
|
+
};
|
|
3345
|
+
// ── Health score (simplified from handleKeyHealth) ──
|
|
3346
|
+
const velocity = this.creditLedger.getSpendingVelocity(actualKey, record.credits, 24);
|
|
3347
|
+
let balanceScore = 100;
|
|
3348
|
+
if (velocity.creditsPerHour > 0) {
|
|
3349
|
+
const hoursLeft = velocity.estimatedHoursRemaining ?? Infinity;
|
|
3350
|
+
if (hoursLeft <= 1)
|
|
3351
|
+
balanceScore = 0;
|
|
3352
|
+
else if (hoursLeft <= 6)
|
|
3353
|
+
balanceScore = 20;
|
|
3354
|
+
else if (hoursLeft <= 24)
|
|
3355
|
+
balanceScore = 40;
|
|
3356
|
+
else if (hoursLeft <= 72)
|
|
3357
|
+
balanceScore = 60;
|
|
3358
|
+
else if (hoursLeft <= 168)
|
|
3359
|
+
balanceScore = 80;
|
|
3360
|
+
}
|
|
3361
|
+
else if (record.credits <= 0) {
|
|
3362
|
+
balanceScore = 0;
|
|
3363
|
+
}
|
|
3364
|
+
// Quota component
|
|
3365
|
+
let quotaScore = 100;
|
|
3366
|
+
const quotaConfig = record.quota || this.config.globalQuota;
|
|
3367
|
+
if (quotaConfig) {
|
|
3368
|
+
this.gate.quotaTracker.resetIfNeeded(record);
|
|
3369
|
+
let maxUtil = 0;
|
|
3370
|
+
if (quotaConfig.dailyCallLimit && quotaConfig.dailyCallLimit > 0)
|
|
3371
|
+
maxUtil = Math.max(maxUtil, record.quotaDailyCalls / quotaConfig.dailyCallLimit);
|
|
3372
|
+
if (quotaConfig.monthlyCallLimit && quotaConfig.monthlyCallLimit > 0)
|
|
3373
|
+
maxUtil = Math.max(maxUtil, record.quotaMonthlyCalls / quotaConfig.monthlyCallLimit);
|
|
3374
|
+
if (quotaConfig.dailyCreditLimit && quotaConfig.dailyCreditLimit > 0)
|
|
3375
|
+
maxUtil = Math.max(maxUtil, record.quotaDailyCredits / quotaConfig.dailyCreditLimit);
|
|
3376
|
+
if (quotaConfig.monthlyCreditLimit && quotaConfig.monthlyCreditLimit > 0)
|
|
3377
|
+
maxUtil = Math.max(maxUtil, record.quotaMonthlyCredits / quotaConfig.monthlyCreditLimit);
|
|
3378
|
+
quotaScore = Math.max(0, Math.round((1 - maxUtil) * 100));
|
|
3379
|
+
}
|
|
3380
|
+
// Rate limit component
|
|
3381
|
+
const rateStatus = this.gate.rateLimiter.getStatus(actualKey);
|
|
3382
|
+
let rateLimitScore = 100;
|
|
3383
|
+
if (rateStatus.limit > 0) {
|
|
3384
|
+
const utilization = rateStatus.used / rateStatus.limit;
|
|
3385
|
+
rateLimitScore = Math.max(0, Math.round((1 - utilization) * 100));
|
|
3386
|
+
}
|
|
3387
|
+
// Error rate component
|
|
3388
|
+
const keyUsage = this.gate.meter.getKeyUsage(actualKey);
|
|
3389
|
+
let errorScore = 100;
|
|
3390
|
+
if (keyUsage.totalCalls > 0) {
|
|
3391
|
+
const errorRate = keyUsage.totalDenied / keyUsage.totalCalls;
|
|
3392
|
+
errorScore = Math.max(0, Math.round((1 - errorRate) * 100));
|
|
3393
|
+
}
|
|
3394
|
+
const healthScore = Math.round(balanceScore * 0.30 + quotaScore * 0.25 + rateLimitScore * 0.20 + errorScore * 0.25);
|
|
3395
|
+
let healthStatus = 'healthy';
|
|
3396
|
+
if (healthScore < 25)
|
|
3397
|
+
healthStatus = 'critical';
|
|
3398
|
+
else if (healthScore < 50)
|
|
3399
|
+
healthStatus = 'warning';
|
|
3400
|
+
else if (healthScore < 75)
|
|
3401
|
+
healthStatus = 'caution';
|
|
3402
|
+
else if (healthScore < 90)
|
|
3403
|
+
healthStatus = 'good';
|
|
3404
|
+
// ── Velocity ──
|
|
3405
|
+
const velocitySummary = {
|
|
3406
|
+
creditsPerHour: velocity.creditsPerHour,
|
|
3407
|
+
creditsPerDay: velocity.creditsPerDay,
|
|
3408
|
+
callsPerHour: velocity.callsPerHour,
|
|
3409
|
+
callsPerDay: velocity.callsPerDay,
|
|
3410
|
+
estimatedDepletionDate: velocity.estimatedDepletionDate || null,
|
|
3411
|
+
};
|
|
3412
|
+
// ── Rate limits ──
|
|
3413
|
+
const rateLimits = {
|
|
3414
|
+
global: {
|
|
3415
|
+
limit: rateStatus.limit,
|
|
3416
|
+
used: rateStatus.used,
|
|
3417
|
+
remaining: rateStatus.remaining,
|
|
3418
|
+
resetInMs: rateStatus.resetInMs,
|
|
3419
|
+
},
|
|
3420
|
+
};
|
|
3421
|
+
// ── Quotas ──
|
|
3422
|
+
let quotas;
|
|
3423
|
+
if (quotaConfig) {
|
|
3424
|
+
this.gate.quotaTracker.resetIfNeeded(record);
|
|
3425
|
+
quotas = {
|
|
3426
|
+
source: record.quota ? 'per-key' : 'global',
|
|
3427
|
+
daily: {
|
|
3428
|
+
callsUsed: record.quotaDailyCalls,
|
|
3429
|
+
callsLimit: quotaConfig.dailyCallLimit || 0,
|
|
3430
|
+
creditsUsed: record.quotaDailyCredits,
|
|
3431
|
+
creditsLimit: quotaConfig.dailyCreditLimit || 0,
|
|
3432
|
+
},
|
|
3433
|
+
monthly: {
|
|
3434
|
+
callsUsed: record.quotaMonthlyCalls,
|
|
3435
|
+
callsLimit: quotaConfig.monthlyCallLimit || 0,
|
|
3436
|
+
creditsUsed: record.quotaMonthlyCredits,
|
|
3437
|
+
creditsLimit: quotaConfig.monthlyCreditLimit || 0,
|
|
3438
|
+
},
|
|
3439
|
+
};
|
|
3440
|
+
}
|
|
3441
|
+
// ── Usage summary ──
|
|
3442
|
+
const usage = {
|
|
3443
|
+
totalCalls: keyUsage.totalCalls || 0,
|
|
3444
|
+
totalAllowed: keyUsage.totalAllowed || 0,
|
|
3445
|
+
totalDenied: keyUsage.totalDenied || 0,
|
|
3446
|
+
totalCredits: keyUsage.totalCreditsSpent || 0,
|
|
3447
|
+
};
|
|
3448
|
+
// ── Recent activity (last 10 events) ──
|
|
3449
|
+
const maskedForAudit = (0, audit_1.maskKeyForAudit)(actualKey);
|
|
3450
|
+
const auditResult = this.audit.query({ limit: 100 });
|
|
3451
|
+
const recentActivity = auditResult.events
|
|
3452
|
+
.filter(e => {
|
|
3453
|
+
for (const field of ['key', 'keyMasked', 'sourceKey', 'destKey']) {
|
|
3454
|
+
const val = e.metadata?.[field];
|
|
3455
|
+
if (val && typeof val === 'string' && val === maskedForAudit)
|
|
3456
|
+
return true;
|
|
3457
|
+
}
|
|
3458
|
+
if (e.actor === maskedForAudit)
|
|
3459
|
+
return true;
|
|
3460
|
+
return false;
|
|
3461
|
+
})
|
|
3462
|
+
.slice(0, 10)
|
|
3463
|
+
.map(e => ({
|
|
3464
|
+
timestamp: e.timestamp,
|
|
3465
|
+
event: e.type,
|
|
3466
|
+
...(e.metadata?.tool ? { tool: e.metadata.tool } : {}),
|
|
3467
|
+
...(e.metadata?.credits ? { credits: e.metadata.credits } : {}),
|
|
3468
|
+
}));
|
|
3469
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
3470
|
+
res.end(JSON.stringify({
|
|
3471
|
+
...metadata,
|
|
3472
|
+
balance,
|
|
3473
|
+
health: { score: healthScore, status: healthStatus },
|
|
3474
|
+
velocity: velocitySummary,
|
|
3475
|
+
rateLimits,
|
|
3476
|
+
...(quotas ? { quotas } : {}),
|
|
3477
|
+
usage,
|
|
3478
|
+
recentActivity: recentActivity.length > 0 ? recentActivity : [],
|
|
3479
|
+
}));
|
|
3480
|
+
}
|
|
3292
3481
|
// ─── /keys/auto-topup — Configure auto-topup ────────────────────────────────
|
|
3293
3482
|
async handleSetAutoTopup(req, res) {
|
|
3294
3483
|
if (req.method !== 'POST') {
|