paygate-mcp 8.15.0 → 8.17.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 +51 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +162 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -122,6 +122,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
122
122
|
- **Usage Forecasting** — `GET /admin/forecast` predicts future credit consumption with per-key depletion estimates, calls remaining, at-risk key identification, system-wide consumption aggregates, and per-tool cost breakdown
|
|
123
123
|
- **Compliance Report** — `GET /admin/compliance` generates compliance-ready report with key governance (expiry coverage), access control (ACL/IP/spending limit coverage), audit trail completeness, weighted overall score, and actionable recommendations
|
|
124
124
|
- **SLA Monitoring** — `GET /admin/sla` tracks service level metrics: success rates, denial breakdowns by reason, per-tool availability and error rates, uptime tracking, sorted by call volume
|
|
125
|
+
- **Capacity Planning** — `GET /admin/capacity` system capacity analysis with credit burn rates, utilization percentages, top consumers, per-namespace breakdown, and scaling recommendations
|
|
126
|
+
- **Key Dependency Map** — `GET /admin/dependencies` tool-to-key relationship map with tool usage popularity, unique key counts per tool, per-key tool lists, and used/unused tool identification
|
|
125
127
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
126
128
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
127
129
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -2816,6 +2818,55 @@ curl http://localhost:3000/admin/sla -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
|
2816
2818
|
|
|
2817
2819
|
Service level metrics: overall success rate, denial breakdown by canonical reason (insufficient_credits, rate_limited, quota_exceeded, acl_denied, spending_limit, key_suspended, key_expired), per-tool availability sorted by call volume, and server uptime tracking. Read-only.
|
|
2818
2820
|
|
|
2821
|
+
### Capacity Planning
|
|
2822
|
+
|
|
2823
|
+
```bash
|
|
2824
|
+
curl http://localhost:3000/admin/capacity -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
2825
|
+
```
|
|
2826
|
+
|
|
2827
|
+
```json
|
|
2828
|
+
{
|
|
2829
|
+
"summary": {
|
|
2830
|
+
"totalCreditsAllocated": 10000, "totalCreditsSpent": 3500, "totalCreditsRemaining": 6500,
|
|
2831
|
+
"utilizationPct": 35,
|
|
2832
|
+
"burnRate": { "creditsPerCall": 10, "totalCalls": 350 }
|
|
2833
|
+
},
|
|
2834
|
+
"topConsumers": [
|
|
2835
|
+
{ "keyName": "heavy-user", "creditsSpent": 2000, "creditsRemaining": 500, "callCount": 200 }
|
|
2836
|
+
],
|
|
2837
|
+
"byNamespace": {
|
|
2838
|
+
"prod": { "allocated": 8000, "spent": 3000, "remaining": 5000, "keys": 3, "utilizationPct": 37 }
|
|
2839
|
+
},
|
|
2840
|
+
"recommendations": ["1 key(s) have less than 10% credits remaining"],
|
|
2841
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
2842
|
+
}
|
|
2843
|
+
```
|
|
2844
|
+
|
|
2845
|
+
System capacity analysis: overall credit utilization, burn rate (credits/call), top 10 consumers ranked by spend, per-namespace breakdown, and scaling recommendations for high utilization (>=75%) or depleted keys. Read-only.
|
|
2846
|
+
|
|
2847
|
+
### Key Dependency Map
|
|
2848
|
+
|
|
2849
|
+
```bash
|
|
2850
|
+
curl http://localhost:3000/admin/dependencies -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
2851
|
+
```
|
|
2852
|
+
|
|
2853
|
+
```json
|
|
2854
|
+
{
|
|
2855
|
+
"summary": { "totalTools": 5, "usedTools": 3, "unusedTools": 2 },
|
|
2856
|
+
"toolUsage": [
|
|
2857
|
+
{ "tool": "search", "totalCalls": 150, "uniqueKeys": 8 },
|
|
2858
|
+
{ "tool": "translate", "totalCalls": 45, "uniqueKeys": 3 }
|
|
2859
|
+
],
|
|
2860
|
+
"keyToolMap": [
|
|
2861
|
+
{ "keyName": "power-user", "tools": ["search", "translate", "summarize"], "toolCount": 3 },
|
|
2862
|
+
{ "keyName": "basic-user", "tools": ["search"], "toolCount": 1 }
|
|
2863
|
+
],
|
|
2864
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
2865
|
+
}
|
|
2866
|
+
```
|
|
2867
|
+
|
|
2868
|
+
Tool-to-key relationship map: shows which tools each key uses, tool popularity ranked by total calls, unique key counts per tool, and identifies orphaned tools (available but unused). Useful for understanding tool adoption and pruning unused capabilities. Read-only.
|
|
2869
|
+
|
|
2819
2870
|
### IP Allowlisting
|
|
2820
2871
|
|
|
2821
2872
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
package/dist/server.d.ts
CHANGED
|
@@ -257,6 +257,8 @@ export declare class PayGateServer {
|
|
|
257
257
|
private handleUsageForecasting;
|
|
258
258
|
private handleComplianceReport;
|
|
259
259
|
private handleSlaMonitoring;
|
|
260
|
+
private handleCapacityPlanning;
|
|
261
|
+
private handleDependencyMap;
|
|
260
262
|
private handleGetNotes;
|
|
261
263
|
private handleAddNote;
|
|
262
264
|
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
|
@@ -888,6 +888,18 @@ class PayGateServer {
|
|
|
888
888
|
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
889
889
|
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
890
890
|
return;
|
|
891
|
+
case '/admin/capacity':
|
|
892
|
+
if (req.method === 'GET')
|
|
893
|
+
return this.handleCapacityPlanning(req, res);
|
|
894
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
895
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
896
|
+
return;
|
|
897
|
+
case '/admin/dependencies':
|
|
898
|
+
if (req.method === 'GET')
|
|
899
|
+
return this.handleDependencyMap(req, res);
|
|
900
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
901
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
902
|
+
return;
|
|
891
903
|
// ─── Plugin endpoints ──────────────────────────────────────────────
|
|
892
904
|
case '/plugins':
|
|
893
905
|
return this.handleListPlugins(req, res);
|
|
@@ -1443,6 +1455,8 @@ class PayGateServer {
|
|
|
1443
1455
|
usageForecasting: 'GET /admin/forecast — Usage forecasting with per-key depletion estimates, system-wide consumption trends, per-tool breakdown, and at-risk key identification (requires X-Admin-Key)',
|
|
1444
1456
|
complianceReport: 'GET /admin/compliance — Compliance report with key governance, access control coverage, audit trail completeness, recommendations, and overall compliance score (requires X-Admin-Key)',
|
|
1445
1457
|
slaMonitoring: 'GET /admin/sla — SLA monitoring with success rates, denial breakdowns, per-tool availability, uptime tracking, and denial reason aggregation (requires X-Admin-Key)',
|
|
1458
|
+
capacityPlanning: 'GET /admin/capacity — Capacity planning with credit burn rates, utilization percentages, top consumers, per-namespace breakdown, and scaling recommendations (requires X-Admin-Key)',
|
|
1459
|
+
dependencyMap: 'GET /admin/dependencies — Tool-to-key dependency map with tool usage popularity, unique key counts, per-key tool lists, and used/unused tool identification (requires X-Admin-Key)',
|
|
1446
1460
|
...(this.oauth ? {
|
|
1447
1461
|
oauthMetadata: 'GET /.well-known/oauth-authorization-server — OAuth 2.1 server metadata',
|
|
1448
1462
|
oauthRegister: 'POST /oauth/register — Register OAuth client',
|
|
@@ -5947,6 +5961,154 @@ class PayGateServer {
|
|
|
5947
5961
|
generatedAt: new Date().toISOString(),
|
|
5948
5962
|
}));
|
|
5949
5963
|
}
|
|
5964
|
+
// ─── /admin/capacity — Capacity Planning ─────────────────────────────────
|
|
5965
|
+
handleCapacityPlanning(req, res) {
|
|
5966
|
+
if (!this.checkAdmin(req, res))
|
|
5967
|
+
return;
|
|
5968
|
+
const events = this.gate.meter.getEvents();
|
|
5969
|
+
const allRecords = this.gate.store.getAllRecords();
|
|
5970
|
+
const activeRecords = allRecords.filter(r => r.active);
|
|
5971
|
+
// ── Summary ──
|
|
5972
|
+
const totalCreditsAllocated = activeRecords.reduce((sum, r) => sum + r.credits + (r.totalSpent || 0), 0);
|
|
5973
|
+
const totalCreditsSpent = activeRecords.reduce((sum, r) => sum + (r.totalSpent || 0), 0);
|
|
5974
|
+
const totalCreditsRemaining = activeRecords.reduce((sum, r) => sum + r.credits, 0);
|
|
5975
|
+
const utilizationPct = totalCreditsAllocated > 0
|
|
5976
|
+
? Math.round(totalCreditsSpent / totalCreditsAllocated * 100)
|
|
5977
|
+
: 0;
|
|
5978
|
+
// ── Burn rate ──
|
|
5979
|
+
const allowedEvents = events.filter(e => e.allowed);
|
|
5980
|
+
const totalCalls = allowedEvents.length;
|
|
5981
|
+
const totalCreditsFromEvents = allowedEvents.reduce((sum, e) => sum + (e.creditsCharged || 0), 0);
|
|
5982
|
+
const creditsPerCall = totalCalls > 0 ? Math.round(totalCreditsFromEvents / totalCalls * 100) / 100 : 0;
|
|
5983
|
+
// ── Top consumers (by credits spent) ──
|
|
5984
|
+
const topConsumers = activeRecords
|
|
5985
|
+
.filter(r => (r.totalSpent || 0) > 0)
|
|
5986
|
+
.map(r => ({
|
|
5987
|
+
keyName: r.name,
|
|
5988
|
+
creditsSpent: r.totalSpent || 0,
|
|
5989
|
+
creditsRemaining: r.credits,
|
|
5990
|
+
callCount: r.totalCalls || 0,
|
|
5991
|
+
}))
|
|
5992
|
+
.sort((a, b) => b.creditsSpent - a.creditsSpent)
|
|
5993
|
+
.slice(0, 10);
|
|
5994
|
+
// ── Per-namespace breakdown ──
|
|
5995
|
+
const nsMap = new Map();
|
|
5996
|
+
for (const r of activeRecords) {
|
|
5997
|
+
const ns = r.namespace || 'default';
|
|
5998
|
+
if (!nsMap.has(ns))
|
|
5999
|
+
nsMap.set(ns, { allocated: 0, spent: 0, remaining: 0, keys: 0 });
|
|
6000
|
+
const n = nsMap.get(ns);
|
|
6001
|
+
n.allocated += r.credits + (r.totalSpent || 0);
|
|
6002
|
+
n.spent += r.totalSpent || 0;
|
|
6003
|
+
n.remaining += r.credits;
|
|
6004
|
+
n.keys++;
|
|
6005
|
+
}
|
|
6006
|
+
const byNamespace = {};
|
|
6007
|
+
for (const [ns, stats] of nsMap) {
|
|
6008
|
+
byNamespace[ns] = {
|
|
6009
|
+
...stats,
|
|
6010
|
+
utilizationPct: stats.allocated > 0 ? Math.round(stats.spent / stats.allocated * 100) : 0,
|
|
6011
|
+
};
|
|
6012
|
+
}
|
|
6013
|
+
// ── Recommendations ──
|
|
6014
|
+
const recommendations = [];
|
|
6015
|
+
if (utilizationPct >= 90) {
|
|
6016
|
+
recommendations.push(`System utilization is at ${utilizationPct}% — top up credits immediately to avoid service disruption`);
|
|
6017
|
+
}
|
|
6018
|
+
else if (utilizationPct >= 75) {
|
|
6019
|
+
recommendations.push(`System utilization is at ${utilizationPct}% — consider adding more credits soon`);
|
|
6020
|
+
}
|
|
6021
|
+
const depleted = activeRecords.filter(r => r.credits <= 0 && (r.totalSpent || 0) > 0);
|
|
6022
|
+
if (depleted.length > 0) {
|
|
6023
|
+
recommendations.push(`${depleted.length} key(s) have zero remaining credits and need top-up`);
|
|
6024
|
+
}
|
|
6025
|
+
const lowCredit = activeRecords.filter(r => {
|
|
6026
|
+
const alloc = r.credits + (r.totalSpent || 0);
|
|
6027
|
+
return alloc > 0 && r.credits > 0 && r.credits / alloc <= 0.1;
|
|
6028
|
+
});
|
|
6029
|
+
if (lowCredit.length > 0) {
|
|
6030
|
+
recommendations.push(`${lowCredit.length} key(s) have less than 10% credits remaining`);
|
|
6031
|
+
}
|
|
6032
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
6033
|
+
res.end(JSON.stringify({
|
|
6034
|
+
summary: {
|
|
6035
|
+
totalCreditsAllocated,
|
|
6036
|
+
totalCreditsSpent,
|
|
6037
|
+
totalCreditsRemaining,
|
|
6038
|
+
utilizationPct,
|
|
6039
|
+
burnRate: {
|
|
6040
|
+
creditsPerCall,
|
|
6041
|
+
totalCalls,
|
|
6042
|
+
},
|
|
6043
|
+
},
|
|
6044
|
+
topConsumers,
|
|
6045
|
+
byNamespace,
|
|
6046
|
+
recommendations,
|
|
6047
|
+
generatedAt: new Date().toISOString(),
|
|
6048
|
+
}));
|
|
6049
|
+
}
|
|
6050
|
+
// ─── /admin/dependencies — Key Dependency Map ───────────────────────────
|
|
6051
|
+
handleDependencyMap(req, res) {
|
|
6052
|
+
if (!this.checkAdmin(req, res))
|
|
6053
|
+
return;
|
|
6054
|
+
const events = this.gate.meter.getEvents();
|
|
6055
|
+
// ── Tool usage from events ──
|
|
6056
|
+
const toolStats = new Map();
|
|
6057
|
+
const keyTools = new Map();
|
|
6058
|
+
for (const e of events) {
|
|
6059
|
+
if (!e.allowed || !e.tool)
|
|
6060
|
+
continue;
|
|
6061
|
+
const tool = e.tool;
|
|
6062
|
+
const keyName = e.keyName || e.apiKey;
|
|
6063
|
+
if (!toolStats.has(tool))
|
|
6064
|
+
toolStats.set(tool, { totalCalls: 0, keys: new Set() });
|
|
6065
|
+
const ts = toolStats.get(tool);
|
|
6066
|
+
ts.totalCalls++;
|
|
6067
|
+
ts.keys.add(keyName);
|
|
6068
|
+
if (!keyTools.has(keyName))
|
|
6069
|
+
keyTools.set(keyName, new Set());
|
|
6070
|
+
keyTools.get(keyName).add(tool);
|
|
6071
|
+
}
|
|
6072
|
+
// ── Collect all known tool names (from config pricing + events) ──
|
|
6073
|
+
const allToolNames = new Set();
|
|
6074
|
+
const toolPricing = this.config?.toolPricing;
|
|
6075
|
+
if (toolPricing) {
|
|
6076
|
+
for (const name of Object.keys(toolPricing))
|
|
6077
|
+
allToolNames.add(name);
|
|
6078
|
+
}
|
|
6079
|
+
for (const tool of toolStats.keys())
|
|
6080
|
+
allToolNames.add(tool);
|
|
6081
|
+
const usedTools = toolStats.size;
|
|
6082
|
+
const totalTools = Math.max(allToolNames.size, usedTools);
|
|
6083
|
+
const unusedTools = totalTools - usedTools;
|
|
6084
|
+
// ── Tool usage sorted by popularity ──
|
|
6085
|
+
const toolUsage = Array.from(toolStats.entries())
|
|
6086
|
+
.map(([tool, stats]) => ({
|
|
6087
|
+
tool,
|
|
6088
|
+
totalCalls: stats.totalCalls,
|
|
6089
|
+
uniqueKeys: stats.keys.size,
|
|
6090
|
+
}))
|
|
6091
|
+
.sort((a, b) => b.totalCalls - a.totalCalls);
|
|
6092
|
+
// ── Per-key tool map ──
|
|
6093
|
+
const keyToolMap = Array.from(keyTools.entries())
|
|
6094
|
+
.map(([keyName, tools]) => ({
|
|
6095
|
+
keyName,
|
|
6096
|
+
tools: Array.from(tools).sort(),
|
|
6097
|
+
toolCount: tools.size,
|
|
6098
|
+
}))
|
|
6099
|
+
.sort((a, b) => b.toolCount - a.toolCount);
|
|
6100
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
6101
|
+
res.end(JSON.stringify({
|
|
6102
|
+
summary: {
|
|
6103
|
+
totalTools,
|
|
6104
|
+
usedTools,
|
|
6105
|
+
unusedTools,
|
|
6106
|
+
},
|
|
6107
|
+
toolUsage,
|
|
6108
|
+
keyToolMap,
|
|
6109
|
+
generatedAt: new Date().toISOString(),
|
|
6110
|
+
}));
|
|
6111
|
+
}
|
|
5950
6112
|
// ─── /keys/notes — Timestamped notes on API keys ─────────────────────────
|
|
5951
6113
|
handleGetNotes(req, res) {
|
|
5952
6114
|
if (!this.checkAdmin(req, res))
|