paygate-mcp 4.2.0 → 4.3.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.
@@ -22,6 +22,27 @@ class RateLimiter {
22
22
  this.cleanupInterval = setInterval(() => this.cleanup(), 60_000);
23
23
  }
24
24
  }
25
+ /**
26
+ * Update the global rate limit at runtime. Takes effect immediately.
27
+ */
28
+ setGlobalLimit(maxCallsPerMin) {
29
+ this.maxCalls = maxCallsPerMin;
30
+ // Start cleanup interval if we now have a limit but didn't before
31
+ if (maxCallsPerMin > 0 && !this.cleanupInterval) {
32
+ this.cleanupInterval = setInterval(() => this.cleanup(), 60_000);
33
+ if (this.cleanupInterval.unref)
34
+ this.cleanupInterval.unref();
35
+ }
36
+ // Stop cleanup interval if limit is now unlimited
37
+ if (maxCallsPerMin <= 0 && this.cleanupInterval) {
38
+ clearInterval(this.cleanupInterval);
39
+ this.cleanupInterval = null;
40
+ }
41
+ }
42
+ /** Get the current global limit */
43
+ get globalLimit() {
44
+ return this.maxCalls;
45
+ }
25
46
  check(key) {
26
47
  if (this.maxCalls <= 0) {
27
48
  return { allowed: true, remaining: Infinity, resetInMs: 0 };
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -74,11 +74,18 @@ export declare class PayGateServer {
74
74
  private draining;
75
75
  /** Number of in-flight /mcp requests */
76
76
  private inflight;
77
+ /** Config file path for hot reload (null if not using config file) */
78
+ private configPath;
77
79
  /** The active request handler — either proxy or router */
78
80
  private get handler();
79
81
  constructor(config: Partial<PayGateConfig> & {
80
82
  serverCommand: string;
81
83
  }, adminKey?: string, statePath?: string, remoteUrl?: string, stripeWebhookSecret?: string, servers?: ServerBackendConfig[], redisUrl?: string);
84
+ /**
85
+ * Set the config file path for hot-reload support.
86
+ * Called by CLI after parsing --config flag.
87
+ */
88
+ setConfigPath(path: string): void;
82
89
  /**
83
90
  * Register a plugin for extensible middleware hooks.
84
91
  * Plugins run in registration order.
@@ -163,6 +170,7 @@ export declare class PayGateServer {
163
170
  private handleGetDeadLetters;
164
171
  private handleClearDeadLetters;
165
172
  private handleWebhookReplay;
173
+ private handleConfigReload;
166
174
  private handleWebhookStats;
167
175
  private handleListWebhookFilters;
168
176
  private handleCreateWebhookFilter;
@@ -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
@@ -19,6 +19,7 @@ const http_1 = require("http");
19
19
  const fs_1 = require("fs");
20
20
  const path_1 = require("path");
21
21
  const types_1 = require("./types");
22
+ const config_validator_1 = require("./config-validator");
22
23
  /** Read version from package.json at runtime */
23
24
  const PKG_VERSION = (() => {
24
25
  try {
@@ -93,6 +94,8 @@ class PayGateServer {
93
94
  draining = false;
94
95
  /** Number of in-flight /mcp requests */
95
96
  inflight = 0;
97
+ /** Config file path for hot reload (null if not using config file) */
98
+ configPath = null;
96
99
  /** The active request handler — either proxy or router */
97
100
  get handler() {
98
101
  return (this.router || this.proxy);
@@ -231,6 +234,13 @@ class PayGateServer {
231
234
  sync.groupManager = this.groups;
232
235
  }
233
236
  }
237
+ /**
238
+ * Set the config file path for hot-reload support.
239
+ * Called by CLI after parsing --config flag.
240
+ */
241
+ setConfigPath(path) {
242
+ this.configPath = path;
243
+ }
234
244
  /**
235
245
  * Register a plugin for extensible middleware hooks.
236
246
  * Plugins run in registration order.
@@ -448,6 +458,9 @@ class PayGateServer {
448
458
  return this.handleAssignKeyToGroup(req, res);
449
459
  case '/groups/remove':
450
460
  return this.handleRemoveKeyFromGroup(req, res);
461
+ // ─── Config hot reload ──────────────────────────────────────────
462
+ case '/config/reload':
463
+ return this.handleConfigReload(req, res);
451
464
  // ─── OAuth 2.1 endpoints ─────────────────────────────────────────
452
465
  case '/.well-known/oauth-authorization-server':
453
466
  return this.handleOAuthMetadata(req, res);
@@ -872,6 +885,7 @@ class PayGateServer {
872
885
  deleteGroup: 'POST /groups/delete — Delete a key group (requires X-Admin-Key)',
873
886
  assignKeyToGroup: 'POST /groups/assign — Assign a key to a group (requires X-Admin-Key)',
874
887
  removeKeyFromGroup: 'POST /groups/remove — Remove a key from a group (requires X-Admin-Key)',
888
+ configReload: 'POST /config/reload — Hot reload config from file (requires X-Admin-Key)',
875
889
  ...(this.oauth ? {
876
890
  oauthMetadata: 'GET /.well-known/oauth-authorization-server — OAuth 2.1 server metadata',
877
891
  oauthRegister: 'POST /oauth/register — Register OAuth client',
@@ -2485,6 +2499,139 @@ class PayGateServer {
2485
2499
  message: `Replayed ${replayed} dead letter entries`,
2486
2500
  }));
2487
2501
  }
2502
+ // ─── /config/reload — Hot reload configuration from file ─────────────────
2503
+ async handleConfigReload(req, res) {
2504
+ if (req.method !== 'POST') {
2505
+ res.writeHead(405, { 'Content-Type': 'application/json' });
2506
+ res.end(JSON.stringify({ error: 'Method not allowed. Use POST.' }));
2507
+ return;
2508
+ }
2509
+ if (!this.checkAdmin(req, res, 'admin'))
2510
+ return;
2511
+ // Parse optional body (may provide configPath override)
2512
+ let body = {};
2513
+ try {
2514
+ const raw = await this.readBody(req);
2515
+ if (raw.trim()) {
2516
+ body = JSON.parse(raw);
2517
+ }
2518
+ }
2519
+ catch {
2520
+ res.writeHead(400, { 'Content-Type': 'application/json' });
2521
+ res.end(JSON.stringify({ error: 'Invalid JSON body' }));
2522
+ return;
2523
+ }
2524
+ const filePath = body.configPath || this.configPath;
2525
+ if (!filePath) {
2526
+ res.writeHead(400, { 'Content-Type': 'application/json' });
2527
+ res.end(JSON.stringify({
2528
+ error: 'No config file path available. Start with --config or provide configPath in request body.',
2529
+ }));
2530
+ return;
2531
+ }
2532
+ // Read and parse config file
2533
+ let fileConfig;
2534
+ try {
2535
+ const raw = (0, fs_1.readFileSync)(filePath, 'utf-8');
2536
+ fileConfig = JSON.parse(raw);
2537
+ }
2538
+ catch (err) {
2539
+ res.writeHead(400, { 'Content-Type': 'application/json' });
2540
+ res.end(JSON.stringify({
2541
+ error: `Failed to read config file: ${err.message}`,
2542
+ }));
2543
+ return;
2544
+ }
2545
+ // Validate the loaded config
2546
+ const diags = (0, config_validator_1.validateConfig)(fileConfig);
2547
+ const errors = diags.filter(d => d.level === 'error');
2548
+ if (errors.length > 0) {
2549
+ res.writeHead(400, { 'Content-Type': 'application/json' });
2550
+ res.end(JSON.stringify({
2551
+ error: 'Config validation failed',
2552
+ diagnostics: errors.map(d => ({ field: d.field, message: d.message })),
2553
+ }));
2554
+ return;
2555
+ }
2556
+ // Build a config patch from the file (only hot-reloadable fields)
2557
+ const patch = {};
2558
+ if (fileConfig.defaultCreditsPerCall !== undefined) {
2559
+ patch.defaultCreditsPerCall = Number(fileConfig.defaultCreditsPerCall);
2560
+ }
2561
+ if (fileConfig.toolPricing !== undefined) {
2562
+ patch.toolPricing = fileConfig.toolPricing;
2563
+ }
2564
+ if (fileConfig.globalRateLimitPerMin !== undefined) {
2565
+ patch.globalRateLimitPerMin = Number(fileConfig.globalRateLimitPerMin);
2566
+ }
2567
+ if (fileConfig.shadowMode !== undefined) {
2568
+ patch.shadowMode = !!fileConfig.shadowMode;
2569
+ }
2570
+ if (fileConfig.refundOnFailure !== undefined) {
2571
+ patch.refundOnFailure = !!fileConfig.refundOnFailure;
2572
+ }
2573
+ if (fileConfig.freeMethods !== undefined) {
2574
+ patch.freeMethods = fileConfig.freeMethods;
2575
+ }
2576
+ if (fileConfig.webhookUrl !== undefined) {
2577
+ patch.webhookUrl = fileConfig.webhookUrl || null;
2578
+ }
2579
+ if (fileConfig.webhookSecret !== undefined) {
2580
+ patch.webhookSecret = fileConfig.webhookSecret || null;
2581
+ }
2582
+ if (fileConfig.webhookMaxRetries !== undefined) {
2583
+ patch.webhookMaxRetries = Number(fileConfig.webhookMaxRetries);
2584
+ }
2585
+ if (fileConfig.globalQuota !== undefined) {
2586
+ const q = fileConfig.globalQuota;
2587
+ patch.globalQuota = {
2588
+ dailyCallLimit: Math.max(0, Math.floor(Number(q.dailyCallLimit) || 0)),
2589
+ monthlyCallLimit: Math.max(0, Math.floor(Number(q.monthlyCallLimit) || 0)),
2590
+ dailyCreditLimit: Math.max(0, Math.floor(Number(q.dailyCreditLimit) || 0)),
2591
+ monthlyCreditLimit: Math.max(0, Math.floor(Number(q.monthlyCreditLimit) || 0)),
2592
+ };
2593
+ }
2594
+ if (fileConfig.alertRules !== undefined) {
2595
+ patch.alertRules = fileConfig.alertRules;
2596
+ }
2597
+ // Apply the patch to the gate (mutates shared config object)
2598
+ const changed = this.gate.updateConfig(patch);
2599
+ // Update alert engine if rules changed
2600
+ if (changed.includes('alertRules') && patch.alertRules) {
2601
+ this.alerts.setRules(patch.alertRules);
2602
+ }
2603
+ // Update stored config path only if not already set (body override is one-time)
2604
+ if (!this.configPath && filePath) {
2605
+ this.configPath = filePath;
2606
+ }
2607
+ // Fields that were skipped (not hot-reloadable)
2608
+ const skipped = [];
2609
+ if (fileConfig.serverCommand !== undefined)
2610
+ skipped.push('serverCommand');
2611
+ if (fileConfig.serverArgs !== undefined)
2612
+ skipped.push('serverArgs');
2613
+ if (fileConfig.port !== undefined)
2614
+ skipped.push('port');
2615
+ if (fileConfig.oauth !== undefined)
2616
+ skipped.push('oauth');
2617
+ // Audit
2618
+ this.audit.log('config.reloaded', 'admin', `Config reloaded from ${filePath}: ${changed.length} field(s) changed`, {
2619
+ filePath,
2620
+ changed,
2621
+ skipped,
2622
+ });
2623
+ const warnings = diags.filter(d => d.level === 'warning');
2624
+ res.writeHead(200, { 'Content-Type': 'application/json' });
2625
+ res.end(JSON.stringify({
2626
+ reloaded: true,
2627
+ changed,
2628
+ skipped,
2629
+ message: changed.length > 0
2630
+ ? `Config reloaded: ${changed.join(', ')} updated`
2631
+ : 'Config reloaded: no changes detected',
2632
+ ...(warnings.length > 0 ? { warnings: warnings.map(w => ({ field: w.field, message: w.message })) } : {}),
2633
+ }));
2634
+ }
2488
2635
  // ─── /webhooks/stats — Webhook delivery statistics ──────────────────────
2489
2636
  handleWebhookStats(req, res) {
2490
2637
  if (req.method !== 'GET') {