paygate-mcp 8.30.0 → 8.32.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 +57 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +129 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -137,6 +137,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
137
137
|
- **Consumer Insights** — `GET /admin/consumer-insights` per-key behavioral analytics with top spenders, most active callers, tool diversity, and spending patterns
|
|
138
138
|
- **System Health Score** — `GET /admin/system-health` composite 0-100 health score with weighted component breakdowns for key health, error rates, and credit utilization
|
|
139
139
|
- **Tool Adoption** — `GET /admin/tool-adoption` per-tool adoption metrics with unique consumers, adoption rate, first/last seen timestamps, and usage ranking
|
|
140
|
+
- **Credit Efficiency** — `GET /admin/credit-efficiency` credit allocation efficiency with burn efficiency, waste ratio, over-provisioned and under-provisioned key detection
|
|
141
|
+
- **Access Heatmap** — `GET /admin/access-heatmap` hourly access patterns with tool breakdown, unique consumers, and peak hour identification
|
|
140
142
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
141
143
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
142
144
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -3195,6 +3197,61 @@ curl http://localhost:3000/admin/tool-adoption -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
|
3195
3197
|
|
|
3196
3198
|
Per-tool adoption metrics showing which tools are being used and by how many consumers. `uniqueConsumers` counts distinct API keys that called the tool. `adoptionRate` is the percentage of active keys that have used the tool. Sorted by adoption rate descending, then by total calls. Read-only.
|
|
3197
3199
|
|
|
3200
|
+
### Credit Efficiency
|
|
3201
|
+
|
|
3202
|
+
```bash
|
|
3203
|
+
curl http://localhost:3000/admin/credit-efficiency -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
3204
|
+
```
|
|
3205
|
+
|
|
3206
|
+
```json
|
|
3207
|
+
{
|
|
3208
|
+
"summary": {
|
|
3209
|
+
"totalAllocated": 5000,
|
|
3210
|
+
"totalSpent": 1200,
|
|
3211
|
+
"totalRemaining": 3800,
|
|
3212
|
+
"burnEfficiency": 24,
|
|
3213
|
+
"wasteRatio": 76,
|
|
3214
|
+
"activeKeys": 10
|
|
3215
|
+
},
|
|
3216
|
+
"overProvisioned": [
|
|
3217
|
+
{ "name": "idle-whale", "credits": 950, "totalAllocated": 1000, "totalSpent": 50, "remainingPercent": 95 }
|
|
3218
|
+
],
|
|
3219
|
+
"underProvisioned": [
|
|
3220
|
+
{ "name": "heavy-user", "credits": 3, "totalAllocated": 500, "totalSpent": 497, "remainingPercent": 1 }
|
|
3221
|
+
],
|
|
3222
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
3223
|
+
}
|
|
3224
|
+
```
|
|
3225
|
+
|
|
3226
|
+
Credit allocation efficiency analysis. `burnEfficiency` is the percentage of allocated credits actually spent. `wasteRatio` is the percentage remaining unused. Over-provisioned keys have >90% remaining credits. Under-provisioned keys have <=10 credits or <=10% remaining with active usage. Top 10 in each category, sorted by urgency. Read-only.
|
|
3227
|
+
|
|
3228
|
+
### Access Heatmap
|
|
3229
|
+
|
|
3230
|
+
```bash
|
|
3231
|
+
curl http://localhost:3000/admin/access-heatmap -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
3232
|
+
```
|
|
3233
|
+
|
|
3234
|
+
```json
|
|
3235
|
+
{
|
|
3236
|
+
"hourly": [
|
|
3237
|
+
{
|
|
3238
|
+
"hour": "2025-01-15T14:00:00.000Z",
|
|
3239
|
+
"total": 45,
|
|
3240
|
+
"uniqueConsumers": 8,
|
|
3241
|
+
"tools": { "search": 30, "translate": 15 }
|
|
3242
|
+
}
|
|
3243
|
+
],
|
|
3244
|
+
"summary": {
|
|
3245
|
+
"totalRequests": 45,
|
|
3246
|
+
"totalHours": 1,
|
|
3247
|
+
"peakHour": { "hour": "2025-01-15T14:00:00.000Z", "total": 45 }
|
|
3248
|
+
},
|
|
3249
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
3250
|
+
}
|
|
3251
|
+
```
|
|
3252
|
+
|
|
3253
|
+
Hourly access patterns for capacity planning. Each bucket shows total requests, unique consumers, and per-tool breakdown. Peak hour identification helps spot usage spikes. Only counts allowed requests. Sorted chronologically. Read-only.
|
|
3254
|
+
|
|
3198
3255
|
### IP Allowlisting
|
|
3199
3256
|
|
|
3200
3257
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
package/dist/server.d.ts
CHANGED
|
@@ -272,6 +272,8 @@ export declare class PayGateServer {
|
|
|
272
272
|
private handleConsumerInsights;
|
|
273
273
|
private handleSystemHealth;
|
|
274
274
|
private handleToolAdoption;
|
|
275
|
+
private handleCreditEfficiency;
|
|
276
|
+
private handleAccessHeatmap;
|
|
275
277
|
private handleGetNotes;
|
|
276
278
|
private handleAddNote;
|
|
277
279
|
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
|
@@ -978,6 +978,18 @@ class PayGateServer {
|
|
|
978
978
|
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
979
979
|
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
980
980
|
return;
|
|
981
|
+
case '/admin/credit-efficiency':
|
|
982
|
+
if (req.method === 'GET')
|
|
983
|
+
return this.handleCreditEfficiency(req, res);
|
|
984
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
985
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
986
|
+
return;
|
|
987
|
+
case '/admin/access-heatmap':
|
|
988
|
+
if (req.method === 'GET')
|
|
989
|
+
return this.handleAccessHeatmap(req, res);
|
|
990
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
991
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
992
|
+
return;
|
|
981
993
|
// ─── Plugin endpoints ──────────────────────────────────────────────
|
|
982
994
|
case '/plugins':
|
|
983
995
|
return this.handleListPlugins(req, res);
|
|
@@ -1548,6 +1560,8 @@ class PayGateServer {
|
|
|
1548
1560
|
consumerInsights: 'GET /admin/consumer-insights — Per-key behavioral analytics with top spenders, most active callers, tool diversity, and spending patterns (requires X-Admin-Key)',
|
|
1549
1561
|
systemHealth: 'GET /admin/system-health — Composite system health score 0-100 with component breakdowns for key health, error rates, and credit utilization (requires X-Admin-Key)',
|
|
1550
1562
|
toolAdoption: 'GET /admin/tool-adoption — Per-tool adoption metrics with unique consumers, adoption rate, first/last seen, and never-used tool identification (requires X-Admin-Key)',
|
|
1563
|
+
creditEfficiency: 'GET /admin/credit-efficiency — Credit allocation efficiency with burn efficiency, waste ratio, over-provisioned and under-provisioned key detection (requires X-Admin-Key)',
|
|
1564
|
+
accessHeatmap: 'GET /admin/access-heatmap — Hourly access patterns with tool breakdown, unique consumers, and peak hour identification for capacity planning (requires X-Admin-Key)',
|
|
1551
1565
|
...(this.oauth ? {
|
|
1552
1566
|
oauthMetadata: 'GET /.well-known/oauth-authorization-server — OAuth 2.1 server metadata',
|
|
1553
1567
|
oauthRegister: 'POST /oauth/register — Register OAuth client',
|
|
@@ -7010,6 +7024,121 @@ class PayGateServer {
|
|
|
7010
7024
|
generatedAt: new Date().toISOString(),
|
|
7011
7025
|
}));
|
|
7012
7026
|
}
|
|
7027
|
+
// ─── /admin/credit-efficiency — Credit allocation efficiency ──────────────
|
|
7028
|
+
handleCreditEfficiency(req, res) {
|
|
7029
|
+
if (!this.checkAdmin(req, res))
|
|
7030
|
+
return;
|
|
7031
|
+
const allRecords = this.gate.store.getAllRecords();
|
|
7032
|
+
const activeRecords = allRecords.filter(r => r.active && !r.suspended);
|
|
7033
|
+
let totalAllocated = 0;
|
|
7034
|
+
let totalSpent = 0;
|
|
7035
|
+
let totalRemaining = 0;
|
|
7036
|
+
const overProvisioned = [];
|
|
7037
|
+
const underProvisioned = [];
|
|
7038
|
+
for (const rec of activeRecords) {
|
|
7039
|
+
const allocated = (rec.credits || 0) + (rec.totalSpent || 0);
|
|
7040
|
+
const spent = rec.totalSpent || 0;
|
|
7041
|
+
const remaining = rec.credits || 0;
|
|
7042
|
+
totalAllocated += allocated;
|
|
7043
|
+
totalSpent += spent;
|
|
7044
|
+
totalRemaining += remaining;
|
|
7045
|
+
if (allocated > 0) {
|
|
7046
|
+
const remainingPercent = Math.round((remaining / allocated) * 100);
|
|
7047
|
+
// Over-provisioned: >90% remaining with some activity or never used
|
|
7048
|
+
if (remainingPercent > 90 && allocated > 0) {
|
|
7049
|
+
overProvisioned.push({
|
|
7050
|
+
name: rec.name || 'unnamed',
|
|
7051
|
+
credits: remaining,
|
|
7052
|
+
totalAllocated: allocated,
|
|
7053
|
+
totalSpent: spent,
|
|
7054
|
+
remainingPercent,
|
|
7055
|
+
});
|
|
7056
|
+
}
|
|
7057
|
+
// Under-provisioned: <=10 credits remaining or <=10% remaining (with some usage)
|
|
7058
|
+
if (spent > 0 && (remaining <= 10 || remainingPercent <= 10)) {
|
|
7059
|
+
underProvisioned.push({
|
|
7060
|
+
name: rec.name || 'unnamed',
|
|
7061
|
+
credits: remaining,
|
|
7062
|
+
totalAllocated: allocated,
|
|
7063
|
+
totalSpent: spent,
|
|
7064
|
+
remainingPercent,
|
|
7065
|
+
});
|
|
7066
|
+
}
|
|
7067
|
+
}
|
|
7068
|
+
}
|
|
7069
|
+
// Sort over-provisioned by remaining credits descending
|
|
7070
|
+
overProvisioned.sort((a, b) => b.credits - a.credits);
|
|
7071
|
+
// Sort under-provisioned by remaining credits ascending (most urgent first)
|
|
7072
|
+
underProvisioned.sort((a, b) => a.credits - b.credits);
|
|
7073
|
+
const burnEfficiency = totalAllocated > 0
|
|
7074
|
+
? Math.round((totalSpent / totalAllocated) * 100)
|
|
7075
|
+
: 0;
|
|
7076
|
+
const wasteRatio = totalAllocated > 0
|
|
7077
|
+
? Math.round((totalRemaining / totalAllocated) * 100)
|
|
7078
|
+
: 0;
|
|
7079
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7080
|
+
res.end(JSON.stringify({
|
|
7081
|
+
summary: {
|
|
7082
|
+
totalAllocated,
|
|
7083
|
+
totalSpent,
|
|
7084
|
+
totalRemaining,
|
|
7085
|
+
burnEfficiency,
|
|
7086
|
+
wasteRatio,
|
|
7087
|
+
activeKeys: activeRecords.length,
|
|
7088
|
+
},
|
|
7089
|
+
overProvisioned: overProvisioned.slice(0, 10),
|
|
7090
|
+
underProvisioned: underProvisioned.slice(0, 10),
|
|
7091
|
+
generatedAt: new Date().toISOString(),
|
|
7092
|
+
}));
|
|
7093
|
+
}
|
|
7094
|
+
// ─── /admin/access-heatmap — Hourly access patterns ───────────────────────
|
|
7095
|
+
handleAccessHeatmap(req, res) {
|
|
7096
|
+
if (!this.checkAdmin(req, res))
|
|
7097
|
+
return;
|
|
7098
|
+
// Build hourly buckets from request log
|
|
7099
|
+
const hourMap = new Map();
|
|
7100
|
+
for (const entry of this.requestLog) {
|
|
7101
|
+
if (entry.status !== 'allowed')
|
|
7102
|
+
continue;
|
|
7103
|
+
const ts = new Date(entry.timestamp);
|
|
7104
|
+
const hourKey = ts.toISOString().slice(0, 13) + ':00:00.000Z';
|
|
7105
|
+
let bucket = hourMap.get(hourKey);
|
|
7106
|
+
if (!bucket) {
|
|
7107
|
+
bucket = { total: 0, tools: new Map(), consumers: new Set() };
|
|
7108
|
+
hourMap.set(hourKey, bucket);
|
|
7109
|
+
}
|
|
7110
|
+
bucket.total++;
|
|
7111
|
+
bucket.tools.set(entry.tool, (bucket.tools.get(entry.tool) || 0) + 1);
|
|
7112
|
+
bucket.consumers.add(entry.key);
|
|
7113
|
+
}
|
|
7114
|
+
// Convert to sorted array
|
|
7115
|
+
const hourly = Array.from(hourMap.entries())
|
|
7116
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
7117
|
+
.map(([hour, data]) => ({
|
|
7118
|
+
hour,
|
|
7119
|
+
total: data.total,
|
|
7120
|
+
uniqueConsumers: data.consumers.size,
|
|
7121
|
+
tools: Object.fromEntries(data.tools),
|
|
7122
|
+
}));
|
|
7123
|
+
// Find peak hour
|
|
7124
|
+
let peakHour = null;
|
|
7125
|
+
for (const h of hourly) {
|
|
7126
|
+
if (!peakHour || h.total > peakHour.total) {
|
|
7127
|
+
peakHour = { hour: h.hour, total: h.total };
|
|
7128
|
+
}
|
|
7129
|
+
}
|
|
7130
|
+
const totalRequests = hourly.reduce((s, h) => s + h.total, 0);
|
|
7131
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7132
|
+
res.end(JSON.stringify({
|
|
7133
|
+
hourly,
|
|
7134
|
+
summary: {
|
|
7135
|
+
totalRequests,
|
|
7136
|
+
totalHours: hourly.length,
|
|
7137
|
+
...(peakHour ? { peakHour } : {}),
|
|
7138
|
+
},
|
|
7139
|
+
generatedAt: new Date().toISOString(),
|
|
7140
|
+
}));
|
|
7141
|
+
}
|
|
7013
7142
|
// ─── /keys/notes — Timestamped notes on API keys ─────────────────────────
|
|
7014
7143
|
handleGetNotes(req, res) {
|
|
7015
7144
|
if (!this.checkAdmin(req, res))
|