diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index 3d02ce25f19..ea38ee02d6d 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -161,14 +161,25 @@ export class McpHub { private isProgrammaticUpdate: boolean = false private flagResetTimer?: NodeJS.Timeout private sanitizedNameRegistry: Map = new Map() + private initializationPromise: Promise constructor(provider: ClineProvider) { this.providerRef = new WeakRef(provider) this.watchMcpSettingsFile() this.watchProjectMcpFile().catch(console.error) this.setupWorkspaceFoldersWatcher() - this.initializeGlobalMcpServers() - this.initializeProjectMcpServers() + this.initializationPromise = Promise.all([ + this.initializeGlobalMcpServers(), + this.initializeProjectMcpServers(), + ]).then(() => {}) + } + + /** + * Waits until all MCP servers have finished their initial connection attempts. + * Each server individually handles its own timeout, so this will not block indefinitely. + */ + async waitUntilReady(): Promise { + await this.initializationPromise } /** * Registers a client (e.g., ClineProvider) using this hub. diff --git a/src/services/mcp/McpServerManager.ts b/src/services/mcp/McpServerManager.ts index e15f9db0a7a..3fd7146d9f9 100644 --- a/src/services/mcp/McpServerManager.ts +++ b/src/services/mcp/McpServerManager.ts @@ -36,7 +36,10 @@ export class McpServerManager { try { // Double-check instance in case it was created while we were waiting if (!this.instance) { - this.instance = new McpHub(provider) + const hub = new McpHub(provider) + // Wait for all MCP servers to finish connecting (or timing out) + await hub.waitUntilReady() + this.instance = hub // Store a unique identifier in global state to track the primary instance await context.globalState.update(this.GLOBAL_STATE_KEY, Date.now().toString()) }