@agenite/mcp
Version:
A MCP implementation for Agenite
150 lines (147 loc) • 4.59 kB
JavaScript
;
var index_js = require('@modelcontextprotocol/sdk/client/index.js');
var stdio_js = require('@modelcontextprotocol/sdk/client/stdio.js');
var sse_js = require('@modelcontextprotocol/sdk/client/sse.js');
var tool = require('@agenite/tool');
// src/mcp.ts
var MCPClient = class {
constructor(config) {
this.config = config;
this.clientConfig = {
name: this.config.name || "mcp-client",
version: this.config.version || "1.0.0"
};
Object.entries(this.config.mcpServers).forEach(([name, serverConfig]) => {
this.clients.set(name, {
client: new index_js.Client(this.clientConfig),
connected: false,
serverConfig
});
});
}
clients = /* @__PURE__ */ new Map();
clientConfig;
/**
* Connect to a specific MCP server
* @private
*/
async connect(serverName) {
const serverClient = this.clients.get(serverName);
if (!serverClient) {
throw new Error(`Server ${serverName} not found in configuration`);
}
if (serverClient.connected) return;
const { serverConfig } = serverClient;
let transport;
if ("url" in serverConfig) {
if (!serverConfig.url) {
throw new Error("URL is required for SSE transport");
}
transport = new sse_js.SSEClientTransport(new URL(serverConfig.url));
} else if ("command" in serverConfig) {
if (!serverConfig.command || !serverConfig.args) {
throw new Error("Command and args are required for stdio transport");
}
transport = new stdio_js.StdioClientTransport({
command: serverConfig.command,
args: serverConfig.args,
env: serverConfig.env
});
}
if (!transport) {
throw new Error("Transport is required");
}
await serverClient.client.connect(transport);
serverClient.connected = true;
}
/**
* Connect to all configured MCP servers
* @private
*/
async connectAll() {
const serverNames = Array.from(this.clients.keys());
await Promise.all(serverNames.map((name) => this.connect(name)));
}
/**
* Get available tools from a specific MCP server
*/
async getTools(serverName) {
const serverClient = this.clients.get(serverName);
if (!serverClient) {
throw new Error(`Server ${serverName} not found in configuration`);
}
if (!serverClient.connected) {
await this.connect(serverName);
}
const toolList = await serverClient.client.listTools();
return toolList.tools.map((toolSchema) => {
return new tool.Tool({
name: `${serverName}.${toolSchema.name}`,
description: toolSchema.description || "",
inputSchema: toolSchema.inputSchema,
execute: async ({ input }) => {
const result = await this.callTool(
serverName,
toolSchema.name,
input
);
return result;
}
});
});
}
/**
* Get available tools from all connected MCP servers as a flat array
* This is the preferred method for integration with Agent
*/
async getAllTools() {
await this.connectAll();
const serverNames = Array.from(this.clients.keys());
const toolPromises = serverNames.map((name) => this.getTools(name));
const results = await Promise.all(toolPromises);
return results.flat();
}
/**
* Get available tools from all connected MCP servers organized by server
*/
async getAllToolsByServer() {
await this.connectAll();
const serverNames = Array.from(this.clients.keys());
const toolsPromises = serverNames.map(async (name) => {
const tools = await this.getTools(name);
return [name, tools];
});
const results = await Promise.all(toolsPromises);
return Object.fromEntries(results);
}
/**
* Call a tool on a specific MCP server
* @private This is internally used by the Tool execute functions
*/
async callTool(serverName, toolName, input) {
const serverClient = this.clients.get(serverName);
if (!serverClient) {
throw new Error(`Server ${serverName} not found in configuration`);
}
if (!serverClient.connected) {
await this.connect(serverName);
}
const result = await serverClient.client.callTool({
name: toolName,
arguments: input
});
return {
isError: !!result.isError,
data: result.content
};
}
/**
* Get configured server names
*/
getServerNames() {
return Array.from(this.clients.keys());
}
};
exports.MCPClient = MCPClient;
//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map