paygate-mcp 8.39.0 → 8.41.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 +111 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -146,6 +146,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
146
146
|
- **Response Time Distribution** — `GET /admin/response-time-distribution` histogram of response times with latency buckets and p50/p95/p99 percentiles
|
|
147
147
|
- **Consumer Lifetime Value** — `GET /admin/consumer-lifetime-value` per-consumer spend analysis with value tiers, tool diversity, and top spender rankings
|
|
148
148
|
- **Tool Revenue Ranking** — `GET /admin/tool-revenue` ranks tools by total credits consumed with call counts, unique consumers, and percentage breakdown
|
|
149
|
+
- **Consumer Retention Cohorts** — `GET /admin/consumer-retention` groups consumers by creation date with retention rates and avg spend per cohort
|
|
150
|
+
- **Error Breakdown** — `GET /admin/error-breakdown` categorizes denied requests by reason with counts, percentages, affected consumers, and error rate
|
|
149
151
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
150
152
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
151
153
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -3406,6 +3408,45 @@ curl http://localhost:3000/admin/tool-revenue -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
|
3406
3408
|
|
|
3407
3409
|
Ranks tools by total credits consumed from allowed requests. Each tool entry includes call count, average credits per call, unique consumer count, and revenue percentage. `topTool` is the highest revenue generator. Only allowed requests are counted; denied requests are excluded. Sorted by total credits descending. Read-only.
|
|
3408
3410
|
|
|
3411
|
+
### Consumer Retention Cohorts
|
|
3412
|
+
|
|
3413
|
+
```bash
|
|
3414
|
+
curl http://localhost:3000/admin/consumer-retention -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
3415
|
+
```
|
|
3416
|
+
|
|
3417
|
+
```json
|
|
3418
|
+
{
|
|
3419
|
+
"cohorts": [
|
|
3420
|
+
{ "period": "2025-01-15", "created": 10, "retained": 8, "retentionRate": 80, "avgSpend": 150 },
|
|
3421
|
+
{ "period": "2025-01-14", "created": 5, "retained": 3, "retentionRate": 60, "avgSpend": 80 }
|
|
3422
|
+
],
|
|
3423
|
+
"summary": { "totalKeys": 15, "retainedKeys": 11, "overallRetentionRate": 73 },
|
|
3424
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
3425
|
+
}
|
|
3426
|
+
```
|
|
3427
|
+
|
|
3428
|
+
Groups active consumers by creation date (YYYY-MM-DD cohorts). A consumer is "retained" if they have at least 1 tool call. Per-cohort: created count, retained count, retention rate percentage, and average spend. Excludes revoked/suspended keys. Cohorts sorted newest first. Read-only.
|
|
3429
|
+
|
|
3430
|
+
### Error Breakdown
|
|
3431
|
+
|
|
3432
|
+
```bash
|
|
3433
|
+
curl http://localhost:3000/admin/error-breakdown -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
3434
|
+
```
|
|
3435
|
+
|
|
3436
|
+
```json
|
|
3437
|
+
{
|
|
3438
|
+
"errors": [
|
|
3439
|
+
{ "reason": "insufficient_credits", "count": 45, "percentage": 75, "affectedConsumers": 12 },
|
|
3440
|
+
{ "reason": "rate_limited", "count": 10, "percentage": 17, "affectedConsumers": 3 },
|
|
3441
|
+
{ "reason": "acl_denied", "count": 5, "percentage": 8, "affectedConsumers": 2 }
|
|
3442
|
+
],
|
|
3443
|
+
"summary": { "totalDenied": 60, "totalAllowed": 940, "errorRate": 6 },
|
|
3444
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
3445
|
+
}
|
|
3446
|
+
```
|
|
3447
|
+
|
|
3448
|
+
Categorizes denied requests by deny reason for root-cause analysis. Per-reason: count, percentage of total denials, and affected consumer count. `errorRate` is the percentage of total requests that were denied. Sorted by count descending. Read-only.
|
|
3449
|
+
|
|
3409
3450
|
### IP Allowlisting
|
|
3410
3451
|
|
|
3411
3452
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
package/dist/server.d.ts
CHANGED
|
@@ -281,6 +281,8 @@ export declare class PayGateServer {
|
|
|
281
281
|
private handleResponseTimeDistribution;
|
|
282
282
|
private handleConsumerLifetimeValue;
|
|
283
283
|
private handleToolRevenue;
|
|
284
|
+
private handleConsumerRetention;
|
|
285
|
+
private handleErrorBreakdown;
|
|
284
286
|
private handleGetNotes;
|
|
285
287
|
private handleAddNote;
|
|
286
288
|
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
|
@@ -1032,6 +1032,18 @@ class PayGateServer {
|
|
|
1032
1032
|
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
1033
1033
|
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
1034
1034
|
return;
|
|
1035
|
+
case '/admin/consumer-retention':
|
|
1036
|
+
if (req.method === 'GET')
|
|
1037
|
+
return this.handleConsumerRetention(req, res);
|
|
1038
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
1039
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
1040
|
+
return;
|
|
1041
|
+
case '/admin/error-breakdown':
|
|
1042
|
+
if (req.method === 'GET')
|
|
1043
|
+
return this.handleErrorBreakdown(req, res);
|
|
1044
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
1045
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
1046
|
+
return;
|
|
1035
1047
|
// ─── Plugin endpoints ──────────────────────────────────────────────
|
|
1036
1048
|
case '/plugins':
|
|
1037
1049
|
return this.handleListPlugins(req, res);
|
|
@@ -1611,6 +1623,8 @@ class PayGateServer {
|
|
|
1611
1623
|
responseTimeDistribution: 'GET /admin/response-time-distribution — Histogram of response times with latency buckets, percentiles p50/p95/p99, and performance analysis (requires X-Admin-Key)',
|
|
1612
1624
|
consumerLifetimeValue: 'GET /admin/consumer-lifetime-value — Per-consumer value metrics with spend, calls, tool diversity, and tier classification (requires X-Admin-Key)',
|
|
1613
1625
|
toolRevenue: 'GET /admin/tool-revenue — Tool revenue ranking with credits consumed, call counts, unique consumers, and percentage breakdown (requires X-Admin-Key)',
|
|
1626
|
+
consumerRetention: 'GET /admin/consumer-retention — Consumer retention cohorts grouped by creation date with retention rates and avg spend per cohort (requires X-Admin-Key)',
|
|
1627
|
+
errorBreakdown: 'GET /admin/error-breakdown — Denied request breakdown by reason with counts, percentages, affected consumers, and overall error rate (requires X-Admin-Key)',
|
|
1614
1628
|
...(this.oauth ? {
|
|
1615
1629
|
oauthMetadata: 'GET /.well-known/oauth-authorization-server — OAuth 2.1 server metadata',
|
|
1616
1630
|
oauthRegister: 'POST /oauth/register — Register OAuth client',
|
|
@@ -7603,6 +7617,103 @@ class PayGateServer {
|
|
|
7603
7617
|
generatedAt: new Date().toISOString(),
|
|
7604
7618
|
}));
|
|
7605
7619
|
}
|
|
7620
|
+
// ─── /admin/consumer-retention — Retention cohorts ───────────────────────
|
|
7621
|
+
handleConsumerRetention(_req, res) {
|
|
7622
|
+
if (!this.checkAdmin(_req, res))
|
|
7623
|
+
return;
|
|
7624
|
+
const allRecords = this.gate.store.getAllRecords();
|
|
7625
|
+
const activeRecords = allRecords.filter(r => r.active && !r.suspended);
|
|
7626
|
+
if (activeRecords.length === 0) {
|
|
7627
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7628
|
+
res.end(JSON.stringify({
|
|
7629
|
+
cohorts: [],
|
|
7630
|
+
summary: { totalKeys: 0, retainedKeys: 0, overallRetentionRate: 0 },
|
|
7631
|
+
generatedAt: new Date().toISOString(),
|
|
7632
|
+
}));
|
|
7633
|
+
return;
|
|
7634
|
+
}
|
|
7635
|
+
// Group by creation date (YYYY-MM-DD)
|
|
7636
|
+
const cohortMap = new Map();
|
|
7637
|
+
for (const rec of activeRecords) {
|
|
7638
|
+
const dateStr = rec.createdAt
|
|
7639
|
+
? new Date(rec.createdAt).toISOString().slice(0, 10)
|
|
7640
|
+
: 'unknown';
|
|
7641
|
+
let cohort = cohortMap.get(dateStr);
|
|
7642
|
+
if (!cohort) {
|
|
7643
|
+
cohort = { created: 0, retained: 0, totalSpend: 0 };
|
|
7644
|
+
cohortMap.set(dateStr, cohort);
|
|
7645
|
+
}
|
|
7646
|
+
cohort.created += 1;
|
|
7647
|
+
cohort.totalSpend += rec.totalSpent || 0;
|
|
7648
|
+
if ((rec.totalCalls || 0) > 0) {
|
|
7649
|
+
cohort.retained += 1;
|
|
7650
|
+
}
|
|
7651
|
+
}
|
|
7652
|
+
const totalKeys = activeRecords.length;
|
|
7653
|
+
const retainedKeys = activeRecords.filter(r => (r.totalCalls || 0) > 0).length;
|
|
7654
|
+
const cohorts = Array.from(cohortMap.entries())
|
|
7655
|
+
.map(([period, data]) => ({
|
|
7656
|
+
period,
|
|
7657
|
+
created: data.created,
|
|
7658
|
+
retained: data.retained,
|
|
7659
|
+
retentionRate: data.created > 0 ? Math.round((data.retained / data.created) * 100) : 0,
|
|
7660
|
+
avgSpend: data.created > 0 ? Math.round(data.totalSpend / data.created) : 0,
|
|
7661
|
+
}))
|
|
7662
|
+
.sort((a, b) => b.period.localeCompare(a.period));
|
|
7663
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7664
|
+
res.end(JSON.stringify({
|
|
7665
|
+
cohorts,
|
|
7666
|
+
summary: {
|
|
7667
|
+
totalKeys,
|
|
7668
|
+
retainedKeys,
|
|
7669
|
+
overallRetentionRate: totalKeys > 0 ? Math.round((retainedKeys / totalKeys) * 100) : 0,
|
|
7670
|
+
},
|
|
7671
|
+
generatedAt: new Date().toISOString(),
|
|
7672
|
+
}));
|
|
7673
|
+
}
|
|
7674
|
+
// ─── /admin/error-breakdown — Denied request analysis ────────────────────
|
|
7675
|
+
handleErrorBreakdown(_req, res) {
|
|
7676
|
+
if (!this.checkAdmin(_req, res))
|
|
7677
|
+
return;
|
|
7678
|
+
let totalAllowed = 0;
|
|
7679
|
+
let totalDenied = 0;
|
|
7680
|
+
const reasonMap = new Map();
|
|
7681
|
+
for (const entry of this.requestLog) {
|
|
7682
|
+
if (entry.status === 'allowed') {
|
|
7683
|
+
totalAllowed++;
|
|
7684
|
+
}
|
|
7685
|
+
else if (entry.status === 'denied') {
|
|
7686
|
+
totalDenied++;
|
|
7687
|
+
const reason = entry.denyReason || 'unknown';
|
|
7688
|
+
let data = reasonMap.get(reason);
|
|
7689
|
+
if (!data) {
|
|
7690
|
+
data = { count: 0, consumers: new Set() };
|
|
7691
|
+
reasonMap.set(reason, data);
|
|
7692
|
+
}
|
|
7693
|
+
data.count++;
|
|
7694
|
+
data.consumers.add(entry.key);
|
|
7695
|
+
}
|
|
7696
|
+
}
|
|
7697
|
+
const totalRequests = totalAllowed + totalDenied;
|
|
7698
|
+
const errors = Array.from(reasonMap.entries())
|
|
7699
|
+
.map(([reason, data]) => ({
|
|
7700
|
+
reason,
|
|
7701
|
+
count: data.count,
|
|
7702
|
+
percentage: totalDenied > 0 ? Math.round((data.count / totalDenied) * 100) : 0,
|
|
7703
|
+
affectedConsumers: data.consumers.size,
|
|
7704
|
+
}))
|
|
7705
|
+
.sort((a, b) => b.count - a.count);
|
|
7706
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7707
|
+
res.end(JSON.stringify({
|
|
7708
|
+
errors,
|
|
7709
|
+
summary: {
|
|
7710
|
+
totalDenied,
|
|
7711
|
+
totalAllowed,
|
|
7712
|
+
errorRate: totalRequests > 0 ? Math.round((totalDenied / totalRequests) * 100) : 0,
|
|
7713
|
+
},
|
|
7714
|
+
generatedAt: new Date().toISOString(),
|
|
7715
|
+
}));
|
|
7716
|
+
}
|
|
7606
7717
|
// ─── /keys/notes — Timestamped notes on API keys ─────────────────────────
|
|
7607
7718
|
handleGetNotes(req, res) {
|
|
7608
7719
|
if (!this.checkAdmin(req, res))
|