@winstonsayno/mcp-gateway 0.0.0-stage → 0.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.
Files changed (114) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/LICENSE +21 -0
  3. package/README.md +377 -2
  4. package/dashboard/README.md +27 -0
  5. package/dashboard/index.html +415 -0
  6. package/dist/auth/middleware.d.ts +24 -0
  7. package/dist/auth/middleware.d.ts.map +1 -0
  8. package/dist/auth/middleware.js +108 -0
  9. package/dist/auth/middleware.js.map +1 -0
  10. package/dist/auth/ratelimit.d.ts +19 -0
  11. package/dist/auth/ratelimit.d.ts.map +1 -0
  12. package/dist/auth/ratelimit.js +81 -0
  13. package/dist/auth/ratelimit.js.map +1 -0
  14. package/dist/cli.d.ts +6 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +129 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/config/loader.d.ts +13 -0
  19. package/dist/config/loader.d.ts.map +1 -0
  20. package/dist/config/loader.js +268 -0
  21. package/dist/config/loader.js.map +1 -0
  22. package/dist/config/watcher.d.ts +29 -0
  23. package/dist/config/watcher.d.ts.map +1 -0
  24. package/dist/config/watcher.js +96 -0
  25. package/dist/config/watcher.js.map +1 -0
  26. package/dist/gateway/api.d.ts +29 -0
  27. package/dist/gateway/api.d.ts.map +1 -0
  28. package/dist/gateway/api.js +280 -0
  29. package/dist/gateway/api.js.map +1 -0
  30. package/dist/gateway/index.d.ts +49 -0
  31. package/dist/gateway/index.d.ts.map +1 -0
  32. package/dist/gateway/index.js +260 -0
  33. package/dist/gateway/index.js.map +1 -0
  34. package/dist/gateway/supervisor.d.ts +58 -0
  35. package/dist/gateway/supervisor.d.ts.map +1 -0
  36. package/dist/gateway/supervisor.js +205 -0
  37. package/dist/gateway/supervisor.js.map +1 -0
  38. package/dist/index.d.ts +15 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +12 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/middleware/cors.d.ts +19 -0
  43. package/dist/middleware/cors.d.ts.map +1 -0
  44. package/dist/middleware/cors.js +65 -0
  45. package/dist/middleware/cors.js.map +1 -0
  46. package/dist/middleware/error-handler.d.ts +40 -0
  47. package/dist/middleware/error-handler.d.ts.map +1 -0
  48. package/dist/middleware/error-handler.js +98 -0
  49. package/dist/middleware/error-handler.js.map +1 -0
  50. package/dist/middleware/request-id.d.ts +23 -0
  51. package/dist/middleware/request-id.d.ts.map +1 -0
  52. package/dist/middleware/request-id.js +30 -0
  53. package/dist/middleware/request-id.js.map +1 -0
  54. package/dist/middleware/timeout.d.ts +12 -0
  55. package/dist/middleware/timeout.d.ts.map +1 -0
  56. package/dist/middleware/timeout.js +39 -0
  57. package/dist/middleware/timeout.js.map +1 -0
  58. package/dist/monitor/index.d.ts +49 -0
  59. package/dist/monitor/index.d.ts.map +1 -0
  60. package/dist/monitor/index.js +204 -0
  61. package/dist/monitor/index.js.map +1 -0
  62. package/dist/proxy/index.d.ts +86 -0
  63. package/dist/proxy/index.d.ts.map +1 -0
  64. package/dist/proxy/index.js +389 -0
  65. package/dist/proxy/index.js.map +1 -0
  66. package/dist/registry/index.d.ts +41 -0
  67. package/dist/registry/index.d.ts.map +1 -0
  68. package/dist/registry/index.js +157 -0
  69. package/dist/registry/index.js.map +1 -0
  70. package/dist/transport/channel.d.ts +61 -0
  71. package/dist/transport/channel.d.ts.map +1 -0
  72. package/dist/transport/channel.js +38 -0
  73. package/dist/transport/channel.js.map +1 -0
  74. package/dist/transport/sse-parser.d.ts +30 -0
  75. package/dist/transport/sse-parser.d.ts.map +1 -0
  76. package/dist/transport/sse-parser.js +107 -0
  77. package/dist/transport/sse-parser.js.map +1 -0
  78. package/dist/transport/sse.d.ts +39 -0
  79. package/dist/transport/sse.d.ts.map +1 -0
  80. package/dist/transport/sse.js +142 -0
  81. package/dist/transport/sse.js.map +1 -0
  82. package/dist/transport/stdio.d.ts +35 -0
  83. package/dist/transport/stdio.d.ts.map +1 -0
  84. package/dist/transport/stdio.js +149 -0
  85. package/dist/transport/stdio.js.map +1 -0
  86. package/dist/transport/streamable-http.d.ts +45 -0
  87. package/dist/transport/streamable-http.d.ts.map +1 -0
  88. package/dist/transport/streamable-http.js +183 -0
  89. package/dist/transport/streamable-http.js.map +1 -0
  90. package/dist/transport/websocket.d.ts +38 -0
  91. package/dist/transport/websocket.d.ts.map +1 -0
  92. package/dist/transport/websocket.js +172 -0
  93. package/dist/transport/websocket.js.map +1 -0
  94. package/dist/utils/logger.d.ts +16 -0
  95. package/dist/utils/logger.d.ts.map +1 -0
  96. package/dist/utils/logger.js +60 -0
  97. package/dist/utils/logger.js.map +1 -0
  98. package/dist/utils/mutex.d.ts +25 -0
  99. package/dist/utils/mutex.d.ts.map +1 -0
  100. package/dist/utils/mutex.js +62 -0
  101. package/dist/utils/mutex.js.map +1 -0
  102. package/dist/utils/semaphore.d.ts +16 -0
  103. package/dist/utils/semaphore.d.ts.map +1 -0
  104. package/dist/utils/semaphore.js +42 -0
  105. package/dist/utils/semaphore.js.map +1 -0
  106. package/dist/utils/types.d.ts +215 -0
  107. package/dist/utils/types.d.ts.map +1 -0
  108. package/dist/utils/types.js +5 -0
  109. package/dist/utils/types.js.map +1 -0
  110. package/dist/utils/version.d.ts +6 -0
  111. package/dist/utils/version.d.ts.map +1 -0
  112. package/dist/utils/version.js +18 -0
  113. package/dist/utils/version.js.map +1 -0
  114. package/package.json +78 -4
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Server supervisor — keeps every enabled MCP server connected.
3
+ *
4
+ * - Connects servers and publishes their tools and health to the registry.
5
+ * - When a server fails to connect, crashes or disconnects (`proxy` emits
6
+ * `disconnected`), it schedules a reconnect with exponential backoff and
7
+ * jitter, re-running the full MCP handshake on a fresh channel.
8
+ * - Reconnect state (attempt, next attempt time, last error, reconnect count)
9
+ * is mirrored into the registry so `/servers`, `/health`, the dashboard and
10
+ * Prometheus can show it.
11
+ *
12
+ * Each server carries a generation number; a hot reload or removal bumps it so
13
+ * an in-flight attempt that finishes late can never resurrect stale state.
14
+ *
15
+ * @module gateway/supervisor
16
+ */
17
+ import type { McpServerConfig, ReconnectConfig, ReconnectState } from '../utils/types.js';
18
+ import type { McpProxy } from '../proxy/index.js';
19
+ import type { ServerRegistry } from '../registry/index.js';
20
+ export declare const DEFAULT_RECONNECT: ReconnectConfig;
21
+ export declare function resolveReconnect(gateway?: Partial<ReconnectConfig>, server?: Partial<ReconnectConfig>): ReconnectConfig;
22
+ /**
23
+ * Delay before reconnect attempt `attempt` (1-based):
24
+ * `min(maxDelay, initialDelay * multiplier^(attempt-1))`, then ±jitter.
25
+ */
26
+ export declare function computeBackoff(attempt: number, cfg: ReconnectConfig, random?: () => number): number;
27
+ export interface SupervisorOptions {
28
+ /** Gateway-wide reconnect defaults (merged with each server's `reconnect`). */
29
+ reconnect?: Partial<ReconnectConfig>;
30
+ random?: () => number;
31
+ }
32
+ export declare class ServerSupervisor {
33
+ private readonly proxy;
34
+ private readonly registry;
35
+ private readonly entries;
36
+ private reconnectDefaults?;
37
+ private readonly random;
38
+ private stopped;
39
+ private readonly onDisconnected;
40
+ private readonly onToolsChanged;
41
+ constructor(proxy: McpProxy, registry: ServerRegistry, options?: SupervisorOptions);
42
+ /** Update gateway-wide reconnect defaults (hot reload). Applies to future attempts. */
43
+ setReconnectDefaults(reconnect?: Partial<ReconnectConfig>): void;
44
+ /** Connect (or reconnect with a new config) now. Resolves true on success. */
45
+ connect(config: McpServerConfig): Promise<boolean>;
46
+ /** Stop managing a server (cancel pending reconnects). Does not disconnect it. */
47
+ forget(serverId: string): void;
48
+ /** Is a reconnect scheduled or in progress for this server? */
49
+ isRecovering(serverId: string): boolean;
50
+ getState(serverId: string): ReconnectState | undefined;
51
+ stop(): void;
52
+ private current;
53
+ private attempt;
54
+ private handleDisconnect;
55
+ private scheduleRetry;
56
+ private publish;
57
+ }
58
+ //# sourceMappingURL=supervisor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../../src/gateway/supervisor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAY,MAAM,mBAAmB,CAAC;AACpG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,eAAO,MAAM,iBAAiB,EAAE,eAO/B,CAAC;AAEF,wBAAgB,gBAAgB,CAC9B,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EAClC,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAChC,eAAe,CAMjB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,GAAE,MAAM,MAAoB,GAAG,MAAM,CAMhH;AAUD,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAED,qBAAa,gBAAgB;IAazB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAb3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,OAAO,CAAC,iBAAiB,CAAC,CAA2B;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0E;IACzG,OAAO,CAAC,QAAQ,CAAC,cAAc,CAI7B;gBAGiB,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,cAAc,EACzC,OAAO,GAAE,iBAAsB;IAQjC,uFAAuF;IACvF,oBAAoB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IAKhE,8EAA8E;IACxE,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAexD,kFAAkF;IAClF,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAO9B,+DAA+D;IAC/D,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAKvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAKtD,IAAI,IAAI,IAAI;IAUZ,OAAO,CAAC,OAAO;YAID,OAAO;IAgCrB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,OAAO;CAUhB"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Server supervisor — keeps every enabled MCP server connected.
3
+ *
4
+ * - Connects servers and publishes their tools and health to the registry.
5
+ * - When a server fails to connect, crashes or disconnects (`proxy` emits
6
+ * `disconnected`), it schedules a reconnect with exponential backoff and
7
+ * jitter, re-running the full MCP handshake on a fresh channel.
8
+ * - Reconnect state (attempt, next attempt time, last error, reconnect count)
9
+ * is mirrored into the registry so `/servers`, `/health`, the dashboard and
10
+ * Prometheus can show it.
11
+ *
12
+ * Each server carries a generation number; a hot reload or removal bumps it so
13
+ * an in-flight attempt that finishes late can never resurrect stale state.
14
+ *
15
+ * @module gateway/supervisor
16
+ */
17
+ import { logger } from '../utils/logger.js';
18
+ export const DEFAULT_RECONNECT = {
19
+ enabled: true,
20
+ initialDelayMs: 1_000,
21
+ maxDelayMs: 60_000,
22
+ multiplier: 2,
23
+ jitter: 0.2,
24
+ maxAttempts: 0,
25
+ };
26
+ export function resolveReconnect(gateway, server) {
27
+ const strip = (o) => Object.fromEntries(Object.entries(o ?? {}).filter(([, v]) => v !== undefined));
28
+ const merged = { ...DEFAULT_RECONNECT, ...strip(gateway), ...strip(server) };
29
+ merged.maxDelayMs = Math.max(merged.maxDelayMs, merged.initialDelayMs);
30
+ return merged;
31
+ }
32
+ /**
33
+ * Delay before reconnect attempt `attempt` (1-based):
34
+ * `min(maxDelay, initialDelay * multiplier^(attempt-1))`, then ±jitter.
35
+ */
36
+ export function computeBackoff(attempt, cfg, random = Math.random) {
37
+ const exp = cfg.initialDelayMs * Math.pow(cfg.multiplier, Math.max(0, attempt - 1));
38
+ const base = Math.min(cfg.maxDelayMs, exp);
39
+ const spread = base * cfg.jitter;
40
+ const jittered = base - spread + random() * 2 * spread;
41
+ return Math.max(0, Math.round(Math.min(cfg.maxDelayMs, jittered)));
42
+ }
43
+ export class ServerSupervisor {
44
+ proxy;
45
+ registry;
46
+ entries = new Map();
47
+ reconnectDefaults;
48
+ random;
49
+ stopped = false;
50
+ onDisconnected = (serverId, err) => this.handleDisconnect(serverId, err);
51
+ onToolsChanged = (serverId, tools) => {
52
+ if (!this.entries.has(serverId))
53
+ return;
54
+ this.registry.setTools(serverId, tools);
55
+ logger.info(`Server "${serverId}" updated its tool list (${tools.length} tools)`);
56
+ };
57
+ constructor(proxy, registry, options = {}) {
58
+ this.proxy = proxy;
59
+ this.registry = registry;
60
+ this.reconnectDefaults = options.reconnect;
61
+ this.random = options.random ?? Math.random;
62
+ proxy.on('disconnected', this.onDisconnected);
63
+ proxy.on('tools-changed', this.onToolsChanged);
64
+ }
65
+ /** Update gateway-wide reconnect defaults (hot reload). Applies to future attempts. */
66
+ setReconnectDefaults(reconnect) {
67
+ this.reconnectDefaults = reconnect;
68
+ for (const e of this.entries.values())
69
+ e.policy = resolveReconnect(reconnect, e.config.reconnect);
70
+ }
71
+ /** Connect (or reconnect with a new config) now. Resolves true on success. */
72
+ async connect(config) {
73
+ if (this.stopped)
74
+ return false;
75
+ const prev = this.entries.get(config.id);
76
+ if (prev?.timer)
77
+ clearTimeout(prev.timer);
78
+ const entry = {
79
+ config,
80
+ policy: resolveReconnect(this.reconnectDefaults, config.reconnect),
81
+ gen: (prev?.gen ?? 0) + 1,
82
+ state: { state: 'connecting', attempt: 0, reconnects: prev?.state.reconnects ?? 0 },
83
+ };
84
+ this.entries.set(config.id, entry);
85
+ this.publish(entry);
86
+ return this.attempt(entry, entry.gen, false);
87
+ }
88
+ /** Stop managing a server (cancel pending reconnects). Does not disconnect it. */
89
+ forget(serverId) {
90
+ const e = this.entries.get(serverId);
91
+ if (!e)
92
+ return;
93
+ if (e.timer)
94
+ clearTimeout(e.timer);
95
+ this.entries.delete(serverId);
96
+ }
97
+ /** Is a reconnect scheduled or in progress for this server? */
98
+ isRecovering(serverId) {
99
+ const s = this.entries.get(serverId)?.state.state;
100
+ return s === 'scheduled' || s === 'connecting';
101
+ }
102
+ getState(serverId) {
103
+ const e = this.entries.get(serverId);
104
+ return e ? { ...e.state } : undefined;
105
+ }
106
+ stop() {
107
+ this.stopped = true;
108
+ for (const e of this.entries.values())
109
+ if (e.timer)
110
+ clearTimeout(e.timer);
111
+ this.entries.clear();
112
+ this.proxy.off('disconnected', this.onDisconnected);
113
+ this.proxy.off('tools-changed', this.onToolsChanged);
114
+ }
115
+ // ─── Internal ───────────────────────────────────────────────────────────────
116
+ current(entry, gen) {
117
+ return !this.stopped && this.entries.get(entry.config.id) === entry && entry.gen === gen;
118
+ }
119
+ async attempt(entry, gen, isReconnect) {
120
+ const { config } = entry;
121
+ entry.state.state = 'connecting';
122
+ entry.state.nextAttemptAt = undefined;
123
+ this.publish(entry);
124
+ try {
125
+ const tools = await this.proxy.connect(config);
126
+ if (!this.current(entry, gen))
127
+ return false; // superseded by reload/removal
128
+ entry.state = {
129
+ state: 'idle',
130
+ attempt: 0,
131
+ reconnects: entry.state.reconnects + (isReconnect ? 1 : 0),
132
+ lastDisconnectAt: entry.state.lastDisconnectAt,
133
+ };
134
+ this.registry.setTools(config.id, tools);
135
+ this.registry.updateHealth(config.id, 'online', undefined, undefined, {
136
+ connectedSince: new Date(),
137
+ reconnect: { ...entry.state },
138
+ });
139
+ logger.info(`✓ ${config.name} — ${tools.length} tools available${isReconnect ? ' (reconnected)' : ''}`);
140
+ return true;
141
+ }
142
+ catch (err) {
143
+ if (!this.current(entry, gen))
144
+ return false;
145
+ const msg = err instanceof Error ? err.message : String(err);
146
+ entry.state.lastError = msg;
147
+ if (!isReconnect)
148
+ this.registry.setTools(config.id, []);
149
+ logger.warn(`✗ ${config.name} — failed to connect: ${msg}`);
150
+ this.scheduleRetry(entry, gen);
151
+ return false;
152
+ }
153
+ }
154
+ handleDisconnect(serverId, err) {
155
+ const entry = this.entries.get(serverId);
156
+ if (!entry || this.stopped)
157
+ return;
158
+ entry.state.lastError = err.message;
159
+ entry.state.lastDisconnectAt = new Date();
160
+ entry.state.attempt = 0;
161
+ // Tools stay listed (marked unavailable via health) so clients see what will come back.
162
+ logger.warn(`Server "${serverId}" disconnected: ${err.message}`);
163
+ this.scheduleRetry(entry, entry.gen);
164
+ }
165
+ scheduleRetry(entry, gen) {
166
+ const { policy } = entry;
167
+ if (!policy.enabled) {
168
+ entry.state.state = 'disabled';
169
+ this.publish(entry, 'offline');
170
+ return;
171
+ }
172
+ if (policy.maxAttempts > 0 && entry.state.attempt >= policy.maxAttempts) {
173
+ entry.state.state = 'gave-up';
174
+ logger.error(`Server "${entry.config.id}": giving up after ${entry.state.attempt} reconnect attempts`);
175
+ this.publish(entry, 'offline');
176
+ return;
177
+ }
178
+ entry.state.attempt++;
179
+ const delay = computeBackoff(entry.state.attempt, policy, this.random);
180
+ entry.state.state = 'scheduled';
181
+ entry.state.nextAttemptAt = new Date(Date.now() + delay);
182
+ logger.info(`Reconnecting "${entry.config.id}" in ${delay}ms (attempt ${entry.state.attempt})`);
183
+ this.publish(entry, 'reconnecting');
184
+ if (entry.timer)
185
+ clearTimeout(entry.timer);
186
+ entry.timer = setTimeout(() => {
187
+ entry.timer = undefined;
188
+ if (this.current(entry, gen))
189
+ void this.attempt(entry, gen, true);
190
+ }, delay);
191
+ entry.timer.unref();
192
+ }
193
+ publish(entry, status) {
194
+ const id = entry.config.id;
195
+ if (!this.registry.getServer(id))
196
+ return;
197
+ const prev = this.registry.getHealth(id);
198
+ const next = status ?? prev?.status ?? 'unknown';
199
+ this.registry.updateHealth(id, next, undefined, entry.state.lastError, {
200
+ reconnect: { ...entry.state },
201
+ connectedSince: status ? undefined : prev?.connectedSince,
202
+ });
203
+ }
204
+ }
205
+ //# sourceMappingURL=supervisor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../../src/gateway/supervisor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * mcp-gateway public API
3
+ * Use this when embedding the gateway as a library
4
+ */
5
+ export { Gateway } from './gateway/index.js';
6
+ export { ServerRegistry } from './registry/index.js';
7
+ export { McpProxy, defaultChannelFactory, MCP_PROTOCOL_VERSION } from './proxy/index.js';
8
+ export type { ProxyOptions, SessionInfo } from './proxy/index.js';
9
+ export { ServerSupervisor, computeBackoff, DEFAULT_RECONNECT } from './gateway/supervisor.js';
10
+ export type { UpstreamChannel, ChannelFactory, ChannelOptions, JsonRpcMessage } from './transport/channel.js';
11
+ export { MetricsCollector } from './monitor/index.js';
12
+ export { loadConfig, generateDefaultConfig } from './config/loader.js';
13
+ export { logger } from './utils/logger.js';
14
+ export type { GatewayConfig, McpServerConfig, ServerHealth, ServerStatus, ServerTransport, ToolInfo, RequestMetric, AggregatedMetrics, AuthConfig, RateLimitConfig, MonitorConfig, ReconnectConfig, ReconnectState, } from './utils/types.js';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACzF,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC9F,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC9G,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,YAAY,EACV,aAAa,EACb,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * mcp-gateway public API
3
+ * Use this when embedding the gateway as a library
4
+ */
5
+ export { Gateway } from './gateway/index.js';
6
+ export { ServerRegistry } from './registry/index.js';
7
+ export { McpProxy, defaultChannelFactory, MCP_PROTOCOL_VERSION } from './proxy/index.js';
8
+ export { ServerSupervisor, computeBackoff, DEFAULT_RECONNECT } from './gateway/supervisor.js';
9
+ export { MetricsCollector } from './monitor/index.js';
10
+ export { loadConfig, generateDefaultConfig } from './config/loader.js';
11
+ export { logger } from './utils/logger.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAEzF,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE9F,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * CORS Middleware
3
+ *
4
+ * Configurable Cross-Origin Resource Sharing headers.
5
+ * Supports wildcard, specific origins list, and regex patterns.
6
+ *
7
+ * @module middleware/cors
8
+ */
9
+ import { Request, Response, NextFunction } from 'express';
10
+ export interface CORSOptions {
11
+ origins: string[];
12
+ methods?: string[];
13
+ allowedHeaders?: string[];
14
+ exposedHeaders?: string[];
15
+ credentials?: boolean;
16
+ maxAge?: number;
17
+ }
18
+ export declare function corsMiddleware(options: CORSOptions): (req: Request, res: Response, next: NextFunction) => void;
19
+ //# sourceMappingURL=cors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAUD,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,IA0BzC,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,IAAI,CA+B/D"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * CORS Middleware
3
+ *
4
+ * Configurable Cross-Origin Resource Sharing headers.
5
+ * Supports wildcard, specific origins list, and regex patterns.
6
+ *
7
+ * @module middleware/cors
8
+ */
9
+ const DEFAULT_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'];
10
+ const DEFAULT_HEADERS = [
11
+ 'Content-Type',
12
+ 'Authorization',
13
+ 'X-API-Key',
14
+ 'X-Request-Id',
15
+ ];
16
+ export function corsMiddleware(options) {
17
+ const { origins, methods = DEFAULT_METHODS, allowedHeaders = DEFAULT_HEADERS, exposedHeaders = ['X-Request-Id', 'X-RateLimit-Limit', 'X-RateLimit-Remaining', 'X-RateLimit-Reset'], credentials = false, maxAge = 86400, } = options;
18
+ const isAllowed = (origin) => {
19
+ for (const o of origins) {
20
+ if (o === '*')
21
+ return true;
22
+ if (o === origin)
23
+ return true;
24
+ // Support regex patterns wrapped in /…/
25
+ if (o.startsWith('/') && o.endsWith('/')) {
26
+ try {
27
+ if (new RegExp(o.slice(1, -1)).test(origin))
28
+ return true;
29
+ }
30
+ catch {
31
+ // invalid regex — skip
32
+ }
33
+ }
34
+ }
35
+ return false;
36
+ };
37
+ return (req, res, next) => {
38
+ const origin = req.headers.origin ?? '';
39
+ const wildcard = origins.includes('*');
40
+ if (wildcard && !credentials) {
41
+ res.setHeader('Access-Control-Allow-Origin', '*');
42
+ }
43
+ else {
44
+ // Response depends on Origin: tell caches so (even when disallowed).
45
+ res.vary('Origin');
46
+ // Browsers reject "*" together with credentials, so reflect the origin.
47
+ if (origin && isAllowed(origin)) {
48
+ res.setHeader('Access-Control-Allow-Origin', origin);
49
+ }
50
+ }
51
+ if (credentials) {
52
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
53
+ }
54
+ res.setHeader('Access-Control-Expose-Headers', exposedHeaders.join(', '));
55
+ if (req.method === 'OPTIONS') {
56
+ res.setHeader('Access-Control-Allow-Methods', methods.join(', '));
57
+ res.setHeader('Access-Control-Allow-Headers', allowedHeaders.join(', '));
58
+ res.setHeader('Access-Control-Max-Age', String(maxAge));
59
+ res.status(204).end();
60
+ return;
61
+ }
62
+ next();
63
+ };
64
+ }
65
+ //# sourceMappingURL=cors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC7E,MAAM,eAAe,GAAG;IACtB,cAAc;IACd,eAAe;IACf,WAAW;IACX,cAAc;CACf,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,OAAoB;IACjD,MAAM,EACJ,OAAO,EACP,OAAO,GAAG,eAAe,EACzB,cAAc,GAAG,eAAe,EAChC,cAAc,GAAG,CAAC,cAAc,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,mBAAmB,CAAC,EACpG,WAAW,GAAG,KAAK,EACnB,MAAM,GAAG,KAAK,GACf,GAAG,OAAO,CAAC;IAEZ,MAAM,SAAS,GAAG,CAAC,MAAc,EAAW,EAAE;QAC5C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAC;YAC3B,IAAI,CAAC,KAAK,MAAM;gBAAE,OAAO,IAAI,CAAC;YAC9B,wCAAwC;YACxC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzC,IAAI,CAAC;oBACH,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;wBAAE,OAAO,IAAI,CAAC;gBAC3D,CAAC;gBAAC,MAAM,CAAC;oBACP,uBAAuB;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAQ,EAAE;QAC/D,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;QAExC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,QAAQ,IAAI,CAAC,WAAW,EAAE,CAAC;YAC7B,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,qEAAqE;YACrE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnB,wEAAwE;YACxE,IAAI,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChC,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QAED,IAAI,WAAW,EAAE,CAAC;YAChB,GAAG,CAAC,SAAS,CAAC,kCAAkC,EAAE,MAAM,CAAC,CAAC;QAC5D,CAAC;QAED,GAAG,CAAC,SAAS,CAAC,+BAA+B,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAE1E,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC7B,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAClE,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACzE,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YACxD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QAED,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Centralized Error Handler Middleware
3
+ *
4
+ * Bug fix (v0.1.0): unhandled errors leaked raw stack traces and returned
5
+ * inconsistent response shapes. This middleware normalises all errors into
6
+ * a single JSON envelope and never exposes internal stack traces in production.
7
+ *
8
+ * @module middleware/error-handler
9
+ */
10
+ import { Request, Response, NextFunction } from 'express';
11
+ export interface ErrorResponse {
12
+ error: {
13
+ code: string;
14
+ message: string;
15
+ requestId?: string;
16
+ details?: unknown;
17
+ };
18
+ }
19
+ export declare class GatewayError extends Error {
20
+ readonly statusCode: number;
21
+ readonly code: string;
22
+ readonly details?: unknown | undefined;
23
+ constructor(statusCode: number, code: string, message: string, details?: unknown | undefined);
24
+ }
25
+ export declare const ErrorCodes: {
26
+ readonly UNAUTHORIZED: "UNAUTHORIZED";
27
+ readonly FORBIDDEN: "FORBIDDEN";
28
+ readonly NOT_FOUND: "NOT_FOUND";
29
+ readonly TOOL_NOT_FOUND: "TOOL_NOT_FOUND";
30
+ readonly SERVER_NOT_FOUND: "SERVER_NOT_FOUND";
31
+ readonly SERVER_UNAVAILABLE: "SERVER_UNAVAILABLE";
32
+ readonly RATE_LIMITED: "RATE_LIMITED";
33
+ readonly TIMEOUT: "TIMEOUT";
34
+ readonly BAD_REQUEST: "BAD_REQUEST";
35
+ readonly INTERNAL_ERROR: "INTERNAL_ERROR";
36
+ readonly VALIDATION_ERROR: "VALIDATION_ERROR";
37
+ };
38
+ export declare function errorHandler(err: unknown, req: Request, res: Response, _next: NextFunction): void;
39
+ export declare function notFoundHandler(req: Request, res: Response): void;
40
+ //# sourceMappingURL=error-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;CACH;AAED,qBAAa,YAAa,SAAQ,KAAK;aAEnB,UAAU,EAAE,MAAM;aAClB,IAAI,EAAE,MAAM;aAEZ,OAAO,CAAC,EAAE,OAAO;gBAHjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM,EACC,OAAO,CAAC,EAAE,OAAO,YAAA;CAKpC;AAGD,eAAO,MAAM,UAAU;;;;;;;;;;;;CAYb,CAAC;AAEX,wBAAgB,YAAY,CAC1B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,YAAY,GAClB,IAAI,CAmDN;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CASjE"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Centralized Error Handler Middleware
3
+ *
4
+ * Bug fix (v0.1.0): unhandled errors leaked raw stack traces and returned
5
+ * inconsistent response shapes. This middleware normalises all errors into
6
+ * a single JSON envelope and never exposes internal stack traces in production.
7
+ *
8
+ * @module middleware/error-handler
9
+ */
10
+ export class GatewayError extends Error {
11
+ statusCode;
12
+ code;
13
+ details;
14
+ constructor(statusCode, code, message, details) {
15
+ super(message);
16
+ this.statusCode = statusCode;
17
+ this.code = code;
18
+ this.details = details;
19
+ this.name = 'GatewayError';
20
+ }
21
+ }
22
+ // Well-known error codes
23
+ export const ErrorCodes = {
24
+ UNAUTHORIZED: 'UNAUTHORIZED',
25
+ FORBIDDEN: 'FORBIDDEN',
26
+ NOT_FOUND: 'NOT_FOUND',
27
+ TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',
28
+ SERVER_NOT_FOUND: 'SERVER_NOT_FOUND',
29
+ SERVER_UNAVAILABLE: 'SERVER_UNAVAILABLE',
30
+ RATE_LIMITED: 'RATE_LIMITED',
31
+ TIMEOUT: 'TIMEOUT',
32
+ BAD_REQUEST: 'BAD_REQUEST',
33
+ INTERNAL_ERROR: 'INTERNAL_ERROR',
34
+ VALIDATION_ERROR: 'VALIDATION_ERROR',
35
+ };
36
+ export function errorHandler(err, req, res, _next) {
37
+ const isDev = process.env.NODE_ENV !== 'production';
38
+ // Headers already flushed (e.g. a late timeout): let Express close the socket.
39
+ if (res.headersSent) {
40
+ _next(err);
41
+ return;
42
+ }
43
+ if (err instanceof GatewayError) {
44
+ const body = {
45
+ error: {
46
+ code: err.code,
47
+ message: err.message,
48
+ requestId: req.requestId,
49
+ ...(isDev && err.details ? { details: err.details } : {}),
50
+ },
51
+ };
52
+ res.status(err.statusCode).json(body);
53
+ return;
54
+ }
55
+ // Client errors raised by Express / body-parser (malformed JSON, payload too
56
+ // large, …) carry a 4xx status and must not be reported as 500s.
57
+ const status = getHttpStatus(err);
58
+ if (status !== undefined && status >= 400 && status < 500) {
59
+ const body = {
60
+ error: {
61
+ code: status === 413 ? 'PAYLOAD_TOO_LARGE' : ErrorCodes.BAD_REQUEST,
62
+ message: err instanceof Error ? err.message : 'Bad request',
63
+ requestId: req.requestId,
64
+ },
65
+ };
66
+ res.status(status).json(body);
67
+ return;
68
+ }
69
+ // Unknown / unexpected errors
70
+ const message = isDev && err instanceof Error ? err.message : 'Internal server error';
71
+ const body = {
72
+ error: {
73
+ code: ErrorCodes.INTERNAL_ERROR,
74
+ message,
75
+ requestId: req.requestId,
76
+ ...(isDev && err instanceof Error ? { details: err.stack } : {}),
77
+ },
78
+ };
79
+ res.status(500).json(body);
80
+ }
81
+ export function notFoundHandler(req, res) {
82
+ const body = {
83
+ error: {
84
+ code: ErrorCodes.NOT_FOUND,
85
+ message: `Route ${req.method} ${req.path} not found`,
86
+ requestId: req.requestId,
87
+ },
88
+ };
89
+ res.status(404).json(body);
90
+ }
91
+ function getHttpStatus(err) {
92
+ if (!err || typeof err !== 'object')
93
+ return undefined;
94
+ const e = err;
95
+ const s = typeof e.status === 'number' ? e.status : typeof e.statusCode === 'number' ? e.statusCode : undefined;
96
+ return s !== undefined && Number.isInteger(s) ? s : undefined;
97
+ }
98
+ //# sourceMappingURL=error-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Request ID Middleware
3
+ *
4
+ * Attaches a unique `X-Request-Id` header to every request and response,
5
+ * enabling end-to-end tracing across logs and downstream systems.
6
+ *
7
+ * Priority order:
8
+ * 1. Honour an existing `X-Request-Id` header sent by the client
9
+ * 2. Honour `X-Correlation-Id` (common in enterprise proxies)
10
+ * 3. Generate a new UUID v4
11
+ *
12
+ * @module middleware/request-id
13
+ */
14
+ import { Request, Response, NextFunction } from 'express';
15
+ declare global {
16
+ namespace Express {
17
+ interface Request {
18
+ requestId: string;
19
+ }
20
+ }
21
+ }
22
+ export declare function requestIdMiddleware(req: Request, res: Response, next: NextFunction): void;
23
+ //# sourceMappingURL=request-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-id.d.ts","sourceRoot":"","sources":["../../src/middleware/request-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG1D,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,SAAS,EAAE,MAAM,CAAC;SACnB;KACF;CACF;AAWD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CASN"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Request ID Middleware
3
+ *
4
+ * Attaches a unique `X-Request-Id` header to every request and response,
5
+ * enabling end-to-end tracing across logs and downstream systems.
6
+ *
7
+ * Priority order:
8
+ * 1. Honour an existing `X-Request-Id` header sent by the client
9
+ * 2. Honour `X-Correlation-Id` (common in enterprise proxies)
10
+ * 3. Generate a new UUID v4
11
+ *
12
+ * @module middleware/request-id
13
+ */
14
+ import { randomUUID } from 'crypto';
15
+ // Client-supplied ids are echoed into headers and logs: accept only a safe,
16
+ // bounded charset to prevent log forging / oversized headers.
17
+ const SAFE_ID = /^[A-Za-z0-9._:\-]{1,128}$/;
18
+ function pick(value) {
19
+ const v = Array.isArray(value) ? value[0] : value;
20
+ return v && SAFE_ID.test(v) ? v : undefined;
21
+ }
22
+ export function requestIdMiddleware(req, res, next) {
23
+ const id = pick(req.headers['x-request-id']) ||
24
+ pick(req.headers['x-correlation-id']) ||
25
+ randomUUID();
26
+ req.requestId = id;
27
+ res.setHeader('X-Request-Id', id);
28
+ next();
29
+ }
30
+ //# sourceMappingURL=request-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-id.js","sourceRoot":"","sources":["../../src/middleware/request-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAWpC,4EAA4E;AAC5E,8DAA8D;AAC9D,MAAM,OAAO,GAAG,2BAA2B,CAAC;AAE5C,SAAS,IAAI,CAAC,KAAoC;IAChD,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAClD,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,GAAY,EACZ,GAAa,EACb,IAAkB;IAElB,MAAM,EAAE,GACN,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACrC,UAAU,EAAE,CAAC;IAEf,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC;IACnB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAClC,IAAI,EAAE,CAAC;AACT,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Request Timeout Middleware
3
+ *
4
+ * Bug fix (v0.1.0): tool-call requests to slow or unresponsive MCP servers
5
+ * could hang indefinitely, exhausting the Node.js event loop.
6
+ * This middleware enforces a per-request deadline and returns a 504 response.
7
+ *
8
+ * @module middleware/timeout
9
+ */
10
+ import { Request, Response, NextFunction } from 'express';
11
+ export declare function timeoutMiddleware(timeoutMs: number): (req: Request, res: Response, next: NextFunction) => void;
12
+ //# sourceMappingURL=timeout.d.ts.map