paygate-mcp 8.13.0 → 8.15.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 +52 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +200 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -120,6 +120,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
120
120
|
- **Key Portfolio Health** — `GET /admin/key-portfolio` portfolio-wide key health with active/inactive/suspended counts, stale keys, expiring-soon keys, age distribution, credit utilization, and namespace breakdown
|
|
121
121
|
- **Anomaly Detection** — `GET /admin/anomalies` identifies unusual patterns: keys with high denial rates, rapid credit depletion, low remaining credits, with severity ratings and detailed descriptions
|
|
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
|
+
- **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
|
+
- **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
|
|
123
125
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
124
126
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
125
127
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -2764,6 +2766,56 @@ curl http://localhost:3000/admin/forecast -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
|
2764
2766
|
|
|
2765
2767
|
Forecasts credit consumption for all active keys: per-key depletion estimates with calls remaining, at-risk identification (<=5 estimated calls), system-wide credit aggregates, and per-tool cost breakdown sorted by revenue. Keys with no usage history show `estimatedCallsRemaining: null`. Read-only.
|
|
2766
2768
|
|
|
2769
|
+
### Compliance Report
|
|
2770
|
+
|
|
2771
|
+
```bash
|
|
2772
|
+
curl http://localhost:3000/admin/compliance -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
2773
|
+
```
|
|
2774
|
+
|
|
2775
|
+
```json
|
|
2776
|
+
{
|
|
2777
|
+
"keyGovernance": { "totalKeys": 5, "keysWithExpiry": 3, "keysWithoutExpiry": 2 },
|
|
2778
|
+
"accessControl": {
|
|
2779
|
+
"keysWithAcl": 3, "keysWithoutAcl": 2,
|
|
2780
|
+
"keysWithIpRestriction": 2, "keysWithoutIpRestriction": 3,
|
|
2781
|
+
"keysWithSpendingLimit": 4, "keysWithoutSpendingLimit": 1
|
|
2782
|
+
},
|
|
2783
|
+
"auditTrail": { "totalEvents": 150, "uniqueTools": 5, "uniqueKeys": 4 },
|
|
2784
|
+
"overallScore": 72,
|
|
2785
|
+
"recommendations": [
|
|
2786
|
+
"Set expiry dates on 2 key(s) without time-limited access",
|
|
2787
|
+
"Add tool ACL restrictions to 2 key(s) with unrestricted tool access"
|
|
2788
|
+
],
|
|
2789
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
2790
|
+
}
|
|
2791
|
+
```
|
|
2792
|
+
|
|
2793
|
+
Compliance-ready report scoring key governance (expiry 25%), access control (ACL 25%, IP 20%, spending limits 15%), and audit trail (15%). Actionable recommendations for each gap. Read-only.
|
|
2794
|
+
|
|
2795
|
+
### SLA Monitoring
|
|
2796
|
+
|
|
2797
|
+
```bash
|
|
2798
|
+
curl http://localhost:3000/admin/sla -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
2799
|
+
```
|
|
2800
|
+
|
|
2801
|
+
```json
|
|
2802
|
+
{
|
|
2803
|
+
"summary": {
|
|
2804
|
+
"totalCalls": 150, "allowedCalls": 140, "deniedCalls": 10,
|
|
2805
|
+
"successRate": 93.33,
|
|
2806
|
+
"denialReasons": { "insufficient_credits": 6, "rate_limited": 3, "acl_denied": 1 }
|
|
2807
|
+
},
|
|
2808
|
+
"byTool": [
|
|
2809
|
+
{ "tool": "tool_a", "totalCalls": 100, "allowedCalls": 95, "deniedCalls": 5, "successRate": 95 },
|
|
2810
|
+
{ "tool": "tool_b", "totalCalls": 50, "allowedCalls": 45, "deniedCalls": 5, "successRate": 90 }
|
|
2811
|
+
],
|
|
2812
|
+
"uptime": { "startedAt": "2025-01-15T10:00:00Z", "uptimeSeconds": 16200 },
|
|
2813
|
+
"generatedAt": "2025-01-15T14:30:00Z"
|
|
2814
|
+
}
|
|
2815
|
+
```
|
|
2816
|
+
|
|
2817
|
+
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
|
+
|
|
2767
2819
|
### IP Allowlisting
|
|
2768
2820
|
|
|
2769
2821
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
package/dist/server.d.ts
CHANGED
|
@@ -255,6 +255,8 @@ export declare class PayGateServer {
|
|
|
255
255
|
private handleLifecycleAnalysis;
|
|
256
256
|
private handleAnomalyDetection;
|
|
257
257
|
private handleUsageForecasting;
|
|
258
|
+
private handleComplianceReport;
|
|
259
|
+
private handleSlaMonitoring;
|
|
258
260
|
private handleGetNotes;
|
|
259
261
|
private handleAddNote;
|
|
260
262
|
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
|
@@ -876,6 +876,18 @@ class PayGateServer {
|
|
|
876
876
|
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
877
877
|
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
878
878
|
return;
|
|
879
|
+
case '/admin/compliance':
|
|
880
|
+
if (req.method === 'GET')
|
|
881
|
+
return this.handleComplianceReport(req, res);
|
|
882
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
883
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
884
|
+
return;
|
|
885
|
+
case '/admin/sla':
|
|
886
|
+
if (req.method === 'GET')
|
|
887
|
+
return this.handleSlaMonitoring(req, res);
|
|
888
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
889
|
+
res.end(JSON.stringify({ error: 'Method not allowed. Use GET.' }));
|
|
890
|
+
return;
|
|
879
891
|
// ─── Plugin endpoints ──────────────────────────────────────────────
|
|
880
892
|
case '/plugins':
|
|
881
893
|
return this.handleListPlugins(req, res);
|
|
@@ -1429,6 +1441,8 @@ class PayGateServer {
|
|
|
1429
1441
|
keyPortfolio: 'GET /admin/key-portfolio — Key portfolio health with active/inactive/suspended counts, stale keys, expiring-soon keys, age distribution, credit utilization, and namespace breakdown (requires X-Admin-Key)',
|
|
1430
1442
|
anomalyDetection: 'GET /admin/anomalies — Anomaly detection identifying high denial rates, rapid credit depletion, low credit balances, and other unusual patterns (requires X-Admin-Key)',
|
|
1431
1443
|
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
|
+
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
|
+
slaMonitoring: 'GET /admin/sla — SLA monitoring with success rates, denial breakdowns, per-tool availability, uptime tracking, and denial reason aggregation (requires X-Admin-Key)',
|
|
1432
1446
|
...(this.oauth ? {
|
|
1433
1447
|
oauthMetadata: 'GET /.well-known/oauth-authorization-server — OAuth 2.1 server metadata',
|
|
1434
1448
|
oauthRegister: 'POST /oauth/register — Register OAuth client',
|
|
@@ -5747,6 +5761,192 @@ class PayGateServer {
|
|
|
5747
5761
|
generatedAt: new Date().toISOString(),
|
|
5748
5762
|
}));
|
|
5749
5763
|
}
|
|
5764
|
+
// ─── /admin/compliance — Compliance Report ──────────────────────────────
|
|
5765
|
+
handleComplianceReport(req, res) {
|
|
5766
|
+
if (!this.checkAdmin(req, res))
|
|
5767
|
+
return;
|
|
5768
|
+
const events = this.gate.meter.getEvents();
|
|
5769
|
+
const allRecords = this.gate.store.getAllRecords();
|
|
5770
|
+
const activeRecords = allRecords.filter(r => r.active);
|
|
5771
|
+
// ── Key Governance ──
|
|
5772
|
+
const totalKeys = activeRecords.length;
|
|
5773
|
+
let keysWithExpiry = 0;
|
|
5774
|
+
let keysWithoutExpiry = 0;
|
|
5775
|
+
for (const r of activeRecords) {
|
|
5776
|
+
if (r.expiresAt)
|
|
5777
|
+
keysWithExpiry++;
|
|
5778
|
+
else
|
|
5779
|
+
keysWithoutExpiry++;
|
|
5780
|
+
}
|
|
5781
|
+
// ── Access Control ──
|
|
5782
|
+
let keysWithAcl = 0;
|
|
5783
|
+
let keysWithoutAcl = 0;
|
|
5784
|
+
let keysWithIpRestriction = 0;
|
|
5785
|
+
let keysWithoutIpRestriction = 0;
|
|
5786
|
+
let keysWithSpendingLimit = 0;
|
|
5787
|
+
let keysWithoutSpendingLimit = 0;
|
|
5788
|
+
for (const r of activeRecords) {
|
|
5789
|
+
if (r.allowedTools && r.allowedTools.length > 0)
|
|
5790
|
+
keysWithAcl++;
|
|
5791
|
+
else
|
|
5792
|
+
keysWithoutAcl++;
|
|
5793
|
+
if (r.ipAllowlist && r.ipAllowlist.length > 0)
|
|
5794
|
+
keysWithIpRestriction++;
|
|
5795
|
+
else
|
|
5796
|
+
keysWithoutIpRestriction++;
|
|
5797
|
+
if (r.spendingLimit && r.spendingLimit > 0)
|
|
5798
|
+
keysWithSpendingLimit++;
|
|
5799
|
+
else
|
|
5800
|
+
keysWithoutSpendingLimit++;
|
|
5801
|
+
}
|
|
5802
|
+
// ── Audit Trail ──
|
|
5803
|
+
const totalEvents = events.length;
|
|
5804
|
+
const tools = new Set();
|
|
5805
|
+
const keys = new Set();
|
|
5806
|
+
for (const e of events) {
|
|
5807
|
+
if (e.tool)
|
|
5808
|
+
tools.add(e.tool);
|
|
5809
|
+
if (e.keyName || e.apiKey)
|
|
5810
|
+
keys.add(e.keyName || e.apiKey);
|
|
5811
|
+
}
|
|
5812
|
+
// ── Overall Score (0-100) ──
|
|
5813
|
+
// Weighted: expiry 25%, ACL 25%, IP 20%, spending limit 15%, audit trail 15%
|
|
5814
|
+
let score = 100;
|
|
5815
|
+
if (totalKeys > 0) {
|
|
5816
|
+
const expiryPct = keysWithExpiry / totalKeys;
|
|
5817
|
+
const aclPct = keysWithAcl / totalKeys;
|
|
5818
|
+
const ipPct = keysWithIpRestriction / totalKeys;
|
|
5819
|
+
const spendPct = keysWithSpendingLimit / totalKeys;
|
|
5820
|
+
score = Math.round(expiryPct * 25 +
|
|
5821
|
+
aclPct * 25 +
|
|
5822
|
+
ipPct * 20 +
|
|
5823
|
+
spendPct * 15 +
|
|
5824
|
+
(totalEvents > 0 ? 15 : 0));
|
|
5825
|
+
}
|
|
5826
|
+
// ── Recommendations ──
|
|
5827
|
+
const recommendations = [];
|
|
5828
|
+
if (keysWithoutExpiry > 0) {
|
|
5829
|
+
recommendations.push(`Set expiry dates on ${keysWithoutExpiry} key(s) without time-limited access`);
|
|
5830
|
+
}
|
|
5831
|
+
if (keysWithoutAcl > 0) {
|
|
5832
|
+
recommendations.push(`Add tool ACL restrictions to ${keysWithoutAcl} key(s) with unrestricted tool access`);
|
|
5833
|
+
}
|
|
5834
|
+
if (keysWithoutIpRestriction > 0) {
|
|
5835
|
+
recommendations.push(`Add IP allowlists to ${keysWithoutIpRestriction} key(s) accessible from any IP`);
|
|
5836
|
+
}
|
|
5837
|
+
if (keysWithoutSpendingLimit > 0) {
|
|
5838
|
+
recommendations.push(`Set spending limits on ${keysWithoutSpendingLimit} key(s) without cost controls`);
|
|
5839
|
+
}
|
|
5840
|
+
if (totalEvents === 0 && totalKeys > 0) {
|
|
5841
|
+
recommendations.push('No usage events recorded — ensure audit trail is capturing tool calls');
|
|
5842
|
+
}
|
|
5843
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
5844
|
+
res.end(JSON.stringify({
|
|
5845
|
+
keyGovernance: {
|
|
5846
|
+
totalKeys,
|
|
5847
|
+
keysWithExpiry,
|
|
5848
|
+
keysWithoutExpiry,
|
|
5849
|
+
},
|
|
5850
|
+
accessControl: {
|
|
5851
|
+
keysWithAcl,
|
|
5852
|
+
keysWithoutAcl,
|
|
5853
|
+
keysWithIpRestriction,
|
|
5854
|
+
keysWithoutIpRestriction,
|
|
5855
|
+
keysWithSpendingLimit,
|
|
5856
|
+
keysWithoutSpendingLimit,
|
|
5857
|
+
},
|
|
5858
|
+
auditTrail: {
|
|
5859
|
+
totalEvents,
|
|
5860
|
+
uniqueTools: tools.size,
|
|
5861
|
+
uniqueKeys: keys.size,
|
|
5862
|
+
},
|
|
5863
|
+
overallScore: score,
|
|
5864
|
+
recommendations,
|
|
5865
|
+
generatedAt: new Date().toISOString(),
|
|
5866
|
+
}));
|
|
5867
|
+
}
|
|
5868
|
+
// ─── /admin/sla — SLA Monitoring ─────────────────────────────────────────
|
|
5869
|
+
handleSlaMonitoring(req, res) {
|
|
5870
|
+
if (!this.checkAdmin(req, res))
|
|
5871
|
+
return;
|
|
5872
|
+
const events = this.gate.meter.getEvents();
|
|
5873
|
+
// ── Summary metrics ──
|
|
5874
|
+
let allowedCalls = 0;
|
|
5875
|
+
let deniedCalls = 0;
|
|
5876
|
+
const denialReasons = {};
|
|
5877
|
+
for (const e of events) {
|
|
5878
|
+
if (e.allowed) {
|
|
5879
|
+
allowedCalls++;
|
|
5880
|
+
}
|
|
5881
|
+
else {
|
|
5882
|
+
deniedCalls++;
|
|
5883
|
+
// Normalize deny reason to canonical type
|
|
5884
|
+
const reason = e.denyReason || 'unknown';
|
|
5885
|
+
let canonical = 'unknown';
|
|
5886
|
+
if (reason.includes('insufficient_credits'))
|
|
5887
|
+
canonical = 'insufficient_credits';
|
|
5888
|
+
else if (reason.includes('rate_limited'))
|
|
5889
|
+
canonical = 'rate_limited';
|
|
5890
|
+
else if (reason.includes('quota'))
|
|
5891
|
+
canonical = 'quota_exceeded';
|
|
5892
|
+
else if (reason.includes('acl') || reason.includes('not allowed'))
|
|
5893
|
+
canonical = 'acl_denied';
|
|
5894
|
+
else if (reason.includes('spending_limit'))
|
|
5895
|
+
canonical = 'spending_limit';
|
|
5896
|
+
else if (reason.includes('suspended'))
|
|
5897
|
+
canonical = 'key_suspended';
|
|
5898
|
+
else if (reason.includes('expired'))
|
|
5899
|
+
canonical = 'key_expired';
|
|
5900
|
+
else
|
|
5901
|
+
canonical = reason.split(':')[0] || 'unknown';
|
|
5902
|
+
denialReasons[canonical] = (denialReasons[canonical] || 0) + 1;
|
|
5903
|
+
}
|
|
5904
|
+
}
|
|
5905
|
+
const totalCalls = allowedCalls + deniedCalls;
|
|
5906
|
+
const successRate = totalCalls > 0 ? Math.round(allowedCalls / totalCalls * 10000) / 100 : 100;
|
|
5907
|
+
// ── Per-tool breakdown ──
|
|
5908
|
+
const toolMap = new Map();
|
|
5909
|
+
for (const e of events) {
|
|
5910
|
+
const tool = e.tool || 'unknown';
|
|
5911
|
+
if (!toolMap.has(tool))
|
|
5912
|
+
toolMap.set(tool, { allowed: 0, denied: 0 });
|
|
5913
|
+
const t = toolMap.get(tool);
|
|
5914
|
+
if (e.allowed)
|
|
5915
|
+
t.allowed++;
|
|
5916
|
+
else
|
|
5917
|
+
t.denied++;
|
|
5918
|
+
}
|
|
5919
|
+
const byTool = Array.from(toolMap.entries())
|
|
5920
|
+
.map(([tool, stats]) => {
|
|
5921
|
+
const total = stats.allowed + stats.denied;
|
|
5922
|
+
return {
|
|
5923
|
+
tool,
|
|
5924
|
+
totalCalls: total,
|
|
5925
|
+
allowedCalls: stats.allowed,
|
|
5926
|
+
deniedCalls: stats.denied,
|
|
5927
|
+
successRate: total > 0 ? Math.round(stats.allowed / total * 10000) / 100 : 100,
|
|
5928
|
+
};
|
|
5929
|
+
})
|
|
5930
|
+
.sort((a, b) => b.totalCalls - a.totalCalls);
|
|
5931
|
+
// ── Uptime ──
|
|
5932
|
+
const uptimeMs = Date.now() - this.startedAt;
|
|
5933
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
5934
|
+
res.end(JSON.stringify({
|
|
5935
|
+
summary: {
|
|
5936
|
+
totalCalls,
|
|
5937
|
+
allowedCalls,
|
|
5938
|
+
deniedCalls,
|
|
5939
|
+
successRate,
|
|
5940
|
+
denialReasons,
|
|
5941
|
+
},
|
|
5942
|
+
byTool,
|
|
5943
|
+
uptime: {
|
|
5944
|
+
startedAt: new Date(this.startedAt).toISOString(),
|
|
5945
|
+
uptimeSeconds: Math.floor(uptimeMs / 1000),
|
|
5946
|
+
},
|
|
5947
|
+
generatedAt: new Date().toISOString(),
|
|
5948
|
+
}));
|
|
5949
|
+
}
|
|
5750
5950
|
// ─── /keys/notes — Timestamped notes on API keys ─────────────────────────
|
|
5751
5951
|
handleGetNotes(req, res) {
|
|
5752
5952
|
if (!this.checkAdmin(req, res))
|