paygate-mcp 8.36.0 → 8.38.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 +43 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +155 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -143,6 +143,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
143
143
|
- **Tool Correlation** — `GET /admin/tool-correlation` tool co-occurrence analysis showing which tools are commonly used together by the same consumers
|
|
144
144
|
- **Consumer Segmentation** — `GET /admin/consumer-segmentation` classifies API key consumers into power/regular/casual/dormant segments with per-segment metrics
|
|
145
145
|
- **Credit Distribution** — `GET /admin/credit-distribution` histogram of credit balances across active keys with bucket ranges and median calculation
|
|
146
|
+
- **Response Time Distribution** — `GET /admin/response-time-distribution` histogram of response times with latency buckets and p50/p95/p99 percentiles
|
|
147
|
+
- **Consumer Lifetime Value** — `GET /admin/consumer-lifetime-value` per-consumer spend analysis with value tiers, tool diversity, and top spender rankings
|
|
146
148
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
147
149
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
148
150
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -3342,6 +3344,47 @@ curl http://localhost:3000/admin/credit-distribution -H "X-Admin-Key: YOUR_ADMIN
|
|
|
3342
3344
|
|
|
3343
3345
|
Histogram of credit balances across active, non-suspended keys. Buckets: 0–10, 11–50, 51–100, 101–500, 501–1000, 1001+. Only non-empty buckets are returned. `medianCredits` is the median remaining balance. Useful for pricing analysis and capacity planning. Read-only.
|
|
3344
3346
|
|
|
3347
|
+
### Response Time Distribution
|
|
3348
|
+
|
|
3349
|
+
```bash
|
|
3350
|
+
curl http://localhost:3000/admin/response-time-distribution -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
3351
|
+
```
|
|
3352
|
+
|
|
3353
|
+
```json
|
|
3354
|
+
{
|
|
3355
|
+
"buckets": [
|
|
3356
|
+
{ "range": "0-50ms", "count": 45, "percentage": 60 },
|
|
3357
|
+
{ "range": "51-100ms", "count": 20, "percentage": 27 },
|
|
3358
|
+
{ "range": "101-250ms", "count": 8, "percentage": 11 },
|
|
3359
|
+
{ "range": "251-500ms", "count": 2, "percentage": 3 }
|
|
3360
|
+
],
|
|
3361
|
+
"summary": { "totalRequests": 75, "avgResponseTime": 62, "p50": 42, "p95": 180, "p99": 350 },
|
|
3362
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
3363
|
+
}
|
|
3364
|
+
```
|
|
3365
|
+
|
|
3366
|
+
Histogram of response times across allowed tool calls. Buckets: 0–50ms, 51–100ms, 101–250ms, 251–500ms, 501–1000ms, 1001ms+. Includes percentile metrics (p50, p95, p99) and average response time. Only non-empty buckets are returned. Useful for SLA monitoring and performance optimization. Read-only.
|
|
3367
|
+
|
|
3368
|
+
### Consumer Lifetime Value
|
|
3369
|
+
|
|
3370
|
+
```bash
|
|
3371
|
+
curl http://localhost:3000/admin/consumer-lifetime-value -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
3372
|
+
```
|
|
3373
|
+
|
|
3374
|
+
```json
|
|
3375
|
+
{
|
|
3376
|
+
"consumers": [
|
|
3377
|
+
{ "name": "enterprise-bot", "lifetimeValue": 2500, "totalCalls": 500, "avgSpendPerCall": 5, "toolsUsed": 8, "tier": "high" },
|
|
3378
|
+
{ "name": "dev-team", "lifetimeValue": 450, "totalCalls": 90, "avgSpendPerCall": 5, "toolsUsed": 4, "tier": "medium" },
|
|
3379
|
+
{ "name": "trial-user", "lifetimeValue": 5, "totalCalls": 1, "avgSpendPerCall": 5, "toolsUsed": 1, "tier": "low" }
|
|
3380
|
+
],
|
|
3381
|
+
"summary": { "totalConsumers": 15, "totalLifetimeValue": 3200, "avgLifetimeValue": 213 },
|
|
3382
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
3383
|
+
}
|
|
3384
|
+
```
|
|
3385
|
+
|
|
3386
|
+
Per-consumer value analysis for active keys with usage. Value tiers: **high** (100+ credits spent), **medium** (10–99), **low** (<10). `toolsUsed` shows tool diversity. Top 20 consumers by lifetime value. Zero-spend consumers excluded from list. `avgLifetimeValue` uses all active keys as denominator. Read-only.
|
|
3387
|
+
|
|
3345
3388
|
### IP Allowlisting
|
|
3346
3389
|
|
|
3347
3390
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
package/dist/server.d.ts
CHANGED
|
@@ -278,6 +278,8 @@ export declare class PayGateServer {
|
|
|
278
278
|
private handleToolCorrelation;
|
|
279
279
|
private handleConsumerSegmentation;
|
|
280
280
|
private handleCreditDistribution;
|
|
281
|
+
private handleResponseTimeDistribution;
|
|
282
|
+
private handleConsumerLifetimeValue;
|
|
281
283
|
private handleGetNotes;
|
|
282
284
|
private handleAddNote;
|
|
283
285
|
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
|
@@ -1014,6 +1014,18 @@ class PayGateServer {
|
|
|
1014
1014
|
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
1015
1015
|
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
1016
1016
|
return;
|
|
1017
|
+
case '/admin/response-time-distribution':
|
|
1018
|
+
if (req.method === 'GET')
|
|
1019
|
+
return this.handleResponseTimeDistribution(req, res);
|
|
1020
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
1021
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
1022
|
+
return;
|
|
1023
|
+
case '/admin/consumer-lifetime-value':
|
|
1024
|
+
if (req.method === 'GET')
|
|
1025
|
+
return this.handleConsumerLifetimeValue(req, res);
|
|
1026
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
1027
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
1028
|
+
return;
|
|
1017
1029
|
// ─── Plugin endpoints ──────────────────────────────────────────────
|
|
1018
1030
|
case '/plugins':
|
|
1019
1031
|
return this.handleListPlugins(req, res);
|
|
@@ -1590,6 +1602,8 @@ class PayGateServer {
|
|
|
1590
1602
|
toolCorrelation: 'GET /admin/tool-correlation — Tool co-occurrence analysis showing which tools are commonly used together by the same consumers (requires X-Admin-Key)',
|
|
1591
1603
|
consumerSegmentation: 'GET /admin/consumer-segmentation — Consumer classification into power/regular/casual/dormant segments with per-segment metrics (requires X-Admin-Key)',
|
|
1592
1604
|
creditDistribution: 'GET /admin/credit-distribution — Histogram of credit balances across active keys with configurable buckets and median calculation (requires X-Admin-Key)',
|
|
1605
|
+
responseTimeDistribution: 'GET /admin/response-time-distribution — Histogram of response times with latency buckets, percentiles p50/p95/p99, and performance analysis (requires X-Admin-Key)',
|
|
1606
|
+
consumerLifetimeValue: 'GET /admin/consumer-lifetime-value — Per-consumer value metrics with spend, calls, tool diversity, and tier classification (requires X-Admin-Key)',
|
|
1593
1607
|
...(this.oauth ? {
|
|
1594
1608
|
oauthMetadata: 'GET /.well-known/oauth-authorization-server — OAuth 2.1 server metadata',
|
|
1595
1609
|
oauthRegister: 'POST /oauth/register — Register OAuth client',
|
|
@@ -7392,6 +7406,147 @@ class PayGateServer {
|
|
|
7392
7406
|
generatedAt: new Date().toISOString(),
|
|
7393
7407
|
}));
|
|
7394
7408
|
}
|
|
7409
|
+
// ─── /admin/response-time-distribution — Latency histogram ───────────────
|
|
7410
|
+
handleResponseTimeDistribution(req, res) {
|
|
7411
|
+
if (!this.checkAdmin(req, res))
|
|
7412
|
+
return;
|
|
7413
|
+
// Collect durations from allowed requests only
|
|
7414
|
+
const durations = [];
|
|
7415
|
+
for (const entry of this.requestLog) {
|
|
7416
|
+
if (entry.status !== 'allowed')
|
|
7417
|
+
continue;
|
|
7418
|
+
if (typeof entry.durationMs === 'number') {
|
|
7419
|
+
durations.push(entry.durationMs);
|
|
7420
|
+
}
|
|
7421
|
+
}
|
|
7422
|
+
if (durations.length === 0) {
|
|
7423
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7424
|
+
res.end(JSON.stringify({
|
|
7425
|
+
buckets: [],
|
|
7426
|
+
summary: { totalRequests: 0, avgResponseTime: 0 },
|
|
7427
|
+
generatedAt: new Date().toISOString(),
|
|
7428
|
+
}));
|
|
7429
|
+
return;
|
|
7430
|
+
}
|
|
7431
|
+
// Define latency buckets
|
|
7432
|
+
const bucketDefs = [
|
|
7433
|
+
{ range: '0-50ms', min: 0, max: 50 },
|
|
7434
|
+
{ range: '51-100ms', min: 51, max: 100 },
|
|
7435
|
+
{ range: '101-250ms', min: 101, max: 250 },
|
|
7436
|
+
{ range: '251-500ms', min: 251, max: 500 },
|
|
7437
|
+
{ range: '501-1000ms', min: 501, max: 1000 },
|
|
7438
|
+
{ range: '1001ms+', min: 1001, max: Infinity },
|
|
7439
|
+
];
|
|
7440
|
+
const bucketCounts = bucketDefs.map(def => ({
|
|
7441
|
+
range: def.range,
|
|
7442
|
+
min: def.min,
|
|
7443
|
+
max: def.max,
|
|
7444
|
+
count: 0,
|
|
7445
|
+
}));
|
|
7446
|
+
for (const d of durations) {
|
|
7447
|
+
for (const bucket of bucketCounts) {
|
|
7448
|
+
if (d >= bucket.min && d <= bucket.max) {
|
|
7449
|
+
bucket.count++;
|
|
7450
|
+
break;
|
|
7451
|
+
}
|
|
7452
|
+
}
|
|
7453
|
+
}
|
|
7454
|
+
// Calculate percentiles
|
|
7455
|
+
const sorted = [...durations].sort((a, b) => a - b);
|
|
7456
|
+
const percentile = (p) => {
|
|
7457
|
+
const idx = Math.ceil((p / 100) * sorted.length) - 1;
|
|
7458
|
+
return sorted[Math.max(0, idx)];
|
|
7459
|
+
};
|
|
7460
|
+
const total = durations.length;
|
|
7461
|
+
const avg = Math.round(durations.reduce((s, d) => s + d, 0) / total);
|
|
7462
|
+
// Only include non-empty buckets
|
|
7463
|
+
const buckets = bucketCounts
|
|
7464
|
+
.filter(b => b.count > 0)
|
|
7465
|
+
.map(({ range, count }) => ({
|
|
7466
|
+
range,
|
|
7467
|
+
count,
|
|
7468
|
+
percentage: Math.round((count / total) * 100),
|
|
7469
|
+
}));
|
|
7470
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7471
|
+
res.end(JSON.stringify({
|
|
7472
|
+
buckets,
|
|
7473
|
+
summary: {
|
|
7474
|
+
totalRequests: total,
|
|
7475
|
+
avgResponseTime: avg,
|
|
7476
|
+
p50: percentile(50),
|
|
7477
|
+
p95: percentile(95),
|
|
7478
|
+
p99: percentile(99),
|
|
7479
|
+
},
|
|
7480
|
+
generatedAt: new Date().toISOString(),
|
|
7481
|
+
}));
|
|
7482
|
+
}
|
|
7483
|
+
// ─── /admin/consumer-lifetime-value — Per-consumer value analysis ────────
|
|
7484
|
+
handleConsumerLifetimeValue(req, res) {
|
|
7485
|
+
if (!this.checkAdmin(req, res))
|
|
7486
|
+
return;
|
|
7487
|
+
const allRecords = this.gate.store.getAllRecords();
|
|
7488
|
+
const activeRecords = allRecords.filter(r => r.active && !r.suspended);
|
|
7489
|
+
if (activeRecords.length === 0) {
|
|
7490
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7491
|
+
res.end(JSON.stringify({
|
|
7492
|
+
consumers: [],
|
|
7493
|
+
summary: { totalConsumers: 0, totalLifetimeValue: 0, avgLifetimeValue: 0 },
|
|
7494
|
+
generatedAt: new Date().toISOString(),
|
|
7495
|
+
}));
|
|
7496
|
+
return;
|
|
7497
|
+
}
|
|
7498
|
+
// Build per-consumer tool sets from request log for diversity count
|
|
7499
|
+
const consumerToolSets = new Map();
|
|
7500
|
+
for (const entry of this.requestLog) {
|
|
7501
|
+
if (entry.status !== 'allowed')
|
|
7502
|
+
continue;
|
|
7503
|
+
let tools = consumerToolSets.get(entry.key);
|
|
7504
|
+
if (!tools) {
|
|
7505
|
+
tools = new Set();
|
|
7506
|
+
consumerToolSets.set(entry.key, tools);
|
|
7507
|
+
}
|
|
7508
|
+
tools.add(entry.tool);
|
|
7509
|
+
}
|
|
7510
|
+
// Build consumer value list
|
|
7511
|
+
const consumers = activeRecords
|
|
7512
|
+
.filter(r => (r.totalSpent || 0) > 0)
|
|
7513
|
+
.map(r => {
|
|
7514
|
+
const spent = r.totalSpent || 0;
|
|
7515
|
+
const calls = r.totalCalls || 0;
|
|
7516
|
+
const maskedKey = r.key.slice(0, 7) + '...' + r.key.slice(-4);
|
|
7517
|
+
const toolSet = consumerToolSets.get(maskedKey);
|
|
7518
|
+
let tier;
|
|
7519
|
+
if (spent >= 100)
|
|
7520
|
+
tier = 'high';
|
|
7521
|
+
else if (spent >= 10)
|
|
7522
|
+
tier = 'medium';
|
|
7523
|
+
else
|
|
7524
|
+
tier = 'low';
|
|
7525
|
+
return {
|
|
7526
|
+
name: r.name || maskedKey,
|
|
7527
|
+
lifetimeValue: spent,
|
|
7528
|
+
totalCalls: calls,
|
|
7529
|
+
avgSpendPerCall: calls > 0 ? Math.round(spent / calls) : 0,
|
|
7530
|
+
toolsUsed: toolSet ? toolSet.size : 0,
|
|
7531
|
+
tier,
|
|
7532
|
+
};
|
|
7533
|
+
})
|
|
7534
|
+
.sort((a, b) => b.lifetimeValue - a.lifetimeValue);
|
|
7535
|
+
const totalLifetimeValue = consumers.reduce((s, c) => s + c.lifetimeValue, 0);
|
|
7536
|
+
const top20 = consumers.slice(0, 20);
|
|
7537
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7538
|
+
res.end(JSON.stringify({
|
|
7539
|
+
consumers: top20,
|
|
7540
|
+
summary: {
|
|
7541
|
+
totalConsumers: activeRecords.length,
|
|
7542
|
+
totalLifetimeValue,
|
|
7543
|
+
avgLifetimeValue: activeRecords.length > 0
|
|
7544
|
+
? Math.round(totalLifetimeValue / activeRecords.length)
|
|
7545
|
+
: 0,
|
|
7546
|
+
},
|
|
7547
|
+
generatedAt: new Date().toISOString(),
|
|
7548
|
+
}));
|
|
7549
|
+
}
|
|
7395
7550
|
// ─── /keys/notes — Timestamped notes on API keys ─────────────────────────
|
|
7396
7551
|
handleGetNotes(req, res) {
|
|
7397
7552
|
if (!this.checkAdmin(req, res))
|