Skip to content

Commit 4d5b0d8

Browse files
committed
fix(mcp): properly terminate stdio processes when refreshing MCP servers
- Enhanced deleteConnection to properly terminate stdio processes (Docker containers) - Added process termination logic with SIGTERM followed by SIGKILL if needed - Added delays after cleanup to ensure processes are fully terminated - Fixes issue where refreshing MCP servers was creating duplicate instances This ensures that Docker-based MCP servers like Tavily are properly cleaned up when using the refresh button, preventing multiple instances from running.
1 parent 3ee6072 commit 4d5b0d8

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

src/services/mcp/McpHub.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,8 +1007,28 @@ export class McpHub {
10071007
for (const connection of connections) {
10081008
try {
10091009
if (connection.type === "connected") {
1010-
await connection.transport.close()
1010+
// First close the client to stop any ongoing operations
10111011
await connection.client.close()
1012+
1013+
// For stdio transports, we need to ensure the process is terminated
1014+
if (connection.transport && "proc" in connection.transport) {
1015+
const proc = (connection.transport as any).proc
1016+
if (proc && !proc.killed) {
1017+
// Try to gracefully terminate the process first
1018+
proc.kill("SIGTERM")
1019+
1020+
// Give it a moment to terminate gracefully
1021+
await new Promise((resolve) => setTimeout(resolve, 100))
1022+
1023+
// If still not killed, force kill it
1024+
if (!proc.killed) {
1025+
proc.kill("SIGKILL")
1026+
}
1027+
}
1028+
}
1029+
1030+
// Now close the transport
1031+
await connection.transport.close()
10121032
}
10131033
} catch (error) {
10141034
console.error(`Failed to close transport for ${name}:`, error)
@@ -1188,7 +1208,12 @@ export class McpHub {
11881208
await this.notifyWebviewOfServerChanges()
11891209
await delay(500) // artificial delay to show user that server is restarting
11901210
try {
1211+
// Ensure complete cleanup before reconnecting
11911212
await this.deleteConnection(serverName, connection.server.source)
1213+
1214+
// Add a small delay to ensure the process is fully terminated
1215+
await delay(200)
1216+
11921217
// Parse the config to validate it
11931218
const parsedConfig = JSON.parse(config)
11941219
try {
@@ -1265,6 +1290,9 @@ export class McpHub {
12651290
await this.deleteConnection(conn.server.name, conn.server.source)
12661291
}
12671292

1293+
// Add a delay to ensure all processes are fully terminated
1294+
await delay(300)
1295+
12681296
// Re-initialize all servers from scratch
12691297
// This ensures proper initialization including fetching tools, resources, etc.
12701298
await this.initializeMcpServers("global")

0 commit comments

Comments
 (0)