@arvoretech/runtime-lens-mcp 1.0.0 → 1.2.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/src/server.ts CHANGED
@@ -1,387 +1,434 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { AgentBridge } from "./agent-bridge.js";
3
4
  import { LogCollector } from "./log-collector.js";
4
5
  import { ProcessInspector } from "./process-inspector.js";
5
6
  import { RuntimeInterceptor } from "./runtime-interceptor.js";
6
7
  import {
7
- TailLogsParamsSchema,
8
- SearchLogsParamsSchema,
9
- GetErrorsParamsSchema,
10
- InspectRequestParamsSchema,
11
- GetPerformanceParamsSchema,
8
+ GetErrorsParamsSchema,
9
+ GetPerformanceParamsSchema,
10
+ InspectRequestParamsSchema,
11
+ SearchLogsParamsSchema,
12
+ TailLogsParamsSchema,
12
13
  } from "./types.js";
13
14
 
14
15
  export class RuntimeLensMCPServer {
15
- private readonly server: McpServer;
16
- private readonly collector: LogCollector;
17
- private readonly inspector: ProcessInspector;
18
- private readonly interceptor: RuntimeInterceptor;
16
+ private readonly server: McpServer;
17
+ private readonly collector: LogCollector;
18
+ private readonly inspector: ProcessInspector;
19
+ private readonly interceptor: RuntimeInterceptor;
20
+ private readonly agentBridge: AgentBridge;
19
21
 
20
- constructor(projectRoot?: string, logPaths?: string[]) {
21
- this.server = new McpServer({
22
- name: "runtime-lens-mcp",
23
- version: "1.0.0",
24
- });
22
+ constructor(projectRoot?: string, logPaths?: string[]) {
23
+ this.server = new McpServer({
24
+ name: "runtime-lens-mcp",
25
+ version: "1.1.0",
26
+ });
27
+ this.collector = new LogCollector(projectRoot, logPaths);
28
+ this.inspector = new ProcessInspector(projectRoot);
29
+ this.interceptor = new RuntimeInterceptor(this.collector);
30
+ this.agentBridge = new AgentBridge(this.collector);
31
+ this.setupTools();
32
+ }
25
33
 
26
- this.collector = new LogCollector(projectRoot, logPaths);
27
- this.inspector = new ProcessInspector(projectRoot);
28
- this.interceptor = new RuntimeInterceptor(this.collector);
34
+ static fromEnvironment(): RuntimeLensMCPServer {
35
+ const projectRoot = process.env.RUNTIME_LENS_PROJECT_ROOT || process.cwd();
36
+ const logPaths =
37
+ process.env.RUNTIME_LENS_LOG_PATHS?.split(",").filter(Boolean) || [];
38
+ return new RuntimeLensMCPServer(projectRoot, logPaths);
39
+ }
29
40
 
30
- this.setupTools();
31
- }
41
+ private setupTools(): void {
42
+ this.registerTailLogs();
43
+ this.registerSearchLogs();
44
+ this.registerGetErrors();
45
+ this.registerInspectRequests();
46
+ this.registerGetPerformance();
47
+ this.registerGetEnvInfo();
48
+ this.registerClearLogs();
49
+ this.registerGetStats();
50
+ this.registerStartInterceptor();
51
+ this.registerStopInterceptor();
52
+ this.registerCollectLogs();
53
+ this.registerScanProject();
54
+ this.registerFindProcesses();
55
+ this.registerGetPorts();
56
+ }
32
57
 
33
- static fromEnvironment(): RuntimeLensMCPServer {
34
- const projectRoot = process.env.RUNTIME_LENS_PROJECT_ROOT || process.cwd();
35
- const logPaths = process.env.RUNTIME_LENS_LOG_PATHS?.split(",").filter(Boolean) || [];
36
- return new RuntimeLensMCPServer(projectRoot, logPaths);
37
- }
58
+ private registerTailLogs(): void {
59
+ this.server.registerTool(
60
+ "tail_logs",
61
+ {
62
+ title: "Tail Logs",
63
+ description:
64
+ "Retrieve recent log entries from the application buffer. Supports filtering by level, framework, and source.",
65
+ inputSchema: {
66
+ lines: TailLogsParamsSchema.shape.lines,
67
+ level: TailLogsParamsSchema.shape.level,
68
+ framework: TailLogsParamsSchema.shape.framework,
69
+ source: TailLogsParamsSchema.shape.source,
70
+ },
71
+ },
72
+ async (params) => ({
73
+ content: [
74
+ {
75
+ type: "text" as const,
76
+ text: JSON.stringify(this.collector.getLogs(params), null, 2),
77
+ },
78
+ ],
79
+ }),
80
+ );
81
+ }
38
82
 
39
- private setupTools(): void {
40
- this.registerTailLogs();
41
- this.registerSearchLogs();
42
- this.registerGetErrors();
43
- this.registerInspectRequests();
44
- this.registerGetPerformance();
45
- this.registerGetEnvInfo();
46
- this.registerClearLogs();
47
- this.registerGetStats();
48
- this.registerStartInterceptor();
49
- this.registerStopInterceptor();
50
- this.registerCollectLogs();
51
- this.registerScanProject();
52
- this.registerFindProcesses();
53
- this.registerGetPorts();
54
- }
83
+ private registerSearchLogs(): void {
84
+ this.server.registerTool(
85
+ "search_logs",
86
+ {
87
+ title: "Search Logs",
88
+ description:
89
+ "Search through collected logs using regex patterns. Filter by level, framework, and time range.",
90
+ inputSchema: {
91
+ query: SearchLogsParamsSchema.shape.query,
92
+ level: SearchLogsParamsSchema.shape.level,
93
+ framework: SearchLogsParamsSchema.shape.framework,
94
+ limit: SearchLogsParamsSchema.shape.limit,
95
+ since: SearchLogsParamsSchema.shape.since,
96
+ },
97
+ },
98
+ async (params) => ({
99
+ content: [
100
+ {
101
+ type: "text" as const,
102
+ text: JSON.stringify(
103
+ this.collector.searchLogs(params as any),
104
+ null,
105
+ 2,
106
+ ),
107
+ },
108
+ ],
109
+ }),
110
+ );
111
+ }
55
112
 
56
- private registerTailLogs(): void {
57
- this.server.registerTool(
58
- "tail_logs",
59
- {
60
- title: "Tail Logs",
61
- description: "Retrieve recent log entries from the application buffer. Supports filtering by level, framework, and source.",
62
- inputSchema: {
63
- lines: TailLogsParamsSchema.shape.lines,
64
- level: TailLogsParamsSchema.shape.level,
65
- framework: TailLogsParamsSchema.shape.framework,
66
- source: TailLogsParamsSchema.shape.source,
67
- },
68
- },
69
- async (params) => {
70
- const logs = this.collector.getLogs(params);
71
- return {
72
- content: [{
73
- type: "text" as const,
74
- text: JSON.stringify(logs, null, 2),
75
- }],
76
- };
77
- }
78
- );
79
- }
113
+ private registerGetErrors(): void {
114
+ this.server.registerTool(
115
+ "get_errors",
116
+ {
117
+ title: "Get Errors",
118
+ description:
119
+ "Retrieve recent errors with stack traces. Optionally group similar errors together to identify patterns.",
120
+ inputSchema: {
121
+ limit: GetErrorsParamsSchema.shape.limit,
122
+ framework: GetErrorsParamsSchema.shape.framework,
123
+ grouped: GetErrorsParamsSchema.shape.grouped,
124
+ },
125
+ },
126
+ async (params) => ({
127
+ content: [
128
+ {
129
+ type: "text" as const,
130
+ text: JSON.stringify(this.collector.getErrors(params), null, 2),
131
+ },
132
+ ],
133
+ }),
134
+ );
135
+ }
80
136
 
81
- private registerSearchLogs(): void {
82
- this.server.registerTool(
83
- "search_logs",
84
- {
85
- title: "Search Logs",
86
- description: "Search through collected logs using regex patterns. Filter by level, framework, and time range.",
87
- inputSchema: {
88
- query: SearchLogsParamsSchema.shape.query,
89
- level: SearchLogsParamsSchema.shape.level,
90
- framework: SearchLogsParamsSchema.shape.framework,
91
- limit: SearchLogsParamsSchema.shape.limit,
92
- since: SearchLogsParamsSchema.shape.since,
93
- },
94
- },
95
- async (params) => {
96
- const logs = this.collector.searchLogs(params as any);
97
- return {
98
- content: [{
99
- type: "text" as const,
100
- text: JSON.stringify(logs, null, 2),
101
- }],
102
- };
103
- }
104
- );
105
- }
137
+ private registerInspectRequests(): void {
138
+ this.server.registerTool(
139
+ "inspect_requests",
140
+ {
141
+ title: "Inspect HTTP Requests",
142
+ description:
143
+ "Inspect captured HTTP requests and responses. Filter by method, URL pattern, status code, or specific request ID.",
144
+ inputSchema: {
145
+ id: InspectRequestParamsSchema.shape.id,
146
+ method: InspectRequestParamsSchema.shape.method,
147
+ urlPattern: InspectRequestParamsSchema.shape.urlPattern,
148
+ statusCode: InspectRequestParamsSchema.shape.statusCode,
149
+ limit: InspectRequestParamsSchema.shape.limit,
150
+ },
151
+ },
152
+ async (params) => ({
153
+ content: [
154
+ {
155
+ type: "text" as const,
156
+ text: JSON.stringify(this.collector.getRequests(params), null, 2),
157
+ },
158
+ ],
159
+ }),
160
+ );
161
+ }
106
162
 
107
- private registerGetErrors(): void {
108
- this.server.registerTool(
109
- "get_errors",
110
- {
111
- title: "Get Errors",
112
- description: "Retrieve recent errors with stack traces. Optionally group similar errors together to identify patterns.",
113
- inputSchema: {
114
- limit: GetErrorsParamsSchema.shape.limit,
115
- framework: GetErrorsParamsSchema.shape.framework,
116
- grouped: GetErrorsParamsSchema.shape.grouped,
117
- },
118
- },
119
- async (params) => {
120
- const errors = this.collector.getErrors(params);
121
- return {
122
- content: [{
123
- type: "text" as const,
124
- text: JSON.stringify(errors, null, 2),
125
- }],
126
- };
127
- }
128
- );
129
- }
163
+ private registerGetPerformance(): void {
164
+ this.server.registerTool(
165
+ "get_performance",
166
+ {
167
+ title: "Get Performance Metrics",
168
+ description:
169
+ "Retrieve performance metrics including memory usage, CPU, and custom metrics from the application.",
170
+ inputSchema: {
171
+ metric: GetPerformanceParamsSchema.shape.metric,
172
+ since: GetPerformanceParamsSchema.shape.since,
173
+ limit: GetPerformanceParamsSchema.shape.limit,
174
+ },
175
+ },
176
+ async (params) => {
177
+ await this.collector.collectFromProcess();
178
+ return {
179
+ content: [
180
+ {
181
+ type: "text" as const,
182
+ text: JSON.stringify(this.collector.getMetrics(params), null, 2),
183
+ },
184
+ ],
185
+ };
186
+ },
187
+ );
188
+ }
130
189
 
131
- private registerInspectRequests(): void {
132
- this.server.registerTool(
133
- "inspect_requests",
134
- {
135
- title: "Inspect HTTP Requests",
136
- description: "Inspect captured HTTP requests and responses. Filter by method, URL pattern, status code, or specific request ID.",
137
- inputSchema: {
138
- id: InspectRequestParamsSchema.shape.id,
139
- method: InspectRequestParamsSchema.shape.method,
140
- urlPattern: InspectRequestParamsSchema.shape.urlPattern,
141
- statusCode: InspectRequestParamsSchema.shape.statusCode,
142
- limit: InspectRequestParamsSchema.shape.limit,
143
- },
144
- },
145
- async (params) => {
146
- const requests = this.collector.getRequests(params);
147
- return {
148
- content: [{
149
- type: "text" as const,
150
- text: JSON.stringify(requests, null, 2),
151
- }],
152
- };
153
- }
154
- );
155
- }
190
+ private registerGetEnvInfo(): void {
191
+ this.server.registerTool(
192
+ "get_env_info",
193
+ {
194
+ title: "Get Environment Info",
195
+ description:
196
+ "Get comprehensive environment information including running Node.js processes, listening ports, project framework detection, and system resources.",
197
+ inputSchema: {},
198
+ },
199
+ async () => ({
200
+ content: [
201
+ {
202
+ type: "text" as const,
203
+ text: JSON.stringify(
204
+ await this.inspector.getEnvironmentInfo(),
205
+ null,
206
+ 2,
207
+ ),
208
+ },
209
+ ],
210
+ }),
211
+ );
212
+ }
156
213
 
157
- private registerGetPerformance(): void {
158
- this.server.registerTool(
159
- "get_performance",
160
- {
161
- title: "Get Performance Metrics",
162
- description: "Retrieve performance metrics including memory usage, CPU, and custom metrics from the application.",
163
- inputSchema: {
164
- metric: GetPerformanceParamsSchema.shape.metric,
165
- since: GetPerformanceParamsSchema.shape.since,
166
- limit: GetPerformanceParamsSchema.shape.limit,
167
- },
168
- },
169
- async (params) => {
170
- await this.collector.collectFromProcess();
171
- const metrics = this.collector.getMetrics(params);
172
- return {
173
- content: [{
174
- type: "text" as const,
175
- text: JSON.stringify(metrics, null, 2),
176
- }],
177
- };
178
- }
179
- );
180
- }
214
+ private registerClearLogs(): void {
215
+ this.server.registerTool(
216
+ "clear_logs",
217
+ {
218
+ title: "Clear Log Buffer",
219
+ description:
220
+ "Clear all collected logs, requests, and metrics from the buffer.",
221
+ inputSchema: {},
222
+ },
223
+ async () => {
224
+ const result = this.collector.clearLogs();
225
+ return {
226
+ content: [
227
+ {
228
+ type: "text" as const,
229
+ text: JSON.stringify({
230
+ message: `Cleared ${result.cleared} entries`,
231
+ }),
232
+ },
233
+ ],
234
+ };
235
+ },
236
+ );
237
+ }
181
238
 
182
- private registerGetEnvInfo(): void {
183
- this.server.registerTool(
184
- "get_env_info",
185
- {
186
- title: "Get Environment Info",
187
- description: "Get comprehensive environment information including running Node.js processes, listening ports, project framework detection, and system resources.",
188
- inputSchema: {},
189
- },
190
- async () => {
191
- const info = await this.inspector.getEnvironmentInfo();
192
- return {
193
- content: [{
194
- type: "text" as const,
195
- text: JSON.stringify(info, null, 2),
196
- }],
197
- };
198
- }
199
- );
200
- }
239
+ private registerGetStats(): void {
240
+ this.server.registerTool(
241
+ "get_stats",
242
+ {
243
+ title: "Get Log Statistics",
244
+ description:
245
+ "Get statistics about collected logs including counts by level and framework.",
246
+ inputSchema: {},
247
+ },
248
+ async () => ({
249
+ content: [
250
+ {
251
+ type: "text" as const,
252
+ text: JSON.stringify(this.collector.getStats(), null, 2),
253
+ },
254
+ ],
255
+ }),
256
+ );
257
+ }
201
258
 
202
- private registerClearLogs(): void {
203
- this.server.registerTool(
204
- "clear_logs",
205
- {
206
- title: "Clear Log Buffer",
207
- description: "Clear all collected logs, requests, and metrics from the buffer.",
208
- inputSchema: {},
209
- },
210
- async () => {
211
- const result = this.collector.clearLogs();
212
- return {
213
- content: [{
214
- type: "text" as const,
215
- text: JSON.stringify({ message: `Cleared ${result.cleared} entries` }),
216
- }],
217
- };
218
- }
219
- );
220
- }
259
+ private registerStartInterceptor(): void {
260
+ this.server.registerTool(
261
+ "start_interceptor",
262
+ {
263
+ title: "Start Console Interceptor",
264
+ description:
265
+ "Start intercepting console.log/warn/error/debug calls and stderr output in real-time. Captured output is stored in the log buffer.",
266
+ inputSchema: {},
267
+ },
268
+ async () => {
269
+ this.interceptor.startIntercepting();
270
+ return {
271
+ content: [
272
+ {
273
+ type: "text" as const,
274
+ text: JSON.stringify({
275
+ message: "Console interceptor started",
276
+ active: true,
277
+ }),
278
+ },
279
+ ],
280
+ };
281
+ },
282
+ );
283
+ }
221
284
 
222
- private registerGetStats(): void {
223
- this.server.registerTool(
224
- "get_stats",
225
- {
226
- title: "Get Log Statistics",
227
- description: "Get statistics about collected logs including counts by level and framework.",
228
- inputSchema: {},
229
- },
230
- async () => {
231
- const stats = this.collector.getStats();
232
- return {
233
- content: [{
234
- type: "text" as const,
235
- text: JSON.stringify(stats, null, 2),
236
- }],
237
- };
238
- }
239
- );
240
- }
285
+ private registerStopInterceptor(): void {
286
+ this.server.registerTool(
287
+ "stop_interceptor",
288
+ {
289
+ title: "Stop Console Interceptor",
290
+ description:
291
+ "Stop intercepting console output. Previously captured logs remain in the buffer.",
292
+ inputSchema: {},
293
+ },
294
+ async () => {
295
+ this.interceptor.stopIntercepting();
296
+ return {
297
+ content: [
298
+ {
299
+ type: "text" as const,
300
+ text: JSON.stringify({
301
+ message: "Console interceptor stopped",
302
+ active: false,
303
+ }),
304
+ },
305
+ ],
306
+ };
307
+ },
308
+ );
309
+ }
241
310
 
242
- private registerStartInterceptor(): void {
243
- this.server.registerTool(
244
- "start_interceptor",
245
- {
246
- title: "Start Console Interceptor",
247
- description: "Start intercepting console.log/warn/error/debug calls and stderr output in real-time. Captured output is stored in the log buffer.",
248
- inputSchema: {},
249
- },
250
- async () => {
251
- this.interceptor.startIntercepting();
252
- return {
253
- content: [{
254
- type: "text" as const,
255
- text: JSON.stringify({ message: "Console interceptor started", active: true }),
256
- }],
257
- };
258
- }
259
- );
260
- }
311
+ private registerCollectLogs(): void {
312
+ this.server.registerTool(
313
+ "collect_from_files",
314
+ {
315
+ title: "Collect Logs from Files",
316
+ description:
317
+ "Scan and collect logs from log files in the project directory. Automatically discovers .log and .json files in common log directories.",
318
+ inputSchema: {},
319
+ },
320
+ async () => {
321
+ await this.collector.collectFromFiles();
322
+ return {
323
+ content: [
324
+ {
325
+ type: "text" as const,
326
+ text: JSON.stringify({
327
+ message: "Log collection complete",
328
+ stats: this.collector.getStats(),
329
+ }),
330
+ },
331
+ ],
332
+ };
333
+ },
334
+ );
335
+ }
261
336
 
262
- private registerStopInterceptor(): void {
263
- this.server.registerTool(
264
- "stop_interceptor",
265
- {
266
- title: "Stop Console Interceptor",
267
- description: "Stop intercepting console output. Previously captured logs remain in the buffer.",
268
- inputSchema: {},
269
- },
270
- async () => {
271
- this.interceptor.stopIntercepting();
272
- return {
273
- content: [{
274
- type: "text" as const,
275
- text: JSON.stringify({ message: "Console interceptor stopped", active: false }),
276
- }],
277
- };
278
- }
279
- );
280
- }
337
+ private registerScanProject(): void {
338
+ this.server.registerTool(
339
+ "scan_project",
340
+ {
341
+ title: "Scan Project Structure",
342
+ description:
343
+ "Analyze the project to detect framework (React/Next.js/NestJS), find log files, and list configuration files.",
344
+ inputSchema: {},
345
+ },
346
+ async () => ({
347
+ content: [
348
+ {
349
+ type: "text" as const,
350
+ text: JSON.stringify(
351
+ await this.collector.scanProjectStructure(),
352
+ null,
353
+ 2,
354
+ ),
355
+ },
356
+ ],
357
+ }),
358
+ );
359
+ }
281
360
 
282
- private registerCollectLogs(): void {
283
- this.server.registerTool(
284
- "collect_from_files",
285
- {
286
- title: "Collect Logs from Files",
287
- description: "Scan and collect logs from log files in the project directory. Automatically discovers .log and .json files in common log directories.",
288
- inputSchema: {},
289
- },
290
- async () => {
291
- await this.collector.collectFromFiles();
292
- const stats = this.collector.getStats();
293
- return {
294
- content: [{
295
- type: "text" as const,
296
- text: JSON.stringify({ message: "Log collection complete", stats }),
297
- }],
298
- };
299
- }
300
- );
301
- }
361
+ private registerFindProcesses(): void {
362
+ this.server.registerTool(
363
+ "find_processes",
364
+ {
365
+ title: "Find Running Node Processes",
366
+ description:
367
+ "Find running Node.js processes related to React, Next.js, or NestJS applications.",
368
+ inputSchema: {},
369
+ },
370
+ async () => ({
371
+ content: [
372
+ {
373
+ type: "text" as const,
374
+ text: JSON.stringify(
375
+ await this.inspector.findRunningProcesses(),
376
+ null,
377
+ 2,
378
+ ),
379
+ },
380
+ ],
381
+ }),
382
+ );
383
+ }
302
384
 
303
- private registerScanProject(): void {
304
- this.server.registerTool(
305
- "scan_project",
306
- {
307
- title: "Scan Project Structure",
308
- description: "Analyze the project to detect framework (React/Next.js/NestJS), find log files, and list configuration files.",
309
- inputSchema: {},
310
- },
311
- async () => {
312
- const structure = await this.collector.scanProjectStructure();
313
- return {
314
- content: [{
315
- type: "text" as const,
316
- text: JSON.stringify(structure, null, 2),
317
- }],
318
- };
319
- }
320
- );
321
- }
385
+ private registerGetPorts(): void {
386
+ this.server.registerTool(
387
+ "get_listening_ports",
388
+ {
389
+ title: "Get Listening Ports",
390
+ description:
391
+ "List all TCP ports currently being listened on by Node.js processes.",
392
+ inputSchema: {},
393
+ },
394
+ async () => ({
395
+ content: [
396
+ {
397
+ type: "text" as const,
398
+ text: JSON.stringify(
399
+ await this.inspector.getPortListeners(),
400
+ null,
401
+ 2,
402
+ ),
403
+ },
404
+ ],
405
+ }),
406
+ );
407
+ }
322
408
 
323
- private registerFindProcesses(): void {
324
- this.server.registerTool(
325
- "find_processes",
326
- {
327
- title: "Find Running Node Processes",
328
- description: "Find running Node.js processes related to React, Next.js, or NestJS applications.",
329
- inputSchema: {},
330
- },
331
- async () => {
332
- const processes = await this.inspector.findRunningProcesses();
333
- return {
334
- content: [{
335
- type: "text" as const,
336
- text: JSON.stringify(processes, null, 2),
337
- }],
338
- };
339
- }
340
- );
341
- }
409
+ async start(): Promise<void> {
410
+ try {
411
+ this.agentBridge.connect();
412
+ const transport = new StdioServerTransport();
413
+ await this.server.connect(transport);
414
+ console.error("Runtime Lens MCP Server started successfully");
415
+ } catch (error) {
416
+ console.error(
417
+ "Failed to start Runtime Lens MCP Server:",
418
+ error instanceof Error ? error.message : error,
419
+ );
420
+ process.exit(1);
421
+ }
422
+ }
342
423
 
343
- private registerGetPorts(): void {
344
- this.server.registerTool(
345
- "get_listening_ports",
346
- {
347
- title: "Get Listening Ports",
348
- description: "List all TCP ports currently being listened on by Node.js processes.",
349
- inputSchema: {},
350
- },
351
- async () => {
352
- const ports = await this.inspector.getPortListeners();
353
- return {
354
- content: [{
355
- type: "text" as const,
356
- text: JSON.stringify(ports, null, 2),
357
- }],
358
- };
359
- }
360
- );
361
- }
362
-
363
- async start(): Promise<void> {
364
- try {
365
- const transport = new StdioServerTransport();
366
- await this.server.connect(transport);
367
- console.error("Runtime Lens MCP Server started successfully");
368
- } catch (error) {
369
- console.error(
370
- "Failed to start Runtime Lens MCP Server:",
371
- error instanceof Error ? error.message : error
372
- );
373
- process.exit(1);
374
- }
375
- }
376
-
377
- setupGracefulShutdown(): void {
378
- const shutdown = async (signal: string): Promise<void> => {
379
- console.error(`Received ${signal}, shutting down gracefully...`);
380
- this.interceptor.stopIntercepting();
381
- process.exit(0);
382
- };
383
-
384
- process.on("SIGINT", () => shutdown("SIGINT"));
385
- process.on("SIGTERM", () => shutdown("SIGTERM"));
386
- }
424
+ setupGracefulShutdown(): void {
425
+ const shutdown = async (signal: string): Promise<void> => {
426
+ console.error(`Received ${signal}, shutting down gracefully...`);
427
+ this.agentBridge.disconnect();
428
+ this.interceptor.stopIntercepting();
429
+ process.exit(0);
430
+ };
431
+ process.on("SIGINT", () => shutdown("SIGINT"));
432
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
433
+ }
387
434
  }