🐛 fix: Error Handling in MCP Tool List Controller (#10570)
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run

* 🔧 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
This commit is contained in:
Danny Avila 2025-11-18 18:28:57 -05:00 committed by GitHub
parent 4a13867a47
commit ce1812b7c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 19 additions and 8 deletions

View file

@ -44,7 +44,13 @@ const getMCPTools = async (req, res) => {
continue; 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) { if (!serverTools) {
logger.debug(`[getMCPTools] No tools found for server ${serverName}`); logger.debug(`[getMCPTools] No tools found for server ${serverName}`);
continue; continue;

View file

@ -16,6 +16,11 @@ async function updateMCPServerTools({ userId, serverName, tools }) {
const serverTools = {}; const serverTools = {};
const mcpDelimiter = Constants.mcp_delimiter; 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) { for (const tool of tools) {
const name = `${tool.name}${mcpDelimiter}${serverName}`; const name = `${tool.name}${mcpDelimiter}${serverName}`;
serverTools[name] = { serverTools[name] = {

View file

@ -20,9 +20,9 @@
"build:watch:prod": "rollup -c -w --bundleConfigAsCjs", "build:watch:prod": "rollup -c -w --bundleConfigAsCjs",
"test": "jest --coverage --watch --testPathIgnorePatterns=\"\\.*integration\\.|\\.*helper\\.\"", "test": "jest --coverage --watch --testPathIgnorePatterns=\"\\.*integration\\.|\\.*helper\\.\"",
"test:ci": "jest --coverage --ci --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:core": "jest --testPathPatterns=\"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:cluster": "jest --testPathPatterns=\"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: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", "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", "verify": "npm run test:ci",
"b:clean": "bun run rimraf dist", "b:clean": "bun run rimraf dist",

View file

@ -336,7 +336,7 @@ export class MCPConnection extends EventEmitter {
} }
} }
} catch (error) { } catch (error) {
this.emitError(error, 'Failed to construct transport:'); this.emitError(error, 'Failed to construct transport');
throw error; throw error;
} }
} }
@ -631,7 +631,7 @@ export class MCPConnection extends EventEmitter {
const { resources } = await this.client.listResources(); const { resources } = await this.client.listResources();
return resources; return resources;
} catch (error) { } catch (error) {
this.emitError(error, 'Failed to fetch resources:'); this.emitError(error, 'Failed to fetch resources');
return []; return [];
} }
} }
@ -641,7 +641,7 @@ export class MCPConnection extends EventEmitter {
const { tools } = await this.client.listTools(); const { tools } = await this.client.listTools();
return tools; return tools;
} catch (error) { } catch (error) {
this.emitError(error, 'Failed to fetch tools:'); this.emitError(error, 'Failed to fetch tools');
return []; return [];
} }
} }
@ -651,7 +651,7 @@ export class MCPConnection extends EventEmitter {
const { prompts } = await this.client.listPrompts(); const { prompts } = await this.client.listPrompts();
return prompts; return prompts;
} catch (error) { } catch (error) {
this.emitError(error, 'Failed to fetch prompts:'); this.emitError(error, 'Failed to fetch prompts');
return []; return [];
} }
} }