fix: MCP connection - Added explicit connectAll() method with timeout - Updated mcp-connect endpoint to use connectAll - Enhanced UI feedback for connection errors

This commit is contained in:
Gemini AI
2025-12-26 11:05:11 +04:00
Unverified
parent c6152cb3ea
commit 4aa4795d4b
3 changed files with 53 additions and 5 deletions

View File

@@ -465,6 +465,33 @@ export class McpManager {
return texts.join("\n") || (result.isError ? "Tool execution failed" : "Tool executed successfully") return texts.join("\n") || (result.isError ? "Tool execution failed" : "Tool executed successfully")
} }
/**
* Connect all configured servers
*/
async connectAll(): Promise<Record<string, { connected: boolean; error?: string }>> {
const results: Record<string, { connected: boolean; error?: string }> = {}
for (const [name, client] of this.clients) {
try {
// Add timeout for connection
const connectPromise = client.connect()
const timeoutPromise = new Promise<never>((_, 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 * Disconnect all servers
*/ */

View File

@@ -313,17 +313,26 @@ export function registerWorkspaceRoutes(app: FastifyInstance, deps: RouteDeps) {
const { getMcpManager } = await import("../../mcp/client") const { getMcpManager } = await import("../../mcp/client")
const mcpManager = getMcpManager() const mcpManager = getMcpManager()
// Load and connect to all configured MCPs // Load config first
await mcpManager.loadConfig(workspace.path) 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 tools = await mcpManager.getAllTools()
const status = mcpManager.getStatus()
// Transform connection results to status format
const status: Record<string, { connected: boolean }> = {}
for (const [name, result] of Object.entries(connectionResults)) {
status[name] = { connected: result.connected }
}
return { return {
success: true, success: true,
servers: status, servers: status,
toolCount: tools.length toolCount: tools.length,
connectionDetails: connectionResults
} }
} catch (error) { } catch (error) {
request.log.error({ err: error }, "Failed to connect MCPs") request.log.error({ err: error }, "Failed to connect MCPs")

View File

@@ -163,12 +163,24 @@ const McpManager: Component<McpManagerProps> = (props) => {
setConnecting(true) setConnecting(true)
setError(null) setError(null)
try { try {
log.info("Connecting to all MCP servers...")
const result = await serverApi.connectWorkspaceMcps(props.instanceId) const result = await serverApi.connectWorkspaceMcps(props.instanceId)
log.info("MCP connection result:", result)
setConnectionStatus(result.servers ?? {}) setConnectionStatus(result.servers ?? {})
setToolCount(result.toolCount ?? 0) 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) { } catch (err) {
log.error("Failed to connect MCPs", 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 { } finally {
setConnecting(false) setConnecting(false)
} }