From ce1812b7c23ef8bcdf7c67920859e1cc6cf85655 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Tue, 18 Nov 2025 18:28:57 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Error=20Handling=20in=20M?= =?UTF-8?q?CP=20Tool=20List=20Controller=20(#10570)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🔧 fix: Handle errors when fetching server tools and log missing tools in MCP tools controller, to prevent all MCP tools from not getting listed * 🔧 fix: Remove trailing colons from error messages in MCPConnection class * chore: Update test command patterns in package.json for cache integration tests --- api/server/controllers/mcp.js | 8 +++++++- api/server/services/Config/mcp.js | 5 +++++ packages/api/package.json | 6 +++--- packages/api/src/mcp/connection.ts | 8 ++++---- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/api/server/controllers/mcp.js b/api/server/controllers/mcp.js index e113b01f17..5bc6f8f23c 100644 --- a/api/server/controllers/mcp.js +++ b/api/server/controllers/mcp.js @@ -44,7 +44,13 @@ const getMCPTools = async (req, res) => { continue; } - const serverTools = await mcpManager.getServerToolFunctions(userId, serverName); + let serverTools; + try { + serverTools = await mcpManager.getServerToolFunctions(userId, serverName); + } catch (error) { + logger.error(`[getMCPTools] Error fetching tools for server ${serverName}:`, error); + continue; + } if (!serverTools) { logger.debug(`[getMCPTools] No tools found for server ${serverName}`); continue; diff --git a/api/server/services/Config/mcp.js b/api/server/services/Config/mcp.js index 7f4210f8c9..15ea62a028 100644 --- a/api/server/services/Config/mcp.js +++ b/api/server/services/Config/mcp.js @@ -16,6 +16,11 @@ async function updateMCPServerTools({ userId, serverName, tools }) { const serverTools = {}; const mcpDelimiter = Constants.mcp_delimiter; + if (tools == null || tools.length === 0) { + logger.debug(`[MCP Cache] No tools to update for server ${serverName} (user: ${userId})`); + return serverTools; + } + for (const tool of tools) { const name = `${tool.name}${mcpDelimiter}${serverName}`; serverTools[name] = { diff --git a/packages/api/package.json b/packages/api/package.json index f079cccb87..600f88b088 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -20,9 +20,9 @@ "build:watch:prod": "rollup -c -w --bundleConfigAsCjs", "test": "jest --coverage --watch --testPathIgnorePatterns=\"\\.*integration\\.|\\.*helper\\.\"", "test:ci": "jest --coverage --ci --testPathIgnorePatterns=\"\\.*integration\\.|\\.*helper\\.\"", - "test:cache-integration:core": "jest --testPathPattern=\"src/cache/.*\\.cache_integration\\.spec\\.ts$\" --coverage=false", - "test:cache-integration:cluster": "jest --testPathPattern=\"src/cluster/.*\\.cache_integration\\.spec\\.ts$\" --coverage=false --runInBand", - "test:cache-integration:mcp": "jest --testPathPattern=\"src/mcp/.*\\.cache_integration\\.spec\\.ts$\" --coverage=false", + "test:cache-integration:core": "jest --testPathPatterns=\"src/cache/.*\\.cache_integration\\.spec\\.ts$\" --coverage=false", + "test:cache-integration:cluster": "jest --testPathPatterns=\"src/cluster/.*\\.cache_integration\\.spec\\.ts$\" --coverage=false --runInBand", + "test:cache-integration:mcp": "jest --testPathPatterns=\"src/mcp/.*\\.cache_integration\\.spec\\.ts$\" --coverage=false", "test:cache-integration": "npm run test:cache-integration:core && npm run test:cache-integration:cluster && npm run test:cache-integration:mcp", "verify": "npm run test:ci", "b:clean": "bun run rimraf dist", diff --git a/packages/api/src/mcp/connection.ts b/packages/api/src/mcp/connection.ts index 7e75acf751..c130b3a467 100644 --- a/packages/api/src/mcp/connection.ts +++ b/packages/api/src/mcp/connection.ts @@ -336,7 +336,7 @@ export class MCPConnection extends EventEmitter { } } } catch (error) { - this.emitError(error, 'Failed to construct transport:'); + this.emitError(error, 'Failed to construct transport'); throw error; } } @@ -631,7 +631,7 @@ export class MCPConnection extends EventEmitter { const { resources } = await this.client.listResources(); return resources; } catch (error) { - this.emitError(error, 'Failed to fetch resources:'); + this.emitError(error, 'Failed to fetch resources'); return []; } } @@ -641,7 +641,7 @@ export class MCPConnection extends EventEmitter { const { tools } = await this.client.listTools(); return tools; } catch (error) { - this.emitError(error, 'Failed to fetch tools:'); + this.emitError(error, 'Failed to fetch tools'); return []; } } @@ -651,7 +651,7 @@ export class MCPConnection extends EventEmitter { const { prompts } = await this.client.listPrompts(); return prompts; } catch (error) { - this.emitError(error, 'Failed to fetch prompts:'); + this.emitError(error, 'Failed to fetch prompts'); return []; } }