diff --git a/api/server/controllers/mcp.js b/api/server/controllers/mcp.js index a629dc9ce7..1afd7095a6 100644 --- a/api/server/controllers/mcp.js +++ b/api/server/controllers/mcp.js @@ -175,6 +175,12 @@ const createMCPServerController = async (req, res) => { }); } catch (error) { logger.error('[createMCPServer]', error); + if (error.message?.startsWith('MCP_INSPECTION_FAILED')) { + return res.status(400).json({ + error: 'MCP_INSPECTION_FAILED', + message: error.message, + }); + } res.status(500).json({ message: error.message }); } }; @@ -229,6 +235,12 @@ const updateMCPServerController = async (req, res) => { res.status(200).json(parsedConfig); } catch (error) { logger.error('[updateMCPServer]', error); + if (error.message?.startsWith('MCP_INSPECTION_FAILED:')) { + return res.status(400).json({ + error: 'MCP_INSPECTION_FAILED', + message: error.message, + }); + } res.status(500).json({ message: error.message }); } }; diff --git a/client/src/components/SidePanel/MCPBuilder/MCPServerDialog.tsx b/client/src/components/SidePanel/MCPBuilder/MCPServerDialog.tsx index e978ee7114..42514182c2 100644 --- a/client/src/components/SidePanel/MCPBuilder/MCPServerDialog.tsx +++ b/client/src/components/SidePanel/MCPBuilder/MCPServerDialog.tsx @@ -283,7 +283,9 @@ export default function MCPServerDialog({ if (error && typeof error === 'object' && 'response' in error) { const axiosError = error as any; - if (axiosError.response?.data?.error) { + if (axiosError.response?.data?.error === 'MCP_INSPECTION_FAILED') { + errorMessage = localize('com_ui_mcp_server_connection_failed'); + } else if (axiosError.response?.data?.error) { errorMessage = axiosError.response.data.error; } } else if (error.message) { diff --git a/client/src/locales/en/translation.json b/client/src/locales/en/translation.json index 4021e5437d..03133c7c47 100644 --- a/client/src/locales/en/translation.json +++ b/client/src/locales/en/translation.json @@ -633,6 +633,7 @@ "com_ui_add_first_mcp_server": "Create your first MCP server to get started", "com_ui_mcp_server_created": "MCP server created successfully", "com_ui_mcp_server_updated": "MCP server updated successfully", + "com_ui_mcp_server_connection_failed": "Connection attempt to the provided MCP server failed. Please make sure the URL, the server type, and any authentication configuration are correct, then try again. Also ensure the URL is reachable.", "com_ui_add_model_preset": "Add a model or preset for an additional response", "com_ui_add_multi_conversation": "Add multi-conversation", "com_ui_add_special_variables": "Add Special Variables", diff --git a/packages/api/src/mcp/registry/MCPServersRegistry.ts b/packages/api/src/mcp/registry/MCPServersRegistry.ts index cf44041f48..32c0c5b52c 100644 --- a/packages/api/src/mcp/registry/MCPServersRegistry.ts +++ b/packages/api/src/mcp/registry/MCPServersRegistry.ts @@ -78,7 +78,13 @@ export class MCPServersRegistry { userId?: string, ): Promise { const configRepo = this.getConfigRepository(storageLocation); - const parsedConfig = await MCPServerInspector.inspect(serverName, config); + let parsedConfig: t.ParsedServerConfig; + try { + parsedConfig = await MCPServerInspector.inspect(serverName, config); + } catch (error) { + logger.error(`[MCPServersRegistry] Failed to inspect server "${serverName}":`, error); + throw new Error(`MCP_INSPECTION_FAILED: Failed to connect to MCP server "${serverName}"`); + } return await configRepo.add(serverName, parsedConfig, userId); } @@ -89,7 +95,13 @@ export class MCPServersRegistry { userId?: string, ): Promise { const configRepo = this.getConfigRepository(storageLocation); - const parsedConfig = await MCPServerInspector.inspect(serverName, config); + let parsedConfig: t.ParsedServerConfig; + try { + parsedConfig = await MCPServerInspector.inspect(serverName, config); + } catch (error) { + logger.error(`[MCPServersRegistry] Failed to inspect server "${serverName}":`, error); + throw new Error(`MCP_INSPECTION_FAILED: Failed to connect to MCP server "${serverName}"`); + } await configRepo.update(serverName, parsedConfig, userId); return parsedConfig; }