paygate-mcp 8.35.0 → 8.37.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 +45 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +152 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -142,6 +142,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
142
142
|
- **Key Churn Analysis** — `GET /admin/key-churn` key churn metrics with creation/revocation rates, churn and retention percentages, and never-used key detection
|
|
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
|
+
- **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
|
|
145
147
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
146
148
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
147
149
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -3319,6 +3321,49 @@ curl http://localhost:3000/admin/consumer-segmentation -H "X-Admin-Key: YOUR_ADM
|
|
|
3319
3321
|
|
|
3320
3322
|
Classifies active API key consumers into segments based on usage: **power** (20+ calls), **regular** (5–19 calls), **casual** (1–4 calls), **dormant** (0 calls). Each segment includes aggregate metrics: count, total credits remaining, total spent, and average calls per key. Excludes revoked and suspended keys. Read-only.
|
|
3321
3323
|
|
|
3324
|
+
### Credit Distribution
|
|
3325
|
+
|
|
3326
|
+
```bash
|
|
3327
|
+
curl http://localhost:3000/admin/credit-distribution -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
3328
|
+
```
|
|
3329
|
+
|
|
3330
|
+
```json
|
|
3331
|
+
{
|
|
3332
|
+
"buckets": [
|
|
3333
|
+
{ "range": "0-10", "count": 5, "totalCredits": 30 },
|
|
3334
|
+
{ "range": "11-50", "count": 12, "totalCredits": 420 },
|
|
3335
|
+
{ "range": "51-100", "count": 8, "totalCredits": 640 },
|
|
3336
|
+
{ "range": "101-500", "count": 4, "totalCredits": 1200 },
|
|
3337
|
+
{ "range": "1001+", "count": 2, "totalCredits": 5000 }
|
|
3338
|
+
],
|
|
3339
|
+
"summary": { "totalKeys": 31, "medianCredits": 50 },
|
|
3340
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
3341
|
+
}
|
|
3342
|
+
```
|
|
3343
|
+
|
|
3344
|
+
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.
|
|
3345
|
+
|
|
3346
|
+
### Response Time Distribution
|
|
3347
|
+
|
|
3348
|
+
```bash
|
|
3349
|
+
curl http://localhost:3000/admin/response-time-distribution -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
3350
|
+
```
|
|
3351
|
+
|
|
3352
|
+
```json
|
|
3353
|
+
{
|
|
3354
|
+
"buckets": [
|
|
3355
|
+
{ "range": "0-50ms", "count": 45, "percentage": 60 },
|
|
3356
|
+
{ "range": "51-100ms", "count": 20, "percentage": 27 },
|
|
3357
|
+
{ "range": "101-250ms", "count": 8, "percentage": 11 },
|
|
3358
|
+
{ "range": "251-500ms", "count": 2, "percentage": 3 }
|
|
3359
|
+
],
|
|
3360
|
+
"summary": { "totalRequests": 75, "avgResponseTime": 62, "p50": 42, "p95": 180, "p99": 350 },
|
|
3361
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
3362
|
+
}
|
|
3363
|
+
```
|
|
3364
|
+
|
|
3365
|
+
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.
|
|
3366
|
+
|
|
3322
3367
|
### IP Allowlisting
|
|
3323
3368
|
|
|
3324
3369
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
package/dist/server.d.ts
CHANGED
|
@@ -277,6 +277,8 @@ export declare class PayGateServer {
|
|
|
277
277
|
private handleKeyChurn;
|
|
278
278
|
private handleToolCorrelation;
|
|
279
279
|
private handleConsumerSegmentation;
|
|
280
|
+
private handleCreditDistribution;
|
|
281
|
+
private handleResponseTimeDistribution;
|
|
280
282
|
private handleGetNotes;
|
|
281
283
|
private handleAddNote;
|
|
282
284
|
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
|
@@ -1008,6 +1008,18 @@ class PayGateServer {
|
|
|
1008
1008
|
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
1009
1009
|
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
1010
1010
|
return;
|
|
1011
|
+
case '/admin/credit-distribution':
|
|
1012
|
+
if (req.method === 'GET')
|
|
1013
|
+
return this.handleCreditDistribution(req, res);
|
|
1014
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
1015
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
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;
|
|
1011
1023
|
// ─── Plugin endpoints ──────────────────────────────────────────────
|
|
1012
1024
|
case '/plugins':
|
|
1013
1025
|
return this.handleListPlugins(req, res);
|
|
@@ -1583,6 +1595,8 @@ class PayGateServer {
|
|
|
1583
1595
|
keyChurn: 'GET /admin/key-churn — Key churn analysis with creation/revocation rates, churn and retention percentages, and never-used key detection (requires X-Admin-Key)',
|
|
1584
1596
|
toolCorrelation: 'GET /admin/tool-correlation — Tool co-occurrence analysis showing which tools are commonly used together by the same consumers (requires X-Admin-Key)',
|
|
1585
1597
|
consumerSegmentation: 'GET /admin/consumer-segmentation — Consumer classification into power/regular/casual/dormant segments with per-segment metrics (requires X-Admin-Key)',
|
|
1598
|
+
creditDistribution: 'GET /admin/credit-distribution — Histogram of credit balances across active keys with configurable buckets and median calculation (requires X-Admin-Key)',
|
|
1599
|
+
responseTimeDistribution: 'GET /admin/response-time-distribution — Histogram of response times with latency buckets, percentiles p50/p95/p99, and performance analysis (requires X-Admin-Key)',
|
|
1586
1600
|
...(this.oauth ? {
|
|
1587
1601
|
oauthMetadata: 'GET /.well-known/oauth-authorization-server — OAuth 2.1 server metadata',
|
|
1588
1602
|
oauthRegister: 'POST /oauth/register — Register OAuth client',
|
|
@@ -7321,6 +7335,144 @@ class PayGateServer {
|
|
|
7321
7335
|
generatedAt: new Date().toISOString(),
|
|
7322
7336
|
}));
|
|
7323
7337
|
}
|
|
7338
|
+
// ─── /admin/credit-distribution — Credit balance histogram ───────────────
|
|
7339
|
+
handleCreditDistribution(req, res) {
|
|
7340
|
+
if (!this.checkAdmin(req, res))
|
|
7341
|
+
return;
|
|
7342
|
+
const allRecords = this.gate.store.getAllRecords();
|
|
7343
|
+
const activeRecords = allRecords.filter(r => r.active && !r.suspended);
|
|
7344
|
+
if (activeRecords.length === 0) {
|
|
7345
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7346
|
+
res.end(JSON.stringify({
|
|
7347
|
+
buckets: [],
|
|
7348
|
+
summary: { totalKeys: 0, medianCredits: 0 },
|
|
7349
|
+
generatedAt: new Date().toISOString(),
|
|
7350
|
+
}));
|
|
7351
|
+
return;
|
|
7352
|
+
}
|
|
7353
|
+
// Define bucket ranges
|
|
7354
|
+
const bucketDefs = [
|
|
7355
|
+
{ range: '0-10', min: 0, max: 10 },
|
|
7356
|
+
{ range: '11-50', min: 11, max: 50 },
|
|
7357
|
+
{ range: '51-100', min: 51, max: 100 },
|
|
7358
|
+
{ range: '101-500', min: 101, max: 500 },
|
|
7359
|
+
{ range: '501-1000', min: 501, max: 1000 },
|
|
7360
|
+
{ range: '1001+', min: 1001, max: Infinity },
|
|
7361
|
+
];
|
|
7362
|
+
// Count keys per bucket
|
|
7363
|
+
const bucketCounts = bucketDefs.map(def => ({
|
|
7364
|
+
range: def.range,
|
|
7365
|
+
min: def.min,
|
|
7366
|
+
max: def.max,
|
|
7367
|
+
count: 0,
|
|
7368
|
+
totalCredits: 0,
|
|
7369
|
+
}));
|
|
7370
|
+
const creditValues = [];
|
|
7371
|
+
for (const rec of activeRecords) {
|
|
7372
|
+
const credits = rec.credits || 0;
|
|
7373
|
+
creditValues.push(credits);
|
|
7374
|
+
for (const bucket of bucketCounts) {
|
|
7375
|
+
if (credits >= bucket.min && credits <= bucket.max) {
|
|
7376
|
+
bucket.count++;
|
|
7377
|
+
bucket.totalCredits += credits;
|
|
7378
|
+
break;
|
|
7379
|
+
}
|
|
7380
|
+
}
|
|
7381
|
+
}
|
|
7382
|
+
// Calculate median
|
|
7383
|
+
creditValues.sort((a, b) => a - b);
|
|
7384
|
+
const mid = Math.floor(creditValues.length / 2);
|
|
7385
|
+
const medianCredits = creditValues.length % 2 === 0
|
|
7386
|
+
? Math.round((creditValues[mid - 1] + creditValues[mid]) / 2)
|
|
7387
|
+
: creditValues[mid];
|
|
7388
|
+
// Only include non-empty buckets, in order
|
|
7389
|
+
const buckets = bucketCounts
|
|
7390
|
+
.filter(b => b.count > 0)
|
|
7391
|
+
.map(({ range, count, totalCredits }) => ({ range, count, totalCredits }));
|
|
7392
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7393
|
+
res.end(JSON.stringify({
|
|
7394
|
+
buckets,
|
|
7395
|
+
summary: {
|
|
7396
|
+
totalKeys: activeRecords.length,
|
|
7397
|
+
medianCredits,
|
|
7398
|
+
},
|
|
7399
|
+
generatedAt: new Date().toISOString(),
|
|
7400
|
+
}));
|
|
7401
|
+
}
|
|
7402
|
+
// ─── /admin/response-time-distribution — Latency histogram ───────────────
|
|
7403
|
+
handleResponseTimeDistribution(req, res) {
|
|
7404
|
+
if (!this.checkAdmin(req, res))
|
|
7405
|
+
return;
|
|
7406
|
+
// Collect durations from allowed requests only
|
|
7407
|
+
const durations = [];
|
|
7408
|
+
for (const entry of this.requestLog) {
|
|
7409
|
+
if (entry.status !== 'allowed')
|
|
7410
|
+
continue;
|
|
7411
|
+
if (typeof entry.durationMs === 'number') {
|
|
7412
|
+
durations.push(entry.durationMs);
|
|
7413
|
+
}
|
|
7414
|
+
}
|
|
7415
|
+
if (durations.length === 0) {
|
|
7416
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7417
|
+
res.end(JSON.stringify({
|
|
7418
|
+
buckets: [],
|
|
7419
|
+
summary: { totalRequests: 0, avgResponseTime: 0 },
|
|
7420
|
+
generatedAt: new Date().toISOString(),
|
|
7421
|
+
}));
|
|
7422
|
+
return;
|
|
7423
|
+
}
|
|
7424
|
+
// Define latency buckets
|
|
7425
|
+
const bucketDefs = [
|
|
7426
|
+
{ range: '0-50ms', min: 0, max: 50 },
|
|
7427
|
+
{ range: '51-100ms', min: 51, max: 100 },
|
|
7428
|
+
{ range: '101-250ms', min: 101, max: 250 },
|
|
7429
|
+
{ range: '251-500ms', min: 251, max: 500 },
|
|
7430
|
+
{ range: '501-1000ms', min: 501, max: 1000 },
|
|
7431
|
+
{ range: '1001ms+', min: 1001, max: Infinity },
|
|
7432
|
+
];
|
|
7433
|
+
const bucketCounts = bucketDefs.map(def => ({
|
|
7434
|
+
range: def.range,
|
|
7435
|
+
min: def.min,
|
|
7436
|
+
max: def.max,
|
|
7437
|
+
count: 0,
|
|
7438
|
+
}));
|
|
7439
|
+
for (const d of durations) {
|
|
7440
|
+
for (const bucket of bucketCounts) {
|
|
7441
|
+
if (d >= bucket.min && d <= bucket.max) {
|
|
7442
|
+
bucket.count++;
|
|
7443
|
+
break;
|
|
7444
|
+
}
|
|
7445
|
+
}
|
|
7446
|
+
}
|
|
7447
|
+
// Calculate percentiles
|
|
7448
|
+
const sorted = [...durations].sort((a, b) => a - b);
|
|
7449
|
+
const percentile = (p) => {
|
|
7450
|
+
const idx = Math.ceil((p / 100) * sorted.length) - 1;
|
|
7451
|
+
return sorted[Math.max(0, idx)];
|
|
7452
|
+
};
|
|
7453
|
+
const total = durations.length;
|
|
7454
|
+
const avg = Math.round(durations.reduce((s, d) => s + d, 0) / total);
|
|
7455
|
+
// Only include non-empty buckets
|
|
7456
|
+
const buckets = bucketCounts
|
|
7457
|
+
.filter(b => b.count > 0)
|
|
7458
|
+
.map(({ range, count }) => ({
|
|
7459
|
+
range,
|
|
7460
|
+
count,
|
|
7461
|
+
percentage: Math.round((count / total) * 100),
|
|
7462
|
+
}));
|
|
7463
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
7464
|
+
res.end(JSON.stringify({
|
|
7465
|
+
buckets,
|
|
7466
|
+
summary: {
|
|
7467
|
+
totalRequests: total,
|
|
7468
|
+
avgResponseTime: avg,
|
|
7469
|
+
p50: percentile(50),
|
|
7470
|
+
p95: percentile(95),
|
|
7471
|
+
p99: percentile(99),
|
|
7472
|
+
},
|
|
7473
|
+
generatedAt: new Date().toISOString(),
|
|
7474
|
+
}));
|
|
7475
|
+
}
|
|
7324
7476
|
// ─── /keys/notes — Timestamped notes on API keys ─────────────────────────
|
|
7325
7477
|
handleGetNotes(req, res) {
|
|
7326
7478
|
if (!this.checkAdmin(req, res))
|