Skip to content

Commit afc5e7b

Browse files
committed
fix: prevent duplicate MCP server instances on refresh/restart
- Added proper cleanup in restartConnection to ensure old instances are fully closed - Added safeguards in connectToServer to check for existing connections - Improved deleteConnection to handle null checks for transport and client - Added delays to ensure cleanup completes before creating new connections This fixes the issue where refreshing MCP servers or clicking the refresh button on individual servers was causing new instances to start without closing old ones.
1 parent 3ee6072 commit afc5e7b

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

src/services/mcp/McpHub.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -618,8 +618,14 @@ export class McpHub {
618618
config: z.infer<typeof ServerConfigSchema>,
619619
source: "global" | "project" = "global",
620620
): Promise<void> {
621-
// Remove existing connection if it exists with the same source
622-
await this.deleteConnection(name, source)
621+
// Check if a connection already exists with the same name and source
622+
const existingConnection = this.findConnection(name, source)
623+
if (existingConnection) {
624+
// Ensure complete cleanup of existing connection
625+
await this.deleteConnection(name, source)
626+
// Wait a moment to ensure cleanup is complete
627+
await delay(100)
628+
}
623629

624630
// Check if MCP is globally enabled
625631
const mcpEnabled = await this.isMcpEnabled()
@@ -1007,8 +1013,14 @@ export class McpHub {
10071013
for (const connection of connections) {
10081014
try {
10091015
if (connection.type === "connected") {
1010-
await connection.transport.close()
1011-
await connection.client.close()
1016+
// Close transport first
1017+
if (connection.transport) {
1018+
await connection.transport.close()
1019+
}
1020+
// Then close client
1021+
if (connection.client) {
1022+
await connection.client.close()
1023+
}
10121024
}
10131025
} catch (error) {
10141026
console.error(`Failed to close transport for ${name}:`, error)
@@ -1186,17 +1198,25 @@ export class McpHub {
11861198
connection.server.status = "connecting"
11871199
connection.server.error = ""
11881200
await this.notifyWebviewOfServerChanges()
1189-
await delay(500) // artificial delay to show user that server is restarting
1201+
11901202
try {
1191-
await this.deleteConnection(serverName, connection.server.source)
1203+
// Store the source before deleting
1204+
const serverSource = connection.server.source || "global"
1205+
1206+
// Ensure complete cleanup of the old connection
1207+
await this.deleteConnection(serverName, serverSource)
1208+
1209+
// Wait a bit to ensure cleanup is complete
1210+
await delay(500)
1211+
11921212
// Parse the config to validate it
11931213
const parsedConfig = JSON.parse(config)
11941214
try {
11951215
// Validate the config
11961216
const validatedConfig = this.validateServerConfig(parsedConfig, serverName)
11971217

11981218
// Try to connect again using validated config
1199-
await this.connectToServer(serverName, validatedConfig, connection.server.source || "global")
1219+
await this.connectToServer(serverName, validatedConfig, serverSource)
12001220
vscode.window.showInformationMessage(t("mcp:info.server_connected", { serverName }))
12011221
} catch (validationError) {
12021222
this.showErrorMessage(`Invalid configuration for MCP server "${serverName}"`, validationError)

0 commit comments

Comments
 (0)