Skip to content

Commit 779d2ba

Browse files
authored
fix: explicitly clear resources (#136)
1 parent c25ef30 commit 779d2ba

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

src/mcp/server.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
ListToolsRequestSchema,
1313
McpError,
1414
} from '@modelcontextprotocol/sdk/types.js';
15+
import type { ValidateFunction } from 'ajv';
1516
import { type ActorCallOptions, ApifyApiError } from 'apify-client';
1617

1718
import log from '@apify/log';
@@ -45,6 +46,7 @@ export class ActorsMcpServer {
4546
public readonly tools: Map<string, ToolEntry>;
4647
private options: ActorsMcpServerOptions;
4748
private toolsChangedHandler: ToolsChangedHandler | undefined;
49+
private sigintHandler: (() => Promise<void>) | undefined;
4850

4951
constructor(options: ActorsMcpServerOptions = {}, setupSigintHandler = true) {
5052
this.options = {
@@ -292,7 +294,6 @@ export class ActorsMcpServer {
292294
public upsertTools(tools: ToolEntry[], shouldNotifyToolsChangedHandler = false) {
293295
for (const wrap of tools) {
294296
this.tools.set(wrap.tool.name, wrap);
295-
log.info(`Added/updated tool: ${wrap.tool.name}`);
296297
}
297298
if (shouldNotifyToolsChangedHandler) this.notifyToolsChangedHandler();
298299
return tools;
@@ -319,12 +320,13 @@ export class ActorsMcpServer {
319320
this.server.onerror = (error) => {
320321
console.error('[MCP Error]', error); // eslint-disable-line no-console
321322
};
322-
// Allow disabling of the SIGINT handler to prevent max listeners warning
323323
if (setupSIGINTHandler) {
324-
process.on('SIGINT', async () => {
324+
const handler = async () => {
325325
await this.server.close();
326326
process.exit(0);
327-
});
327+
};
328+
process.once('SIGINT', handler);
329+
this.sigintHandler = handler; // Store the actual handler
328330
}
329331
}
330332

@@ -497,6 +499,23 @@ export class ActorsMcpServer {
497499
}
498500

499501
async close(): Promise<void> {
502+
// Remove SIGINT handler
503+
if (this.sigintHandler) {
504+
process.removeListener('SIGINT', this.sigintHandler);
505+
this.sigintHandler = undefined;
506+
}
507+
// Clear all tools and their compiled schemas
508+
for (const tool of this.tools.values()) {
509+
if (tool.tool.ajvValidate && typeof tool.tool.ajvValidate === 'function') {
510+
(tool.tool as { ajvValidate: ValidateFunction<unknown> | null }).ajvValidate = null;
511+
}
512+
}
513+
this.tools.clear();
514+
// Unregister tools changed handler
515+
if (this.toolsChangedHandler) {
516+
this.unregisterToolsChangedHandler();
517+
}
518+
// Close server (which should also remove its event handlers)
500519
await this.server.close();
501520
}
502521
}

0 commit comments

Comments
 (0)