UNPKG

@openai/agents-core

Version:

The OpenAI Agents SDK is a lightweight yet powerful framework for building multi-agent workflows.

201 lines (200 loc) 7.78 kB
import { BaseMCPServerStdio, BaseMCPServerStreamableHttp, invalidateServerToolsCache, } from "../../mcp.mjs"; import logger from "../../logger.mjs"; function failedToImport(error) { logger.error(` Failed to load the MCP SDK. Please install the @modelcontextprotocol/sdk package. npm install @modelcontextprotocol/sdk `.trim()); throw error; } export class NodeMCPServerStdio extends BaseMCPServerStdio { session = null; _cacheDirty = true; _toolsList = []; serverInitializeResult = null; clientSessionTimeoutSeconds; params; _name; transport = null; constructor(params) { super(params); this.clientSessionTimeoutSeconds = params.clientSessionTimeoutSeconds ?? 5; if ('fullCommand' in params) { const elements = params.fullCommand.split(' '); const command = elements.shift(); if (!command) { throw new Error('Invalid fullCommand: ' + params.fullCommand); } this.params = { ...params, command: command, args: elements, encoding: params.encoding || 'utf-8', encodingErrorHandler: params.encodingErrorHandler || 'strict', }; } else { this.params = params; } this._name = params.name || `stdio: ${this.params.command}`; } async connect() { try { const { StdioClientTransport } = await import('@modelcontextprotocol/sdk/client/stdio.js').catch(failedToImport); const { Client } = await import('@modelcontextprotocol/sdk/client/index.js').catch(failedToImport); this.transport = new StdioClientTransport({ command: this.params.command, args: this.params.args, env: this.params.env, cwd: this.params.cwd, }); this.session = new Client({ name: this._name, version: '1.0.0', // You may want to make this configurable }); await this.session.connect(this.transport); this.serverInitializeResult = { serverInfo: { name: this._name, version: '1.0.0' }, }; } catch (e) { this.logger.error('Error initializing MCP server:', e); await this.close(); throw e; } this.debugLog(() => `Connected to MCP server: ${this._name}`); } async invalidateToolsCache() { await invalidateServerToolsCache(this.name); this._cacheDirty = true; } async listTools() { const { ListToolsResultSchema } = await import('@modelcontextprotocol/sdk/types.js').catch(failedToImport); if (!this.session) { throw new Error('Server not initialized. Make sure you call connect() first.'); } if (this.cacheToolsList && !this._cacheDirty && this._toolsList) { return this._toolsList; } this._cacheDirty = false; const response = await this.session.listTools(); this.debugLog(() => `Listed tools: ${JSON.stringify(response)}`); this._toolsList = ListToolsResultSchema.parse(response).tools; return this._toolsList; } async callTool(toolName, args) { const { CallToolResultSchema } = await import('@modelcontextprotocol/sdk/types.js').catch(failedToImport); if (!this.session) { throw new Error('Server not initialized. Make sure you call connect() first.'); } const response = await this.session.callTool({ name: toolName, arguments: args ?? {}, }); const parsed = CallToolResultSchema.parse(response); const result = parsed.content; this.debugLog(() => `Called tool ${toolName} (args: ${JSON.stringify(args)}, result: ${JSON.stringify(result)})`); return result; } get name() { return this._name; } async close() { if (this.transport) { await this.transport.close(); this.transport = null; } if (this.session) { await this.session.close(); this.session = null; } } } export class NodeMCPServerStreamableHttp extends BaseMCPServerStreamableHttp { session = null; _cacheDirty = true; _toolsList = []; serverInitializeResult = null; clientSessionTimeoutSeconds; params; _name; transport = null; constructor(params) { super(params); this.clientSessionTimeoutSeconds = params.clientSessionTimeoutSeconds ?? 5; this.params = params; this._name = params.name || `streamable-http: ${this.params.url}`; } async connect() { try { const { StreamableHTTPClientTransport } = await import('@modelcontextprotocol/sdk/client/streamableHttp.js').catch(failedToImport); const { Client } = await import('@modelcontextprotocol/sdk/client/index.js').catch(failedToImport); this.transport = new StreamableHTTPClientTransport(new URL(this.params.url), { authProvider: this.params.authProvider, requestInit: this.params.requestInit, reconnectionOptions: this.params.reconnectionOptions, sessionId: this.params.sessionId, }); this.session = new Client({ name: this._name, version: '1.0.0', // You may want to make this configurable }); await this.session.connect(this.transport); this.serverInitializeResult = { serverInfo: { name: this._name, version: '1.0.0' }, }; } catch (e) { this.logger.error('Error initializing MCP server:', e); await this.close(); throw e; } this.debugLog(() => `Connected to MCP server: ${this._name}`); } async invalidateToolsCache() { await invalidateServerToolsCache(this.name); this._cacheDirty = true; } async listTools() { const { ListToolsResultSchema } = await import('@modelcontextprotocol/sdk/types.js').catch(failedToImport); if (!this.session) { throw new Error('Server not initialized. Make sure you call connect() first.'); } if (this.cacheToolsList && !this._cacheDirty && this._toolsList) { return this._toolsList; } this._cacheDirty = false; const response = await this.session.listTools(); this.debugLog(() => `Listed tools: ${JSON.stringify(response)}`); this._toolsList = ListToolsResultSchema.parse(response).tools; return this._toolsList; } async callTool(toolName, args) { const { CallToolResultSchema } = await import('@modelcontextprotocol/sdk/types.js').catch(failedToImport); if (!this.session) { throw new Error('Server not initialized. Make sure you call connect() first.'); } const response = await this.session.callTool({ name: toolName, arguments: args ?? {}, }); const parsed = CallToolResultSchema.parse(response); const result = parsed.content; this.debugLog(() => `Called tool ${toolName} (args: ${JSON.stringify(args)}, result: ${JSON.stringify(result)})`); return result; } get name() { return this._name; } async close() { if (this.transport) { await this.transport.close(); this.transport = null; } if (this.session) { await this.session.close(); this.session = null; } } } //# sourceMappingURL=node.mjs.map