跳转到主要内容

MCP集成

AG-Kit的MCP集成提供了AG-Kit工具系统与模型上下文协议(MCP)之间的无缝双向转换能力,使您可以:
  • 连接标准MCP服务器并将其工具作为AG-Kit的BaseTool实例使用
  • 将AG-Kit工具暴露为MCP服务器供外部客户端调用
  • 支持多种传输协议包括stdio、HTTP、SSE、内存通信等

概述

MCP集成包含以下核心组件:
  • MCPClientTool:封装外部MCP工具以在AG-Kit中工作
  • MCPToolkit:管理MCP工具的高级工具包
  • AGKitMCPServer:将AG-Kit工具暴露为标准MCP服务器
  • MCPClientManager:管理多个MCP服务器的连接

快速入门

在AG-Kit中使用外部MCP工具

import { MCPClientManager, MCPClientTool } from '@ag-kit/tools/mcp';

// 创建客户端管理器
const clientManager = new MCPClientManager();

// 连接外部MCP服务器
await clientManager.addServer('math-server', {
  name: 'math-client',
  version: '1.0.0',
  transport: {
    type: 'stdio',
    command: 'python',
    args: ['-m', 'math_mcp_server']
  }
});

// 从MCP工具创建AG-Kit工具
const clientTools = clientManager.createClientTools('math-server');

// 在AG-Kit应用中使用这些工具
for (const tool of clientTools) {
  const result = await tool.invoke({ a: 5, b: 3 });
  console.log(result.data);
}

将AG-Kit工具暴露为MCP服务器

import { AGKitMCPServer } from '@ag-kit/tools/mcp';
import { MyCustomTool } from './my-tools';

// 创建您的AG-Kit工具
const calculatorTool = new MyCustomTool();

// 创建MCP服务器
const server = new AGKitMCPServer({
  name: 'ag-kit-mcp-server',
  version: '1.0.0',
  description: '通过MCP暴露的AG-Kit工具'
});

// 注册工具
server.registerTool(calculatorTool);

// 使用stdio传输启动服务器
await server.run({ type: 'stdio' });

传输协议

Stdio传输

MCP服务器最常用的传输方式,使用标准输入/输出。

服务器配置

// 使用stdio启动服务器
await server.run({ type: 'stdio' });

客户端配置

await clientManager.addServer('my-server', {
  name: 'my-client',
  version: '1.0.0',
  transport: {
    type: 'stdio',
    command: 'python',
    args: ['-m', 'my_mcp_server'],
    timeout: 10000
  }
});

HTTP传输(StreamableHTTP)

适用于基于Web的MCP服务器和客户端。

服务器配置

import express from 'express';

const app = express();

await server.run({
  type: 'streamableHttp',
  streamableHttpSetup: async (server, createTransport) => {
    app.post('/mcp', async (req, res) => {
      const transport = await createTransport({
        enableJsonResponse: true,
        sessionIdGenerator: () => crypto.randomUUID()
      });
      
      await transport.handleRequest(req, res, req.body);
    });
  }
});

app.listen(3000, () => {
  console.log('MCP服务器运行在 http://localhost:3000/mcp');
});

客户端配置

await clientManager.addServer('http-server', {
  name: 'http-client',
  version: '1.0.0',
  transport: {
    type: 'streamableHttp',
    url: 'http://localhost:3000/mcp',
    timeout: 15000
  }
});

SSE传输

服务器发送事件(Server-Sent Events)传输,用于实时通信。

服务器配置

import express from 'express';

const app = express();

await server.run({
  type: 'sse',
  sseSetup: async (server, createTransport) => {
    let transport
    app.get('/mcp/sse', async (req, res) => {
      transport = await createTransport('/mcp/sse', res, {
        enableDnsRebindingProtection: false
      });
    });

    // 处理认证的POST请求
    app.post('/mcp/sse', async (req, res) => {
      if (transport) {
        await transport.handlePostMessage(req, res, req.body);
      } else {
        res.status(404).json({ error: '无活跃的SSE连接' });
      }
    });
    app.listen(3000);
  }
});

客户端配置

await clientManager.addServer('sse-server', {
  name: 'sse-client',
  version: '1.0.0',
  transport: {
    type: 'sse',
    url: 'http://localhost:3000/mcp/sse'
  }
});

内存传输

用于测试和同进程通信。

服务器配置

const memoryId = 'my-memory-server';

await server.run({
  type: 'memory',
  memoryId
});

客户端配置

await clientManager.addServer('memory-server', {
  name: 'memory-client',
  version: '1.0.0',
  transport: {
    type: 'memory',
    memoryId: 'my-memory-server'
  }
});

核心示例

示例1:创建并运行MCP服务器

将AG-Kit工具暴露为标准MCP服务器:
import { AGKitMCPServer } from '@ag-kit/tools/mcp';
import { MyExistingTool } from './my-tools';

// 创建MCP服务器实例
const server = new AGKitMCPServer({
  name: 'my-agkit-server',
  version: '1.0.0',
  description: '通过MCP暴露的AG-Kit工具'
});

// 注册现有AG-Kit工具
const myTool = new MyExistingTool();
server.registerTool(myTool);

// 使用共享配置注册多个工具
server.registerTools([tool1, tool2, tool3], {
  namePrefix: 'agkit_'  // 所有工具名称将添加'agkit_'前缀
});

// 使用不同传输协议启动服务器
// 选项1:Stdio(最常用)
await server.run({ type: 'stdio' });

// 选项2:HTTP
await server.run({
  type: 'streamableHttp',
  streamableHttpSetup: async (server, createTransport) => {
    app.post('/mcp', async (req, res) => {
      const transport = await createTransport();
      await transport.handleRequest(req, res, req.body);
    });
  }
});

// 选项3:内存(用于测试)
await server.run({ 
  type: 'memory', 
  memoryId: 'test-server' 
});

示例2:连接外部MCP服务器

将外部MCP服务器作为AG-Kit工具使用:
import { MCPClientManager } from '@ag-kit/tools/mcp';

// 创建客户端管理器
const clientManager = new MCPClientManager();

// 连接不同类型的MCP服务器
// Stdio服务器
await clientManager.addServer('filesystem-server', {
  name: 'fs-client',
  version: '1.0.0',
  transport: {
    type: 'stdio',
    command: 'npx',
    args: ['@modelcontextprotocol/server-filesystem', './workspace']
  }
});

// HTTP服务器
await clientManager.addServer('api-server', {
  name: 'api-client',
  version: '1.0.0',
  transport: {
    type: 'streamableHttp',
    url: 'https://api.example.com/mcp'
  }
});

// 从MCP工具创建AG-Kit工具
const allClientTools = clientManager.createClientTools();

// 创建具有自定义名称的特定工具
const specificTool = clientManager.createClientTool(
  'filesystem-server',
  'read_file',
  'custom_file_reader'
);

// 在AG-Kit中使用这些工具
const result = await specificTool.invoke({ path: 'README.md' });
console.log(result.data);

示例3:使用MCPToolkit简化管理

使用高级工具包管理多个MCP连接:
import { MCPToolkit, createMCPToolkit } from '@ag-kit/tools/mcp';

// 方法1:动态创建工具包并添加服务器
const toolkit = new MCPToolkit('my-toolkit');

await toolkit.addServer('filesystem', {
  name: 'filesystem',
  version: '1.0.0',
  transport: { type: 'stdio', command: 'fs-server' }
});

await toolkit.addServer('database', {
  name: 'db-client',
  version: '1.0.0',
  transport: { type: 'streamableHttp', url: 'http://db-server/mcp' }
});

// 方法2:使用对象映射创建工具包(推荐)
// 匹配标准MCP配置格式(如Claude Desktop)
const toolkit2 = await createMCPToolkit({
  filesystem: {
    command: 'fs-server'  // 直接传输配置
  },
  database: {
    url: 'http://db
```typescript
// 测试工具执行
const tools = clientManager.createClientTools();
const testTool = tools[0];
const result = await testTool.invoke({ test: 'data' });

// 清理操作
await clientManager.disconnectAll();
await server.stop();

示例5:高级连接管理

处理连接选项和错误场景:
import { MCPClientManager } from '@ag-kit/tools/mcp';

const clientManager = new MCPClientManager();

// 添加带连接选项的服务器
await clientManager.addServer('reliable-server', {
  name: 'reliable-client',
  version: '1.0.0',
  transport: {
    type: 'stdio',
    command: 'external-server',
    timeout: 10000
  }
}, {
  autoReconnect: true,
  reconnectDelay: 5000,
  maxReconnectAttempts: 3,
  heartbeatInterval: 30000
});

// 处理预连接客户端
const preConnectedClient = new Client(/* ... */);
await preConnectedClient.connect(transport);

await clientManager.addServer('pre-connected', {
  name: 'pre-connected-client',
  version: '1.0.0',
  client: preConnectedClient,
  onReconnectNeeded: async (serverId, config) => {
    // 自定义重连逻辑
    const newClient = new Client(/* ... */);
    await newClient.connect(/* new transport */);
    return newClient;
  }
});

// 监控连接状态
setInterval(() => {
  const isConnected = clientManager.isServerConnected('reliable-server');
  console.log(`服务器连接状态: ${isConnected}`);
}, 5000);

示例6:事件处理与监控

通过事件监听器监控MCP操作:
import { AGKitMCPServer, MCPClientManager } from '@ag-kit/tools/mcp';

// 服务器事件监控
const server = new AGKitMCPServer({
  name: 'monitored-server',
  version: '1.0.0'
});

server.addEventListener((event) => {
  switch (event.type) {
    case 'connected':
      console.log(`客户端已连接: ${event.clientName}`);
      break;
    case 'tool_called':
      console.log(`工具 ${event.toolName} 被调用,参数:`, event.arguments);
      break;
    case 'tool_result':
      console.log(`工具 ${event.toolName} 返回结果:`, event.result);
      break;
    case 'error':
      console.error(`服务器错误发生在 ${event.context}:`, event.error);
      break;
  }
});

// 客户端事件监控
const clientManager = new MCPClientManager();

clientManager.addEventListener((event) => {
  switch (event.type) {
    case 'connected':
      console.log(`已连接到服务器: ${event.clientName}`);
      break;
    case 'tool_discovered':
      console.log(`发现工具: ${event.tool.name}`);
      break;
    case 'disconnected':
      console.log(`与服务器断开连接: ${event.clientName}`);
      if (event.reason) {
        console.log(`原因: ${event.reason}`);
      }
      break;
    case 'error':
      console.error(`客户端错误:`, event.error);
      break;
  }
});

高级配置

工具配置

自定义AG-Kit工具通过MCP的暴露方式:
// 注册带自定义配置的工具
server.registerTool(calculatorTool, {
  namePrefix: 'math_',           // 工具名前缀
  description: '自定义计算器'     // 覆盖描述
});

// 批量注册工具并共享配置
server.registerTools([tool1, tool2, tool3], {
  namePrefix: 'utils_'
});

客户端工具配置

自定义MCP客户端工具:
const clientTool = new MCPClientTool(
  mcpClient,
  toolMetadata,
  {
    name: 'custom_tool_name',     // 自定义AG-Kit名称
    timeout: 30000,               // 调用超时时间
    retries: 3                    // 重试次数
  },
  {
    includeMetadata: true,        // 包含执行元数据
    transformInput: (input) => {  // MCP调用前转换输入
      return { ...input, timestamp: Date.now() };
    },
    transformOutput: (output) => { // MCP调用后转换输出
      return { result: output, processed: true };
    },
    errorHandler: (error) => {    // 自定义错误处理
      return new ToolResult({
        success: false,
        error: `自定义错误: ${error.message}`
      });
    }
  }
);

连接管理

高级连接选项:
await clientManager.addServer('reliable-server', config, {
  autoReconnect: true,           // 失败时自动重连
  reconnectDelay: 5000,          // 重连间隔时间
  maxReconnectAttempts: 5,       // 最大重连尝试次数
  heartbeatInterval: 30000       // 心跳间隔
});

// 处理预连接客户端
const preConnectedClient = new Client(/* ... */);
await preConnectedClient.connect(transport);

await clientManager.addServer('pre-connected', {
  name: 'pre-connected-client',
  version: '1.0.0',
  client: preConnectedClient,
  onReconnectNeeded: async (serverId, config) => {
    // 处理预连接客户端的重连逻辑
    const newClient = new Client(/* ... */);
    await newClient.connect(/* new transport */);
    return newClient;
  }
});

事件处理

监控MCP操作:
// 服务器事件
server.addEventListener((event) => {
  switch (event.type) {
    case 'connected':
      console.log(`客户端已连接: ${event.clientName}`);
      break;
    case 'tool_called':
      console.log(`工具被调用: ${event.toolName}`, event.arguments);
      break;
    case 'tool_result':
      console.log(`工具返回结果: ${event.toolName}`, event.result);
      break;
    case 'error':
      console.error(`错误发生在 ${event.context}:`, event.error);
      break;
  }
});

// 客户端事件
clientManager.addEventListener((event) => {
  switch (event.type) {
    case 'connected':
      console.log(`已连接到服务器: ${event.clientName}`);
      break;
    case 'tool_discovered':
      console.log(`发现工具: ${event.tool.name}`);
      break;
    case 'disconnected':
      console.log(`与服务器断开连接: ${event.clientName}`);
      break;
  }
});

模式转换

AG-Kit自动在Zod模式与MCP JSON模式间转换:

Zod转MCP模式

import { z } from 'zod';
import { zodSchemaToMCPSchema } from '@ag-kit/tools/mcp';

const zodSchema = z.object({
  name: z.string().describe('用户名'),
  age: z.number().min(0).max(150),
  email: z.string().email().optional(),
  tags: z.array(z.string()),
  preferences: z.record(z.string(), z.any())
});

const mcpSchema = zodSchemaToMCPSchema(zodSchema);
// 生成MCP兼容的JSON模式

MCP转Zod模式

// MCPClientTool自动将MCP模式转换为Zod
const mcpToolMetadata = {
  name: 'user_tool',
  inputSchema: {
    type: 'object',
    properties: {
      name: { type: 'string' },
      age: { type: 'number' }
    },
    required: ['name', 'age']
  }
};

const clientTool = new MCPClientTool(client, mcpToolMetadata);
// 工具现在具有AG-Kit兼容的Zod模式

错误处理

服务器错误处理

const server = new AGKitMCPServer({
  name: 'error-handling-server',
  version: '1.0.0',
  errorHandling: 'return_error', // 或 'throw'
  transformOutput: (output) => {
    // 发送前转换输出
    return output;
  }
});

// 优雅处理工具错误
class SafeTool extends BaseTool {
  protected async _invoke(input: any): Promise<ToolResult> {
    try {
      // 工具逻辑
      return new ToolResult({ success: true, data: result });
    } catch (error) {
      return new ToolResult({
        success: false,
        error: `工具执行失败: ${error.message}`
      });
    }
  }
}

客户端错误处理

const clientTool = new MCPClientTool(
  client,
  metadata,
  { retries: 3, timeout: 10000 },
  {
    errorHandler: (error) => {
      // 自定义错误处理
      if (error.message.includes('timeout')) {
        return new ToolResult({
          success: false,
          error: '操作超时,请重试'
        });
      }
      
      return new ToolResult({
        success: false,
        error: `MCP工具错误: ${error.message}`
      });
    }
  }
);
      return new ToolResult({
        success: false,
        error: `MCP工具错误: ${error.message}`
      });
    }
  }
);

应用程序接口参考

完整应用程序接口文档包含所有接口、类型及详细方法签名,请参阅MCP应用程序接口参考 AGKitMCPServer - 将AG-Kit工具作为标准MCP服务器暴露
  • registerTool(tool: BaseTool, config?: MCPToolConfig): MCPToolMetadata - 注册单个工具
  • registerTools(tools: BaseTool[], config?: MCPToolConfig): MCPToolMetadata[] - 注册多个工具
  • unregisterTool(name: string): boolean - 从服务器移除工具
  • run(transportConfig: MCPTransportConfig): Promise<void> - 使用指定传输方式启动服务器
  • stop(): Promise<void> - 停止服务器并清理资源
  • callTool(name: string, args: Record<string, any>): Promise<CallToolResult> - 直接执行工具
  • listTools() - 获取所有已注册工具列表
  • isServerRunning(): boolean - 检查服务器是否运行中
  • getStats(): object - 获取服务器统计信息
MCPClientManager - 管理外部MCP服务器连接
  • addServer(serverId: string, config: MCPClientConfig, options?: MCPConnectionOptions): Promise<void> - 连接到MCP服务器
  • disconnectServer(serverId: string): Promise<void> - 断开特定服务器连接
  • disconnectAll(): Promise<void> - 断开所有服务器连接
  • createClientTools(serverId?: string): MCPClientTool[] - 创建AG-Kit工具包装器
  • createClientTool(serverId: string, toolName: string, agKitToolName?: string): MCPClientTool - 创建特定工具包装器
  • callTool(serverId: string, toolName: string, args: any): Promise<any> - 直接调用MCP工具
  • isServerConnected(serverId: string): boolean - 检查连接状态
  • getStats(): object - 获取客户端管理器统计信息
MCPClientTool - 封装外部MCP工具以实现AG-Kit兼容性
  • invoke(input: any, context?: ToolExecutionContext): Promise<ToolResult> - 执行MCP工具
  • getMCPMetadata(): MCPToolMetadata - 获取原始MCP工具元数据
  • isConnected(): boolean - 检查底层客户端是否连接
  • updateConfig(newConfig: Partial<MCPToolConfig>): void - 更新工具配置
MCPToolkit - 管理MCP工具的高级工具包
  • addServer(serverId: string, config: MCPClientConfig): Promise<void> - 添加MCP服务器
  • removeServer(serverId: string): Promise<void> - 移除服务器
  • getConnectedServers(): string[] - 获取已连接服务器列表
  • getServerTools(serverId: string): MCPClientTool[] - 获取特定服务器工具
  • refresh(): Promise<void> - 刷新所有连接
  • cleanup(): Promise<void> - 清理所有资源
  • getClientManager(): MCPClientManager - 获取底层客户端管理器
查看完整应用程序接口文档获取详细的接口定义、类型信息、实用函数和高级配置选项。

最佳实践

  1. 使用合适的传输方式:CLI工具使用stdio,Web服务使用HTTP,测试使用内存传输
  2. 优雅处理错误:实现适当的错误处理和重试逻辑
  3. 监控连接:使用事件监听器跟踪连接状态
  4. 清理资源:完成后始终调用清理方法
  5. 全面测试:使用内存传输进行综合测试
  6. 模式验证:确保Zod和MCP JSON Schema之间的模式兼容
  7. 连接管理:生产部署使用连接选项确保可靠性

故障排除

常见问题

  1. 连接超时:增加传输配置中的超时值
  2. 模式转换错误:确保Zod模式使用支持的类型
  3. 工具未找到:检查工具注册和命名
  4. 传输错误:验证传输配置和服务器可用性
  5. 内存泄漏:始终清理连接和事件监听器

调试模式

启用日志记录进行调试:
const server = new AGKitMCPServer({
  name: 'debug-server',
  version: '1.0.0',
  enableLogging: true // 启用调试日志
});
更多详细示例和高级使用模式,请参阅MCP应用程序接口参考部分。