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:
@@ -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<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
|
||||
*/
|
||||
|
||||
@@ -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<string, { connected: boolean }> = {}
|
||||
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")
|
||||
|
||||
@@ -163,12 +163,24 @@ const McpManager: Component<McpManagerProps> = (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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user