@l4t/mcp-ai
Version:
A set of tools for making integration and aggregation of MCP servers extremely easy.
191 lines • 6.6 kB
JavaScript
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