diff --git a/packages/server/src/mcp/client.ts b/packages/server/src/mcp/client.ts index a68eefa..f5741dd 100644 --- a/packages/server/src/mcp/client.ts +++ b/packages/server/src/mcp/client.ts @@ -465,6 +465,33 @@ export class McpManager { return texts.join("\n") || (result.isError ? "Tool execution failed" : "Tool executed successfully") } + /** + * Connect all configured servers + */ + async connectAll(): Promise> { + const results: Record = {} + + for (const [name, client] of this.clients) { + try { + // Add timeout for connection + const connectPromise = client.connect() + const timeoutPromise = new Promise((_, reject) => + setTimeout(() => reject(new Error("Connection timeout")), 15000) + ) + + await Promise.race([connectPromise, timeoutPromise]) + results[name] = { connected: true } + log.info({ server: name }, "MCP server connected successfully") + } catch (error) { + const errorMsg = error instanceof Error ? error.message : String(error) + log.warn({ server: name, error: errorMsg }, "Failed to connect MCP server") + results[name] = { connected: false, error: errorMsg } + } + } + + return results + } + /** * Disconnect all servers */ diff --git a/packages/server/src/server/routes/workspaces.ts b/packages/server/src/server/routes/workspaces.ts index 0110c9b..aadfb20 100644 --- a/packages/server/src/server/routes/workspaces.ts +++ b/packages/server/src/server/routes/workspaces.ts @@ -313,17 +313,26 @@ export function registerWorkspaceRoutes(app: FastifyInstance, deps: RouteDeps) { const { getMcpManager } = await import("../../mcp/client") const mcpManager = getMcpManager() - // Load and connect to all configured MCPs + // Load config first await mcpManager.loadConfig(workspace.path) - // Get the tools to trigger connections + // Explicitly connect all servers + const connectionResults = await mcpManager.connectAll() + + // Get tools from connected servers const tools = await mcpManager.getAllTools() - const status = mcpManager.getStatus() + + // Transform connection results to status format + const status: Record = {} + for (const [name, result] of Object.entries(connectionResults)) { + status[name] = { connected: result.connected } + } return { success: true, servers: status, - toolCount: tools.length + toolCount: tools.length, + connectionDetails: connectionResults } } catch (error) { request.log.error({ err: error }, "Failed to connect MCPs") diff --git a/packages/ui/src/components/mcp-manager.tsx b/packages/ui/src/components/mcp-manager.tsx index 8737774..af0fd5c 100644 --- a/packages/ui/src/components/mcp-manager.tsx +++ b/packages/ui/src/components/mcp-manager.tsx @@ -163,12 +163,24 @@ const McpManager: Component = (props) => { setConnecting(true) setError(null) try { + log.info("Connecting to all MCP servers...") const result = await serverApi.connectWorkspaceMcps(props.instanceId) + log.info("MCP connection result:", result) setConnectionStatus(result.servers ?? {}) setToolCount(result.toolCount ?? 0) + + // Check for any connection errors + const connectionDetails = (result as any).connectionDetails ?? {} + const failedServers = Object.entries(connectionDetails) + .filter(([_, details]: [string, any]) => !details.connected) + .map(([name, details]: [string, any]) => `${name}: ${details.error || 'Unknown error'}`) + + if (failedServers.length > 0) { + setError(`Some servers failed to connect: ${failedServers.join(', ')}`) + } } catch (err) { log.error("Failed to connect MCPs", err) - setError("Failed to connect MCP servers.") + setError("Failed to connect MCP servers. Check console for details.") } finally { setConnecting(false) }