paygate-mcp 8.24.0 → 8.26.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 +44 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +149 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -131,6 +131,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
131
131
|
- **Namespace Usage Summary** — `GET /admin/namespace-usage` per-namespace usage metrics with credit allocation, spending, call counts, and cross-namespace comparison
|
|
132
132
|
- **Audit Summary** — `GET /admin/audit-summary` audit event analytics with type breakdown, top actors, recent events, and activity summary
|
|
133
133
|
- **Group Performance** — `GET /admin/group-performance` per-group analytics with key counts, credit allocation/spending, call volume, utilization, and policy summary
|
|
134
|
+
- **Request Volume Trends** — `GET /admin/request-trends` hourly time-series of request volume, success/failure counts, credit spend, avg duration, and peak hour identification
|
|
135
|
+
- **Key Status Overview** — `GET /admin/key-status` key status dashboard with active/suspended/revoked/expired counts and keys needing attention (low credits, near expiry)
|
|
134
136
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
135
137
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
136
138
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -3036,6 +3038,48 @@ curl http://localhost:3000/admin/group-performance -H "X-Admin-Key: YOUR_ADMIN_K
|
|
|
3036
3038
|
|
|
3037
3039
|
Per-group analytics: key counts, credit allocation/spending/remaining, call volume, and utilization percentages. Includes group policy summary (allowed/denied tools, rate limits). Sorted by spending (highest first). Also reports ungrouped key count. Read-only.
|
|
3038
3040
|
|
|
3041
|
+
### Request Volume Trends
|
|
3042
|
+
|
|
3043
|
+
```bash
|
|
3044
|
+
curl http://localhost:3000/admin/request-trends -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
3045
|
+
```
|
|
3046
|
+
|
|
3047
|
+
```json
|
|
3048
|
+
{
|
|
3049
|
+
"summary": {
|
|
3050
|
+
"totalRequests": 150, "totalAllowed": 130, "totalDenied": 20,
|
|
3051
|
+
"totalCredits": 650, "avgDurationMs": 45,
|
|
3052
|
+
"peakHour": { "hour": "2025-01-15T14:00:00Z", "total": 42 }
|
|
3053
|
+
},
|
|
3054
|
+
"hourly": [
|
|
3055
|
+
{ "hour": "2025-01-15T12:00:00Z", "total": 35, "allowed": 30, "denied": 5, "credits": 150, "avgDurationMs": 40 },
|
|
3056
|
+
{ "hour": "2025-01-15T13:00:00Z", "total": 42, "allowed": 38, "denied": 4, "credits": 190, "avgDurationMs": 50 }
|
|
3057
|
+
],
|
|
3058
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
3059
|
+
}
|
|
3060
|
+
```
|
|
3061
|
+
|
|
3062
|
+
Hourly request volume time-series: total/allowed/denied counts, credit spend, and average duration per hour. Includes summary with peak hour identification. Built from request log data. Sorted chronologically. Read-only.
|
|
3063
|
+
|
|
3064
|
+
### Key Status Overview
|
|
3065
|
+
|
|
3066
|
+
```bash
|
|
3067
|
+
curl http://localhost:3000/admin/key-status -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
3068
|
+
```
|
|
3069
|
+
|
|
3070
|
+
```json
|
|
3071
|
+
{
|
|
3072
|
+
"counts": { "total": 20, "active": 15, "suspended": 2, "revoked": 2, "expired": 1 },
|
|
3073
|
+
"needsAttention": [
|
|
3074
|
+
{ "keyName": "low-balance", "issue": "low_credits", "detail": "5 credits remaining" },
|
|
3075
|
+
{ "keyName": "trial-key", "issue": "expiring_soon", "detail": "Expires in 48 hours" }
|
|
3076
|
+
],
|
|
3077
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
3078
|
+
}
|
|
3079
|
+
```
|
|
3080
|
+
|
|
3081
|
+
Key status dashboard: active/suspended/revoked/expired counts with keys needing attention. Flags active keys with low credits (<=10) and near expiry (within 7 days). Read-only.
|
|
3082
|
+
|
|
3039
3083
|
### IP Allowlisting
|
|
3040
3084
|
|
|
3041
3085
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
package/dist/server.d.ts
CHANGED
|
@@ -266,6 +266,8 @@ export declare class PayGateServer {
|
|
|
266
266
|
private handleNamespaceUsage;
|
|
267
267
|
private handleAuditSummary;
|
|
268
268
|
private handleGroupPerformance;
|
|
269
|
+
private handleRequestTrends;
|
|
270
|
+
private handleKeyStatus;
|
|
269
271
|
private handleGetNotes;
|
|
270
272
|
private handleAddNote;
|
|
271
273
|
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
|
@@ -942,6 +942,18 @@ class PayGateServer {
|
|
|
942
942
|
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
943
943
|
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
944
944
|
return;
|
|
945
|
+
case '/admin/request-trends':
|
|
946
|
+
if (req.method === 'GET')
|
|
947
|
+
return this.handleRequestTrends(req, res);
|
|
948
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
949
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
950
|
+
return;
|
|
951
|
+
case '/admin/key-status':
|
|
952
|
+
if (req.method === 'GET')
|
|
953
|
+
return this.handleKeyStatus(req, res);
|
|
954
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
955
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
956
|
+
return;
|
|
945
957
|
// ─── Plugin endpoints ──────────────────────────────────────────────
|
|
946
958
|
case '/plugins':
|
|
947
959
|
return this.handleListPlugins(req, res);
|
|
@@ -1506,6 +1518,8 @@ class PayGateServer {
|
|
|
1506
1518
|
namespaceUsage: 'GET /admin/namespace-usage — Per-namespace usage metrics with credit allocation, spending, call counts, and cross-namespace comparison (requires X-Admin-Key)',
|
|
1507
1519
|
auditSummary: 'GET /admin/audit-summary — Audit event analytics with type breakdown, top actors, recent events, and activity summary (requires X-Admin-Key)',
|
|
1508
1520
|
groupPerformance: 'GET /admin/group-performance — Per-group analytics with key counts, credit allocation/spending, call volume, and utilization (requires X-Admin-Key)',
|
|
1521
|
+
requestTrends: 'GET /admin/request-trends — Hourly request volume time-series with success/failure counts, credit spend, and avg duration (requires X-Admin-Key)',
|
|
1522
|
+
keyStatus: 'GET /admin/key-status — Key status dashboard with active/suspended/revoked/expired counts and keys needing attention (requires X-Admin-Key)',
|
|
1509
1523
|
...(this.oauth ? {
|
|
1510
1524
|
oauthMetadata: 'GET /.well-known/oauth-authorization-server — OAuth 2.1 server metadata',
|
|
1511
1525
|
oauthRegister: 'POST /oauth/register — Register OAuth client',
|
|
@@ -6583,6 +6597,141 @@ class PayGateServer {
|
|
|
6583
6597
|
generatedAt: new Date().toISOString(),
|
|
6584
6598
|
}));
|
|
6585
6599
|
}
|
|
6600
|
+
// ─── /admin/request-trends — Hourly request volume time-series ──────────
|
|
6601
|
+
handleRequestTrends(req, res) {
|
|
6602
|
+
if (!this.checkAdmin(req, res))
|
|
6603
|
+
return;
|
|
6604
|
+
const entries = this.requestLog;
|
|
6605
|
+
if (entries.length === 0) {
|
|
6606
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
6607
|
+
res.end(JSON.stringify({
|
|
6608
|
+
summary: {
|
|
6609
|
+
totalRequests: 0, totalAllowed: 0, totalDenied: 0,
|
|
6610
|
+
totalCredits: 0, avgDurationMs: 0, peakHour: null,
|
|
6611
|
+
},
|
|
6612
|
+
hourly: [],
|
|
6613
|
+
generatedAt: new Date().toISOString(),
|
|
6614
|
+
}));
|
|
6615
|
+
return;
|
|
6616
|
+
}
|
|
6617
|
+
// ── Aggregate into hourly buckets ──
|
|
6618
|
+
let totalAllowed = 0;
|
|
6619
|
+
let totalDenied = 0;
|
|
6620
|
+
let totalCredits = 0;
|
|
6621
|
+
let totalDuration = 0;
|
|
6622
|
+
const buckets = new Map();
|
|
6623
|
+
for (const e of entries) {
|
|
6624
|
+
const ts = new Date(e.timestamp);
|
|
6625
|
+
const hour = ts.toISOString().slice(0, 13) + ':00:00Z'; // YYYY-MM-DDTHH:00:00Z
|
|
6626
|
+
if (!buckets.has(hour)) {
|
|
6627
|
+
buckets.set(hour, { total: 0, allowed: 0, denied: 0, credits: 0, totalDurationMs: 0 });
|
|
6628
|
+
}
|
|
6629
|
+
const b = buckets.get(hour);
|
|
6630
|
+
b.total++;
|
|
6631
|
+
if (e.status === 'allowed') {
|
|
6632
|
+
b.allowed++;
|
|
6633
|
+
totalAllowed++;
|
|
6634
|
+
b.credits += e.credits || 0;
|
|
6635
|
+
totalCredits += e.credits || 0;
|
|
6636
|
+
}
|
|
6637
|
+
else {
|
|
6638
|
+
b.denied++;
|
|
6639
|
+
totalDenied++;
|
|
6640
|
+
}
|
|
6641
|
+
b.totalDurationMs += e.durationMs || 0;
|
|
6642
|
+
totalDuration += e.durationMs || 0;
|
|
6643
|
+
}
|
|
6644
|
+
const hourly = Array.from(buckets.entries())
|
|
6645
|
+
.map(([hour, b]) => ({
|
|
6646
|
+
hour,
|
|
6647
|
+
total: b.total,
|
|
6648
|
+
allowed: b.allowed,
|
|
6649
|
+
denied: b.denied,
|
|
6650
|
+
credits: b.credits,
|
|
6651
|
+
avgDurationMs: b.total > 0 ? Math.round(b.totalDurationMs / b.total) : 0,
|
|
6652
|
+
}))
|
|
6653
|
+
.sort((a, b) => a.hour.localeCompare(b.hour));
|
|
6654
|
+
// ── Peak hour ──
|
|
6655
|
+
let peakHour = hourly[0];
|
|
6656
|
+
for (const h of hourly) {
|
|
6657
|
+
if (h.total > peakHour.total)
|
|
6658
|
+
peakHour = h;
|
|
6659
|
+
}
|
|
6660
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
6661
|
+
res.end(JSON.stringify({
|
|
6662
|
+
summary: {
|
|
6663
|
+
totalRequests: entries.length,
|
|
6664
|
+
totalAllowed,
|
|
6665
|
+
totalDenied,
|
|
6666
|
+
totalCredits,
|
|
6667
|
+
avgDurationMs: entries.length > 0 ? Math.round(totalDuration / entries.length) : 0,
|
|
6668
|
+
peakHour: { hour: peakHour.hour, total: peakHour.total },
|
|
6669
|
+
},
|
|
6670
|
+
hourly,
|
|
6671
|
+
generatedAt: new Date().toISOString(),
|
|
6672
|
+
}));
|
|
6673
|
+
}
|
|
6674
|
+
// ─── /admin/key-status — Key status dashboard ──────────────────────────
|
|
6675
|
+
handleKeyStatus(req, res) {
|
|
6676
|
+
if (!this.checkAdmin(req, res))
|
|
6677
|
+
return;
|
|
6678
|
+
const allRecords = this.gate.store.getAllRecords();
|
|
6679
|
+
const now = Date.now();
|
|
6680
|
+
const sevenDaysMs = 7 * 24 * 60 * 60 * 1000;
|
|
6681
|
+
let active = 0;
|
|
6682
|
+
let suspended = 0;
|
|
6683
|
+
let revoked = 0;
|
|
6684
|
+
let expired = 0;
|
|
6685
|
+
const needsAttention = [];
|
|
6686
|
+
for (const r of allRecords) {
|
|
6687
|
+
// Count status
|
|
6688
|
+
if (r.suspended) {
|
|
6689
|
+
suspended++;
|
|
6690
|
+
}
|
|
6691
|
+
else if (!r.active) {
|
|
6692
|
+
revoked++;
|
|
6693
|
+
}
|
|
6694
|
+
else if (r.expiresAt && new Date(r.expiresAt).getTime() <= now) {
|
|
6695
|
+
expired++;
|
|
6696
|
+
}
|
|
6697
|
+
else {
|
|
6698
|
+
active++;
|
|
6699
|
+
// Check for issues on active keys
|
|
6700
|
+
// Low credits: <= 10 credits remaining
|
|
6701
|
+
if (r.credits <= 10) {
|
|
6702
|
+
needsAttention.push({
|
|
6703
|
+
keyName: r.name,
|
|
6704
|
+
issue: 'low_credits',
|
|
6705
|
+
detail: `${r.credits} credits remaining`,
|
|
6706
|
+
});
|
|
6707
|
+
}
|
|
6708
|
+
// Expiring soon: within 7 days
|
|
6709
|
+
if (r.expiresAt) {
|
|
6710
|
+
const expiryMs = new Date(r.expiresAt).getTime();
|
|
6711
|
+
if (expiryMs > now && expiryMs <= now + sevenDaysMs) {
|
|
6712
|
+
const hoursLeft = Math.round((expiryMs - now) / (1000 * 60 * 60));
|
|
6713
|
+
needsAttention.push({
|
|
6714
|
+
keyName: r.name,
|
|
6715
|
+
issue: 'expiring_soon',
|
|
6716
|
+
detail: `Expires in ${hoursLeft} hours`,
|
|
6717
|
+
});
|
|
6718
|
+
}
|
|
6719
|
+
}
|
|
6720
|
+
}
|
|
6721
|
+
}
|
|
6722
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
6723
|
+
res.end(JSON.stringify({
|
|
6724
|
+
counts: {
|
|
6725
|
+
total: allRecords.length,
|
|
6726
|
+
active,
|
|
6727
|
+
suspended,
|
|
6728
|
+
revoked,
|
|
6729
|
+
expired,
|
|
6730
|
+
},
|
|
6731
|
+
needsAttention,
|
|
6732
|
+
generatedAt: new Date().toISOString(),
|
|
6733
|
+
}));
|
|
6734
|
+
}
|
|
6586
6735
|
// ─── /keys/notes — Timestamped notes on API keys ─────────────────────────
|
|
6587
6736
|
handleGetNotes(req, res) {
|
|
6588
6737
|
if (!this.checkAdmin(req, res))
|