diff --git a/package-lock.json b/package-lock.json index 9f5e78594c..64b7639e32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20186,9 +20186,9 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.12.3.tgz", - "integrity": "sha512-DyVYSOafBvk3/j1Oka4z5BWT8o4AFmoNyZY9pALOm7Lh3GZglR71Co4r4dEUoqDWdDazIZQHBe7J2Nwkg6gHgQ==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.13.3.tgz", + "integrity": "sha512-bGwA78F/U5G2jrnsdRkPY3IwIwZeWUEfb5o764b79lb0rJmMT76TLwKhdNZOWakOQtedYefwIR4emisEMvInKA==", "license": "MIT", "peer": true, "dependencies": { @@ -20197,6 +20197,7 @@ "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^5.0.0", @@ -46495,7 +46496,7 @@ "peerDependencies": { "@librechat/agents": "^2.4.51", "@librechat/data-schemas": "*", - "@modelcontextprotocol/sdk": "^1.12.3", + "@modelcontextprotocol/sdk": "^1.13.3", "axios": "^1.8.2", "diff": "^7.0.0", "eventsource": "^3.0.2", diff --git a/packages/api/package.json b/packages/api/package.json index 00695e5a3b..9dd34aee83 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -71,7 +71,7 @@ "peerDependencies": { "@librechat/agents": "^2.4.51", "@librechat/data-schemas": "*", - "@modelcontextprotocol/sdk": "^1.12.3", + "@modelcontextprotocol/sdk": "^1.13.3", "axios": "^1.8.2", "diff": "^7.0.0", "eventsource": "^3.0.2", diff --git a/packages/api/src/mcp/connection.ts b/packages/api/src/mcp/connection.ts index 38ca2b23d6..e46d59a3e2 100644 --- a/packages/api/src/mcp/connection.ts +++ b/packages/api/src/mcp/connection.ts @@ -59,9 +59,6 @@ export class MCPConnection extends EventEmitter { private transport: Transport | null = null; // Make this nullable private connectionState: t.ConnectionState = 'disconnected'; private connectPromise: Promise | null = null; - private lastError: Error | null = null; - private lastConfigUpdate = 0; - private readonly CONFIG_TTL = 5 * 60 * 1000; // 5 minutes private readonly MAX_RECONNECT_ATTEMPTS = 3; public readonly serverName: string; private shouldStopReconnecting = false; @@ -135,7 +132,6 @@ export class MCPConnection extends EventEmitter { private emitError(error: unknown, errorContext: string): void { const errorMessage = error instanceof Error ? error.message : String(error); logger.error(`${this.getLogPrefix()} ${errorContext}: ${errorMessage}`); - this.emit('error', new Error(`${errorContext}: ${errorMessage}`)); } private constructTransport(options: t.MCPOptions): Transport { @@ -359,16 +355,10 @@ export class MCPConnection extends EventEmitter { private subscribeToResources(): void { this.client.setNotificationHandler(ResourceListChangedNotificationSchema, async () => { - this.invalidateCache(); this.emit('resourcesChanged'); }); } - private invalidateCache(): void { - // this.cachedConfig = null; - this.lastConfigUpdate = 0; - } - async connectClient(): Promise { if (this.connectionState === 'connected') { return; @@ -527,7 +517,7 @@ export class MCPConnection extends EventEmitter { try { await this.disconnect(); await this.connectClient(); - if (!this.isConnected()) { + if (!(await this.isConnected())) { throw new Error('Connection not established'); } } catch (error) { @@ -564,11 +554,7 @@ export class MCPConnection extends EventEmitter { } this.connectionState = 'disconnected'; this.emit('connectionChange', 'disconnected'); - } catch (error) { - this.emit('error', error); - throw error; } finally { - this.invalidateCache(); this.connectPromise = null; } } @@ -603,79 +589,6 @@ export class MCPConnection extends EventEmitter { } } - // public async modifyConfig(config: ContinueConfig): Promise { - // try { - // // Check cache - // if (this.cachedConfig && Date.now() - this.lastConfigUpdate < this.CONFIG_TTL) { - // return this.cachedConfig; - // } - - // await this.connectClient(); - - // // Fetch and process resources - // const resources = await this.fetchResources(); - // const submenuItems = resources.map(resource => ({ - // title: resource.name, - // description: resource.description, - // id: resource.uri, - // })); - - // if (!config.contextProviders) { - // config.contextProviders = []; - // } - - // config.contextProviders.push( - // new MCPContextProvider({ - // submenuItems, - // client: this.client, - // }), - // ); - - // // Fetch and process tools - // const tools = await this.fetchTools(); - // const continueTools: Tool[] = tools.map(tool => ({ - // displayTitle: tool.name, - // function: { - // description: tool.description, - // name: tool.name, - // parameters: tool.inputSchema, - // }, - // readonly: false, - // type: 'function', - // wouldLikeTo: `use the ${tool.name} tool`, - // uri: `mcp://${tool.name}`, - // })); - - // config.tools = [...(config.tools || []), ...continueTools]; - - // // Fetch and process prompts - // const prompts = await this.fetchPrompts(); - // if (!config.slashCommands) { - // config.slashCommands = []; - // } - - // const slashCommands: SlashCommand[] = prompts.map(prompt => - // constructMcpSlashCommand( - // this.client, - // prompt.name, - // prompt.description, - // prompt.arguments?.map(a => a.name), - // ), - // ); - // config.slashCommands.push(...slashCommands); - - // // Update cache - // this.cachedConfig = config; - // this.lastConfigUpdate = Date.now(); - - // return config; - // } catch (error) { - // this.emit('error', error); - // // Return original config if modification fails - // return config; - // } - // } - public async isConnected(): Promise { try { await this.client.ping();