From 2801202b1707b128f06284cf3632d97de8222d5c Mon Sep 17 00:00:00 2001 From: sugarforever Date: Tue, 17 Dec 2024 21:18:53 +0000 Subject: [PATCH] fix: missing MCP servers config should not cause app failure --- server/api/models/chat/index.post.ts | 7 +++-- server/utils/mcp.ts | 43 ++++++++++++++++++---------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/server/api/models/chat/index.post.ts b/server/api/models/chat/index.post.ts index 1abdfda..31dba68 100644 --- a/server/api/models/chat/index.post.ts +++ b/server/api/models/chat/index.post.ts @@ -17,6 +17,7 @@ import { McpService } from '@/server/utils/mcp' import { zodToJsonSchema } from 'zod-to-json-schema' import { ChatOllama } from '@langchain/ollama' import { tool } from '@langchain/core/tools' +import { BaseChatModel } from '@langchain/core/language_models/chat_models' interface RequestBody { knowledgebaseId: number @@ -185,7 +186,7 @@ export default defineEventHandler(async (event) => { acc[tool.name] = tool return acc }, {}) - if (family === MODEL_FAMILIES.anthropic) { + if (family === MODEL_FAMILIES.anthropic && normalizedTools?.length) { /* if (family === MODEL_FAMILIES.gemini) { llm = llm.bindTools(normalizedTools.map((t) => { @@ -200,7 +201,9 @@ export default defineEventHandler(async (event) => { llm = llm.bindTools(normalizedTools) } */ - llm = llm.bindTools(normalizedTools) + if (llm?.bindTools) { + llm = llm.bindTools(normalizedTools) as BaseChatModel + } } else if (llm instanceof ChatOllama) { /* console.log("Binding tools to ChatOllama") diff --git a/server/utils/mcp.ts b/server/utils/mcp.ts index 3a14572..1ce82ed 100644 --- a/server/utils/mcp.ts +++ b/server/utils/mcp.ts @@ -4,7 +4,6 @@ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js" import { DynamicStructuredTool } from "@langchain/core/tools" import fs from 'fs' import path from 'path' -import zodToJsonSchema from 'zod-to-json-schema' interface McpServerConfig { command: string args: string[] @@ -24,24 +23,38 @@ export class McpService { } console.log("Loading MCP servers from ", mcpConfigPath) - const mcpConfig = JSON.parse(fs.readFileSync(mcpConfigPath, 'utf8')) + if (!fs.existsSync(mcpConfigPath)) { + return [] + } - const allTools: any[] = [] - for (const [serverName, serverConfig] of Object.entries(mcpConfig.mcpServers)) { - console.log("Server name: ", serverName) - console.log("Server config: ", serverConfig) + try { + const mcpConfig = JSON.parse(fs.readFileSync(mcpConfigPath, 'utf8')) as McpConfig - const transport = new StdioClientTransport({ - command: serverConfig.command, - args: serverConfig.args, - env: serverConfig.env - }) + const allTools: any[] = [] + for (const [serverName, serverConfig] of Object.entries(mcpConfig.mcpServers)) { + try { + console.log("Server name: ", serverName) + console.log("Server config: ", serverConfig) - const serverTools = await this.getToolsFromTransport(transport) - allTools.push(...serverTools) - } + const transport = new StdioClientTransport({ + command: serverConfig.command, + args: serverConfig.args, + env: serverConfig.env + }) - return allTools + const serverTools = await this.getToolsFromTransport(transport) + allTools.push(...serverTools) + } catch (error) { + console.error(`Failed to load tools from server ${serverName}:`, error) + // Continue with next server + } + } + + return allTools + } catch (error) { + console.error("Failed to parse MCP config file:", error) + return [] + } } private async getToolsFromTransport(transport: StdioClientTransport): Promise {