paygate-mcp 8.2.0 → 8.3.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 +35 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +106 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -109,6 +109,7 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
109
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
|
|
110
110
|
- **Admin Notifications** — `GET /admin/notifications` scans all keys for actionable issues: expired/expiring keys, zero credits, credit depletion velocity, suspended keys, high error rates, and rate limit pressure — with severity filtering and priority sorting
|
|
111
111
|
- **System Dashboard** — `GET /admin/dashboard` system-wide overview with key counts (active/suspended/revoked/expired), credit summary (allocated/spent/remaining), usage breakdown with deny reasons, top consumers, top tools, notification counts, and uptime
|
|
112
|
+
- **Key Lifecycle Report** — `GET /admin/lifecycle` aggregated lifecycle trends with daily creation/revocation/suspension buckets, average key lifetime, and at-risk keys (expiring, expired, zero credits)
|
|
112
113
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
113
114
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
114
115
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -2467,6 +2468,40 @@ curl http://localhost:3402/admin/dashboard \
|
|
|
2467
2468
|
|
|
2468
2469
|
Combines key counts by state, credit allocation and spending totals, usage breakdown with deny reasons, top 10 consumers ranked by credits spent, top 10 tools ranked by call count, notification severity counts, and server uptime. Read-only.
|
|
2469
2470
|
|
|
2471
|
+
### Key Lifecycle Report
|
|
2472
|
+
|
|
2473
|
+
Track key creation, revocation, suspension trends and identify at-risk keys:
|
|
2474
|
+
|
|
2475
|
+
```bash
|
|
2476
|
+
# Full lifecycle report
|
|
2477
|
+
curl http://localhost:3402/admin/lifecycle \
|
|
2478
|
+
-H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
2479
|
+
|
|
2480
|
+
# Filter by date range
|
|
2481
|
+
curl "http://localhost:3402/admin/lifecycle?since=2026-02-01&until=2026-02-28" \
|
|
2482
|
+
-H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
2483
|
+
```
|
|
2484
|
+
|
|
2485
|
+
**Response:**
|
|
2486
|
+
|
|
2487
|
+
```json
|
|
2488
|
+
{
|
|
2489
|
+
"events": { "created": 25, "revoked": 3, "suspended": 5, "resumed": 4, "rotated": 2, "cloned": 1 },
|
|
2490
|
+
"trends": [
|
|
2491
|
+
{ "date": "2026-02-25", "created": 5, "revoked": 1, "suspended": 2, "resumed": 1 },
|
|
2492
|
+
{ "date": "2026-02-26", "created": 8, "revoked": 0, "suspended": 1, "resumed": 2 },
|
|
2493
|
+
{ "date": "2026-02-27", "created": 12, "revoked": 2, "suspended": 2, "resumed": 1 }
|
|
2494
|
+
],
|
|
2495
|
+
"averageLifetimeHours": 168.5,
|
|
2496
|
+
"atRisk": [
|
|
2497
|
+
{ "key": "pg_c815...09a6", "name": "staging-agent", "risk": "expiring_soon", "details": { "expiresAt": "2026-03-01T...", "daysRemaining": 2.5 } },
|
|
2498
|
+
{ "key": "pg_a3f1...b2e4", "name": "batch-worker", "risk": "zero_credits", "details": { "credits": 0 } }
|
|
2499
|
+
]
|
|
2500
|
+
}
|
|
2501
|
+
```
|
|
2502
|
+
|
|
2503
|
+
Shows aggregated lifecycle event counts, daily trend buckets (sorted chronologically), average key lifetime in hours (for revoked keys), and at-risk keys with their risk category (`expired`, `expiring_soon`, `zero_credits`). Supports `?since=` and `?until=` date filters. Excludes suspended and revoked keys from at-risk list. Read-only.
|
|
2504
|
+
|
|
2470
2505
|
### IP Allowlisting
|
|
2471
2506
|
|
|
2472
2507
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
package/dist/server.d.ts
CHANGED
|
@@ -244,6 +244,7 @@ export declare class PayGateServer {
|
|
|
244
244
|
private handleAdminEventStream;
|
|
245
245
|
private handleAdminNotifications;
|
|
246
246
|
private handleSystemDashboard;
|
|
247
|
+
private handleKeyLifecycleReport;
|
|
247
248
|
private handleGetNotes;
|
|
248
249
|
private handleAddNote;
|
|
249
250
|
private handleDeleteNote;
|
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
|
@@ -810,6 +810,12 @@ class PayGateServer {
|
|
|
810
810
|
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
811
811
|
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
812
812
|
return;
|
|
813
|
+
case '/admin/lifecycle':
|
|
814
|
+
if (req.method === 'GET')
|
|
815
|
+
return this.handleKeyLifecycleReport(req, res);
|
|
816
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
817
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
818
|
+
return;
|
|
813
819
|
// ─── Plugin endpoints ──────────────────────────────────────────────
|
|
814
820
|
case '/plugins':
|
|
815
821
|
return this.handleListPlugins(req, res);
|
|
@@ -1352,6 +1358,7 @@ class PayGateServer {
|
|
|
1352
1358
|
keyDashboard: 'GET /keys/dashboard?key=... — Consolidated key overview with metadata, balance, health, velocity, rate limits, quotas, and recent activity (requires X-Admin-Key)',
|
|
1353
1359
|
adminNotifications: 'GET /admin/notifications — Actionable notifications for expiring keys, low credits, high error rates, and rate limit pressure (requires X-Admin-Key)',
|
|
1354
1360
|
systemDashboard: 'GET /admin/dashboard — System-wide overview with key stats, credit summary, usage breakdown, top consumers, and uptime (requires X-Admin-Key)',
|
|
1361
|
+
keyLifecycle: 'GET /admin/lifecycle — Key lifecycle report with creation/revocation/expiry trends, average lifetime, and at-risk keys (requires X-Admin-Key)',
|
|
1355
1362
|
...(this.oauth ? {
|
|
1356
1363
|
oauthMetadata: 'GET /.well-known/oauth-authorization-server — OAuth 2.1 server metadata',
|
|
1357
1364
|
oauthRegister: 'POST /oauth/register — Register OAuth client',
|
|
@@ -4552,6 +4559,105 @@ class PayGateServer {
|
|
|
4552
4559
|
},
|
|
4553
4560
|
}));
|
|
4554
4561
|
}
|
|
4562
|
+
// ─── /admin/lifecycle — Key lifecycle report ──────────────────────────────
|
|
4563
|
+
handleKeyLifecycleReport(req, res) {
|
|
4564
|
+
if (!this.checkAdmin(req, res))
|
|
4565
|
+
return;
|
|
4566
|
+
const urlParts = req.url?.split('?') || [];
|
|
4567
|
+
const params = new URLSearchParams(urlParts[1] || '');
|
|
4568
|
+
const since = params.get('since') || undefined;
|
|
4569
|
+
const until = params.get('until') || undefined;
|
|
4570
|
+
// Query audit log for key lifecycle events
|
|
4571
|
+
const createdEvents = this.audit.query({
|
|
4572
|
+
types: ['key.created'], since, until, limit: 10_000,
|
|
4573
|
+
}).events;
|
|
4574
|
+
const revokedEvents = this.audit.query({
|
|
4575
|
+
types: ['key.revoked'], since, until, limit: 10_000,
|
|
4576
|
+
}).events;
|
|
4577
|
+
const suspendedEvents = this.audit.query({
|
|
4578
|
+
types: ['key.suspended'], since, until, limit: 10_000,
|
|
4579
|
+
}).events;
|
|
4580
|
+
const resumedEvents = this.audit.query({
|
|
4581
|
+
types: ['key.resumed'], since, until, limit: 10_000,
|
|
4582
|
+
}).events;
|
|
4583
|
+
const rotatedEvents = this.audit.query({
|
|
4584
|
+
types: ['key.rotated'], since, until, limit: 10_000,
|
|
4585
|
+
}).events;
|
|
4586
|
+
const clonedEvents = this.audit.query({
|
|
4587
|
+
types: ['key.cloned'], since, until, limit: 10_000,
|
|
4588
|
+
}).events;
|
|
4589
|
+
// Build daily buckets for trends
|
|
4590
|
+
const dayBuckets = new Map();
|
|
4591
|
+
const addToBucket = (events, field) => {
|
|
4592
|
+
for (const e of events) {
|
|
4593
|
+
const day = e.timestamp.slice(0, 10); // YYYY-MM-DD
|
|
4594
|
+
if (!dayBuckets.has(day))
|
|
4595
|
+
dayBuckets.set(day, { created: 0, revoked: 0, suspended: 0, resumed: 0 });
|
|
4596
|
+
dayBuckets.get(day)[field]++;
|
|
4597
|
+
}
|
|
4598
|
+
};
|
|
4599
|
+
addToBucket(createdEvents, 'created');
|
|
4600
|
+
addToBucket(revokedEvents, 'revoked');
|
|
4601
|
+
addToBucket(suspendedEvents, 'suspended');
|
|
4602
|
+
addToBucket(resumedEvents, 'resumed');
|
|
4603
|
+
const trends = Array.from(dayBuckets.entries())
|
|
4604
|
+
.map(([date, counts]) => ({ date, ...counts }))
|
|
4605
|
+
.sort((a, b) => a.date.localeCompare(b.date));
|
|
4606
|
+
// Average key lifetime (for revoked keys that have creation metadata)
|
|
4607
|
+
const now = Date.now();
|
|
4608
|
+
const allRecords = this.gate.store.getAllRecords();
|
|
4609
|
+
const lifetimes = [];
|
|
4610
|
+
for (const record of allRecords) {
|
|
4611
|
+
if (!record.active && record.createdAt) {
|
|
4612
|
+
// Revoked key — estimate lifetime from created to now (or expiry)
|
|
4613
|
+
const created = new Date(record.createdAt).getTime();
|
|
4614
|
+
const end = record.expiresAt ? Math.min(new Date(record.expiresAt).getTime(), now) : now;
|
|
4615
|
+
if (created > 0 && end > created) {
|
|
4616
|
+
lifetimes.push(end - created);
|
|
4617
|
+
}
|
|
4618
|
+
}
|
|
4619
|
+
}
|
|
4620
|
+
const avgLifetimeHours = lifetimes.length > 0
|
|
4621
|
+
? Math.round(lifetimes.reduce((a, b) => a + b, 0) / lifetimes.length / 3_600_000 * 10) / 10
|
|
4622
|
+
: null;
|
|
4623
|
+
// At-risk keys: active keys expiring within 7 days or with zero credits
|
|
4624
|
+
const atRiskKeys = [];
|
|
4625
|
+
for (const record of allRecords) {
|
|
4626
|
+
if (!record.active)
|
|
4627
|
+
continue;
|
|
4628
|
+
if (record.suspended)
|
|
4629
|
+
continue;
|
|
4630
|
+
const maskedKey = record.key.slice(0, 7) + '...' + record.key.slice(-4);
|
|
4631
|
+
const keyName = record.name || undefined;
|
|
4632
|
+
if (record.credits <= 0) {
|
|
4633
|
+
atRiskKeys.push({ key: maskedKey, name: keyName, risk: 'zero_credits', details: { credits: 0 } });
|
|
4634
|
+
}
|
|
4635
|
+
if (record.expiresAt) {
|
|
4636
|
+
const msToExpiry = new Date(record.expiresAt).getTime() - now;
|
|
4637
|
+
if (msToExpiry <= 0) {
|
|
4638
|
+
atRiskKeys.push({ key: maskedKey, name: keyName, risk: 'expired', details: { expiresAt: record.expiresAt } });
|
|
4639
|
+
}
|
|
4640
|
+
else if (msToExpiry <= 7 * 24 * 3_600_000) {
|
|
4641
|
+
const daysLeft = Math.round(msToExpiry / 86_400_000 * 10) / 10;
|
|
4642
|
+
atRiskKeys.push({ key: maskedKey, name: keyName, risk: 'expiring_soon', details: { expiresAt: record.expiresAt, daysRemaining: daysLeft } });
|
|
4643
|
+
}
|
|
4644
|
+
}
|
|
4645
|
+
}
|
|
4646
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
4647
|
+
res.end(JSON.stringify({
|
|
4648
|
+
events: {
|
|
4649
|
+
created: createdEvents.length,
|
|
4650
|
+
revoked: revokedEvents.length,
|
|
4651
|
+
suspended: suspendedEvents.length,
|
|
4652
|
+
resumed: resumedEvents.length,
|
|
4653
|
+
rotated: rotatedEvents.length,
|
|
4654
|
+
cloned: clonedEvents.length,
|
|
4655
|
+
},
|
|
4656
|
+
trends,
|
|
4657
|
+
averageLifetimeHours: avgLifetimeHours,
|
|
4658
|
+
atRisk: atRiskKeys,
|
|
4659
|
+
}));
|
|
4660
|
+
}
|
|
4555
4661
|
// ─── /keys/notes — Timestamped notes on API keys ─────────────────────────
|
|
4556
4662
|
handleGetNotes(req, res) {
|
|
4557
4663
|
if (!this.checkAdmin(req, res))
|