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")
|
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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user