UNPKG

@l4t/mcp-ai

Version:

A set of tools for making integration and aggregation of MCP servers extremely easy.

191 lines 6.6 kB
import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { asyncMap } from 'modern-async'; import { Provider, McpClientConfigs, } from '../common/types.js'; import { createTransport } from '../common/libs.js'; const DEFAULT_MAX_PARALLEL_CALLS = 10; const createExecuteToolCalls = (client, maxParallelCalls = DEFAULT_MAX_PARALLEL_CALLS) => async (calls) => asyncMap(calls, async (call) => { const result = await client .callTool({ id: call.id, name: call.name, // @ts-ignore I have absolutely seen the requirement to have this. arguments: call.input, input: call.input, }) .catch(e => { console.error(e); throw e; }); return { id: call.id, content: result.content, }; }, maxParallelCalls); const createSharedComponents = (config) => { const transport = createTransport(config.connection); const client = new Client(McpClientConfigs.integrator); const executeToolCalls = createExecuteToolCalls(client, config.maxParallelCalls || DEFAULT_MAX_PARALLEL_CALLS); return { transport, client, executeToolCalls }; }; const createOpenAIService = () => { const formatToolsForProvider = (tools) => tools.map(tool => ({ type: 'function', function: { name: tool.name, description: tool.description, properties: tool.inputSchema, }, })); const extractToolCalls = (response) => response.choices[0].message.tool_calls?.map(call => ({ id: call.id, name: call.function.name, input: JSON.parse(call.function.arguments), })) ?? []; const createToolResponseRequest = (originalRequest, response, results) => ({ ...originalRequest, messages: [ ...originalRequest.messages, response.choices[0].message, ...results.map(result => ({ role: 'tool', tool_call_id: result.id, content: typeof result.content === 'object' ? JSON.stringify(result.content) : typeof result.content === 'string' ? result.content : String(result.content), })), ], }); return { formatToolsForProvider, extractToolCalls, createToolResponseRequest, }; }; const createClaudeService = () => { const formatToolsForProvider = (tools) => tools.map(tool => ({ name: tool.name, description: tool.description, input_schema: tool.inputSchema, })); const extractToolCalls = (response) => response.content .filter((block) => block.type === 'tool_use') .map(block => ({ id: block.id, name: block.name, input: block.input, })); const createToolResponseRequest = (originalRequest, response, results) => ({ ...originalRequest, messages: [ ...originalRequest.messages, { role: 'assistant', content: response.content, }, ...results.map(result => ({ role: 'user', content: [ { type: 'tool_result', tool_use_id: result.id, content: typeof result.content === 'object' ? JSON.stringify(result.content) : typeof result.content === 'string' ? result.content : String(result.content), }, ], })), ], }); return { formatToolsForProvider, extractToolCalls, createToolResponseRequest, }; }; const createAwsBedrockClaudeService = () => { const formatToolsForProvider = (tools) => tools.map(tool => ({ name: tool.name, description: tool.description ?? '', input_schema: tool.inputSchema, })); const extractToolCalls = (response) => response.content .filter((block) => block.type === 'tool_use') .map(block => ({ id: block.id, name: block.name, input: block.input, })); const createToolResponseRequest = (originalRequest, response, results) => ({ ...originalRequest, messages: [ ...originalRequest.messages, { role: 'assistant', content: response.content, }, ...results.map(result => ({ role: 'user', content: [ { type: 'tool_result', tool_use_id: result.id, content: typeof result.content === 'object' ? JSON.stringify(result.content) : typeof result.content === 'string' ? result.content : String(result.content), }, ], })), ], }); return { formatToolsForProvider, extractToolCalls, createToolResponseRequest, }; }; const createIntegrationService = (provider) => { switch (provider) { case Provider.OpenAI: return createOpenAIService(); case Provider.Claude: return createClaudeService(); case Provider.AwsBedrockClaude: return createAwsBedrockClaudeService(); default: throw new Error(`Unknown provider: ${provider}`); } }; export const create = (config) => { const { client, executeToolCalls, transport } = createSharedComponents(config); const integrationService = createIntegrationService(config.provider); const getTools = async () => { const result = await client.listTools().catch(e => { console.error(e); throw e; }); return result.tools; }; const connect = async () => { await client.connect(transport).catch(e => { console.error(e); throw e; }); }; const disconnect = async () => client.close(); return { getTools, executeToolCalls, connect, disconnect, formatToolsForProvider: integrationService.formatToolsForProvider, extractToolCalls: integrationService.extractToolCalls, createToolResponseRequest: integrationService.createToolResponseRequest, }; }; //# sourceMappingURL=services.js.map