@mcp-audit-gateway/core 0.1.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 (145) hide show
  1. package/.github/workflows/npm-publish.yml +21 -0
  2. package/CONTRIBUTING.md +41 -0
  3. package/LICENSE +21 -0
  4. package/README.md +156 -0
  5. package/dist/attestation/audit-log.d.ts +25 -0
  6. package/dist/attestation/audit-log.d.ts.map +1 -0
  7. package/dist/attestation/audit-log.js +95 -0
  8. package/dist/attestation/audit-log.js.map +1 -0
  9. package/dist/attestation/bugfix.test.d.ts +2 -0
  10. package/dist/attestation/bugfix.test.d.ts.map +1 -0
  11. package/dist/attestation/bugfix.test.js +103 -0
  12. package/dist/attestation/bugfix.test.js.map +1 -0
  13. package/dist/attestation/chain.test.d.ts +2 -0
  14. package/dist/attestation/chain.test.d.ts.map +1 -0
  15. package/dist/attestation/chain.test.js +153 -0
  16. package/dist/attestation/chain.test.js.map +1 -0
  17. package/dist/attestation/keygen.d.ts +5 -0
  18. package/dist/attestation/keygen.d.ts.map +1 -0
  19. package/dist/attestation/keygen.js +12 -0
  20. package/dist/attestation/keygen.js.map +1 -0
  21. package/dist/attestation/signer.d.ts +25 -0
  22. package/dist/attestation/signer.d.ts.map +1 -0
  23. package/dist/attestation/signer.js +93 -0
  24. package/dist/attestation/signer.js.map +1 -0
  25. package/dist/attestation/signer.test.d.ts +2 -0
  26. package/dist/attestation/signer.test.d.ts.map +1 -0
  27. package/dist/attestation/signer.test.js +62 -0
  28. package/dist/attestation/signer.test.js.map +1 -0
  29. package/dist/attestation/verify.d.ts +26 -0
  30. package/dist/attestation/verify.d.ts.map +1 -0
  31. package/dist/attestation/verify.js +104 -0
  32. package/dist/attestation/verify.js.map +1 -0
  33. package/dist/attestation/verify.test.d.ts +2 -0
  34. package/dist/attestation/verify.test.d.ts.map +1 -0
  35. package/dist/attestation/verify.test.js +79 -0
  36. package/dist/attestation/verify.test.js.map +1 -0
  37. package/dist/cli.d.ts +3 -0
  38. package/dist/cli.d.ts.map +1 -0
  39. package/dist/cli.js +364 -0
  40. package/dist/cli.js.map +1 -0
  41. package/dist/index.d.ts +12 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +12 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/integration.test.d.ts +2 -0
  46. package/dist/integration.test.d.ts.map +1 -0
  47. package/dist/integration.test.js +88 -0
  48. package/dist/integration.test.js.map +1 -0
  49. package/dist/policy/engine.d.ts +24 -0
  50. package/dist/policy/engine.d.ts.map +1 -0
  51. package/dist/policy/engine.js +130 -0
  52. package/dist/policy/engine.js.map +1 -0
  53. package/dist/policy/engine.test.d.ts +2 -0
  54. package/dist/policy/engine.test.d.ts.map +1 -0
  55. package/dist/policy/engine.test.js +80 -0
  56. package/dist/policy/engine.test.js.map +1 -0
  57. package/dist/proxy/gateway.d.ts +54 -0
  58. package/dist/proxy/gateway.d.ts.map +1 -0
  59. package/dist/proxy/gateway.js +245 -0
  60. package/dist/proxy/gateway.js.map +1 -0
  61. package/dist/proxy/gateway.test.d.ts +2 -0
  62. package/dist/proxy/gateway.test.d.ts.map +1 -0
  63. package/dist/proxy/gateway.test.js +93 -0
  64. package/dist/proxy/gateway.test.js.map +1 -0
  65. package/dist/proxy/mcp-server-adapter.d.ts +21 -0
  66. package/dist/proxy/mcp-server-adapter.d.ts.map +1 -0
  67. package/dist/proxy/mcp-server-adapter.js +98 -0
  68. package/dist/proxy/mcp-server-adapter.js.map +1 -0
  69. package/dist/proxy/mcp-server-adapter.test.d.ts +2 -0
  70. package/dist/proxy/mcp-server-adapter.test.d.ts.map +1 -0
  71. package/dist/proxy/mcp-server-adapter.test.js +160 -0
  72. package/dist/proxy/mcp-server-adapter.test.js.map +1 -0
  73. package/dist/proxy/upstream-manager.d.ts +49 -0
  74. package/dist/proxy/upstream-manager.d.ts.map +1 -0
  75. package/dist/proxy/upstream-manager.js +246 -0
  76. package/dist/proxy/upstream-manager.js.map +1 -0
  77. package/dist/proxy/upstream-manager.test.d.ts +2 -0
  78. package/dist/proxy/upstream-manager.test.d.ts.map +1 -0
  79. package/dist/proxy/upstream-manager.test.js +413 -0
  80. package/dist/proxy/upstream-manager.test.js.map +1 -0
  81. package/dist/telemetry/logger.d.ts +26 -0
  82. package/dist/telemetry/logger.d.ts.map +1 -0
  83. package/dist/telemetry/logger.js +48 -0
  84. package/dist/telemetry/logger.js.map +1 -0
  85. package/dist/telemetry/logger.test.d.ts +2 -0
  86. package/dist/telemetry/logger.test.d.ts.map +1 -0
  87. package/dist/telemetry/logger.test.js +124 -0
  88. package/dist/telemetry/logger.test.js.map +1 -0
  89. package/dist/telemetry/metrics.d.ts +41 -0
  90. package/dist/telemetry/metrics.d.ts.map +1 -0
  91. package/dist/telemetry/metrics.js +64 -0
  92. package/dist/telemetry/metrics.js.map +1 -0
  93. package/dist/telemetry/metrics.test.d.ts +2 -0
  94. package/dist/telemetry/metrics.test.d.ts.map +1 -0
  95. package/dist/telemetry/metrics.test.js +93 -0
  96. package/dist/telemetry/metrics.test.js.map +1 -0
  97. package/dist/telemetry/tracer.d.ts +16 -0
  98. package/dist/telemetry/tracer.d.ts.map +1 -0
  99. package/dist/telemetry/tracer.js +71 -0
  100. package/dist/telemetry/tracer.js.map +1 -0
  101. package/dist/types.d.ts +477 -0
  102. package/dist/types.d.ts.map +1 -0
  103. package/dist/types.js +68 -0
  104. package/dist/types.js.map +1 -0
  105. package/dist/wrap/proxy.d.ts +2 -0
  106. package/dist/wrap/proxy.d.ts.map +1 -0
  107. package/dist/wrap/proxy.js +152 -0
  108. package/dist/wrap/proxy.js.map +1 -0
  109. package/dist/wrap/proxy.test.d.ts +2 -0
  110. package/dist/wrap/proxy.test.d.ts.map +1 -0
  111. package/dist/wrap/proxy.test.js +155 -0
  112. package/dist/wrap/proxy.test.js.map +1 -0
  113. package/examples/README.md +33 -0
  114. package/examples/claude-desktop.json +50 -0
  115. package/examples/multi-agent-production.json +72 -0
  116. package/gateway.config.example.json +61 -0
  117. package/package.json +49 -0
  118. package/src/attestation/audit-log.ts +126 -0
  119. package/src/attestation/bugfix.test.ts +113 -0
  120. package/src/attestation/chain.test.ts +188 -0
  121. package/src/attestation/keygen.ts +18 -0
  122. package/src/attestation/signer.test.ts +75 -0
  123. package/src/attestation/signer.ts +105 -0
  124. package/src/attestation/verify.test.ts +86 -0
  125. package/src/attestation/verify.ts +131 -0
  126. package/src/cli.ts +407 -0
  127. package/src/index.ts +21 -0
  128. package/src/integration.test.ts +108 -0
  129. package/src/policy/engine.test.ts +95 -0
  130. package/src/policy/engine.ts +162 -0
  131. package/src/proxy/gateway.test.ts +108 -0
  132. package/src/proxy/gateway.ts +328 -0
  133. package/src/proxy/mcp-server-adapter.test.ts +197 -0
  134. package/src/proxy/mcp-server-adapter.ts +140 -0
  135. package/src/proxy/upstream-manager.test.ts +534 -0
  136. package/src/proxy/upstream-manager.ts +326 -0
  137. package/src/telemetry/logger.test.ts +139 -0
  138. package/src/telemetry/logger.ts +72 -0
  139. package/src/telemetry/metrics.test.ts +125 -0
  140. package/src/telemetry/metrics.ts +83 -0
  141. package/src/telemetry/tracer.ts +90 -0
  142. package/src/types.ts +113 -0
  143. package/src/wrap/proxy.test.ts +175 -0
  144. package/src/wrap/proxy.ts +192 -0
  145. package/tsconfig.json +18 -0
@@ -0,0 +1,413 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
2
+ import { UpstreamManager, UpstreamUnavailableError, ConnectionTimeoutError, } from "./upstream-manager.js";
3
+ // Mock the MCP SDK modules
4
+ vi.mock("@modelcontextprotocol/sdk/client/index.js", () => {
5
+ return {
6
+ Client: vi.fn().mockImplementation(() => ({
7
+ connect: vi.fn().mockResolvedValue(undefined),
8
+ listTools: vi.fn().mockResolvedValue({
9
+ tools: [
10
+ { name: "tool_a", description: "Tool A" },
11
+ { name: "tool_b", description: "Tool B" },
12
+ ],
13
+ }),
14
+ callTool: vi.fn().mockResolvedValue({ content: [{ type: "text", text: "ok" }] }),
15
+ ping: vi.fn().mockResolvedValue(undefined),
16
+ close: vi.fn().mockResolvedValue(undefined),
17
+ })),
18
+ };
19
+ });
20
+ vi.mock("@modelcontextprotocol/sdk/client/stdio.js", () => ({
21
+ StdioClientTransport: vi.fn().mockImplementation(() => ({})),
22
+ }));
23
+ vi.mock("@modelcontextprotocol/sdk/client/streamableHttp.js", () => ({
24
+ StreamableHTTPClientTransport: vi.fn().mockImplementation(() => ({})),
25
+ }));
26
+ const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
27
+ function createMockClient() {
28
+ const mockClient = {
29
+ connect: vi.fn().mockResolvedValue(undefined),
30
+ listTools: vi.fn().mockResolvedValue({
31
+ tools: [
32
+ { name: "tool_a", description: "Tool A" },
33
+ { name: "tool_b", description: "Tool B" },
34
+ ],
35
+ }),
36
+ callTool: vi.fn().mockResolvedValue({ content: [{ type: "text", text: "ok" }] }),
37
+ ping: vi.fn().mockResolvedValue(undefined),
38
+ close: vi.fn().mockResolvedValue(undefined),
39
+ };
40
+ return mockClient;
41
+ }
42
+ const testUpstream = {
43
+ name: "test-upstream",
44
+ namespace: "test",
45
+ transport: { type: "stdio", command: "echo", args: [] },
46
+ };
47
+ describe("UpstreamManager", () => {
48
+ let manager;
49
+ let mockClient;
50
+ beforeEach(() => {
51
+ vi.useFakeTimers();
52
+ manager = new UpstreamManager();
53
+ mockClient = createMockClient();
54
+ vi.mocked(Client).mockImplementation(() => mockClient);
55
+ });
56
+ afterEach(async () => {
57
+ await manager.disconnectAll();
58
+ vi.useRealTimers();
59
+ vi.clearAllMocks();
60
+ });
61
+ describe("connect", () => {
62
+ it("connects to an upstream and lists tools", async () => {
63
+ const conn = await manager.connect(testUpstream);
64
+ expect(conn.status.status).toBe("healthy");
65
+ expect(conn.tools).toHaveLength(2);
66
+ expect(conn.consecutiveFailures).toBe(0);
67
+ });
68
+ it("times out if connect takes too long", async () => {
69
+ mockClient.connect.mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 20_000)));
70
+ const promise = manager.connect(testUpstream, 100);
71
+ vi.advanceTimersByTime(101);
72
+ await expect(promise).rejects.toThrow(ConnectionTimeoutError);
73
+ await expect(promise).rejects.toThrow("timed out after 100ms");
74
+ });
75
+ it("times out if listTools takes too long", async () => {
76
+ mockClient.listTools.mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 20_000)));
77
+ const promise = manager.connect(testUpstream, 100);
78
+ // Attach rejection handler before advancing timers to prevent unhandled rejection
79
+ const expectation = expect(promise).rejects.toThrow(ConnectionTimeoutError);
80
+ await vi.advanceTimersByTimeAsync(101);
81
+ await expectation;
82
+ });
83
+ it("uses default timeout of 10s", async () => {
84
+ mockClient.connect.mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 20_000)));
85
+ const promise = manager.connect(testUpstream);
86
+ vi.advanceTimersByTime(10_001);
87
+ await expect(promise).rejects.toThrow(ConnectionTimeoutError);
88
+ await expect(promise).rejects.toThrow("10000ms");
89
+ });
90
+ });
91
+ describe("callTool", () => {
92
+ it("calls tool successfully and resets failure count", async () => {
93
+ await manager.connect(testUpstream);
94
+ const result = await manager.callTool("test-upstream", "tool_a", {});
95
+ expect(result).toEqual({ content: [{ type: "text", text: "ok" }] });
96
+ });
97
+ it("throws UpstreamUnavailableError when upstream is unavailable", async () => {
98
+ await manager.connect(testUpstream);
99
+ const conn = manager.getConnection("test-upstream");
100
+ conn.status.status = "unavailable";
101
+ conn.status.unavailableReason = "Health check failures";
102
+ await expect(manager.callTool("test-upstream", "tool_a", {})).rejects.toThrow(UpstreamUnavailableError);
103
+ await expect(manager.callTool("test-upstream", "tool_a", {})).rejects.toThrow('Upstream "test-upstream" is unavailable');
104
+ });
105
+ it("marks upstream degraded after 1-2 failures", async () => {
106
+ await manager.connect(testUpstream);
107
+ mockClient.callTool.mockRejectedValue(new Error("call failed"));
108
+ await expect(manager.callTool("test-upstream", "tool_a", {})).rejects.toThrow();
109
+ const conn = manager.getConnection("test-upstream");
110
+ expect(conn.status.status).toBe("degraded");
111
+ expect(conn.consecutiveFailures).toBe(1);
112
+ });
113
+ it("marks upstream unavailable after 3 consecutive failures", async () => {
114
+ await manager.connect(testUpstream);
115
+ mockClient.callTool.mockRejectedValue(new Error("call failed"));
116
+ for (let i = 0; i < 3; i++) {
117
+ await expect(manager.callTool("test-upstream", "tool_a", {})).rejects.toThrow();
118
+ }
119
+ const conn = manager.getConnection("test-upstream");
120
+ expect(conn.status.status).toBe("unavailable");
121
+ expect(conn.consecutiveFailures).toBe(3);
122
+ });
123
+ it("resets consecutive failures on successful call", async () => {
124
+ await manager.connect(testUpstream);
125
+ // Fail twice
126
+ mockClient.callTool.mockRejectedValueOnce(new Error("fail 1"));
127
+ mockClient.callTool.mockRejectedValueOnce(new Error("fail 2"));
128
+ await expect(manager.callTool("test-upstream", "tool_a", {})).rejects.toThrow();
129
+ await expect(manager.callTool("test-upstream", "tool_a", {})).rejects.toThrow();
130
+ const conn = manager.getConnection("test-upstream");
131
+ expect(conn.consecutiveFailures).toBe(2);
132
+ // Succeed resets counter
133
+ mockClient.callTool.mockResolvedValueOnce({ content: [] });
134
+ await manager.callTool("test-upstream", "tool_a", {});
135
+ expect(conn.consecutiveFailures).toBe(0);
136
+ expect(conn.status.status).toBe("healthy");
137
+ });
138
+ });
139
+ describe("health check transitions", () => {
140
+ it("transitions healthy -> degraded on first ping failure", async () => {
141
+ await manager.connect(testUpstream);
142
+ mockClient.ping.mockRejectedValue(new Error("ping timeout"));
143
+ manager.startHealthChecks(1000);
144
+ await vi.advanceTimersByTimeAsync(1000);
145
+ const conn = manager.getConnection("test-upstream");
146
+ expect(conn.status.status).toBe("degraded");
147
+ expect(conn.consecutiveFailures).toBe(1);
148
+ });
149
+ it("transitions degraded -> unavailable after 3 consecutive ping failures", async () => {
150
+ await manager.connect(testUpstream);
151
+ mockClient.ping.mockRejectedValue(new Error("ping timeout"));
152
+ manager.startHealthChecks(1000);
153
+ // Tick 3 health check cycles
154
+ await vi.advanceTimersByTimeAsync(1000);
155
+ await vi.advanceTimersByTimeAsync(1000);
156
+ await vi.advanceTimersByTimeAsync(1000);
157
+ const conn = manager.getConnection("test-upstream");
158
+ expect(conn.status.status).toBe("unavailable");
159
+ expect(conn.consecutiveFailures).toBe(3);
160
+ });
161
+ it("transitions degraded -> healthy on successful ping", async () => {
162
+ await manager.connect(testUpstream);
163
+ const conn = manager.getConnection("test-upstream");
164
+ // Manually set degraded state
165
+ conn.status.status = "degraded";
166
+ conn.consecutiveFailures = 2;
167
+ mockClient.ping.mockResolvedValue(undefined);
168
+ manager.startHealthChecks(1000);
169
+ await vi.advanceTimersByTimeAsync(1000);
170
+ expect(conn.status.status).toBe("healthy");
171
+ expect(conn.consecutiveFailures).toBe(0);
172
+ });
173
+ it("skips health checks for unavailable upstreams", async () => {
174
+ await manager.connect(testUpstream);
175
+ const conn = manager.getConnection("test-upstream");
176
+ conn.status.status = "unavailable";
177
+ manager.startHealthChecks(1000);
178
+ await vi.advanceTimersByTimeAsync(1000);
179
+ // ping should not be called for unavailable upstreams
180
+ expect(mockClient.ping).not.toHaveBeenCalled();
181
+ });
182
+ it("full cycle: healthy -> degraded -> unavailable -> healthy (via reconnect)", async () => {
183
+ await manager.connect(testUpstream);
184
+ const conn = manager.getConnection("test-upstream");
185
+ expect(conn.status.status).toBe("healthy");
186
+ // Degrade
187
+ mockClient.ping.mockRejectedValue(new Error("down"));
188
+ manager.startHealthChecks(1000);
189
+ await vi.advanceTimersByTimeAsync(1000);
190
+ expect(conn.status.status).toBe("degraded");
191
+ // Become unavailable
192
+ await vi.advanceTimersByTimeAsync(1000);
193
+ await vi.advanceTimersByTimeAsync(1000);
194
+ expect(conn.status.status).toBe("unavailable");
195
+ // Recover via reconnect
196
+ mockClient.connect.mockResolvedValue(undefined);
197
+ mockClient.listTools.mockResolvedValue({
198
+ tools: [{ name: "tool_a", description: "Tool A" }],
199
+ });
200
+ await manager.reconnect("test-upstream");
201
+ expect(conn.status.status).toBe("healthy");
202
+ expect(conn.consecutiveFailures).toBe(0);
203
+ });
204
+ });
205
+ describe("reconnection backoff", () => {
206
+ it("schedules reconnection with exponential backoff on unavailable", async () => {
207
+ await manager.connect(testUpstream);
208
+ mockClient.callTool.mockRejectedValue(new Error("fail"));
209
+ // Trigger 3 failures to become unavailable
210
+ for (let i = 0; i < 3; i++) {
211
+ await expect(manager.callTool("test-upstream", "tool_a", {})).rejects.toThrow();
212
+ }
213
+ const conn = manager.getConnection("test-upstream");
214
+ expect(conn.status.status).toBe("unavailable");
215
+ expect(conn.reconnectTimer).toBeDefined();
216
+ });
217
+ it("uses 1s backoff on first reconnect attempt", async () => {
218
+ await manager.connect(testUpstream);
219
+ const conn = manager.getConnection("test-upstream");
220
+ // Make unavailable (triggers first scheduled reconnect)
221
+ mockClient.callTool.mockRejectedValue(new Error("fail"));
222
+ for (let i = 0; i < 3; i++) {
223
+ await expect(manager.callTool("test-upstream", "tool_a", {})).rejects.toThrow();
224
+ }
225
+ // Mock reconnect to succeed
226
+ mockClient.connect.mockResolvedValue(undefined);
227
+ mockClient.listTools.mockResolvedValue({ tools: [] });
228
+ // Advance less than 1s - should not reconnect yet
229
+ await vi.advanceTimersByTimeAsync(999);
230
+ expect(conn.status.status).toBe("unavailable");
231
+ // Advance to 1s - should trigger reconnect
232
+ await vi.advanceTimersByTimeAsync(1);
233
+ expect(conn.status.status).toBe("healthy");
234
+ });
235
+ it("doubles backoff on consecutive reconnect failures", async () => {
236
+ await manager.connect(testUpstream);
237
+ // Make unavailable
238
+ mockClient.callTool.mockRejectedValue(new Error("fail"));
239
+ for (let i = 0; i < 3; i++) {
240
+ await expect(manager.callTool("test-upstream", "tool_a", {})).rejects.toThrow();
241
+ }
242
+ const conn = manager.getConnection("test-upstream");
243
+ expect(conn.status.status).toBe("unavailable");
244
+ // First reconnect attempt fails after 1s
245
+ mockClient.connect.mockRejectedValue(new Error("still down"));
246
+ await vi.advanceTimersByTimeAsync(1000);
247
+ expect(conn.reconnectAttempts).toBe(1);
248
+ expect(conn.status.status).toBe("unavailable");
249
+ // Second reconnect attempt should be at 2s
250
+ await vi.advanceTimersByTimeAsync(1999);
251
+ expect(conn.reconnectAttempts).toBe(1);
252
+ await vi.advanceTimersByTimeAsync(1);
253
+ expect(conn.reconnectAttempts).toBe(2);
254
+ // Third reconnect attempt should be at 4s
255
+ await vi.advanceTimersByTimeAsync(3999);
256
+ expect(conn.reconnectAttempts).toBe(2);
257
+ await vi.advanceTimersByTimeAsync(1);
258
+ expect(conn.reconnectAttempts).toBe(3);
259
+ });
260
+ it("caps backoff at 30s", async () => {
261
+ await manager.connect(testUpstream);
262
+ const conn = manager.getConnection("test-upstream");
263
+ // Make unavailable
264
+ mockClient.callTool.mockRejectedValue(new Error("fail"));
265
+ for (let i = 0; i < 3; i++) {
266
+ await expect(manager.callTool("test-upstream", "tool_a", {})).rejects.toThrow();
267
+ }
268
+ // Mock reconnect to keep failing
269
+ mockClient.connect.mockRejectedValue(new Error("still down"));
270
+ // Advance through several reconnect attempts to exceed 30s cap
271
+ // Attempts: 1s, 2s, 4s, 8s, 16s, 30s (capped), 30s (capped)
272
+ await vi.advanceTimersByTimeAsync(1000); // attempt 1 at 1s
273
+ expect(conn.reconnectAttempts).toBe(1);
274
+ await vi.advanceTimersByTimeAsync(2000); // attempt 2 at 2s
275
+ expect(conn.reconnectAttempts).toBe(2);
276
+ await vi.advanceTimersByTimeAsync(4000); // attempt 3 at 4s
277
+ expect(conn.reconnectAttempts).toBe(3);
278
+ await vi.advanceTimersByTimeAsync(8000); // attempt 4 at 8s
279
+ expect(conn.reconnectAttempts).toBe(4);
280
+ await vi.advanceTimersByTimeAsync(16000); // attempt 5 at 16s
281
+ expect(conn.reconnectAttempts).toBe(5);
282
+ // Next should be capped at 30s (2^5 = 32s > 30s)
283
+ await vi.advanceTimersByTimeAsync(29999);
284
+ expect(conn.reconnectAttempts).toBe(5);
285
+ await vi.advanceTimersByTimeAsync(1);
286
+ expect(conn.reconnectAttempts).toBe(6);
287
+ });
288
+ it("resets reconnect attempts on successful reconnect", async () => {
289
+ await manager.connect(testUpstream);
290
+ // Make unavailable
291
+ mockClient.callTool.mockRejectedValue(new Error("fail"));
292
+ for (let i = 0; i < 3; i++) {
293
+ await expect(manager.callTool("test-upstream", "tool_a", {})).rejects.toThrow();
294
+ }
295
+ const conn = manager.getConnection("test-upstream");
296
+ // First reconnect fails
297
+ mockClient.connect.mockRejectedValue(new Error("still down"));
298
+ await vi.advanceTimersByTimeAsync(1000);
299
+ expect(conn.reconnectAttempts).toBe(1);
300
+ // Second reconnect succeeds
301
+ mockClient.connect.mockResolvedValue(undefined);
302
+ mockClient.listTools.mockResolvedValue({ tools: [] });
303
+ await vi.advanceTimersByTimeAsync(2000);
304
+ expect(conn.reconnectAttempts).toBe(0);
305
+ expect(conn.status.status).toBe("healthy");
306
+ });
307
+ });
308
+ describe("timeout behavior", () => {
309
+ it("throws ConnectionTimeoutError with upstream name and timeout value", async () => {
310
+ mockClient.connect.mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 60_000)));
311
+ const promise = manager.connect(testUpstream, 5000);
312
+ vi.advanceTimersByTime(5001);
313
+ await expect(promise).rejects.toThrow(ConnectionTimeoutError);
314
+ try {
315
+ vi.advanceTimersByTime(5001);
316
+ await promise;
317
+ }
318
+ catch (err) {
319
+ expect(err).toBeInstanceOf(ConnectionTimeoutError);
320
+ expect(err.upstreamName).toBe("test-upstream");
321
+ expect(err.timeoutMs).toBe(5000);
322
+ }
323
+ });
324
+ it("does not mark as unavailable if connect times out (no prior connection)", async () => {
325
+ mockClient.connect.mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 60_000)));
326
+ const promise = manager.connect(testUpstream, 100);
327
+ vi.advanceTimersByTime(101);
328
+ await expect(promise).rejects.toThrow();
329
+ // No connection was stored
330
+ expect(manager.getConnection("test-upstream")).toBeUndefined();
331
+ });
332
+ it("connect timeout is configurable per-call", async () => {
333
+ mockClient.connect.mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 5000)));
334
+ // Short timeout fails
335
+ const shortPromise = manager.connect(testUpstream, 50);
336
+ vi.advanceTimersByTime(51);
337
+ await expect(shortPromise).rejects.toThrow(ConnectionTimeoutError);
338
+ // Long timeout succeeds
339
+ const longPromise = manager.connect(testUpstream, 10_000);
340
+ vi.advanceTimersByTime(5000);
341
+ const conn = await longPromise;
342
+ expect(conn.status.status).toBe("healthy");
343
+ });
344
+ });
345
+ describe("graceful degradation", () => {
346
+ it("returns clear error with upstream name when upstream is unavailable", async () => {
347
+ await manager.connect(testUpstream);
348
+ const conn = manager.getConnection("test-upstream");
349
+ conn.status.status = "unavailable";
350
+ conn.status.unavailableReason = "Connection lost after 3 ping failures";
351
+ try {
352
+ await manager.callTool("test-upstream", "tool_a", {});
353
+ expect.fail("Should have thrown");
354
+ }
355
+ catch (err) {
356
+ expect(err).toBeInstanceOf(UpstreamUnavailableError);
357
+ const error = err;
358
+ expect(error.upstreamName).toBe("test-upstream");
359
+ expect(error.reason).toBe("Connection lost after 3 ping failures");
360
+ expect(error.message).toContain("test-upstream");
361
+ expect(error.message).toContain("unavailable");
362
+ }
363
+ });
364
+ it("does not attempt tool call when upstream is unavailable", async () => {
365
+ await manager.connect(testUpstream);
366
+ const conn = manager.getConnection("test-upstream");
367
+ conn.status.status = "unavailable";
368
+ await expect(manager.callTool("test-upstream", "tool_a", {})).rejects.toThrow();
369
+ expect(mockClient.callTool).not.toHaveBeenCalled();
370
+ });
371
+ it("allows calls after upstream recovers", async () => {
372
+ await manager.connect(testUpstream);
373
+ const conn = manager.getConnection("test-upstream");
374
+ // Make unavailable
375
+ conn.status.status = "unavailable";
376
+ // Reconnect successfully
377
+ mockClient.connect.mockResolvedValue(undefined);
378
+ mockClient.listTools.mockResolvedValue({ tools: [{ name: "tool_a" }] });
379
+ await manager.reconnect("test-upstream");
380
+ expect(conn.status.status).toBe("healthy");
381
+ // Call should work now
382
+ mockClient.callTool.mockResolvedValue({ content: [] });
383
+ const result = await manager.callTool("test-upstream", "tool_a", {});
384
+ expect(result).toEqual({ content: [] });
385
+ });
386
+ });
387
+ describe("stopHealthChecks", () => {
388
+ it("stops the health check interval", async () => {
389
+ await manager.connect(testUpstream);
390
+ mockClient.ping.mockRejectedValue(new Error("down"));
391
+ manager.startHealthChecks(1000);
392
+ await vi.advanceTimersByTimeAsync(1000);
393
+ const conn = manager.getConnection("test-upstream");
394
+ expect(conn.consecutiveFailures).toBe(1);
395
+ manager.stopHealthChecks();
396
+ await vi.advanceTimersByTimeAsync(5000);
397
+ // Failures should not have increased
398
+ expect(conn.consecutiveFailures).toBe(1);
399
+ });
400
+ });
401
+ describe("disconnectAll", () => {
402
+ it("cleans up all timers and connections", async () => {
403
+ await manager.connect(testUpstream);
404
+ manager.startHealthChecks(1000);
405
+ const conn = manager.getConnection("test-upstream");
406
+ conn.status.status = "unavailable";
407
+ await manager.disconnectAll();
408
+ expect(manager.getConnection("test-upstream")).toBeUndefined();
409
+ expect(manager.getAllStatuses()).toHaveLength(0);
410
+ });
411
+ });
412
+ });
413
+ //# sourceMappingURL=upstream-manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upstream-manager.test.js","sourceRoot":"","sources":["../../src/proxy/upstream-manager.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export type LogLevel = "debug" | "info" | "warn" | "error";
2
+ export interface LogEntry {
3
+ timestamp: string;
4
+ level: LogLevel;
5
+ component: string;
6
+ message: string;
7
+ [key: string]: unknown;
8
+ }
9
+ export interface LoggerOptions {
10
+ component: string;
11
+ level?: LogLevel;
12
+ output?: (line: string) => void;
13
+ }
14
+ export declare class Logger {
15
+ private component;
16
+ private minLevel;
17
+ private output;
18
+ constructor(options: LoggerOptions);
19
+ debug(message: string, context?: Record<string, unknown>): void;
20
+ info(message: string, context?: Record<string, unknown>): void;
21
+ warn(message: string, context?: Record<string, unknown>): void;
22
+ error(message: string, context?: Record<string, unknown>): void;
23
+ private log;
24
+ child(overrides: Partial<LoggerOptions>): Logger;
25
+ }
26
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/telemetry/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAS3D,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAyB;gBAE3B,OAAO,EAAE,aAAa;IAMlC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/D,OAAO,CAAC,GAAG;IAcX,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,MAAM;CAOjD"}
@@ -0,0 +1,48 @@
1
+ const LEVEL_PRIORITY = {
2
+ debug: 0,
3
+ info: 1,
4
+ warn: 2,
5
+ error: 3,
6
+ };
7
+ export class Logger {
8
+ component;
9
+ minLevel;
10
+ output;
11
+ constructor(options) {
12
+ this.component = options.component;
13
+ this.minLevel = LEVEL_PRIORITY[options.level ?? "info"];
14
+ this.output = options.output ?? ((line) => process.stderr.write(line + "\n"));
15
+ }
16
+ debug(message, context) {
17
+ this.log("debug", message, context);
18
+ }
19
+ info(message, context) {
20
+ this.log("info", message, context);
21
+ }
22
+ warn(message, context) {
23
+ this.log("warn", message, context);
24
+ }
25
+ error(message, context) {
26
+ this.log("error", message, context);
27
+ }
28
+ log(level, message, context) {
29
+ if (LEVEL_PRIORITY[level] < this.minLevel)
30
+ return;
31
+ const entry = {
32
+ timestamp: new Date().toISOString(),
33
+ level,
34
+ component: this.component,
35
+ message,
36
+ ...context,
37
+ };
38
+ this.output(JSON.stringify(entry));
39
+ }
40
+ child(overrides) {
41
+ return new Logger({
42
+ component: overrides.component ?? this.component,
43
+ level: overrides.level ?? Object.keys(LEVEL_PRIORITY)[this.minLevel],
44
+ output: overrides.output ?? this.output,
45
+ });
46
+ }
47
+ }
48
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/telemetry/logger.ts"],"names":[],"mappings":"AAEA,MAAM,cAAc,GAA6B;IAC/C,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAgBF,MAAM,OAAO,MAAM;IACT,SAAS,CAAS;IAClB,QAAQ,CAAS;IACjB,MAAM,CAAyB;IAEvC,YAAY,OAAsB;QAChC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;IACxF,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,OAAiC;QACtD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,OAAiC;QACrD,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,OAAiC;QACrD,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,OAAiC;QACtD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAEO,GAAG,CAAC,KAAe,EAAE,OAAe,EAAE,OAAiC;QAC7E,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ;YAAE,OAAO;QAElD,MAAM,KAAK,GAAa;YACtB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO;YACP,GAAG,OAAO;SACX,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,SAAiC;QACrC,OAAO,IAAI,MAAM,CAAC;YAChB,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS;YAChD,KAAK,EAAE,SAAS,CAAC,KAAK,IAAK,MAAM,CAAC,IAAI,CAAC,cAAc,CAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC;YACpF,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM;SACxC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=logger.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.test.d.ts","sourceRoot":"","sources":["../../src/telemetry/logger.test.ts"],"names":[],"mappings":""}