paygate-mcp 8.44.0 → 8.46.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 +41 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +127 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -151,6 +151,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
151
151
|
- **Credit Utilization Rate** — `GET /admin/credit-utilization` shows utilization percentage across active keys with utilization bands and over-provisioning detection
|
|
152
152
|
- **Namespace Revenue** — `GET /admin/namespace-revenue` revenue breakdown by namespace with spend, call counts, key counts, and percentage breakdown
|
|
153
153
|
- **Group Revenue** — `GET /admin/group-revenue` revenue breakdown by key group with spend, call counts, key counts, and percentage breakdown
|
|
154
|
+
- **Peak Usage Times** — `GET /admin/peak-usage` traffic patterns by hour-of-day with request counts, credits, unique consumers, and peak hour identification
|
|
155
|
+
- **Consumer Activity** — `GET /admin/consumer-activity` per-consumer activity metrics with calls, spend, credits remaining, last active time, and active/inactive status
|
|
154
156
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
155
157
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
156
158
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -3512,6 +3514,45 @@ curl http://localhost:3000/admin/group-revenue -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
|
3512
3514
|
|
|
3513
3515
|
Revenue breakdown by key group. Keys not assigned to any group are shown as "ungrouped". Group IDs are resolved to human-readable names. Per-group: total credits spent, call count, key count, and revenue percentage. `topGroup` is the highest revenue generator. Excludes revoked/suspended keys. Sorted by spend descending. Read-only.
|
|
3514
3516
|
|
|
3517
|
+
### Peak Usage Times
|
|
3518
|
+
|
|
3519
|
+
```bash
|
|
3520
|
+
curl http://localhost:3000/admin/peak-usage -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
3521
|
+
```
|
|
3522
|
+
|
|
3523
|
+
```json
|
|
3524
|
+
{
|
|
3525
|
+
"hours": [
|
|
3526
|
+
{ "hour": 9, "requests": 450, "allowed": 420, "denied": 30, "credits": 2100, "uniqueConsumers": 15, "percentage": 30 },
|
|
3527
|
+
{ "hour": 14, "requests": 380, "allowed": 370, "denied": 10, "credits": 1850, "uniqueConsumers": 12, "percentage": 25 },
|
|
3528
|
+
{ "hour": 22, "requests": 120, "allowed": 118, "denied": 2, "credits": 590, "uniqueConsumers": 5, "percentage": 8 }
|
|
3529
|
+
],
|
|
3530
|
+
"summary": { "totalRequests": 1500, "peakHour": 9, "peakRequests": 450 },
|
|
3531
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
3532
|
+
}
|
|
3533
|
+
```
|
|
3534
|
+
|
|
3535
|
+
Traffic patterns by hour-of-day (UTC). Per-hour: total requests, allowed/denied split, credits spent, unique consumers, and traffic percentage. `peakHour` identifies the busiest hour for capacity planning. Hours are 0-23 (UTC), sorted ascending. Only hours with traffic are included. Read-only.
|
|
3536
|
+
|
|
3537
|
+
### Consumer Activity
|
|
3538
|
+
|
|
3539
|
+
```bash
|
|
3540
|
+
curl http://localhost:3000/admin/consumer-activity -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
3541
|
+
```
|
|
3542
|
+
|
|
3543
|
+
```json
|
|
3544
|
+
{
|
|
3545
|
+
"consumers": [
|
|
3546
|
+
{ "name": "alice", "totalCalls": 150, "totalSpent": 750, "creditsRemaining": 250, "lastActive": "2025-01-15T14:30:00Z", "status": "active" },
|
|
3547
|
+
{ "name": "bob", "totalCalls": 0, "totalSpent": 0, "creditsRemaining": 500, "lastActive": null, "status": "inactive" }
|
|
3548
|
+
],
|
|
3549
|
+
"summary": { "totalConsumers": 2, "activeConsumers": 1, "inactiveConsumers": 1 },
|
|
3550
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
3551
|
+
}
|
|
3552
|
+
```
|
|
3553
|
+
|
|
3554
|
+
Per-consumer activity metrics. Shows each active key's call count, total spend, credits remaining, last active timestamp, and active/inactive status. Consumers with zero calls are "inactive". Excludes revoked/suspended keys. Sorted by spend descending. Read-only.
|
|
3555
|
+
|
|
3515
3556
|
### IP Allowlisting
|
|
3516
3557
|
|
|
3517
3558
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
package/dist/server.d.ts
CHANGED
|
@@ -286,6 +286,8 @@ export declare class PayGateServer {
|
|
|
286
286
|
private handleCreditUtilization;
|
|
287
287
|
private handleNamespaceRevenue;
|
|
288
288
|
private handleGroupRevenue;
|
|
289
|
+
private handlePeakUsage;
|
|
290
|
+
private handleConsumerActivity;
|
|
289
291
|
private handleGetNotes;
|
|
290
292
|
private handleAddNote;
|
|
291
293
|
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
|
@@ -1062,6 +1062,18 @@ class PayGateServer {
|
|
|
1062
1062
|
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
1063
1063
|
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
1064
1064
|
return;
|
|
1065
|
+
case '/admin/peak-usage':
|
|
1066
|
+
if (req.method === 'GET')
|
|
1067
|
+
return this.handlePeakUsage(req, res);
|
|
1068
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
1069
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
1070
|
+
return;
|
|
1071
|
+
case '/admin/consumer-activity':
|
|
1072
|
+
if (req.method === 'GET')
|
|
1073
|
+
return this.handleConsumerActivity(req, res);
|
|
1074
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
1075
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
1076
|
+
return;
|
|
1065
1077
|
// ─── Plugin endpoints ──────────────────────────────────────────────
|
|
1066
1078
|
case '/plugins':
|
|
1067
1079
|
return this.handleListPlugins(req, res);
|
|
@@ -1646,6 +1658,8 @@ class PayGateServer {
|
|
|
1646
1658
|
creditUtilization: 'GET /admin/credit-utilization — Credit utilization rate across active keys with utilization bands and over/under-provisioning detection (requires X-Admin-Key)',
|
|
1647
1659
|
namespaceRevenue: 'GET /admin/namespace-revenue — Revenue breakdown by namespace with spend, call counts, key counts, and percentage breakdown (requires X-Admin-Key)',
|
|
1648
1660
|
groupRevenue: 'GET /admin/group-revenue — Revenue breakdown by key group with spend, call counts, key counts, and percentage breakdown (requires X-Admin-Key)',
|
|
1661
|
+
peakUsage: 'GET /admin/peak-usage — Traffic patterns by hour-of-day with requests, credits, consumers per hour for capacity planning (requires X-Admin-Key)',
|
|
1662
|
+
consumerActivity: 'GET /admin/consumer-activity — Per-consumer activity with calls, spend, credits remaining, last active time, and status (requires X-Admin-Key)',
|
|
1649
1663
|
...(this.oauth ? {
|
|
1650
1664
|
oauthMetadata: 'GET /.well-known/oauth-authorization-server — OAuth 2.1 server metadata',
|
|
1651
1665
|
oauthRegister: 'POST /oauth/register — Register OAuth client',
|
|
@@ -7897,6 +7911,119 @@ class PayGateServer {
|
|
|
7897
7911
|
generatedAt: new Date().toISOString(),
|
|
7898
7912
|
}));
|
|
7899
7913
|
}
|
|
7914
|
+
// ─── /admin/peak-usage — Traffic patterns by hour of day ─────────────────
|
|
7915
|
+
handlePeakUsage(_req, res) {
|
|
7916
|
+
if (!this.checkAdmin(_req, res))
|
|
7917
|
+
return;
|
|
7918
|
+
if (this.requestLog.length === 0) {
|
|
7919
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7920
|
+
res.end(JSON.stringify({
|
|
7921
|
+
hours: [],
|
|
7922
|
+
summary: { totalRequests: 0, peakHour: null, peakRequests: 0 },
|
|
7923
|
+
generatedAt: new Date().toISOString(),
|
|
7924
|
+
}));
|
|
7925
|
+
return;
|
|
7926
|
+
}
|
|
7927
|
+
const hourMap = new Map();
|
|
7928
|
+
for (const entry of this.requestLog) {
|
|
7929
|
+
const hour = new Date(entry.timestamp).getUTCHours();
|
|
7930
|
+
let data = hourMap.get(hour);
|
|
7931
|
+
if (!data) {
|
|
7932
|
+
data = { requests: 0, allowed: 0, denied: 0, credits: 0, consumers: new Set() };
|
|
7933
|
+
hourMap.set(hour, data);
|
|
7934
|
+
}
|
|
7935
|
+
data.requests += 1;
|
|
7936
|
+
if (entry.status === 'allowed') {
|
|
7937
|
+
data.allowed += 1;
|
|
7938
|
+
data.credits += entry.credits || 0;
|
|
7939
|
+
}
|
|
7940
|
+
else if (entry.status === 'denied') {
|
|
7941
|
+
data.denied += 1;
|
|
7942
|
+
}
|
|
7943
|
+
data.consumers.add(entry.key);
|
|
7944
|
+
}
|
|
7945
|
+
const totalRequests = this.requestLog.length;
|
|
7946
|
+
const hours = Array.from(hourMap.entries())
|
|
7947
|
+
.map(([hour, data]) => ({
|
|
7948
|
+
hour,
|
|
7949
|
+
requests: data.requests,
|
|
7950
|
+
allowed: data.allowed,
|
|
7951
|
+
denied: data.denied,
|
|
7952
|
+
credits: data.credits,
|
|
7953
|
+
uniqueConsumers: data.consumers.size,
|
|
7954
|
+
percentage: totalRequests > 0 ? Math.round((data.requests / totalRequests) * 100) : 0,
|
|
7955
|
+
}))
|
|
7956
|
+
.sort((a, b) => a.hour - b.hour);
|
|
7957
|
+
const peak = hours.reduce((max, h) => h.requests > max.requests ? h : max, hours[0]);
|
|
7958
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7959
|
+
res.end(JSON.stringify({
|
|
7960
|
+
hours,
|
|
7961
|
+
summary: {
|
|
7962
|
+
totalRequests,
|
|
7963
|
+
peakHour: peak.hour,
|
|
7964
|
+
peakRequests: peak.requests,
|
|
7965
|
+
},
|
|
7966
|
+
generatedAt: new Date().toISOString(),
|
|
7967
|
+
}));
|
|
7968
|
+
}
|
|
7969
|
+
// ─── /admin/consumer-activity — Per-consumer activity metrics ─────────────
|
|
7970
|
+
handleConsumerActivity(_req, res) {
|
|
7971
|
+
if (!this.checkAdmin(_req, res))
|
|
7972
|
+
return;
|
|
7973
|
+
const allRecords = this.gate.store.getAllRecords();
|
|
7974
|
+
const activeRecords = allRecords.filter(r => r.active && !r.suspended);
|
|
7975
|
+
if (activeRecords.length === 0) {
|
|
7976
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7977
|
+
res.end(JSON.stringify({
|
|
7978
|
+
consumers: [],
|
|
7979
|
+
summary: { totalConsumers: 0, activeConsumers: 0, inactiveConsumers: 0 },
|
|
7980
|
+
generatedAt: new Date().toISOString(),
|
|
7981
|
+
}));
|
|
7982
|
+
return;
|
|
7983
|
+
}
|
|
7984
|
+
// Find last active timestamp per key from request log
|
|
7985
|
+
const lastActiveMap = new Map();
|
|
7986
|
+
for (const entry of this.requestLog) {
|
|
7987
|
+
// entry.key is masked (first7...last4), so we need to match differently
|
|
7988
|
+
// Store all timestamps, keyed by the masked key
|
|
7989
|
+
const existing = lastActiveMap.get(entry.key);
|
|
7990
|
+
if (!existing || entry.timestamp > existing) {
|
|
7991
|
+
lastActiveMap.set(entry.key, entry.timestamp);
|
|
7992
|
+
}
|
|
7993
|
+
}
|
|
7994
|
+
let activeCount = 0;
|
|
7995
|
+
let inactiveCount = 0;
|
|
7996
|
+
const consumers = activeRecords.map(rec => {
|
|
7997
|
+
const calls = rec.totalCalls || 0;
|
|
7998
|
+
const spent = rec.totalSpent || 0;
|
|
7999
|
+
const isActive = calls > 0;
|
|
8000
|
+
if (isActive)
|
|
8001
|
+
activeCount++;
|
|
8002
|
+
else
|
|
8003
|
+
inactiveCount++;
|
|
8004
|
+
// Build masked key to match request log entries
|
|
8005
|
+
const masked = rec.key.slice(0, 7) + '...' + rec.key.slice(-4);
|
|
8006
|
+
const lastActive = lastActiveMap.get(masked) || null;
|
|
8007
|
+
return {
|
|
8008
|
+
name: rec.name || 'unnamed',
|
|
8009
|
+
totalCalls: calls,
|
|
8010
|
+
totalSpent: spent,
|
|
8011
|
+
creditsRemaining: rec.credits,
|
|
8012
|
+
lastActive,
|
|
8013
|
+
status: isActive ? 'active' : 'inactive',
|
|
8014
|
+
};
|
|
8015
|
+
}).sort((a, b) => b.totalSpent - a.totalSpent);
|
|
8016
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
8017
|
+
res.end(JSON.stringify({
|
|
8018
|
+
consumers,
|
|
8019
|
+
summary: {
|
|
8020
|
+
totalConsumers: consumers.length,
|
|
8021
|
+
activeConsumers: activeCount,
|
|
8022
|
+
inactiveConsumers: inactiveCount,
|
|
8023
|
+
},
|
|
8024
|
+
generatedAt: new Date().toISOString(),
|
|
8025
|
+
}));
|
|
8026
|
+
}
|
|
7900
8027
|
// ─── /keys/notes — Timestamped notes on API keys ─────────────────────────
|
|
7901
8028
|
handleGetNotes(req, res) {
|
|
7902
8029
|
if (!this.checkAdmin(req, res))
|