MCP编排库

一个TypeScript库,用于通过AI代理编排多个MCP服务器,支持代码模式、工具调用和LLM采样等多种工作流执行方式。

  • by mrorigo
  • TypeScript
  • 本地部署
  • 3 星标
  • 更新于
在 GitHub 查看 mrorigo/mcp-orchestrator

使用说明

MCP编排器

用于编排的TypeScript库 模型上下文协议(MCP) 配备AI代理的服务器。

使用传统的工具调用、LLM采样或创新的 代码模式 它允许LLM为复杂的操作编写和执行TypeScript代码。

为什么选择MCP编排器?

代码模式优势

虽然传统的MCP使用通过“工具调用”令牌将工具直接暴露给LLM,但我们为复杂的工作流程提供了一种更好的方法:

传统工具调用:

  • ❌ 每次工具调用都需要完整的LLM往返
  • ❌ LLM仅接受过合成工具调用示例的培训
  • ❌ 中间结果浪费代币
  • ❌ 复杂的多步骤操作效率低下

代码模式:

  • ✅ LLM使用您的工具作为API编写TypeScript代码
  • ✅ 连锁多个操作,无需LLM往返
  • ✅ 多步骤任务的令牌减少60-75%
  • ✅ 生成的代码是可检查和可重用的

灵活的编排

为每项任务选择正确的方法:

  • 代码模式:复杂的工作流程、数据转换、多步骤操作
  • 工具调用:简单的单步操作
  • LLM采样:双层采样(编排器和子服务器)
  • 构图模式:顺序、并行、重试、有条件执行

🆕 v0.5.0中的新功能:A2A集成

原生代理到代理支持:将您精心策划的专家暴露为符合A2A标准的代理服务器。

  • 允许其他AI代理发现并与您的专家协作
  • 展示“代码模式”作为一种可训练的技能
  • 自动将任何MCP工具桥接到A2A协议
  • 完全支持任务生命周期、流式传输和取消

快速开始

import { MCPOrchestrator } from 'mcp-orchestrator';
import { OpenAIProvider } from 'mcp-orchestrator/llm';

const orchestrator = new MCPOrchestrator({
  servers: {
    filesystem: {
      command: 'npx',
      args: ['-y', '@modelcontextprotocol/server-filesystem', './']
    },
    github: {
      command: 'npx',
      args: ['-y', '@modelcontextprotocol/server-github']
    }
  },
  llm: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY })
});

await orchestrator.connect();

// Code Mode: Let LLM write and execute code
const result = await orchestrator.generateAndExecute(
  'Find all TypeScript files, count lines in each, and return the top 5 largest'
);

console.log(result.code);   // See generated code
console.log(result.result); // Get results

生成代码示例:

const files = await tools.list_directory({ path: './' });
const tsFiles = files.content.filter(f => f.name.endsWith('.ts'));

const fileSizes = [];
for (const file of tsFiles) {
  const content = await tools.read_file({ path: file.path });
  fileSizes.push({ name: file.name, lines: content.split('\n').length });
}

return fileSizes.sort((a, b) => b.lines - a.lines).slice(0, 5);

特性

编排能力

  • 🌐 多服务器管理:连接和协调多个MCP服务器(Stdio、HTTP)
  • 🎯 灵活执行:在代码模式、工具调用或每个任务的LLM采样之间进行选择
  • 🔄 构图模式:顺序、并行、重试和条件工作流
  • 🛠️ 类型安全工具:使用可选的静态类型生成进行运行时验证

代码模式

  • 🚀 LLM代码生成:AI使用您的工具作为API编写TypeScript代码
  • 🔒 安全沙盒:具有超时强制的基于VM的隔离
  • 🤖 智能重试:具有LLM自校正功能的自动错误恢复
  • 📊 代币效率:多步骤操作减少60-75%

高级功能

  • 📝 结构化输出:OpenAI和Anthropic支持Zod验证
  • 🔄 双水平采样:通过MCP进行编排器和子服务器LLM采样
  • 🤝 A2A桥:支持多代理协作的本地代理到代理协议
  • 🔧 零意见:与任何工作流引擎或纯async/await一起使用
  • 🔐 安全:审批工作流、审计日志记录、速率限制

安装

npm install mcp-orchestrator-ts

直接代码执行

您也可以直接编写和执行自己的代码:

const code = `
  const files = await tools.list_directory({ path: './' });
  const tsFiles = files.content.filter(f => f.name.endsWith('.ts'));
  
  const fileSizes = [];
  for (const file of tsFiles) {
    const content = await tools.read_file({ path: file.path });
    fileSizes.push({ 
      name: file.name, 
      lines: content.split('\\n').length 
    });
  }
  
  return fileSizes.sort((a, b) => b.lines - a.lines).slice(0, 5);
`;

const result = await orchestrator.executeCode(code, {
  timeout: 30000
});
});

代码段系统(代码重用)

自动将有用的“代码模式”脚本升级为一流的MCP工具。

1.启用代码段模式

设置环境变量:

ENABLE_SNIPPET_MODE=true
SNIPPET_STORAGE_PATH=./snippets  # Optional, defaults to ./snippets

2.创建代码段

指示LLM在生成的代码中包含元数据注释:

// @name: my-tool-name
// @description: A description of what the tool does
// @input: {"type": "object", "properties": {"arg1": {"type": "string"}}}

// Your code using 'args'
console.log(args.arg1);

3.使用代码段

代码段会自动保存并注册为工具。现在,您可以像使用其他MCP工具一样使用它:

await orchestrator.callTool('my-tool-name', { arg1: 'value' });

4.自动保存

如果你使用 generateAndExecute 和 saveToSnippets: true,编排器将自动保存任何成功执行的具有有效元数据的代码。

await orchestrator.generateAndExecute('Create a tool named "echo" that prints the input', {
  saveToSnippets: true
});

A2A集成(代理到代理)

将您精心策划的专家暴露为本地A2A代理,允许其他代理与之协作。

1.搭建桥梁

import { McpA2aBridge } from 'mcp-orchestrator/a2a';

// Create a bridge for your orchestrator
const bridge = new McpA2aBridge(orchestrator, {
    name: "My Expert Agent",
    description: "An agent that helps with X, Y, and Z"
});

2.添加技能

您可以将特定功能作为A2A“技能”公开:

// Expose the "Code Mode" engine (Natural Language -> Code -> Execution)
bridge.addCodeModeSkill({
    name: "Code Expert",
    systemPrompt: "You are a helpful coding assistant."
});

// Expose a specific tool directly
bridge.addToolSkill("calculate_sum");

3.快速装载

const app = express();
app.use(express.json());

// Mount the A2A protocol endpoints
app.use("/a2a", bridge.createExpressRouter());

您的代理现在可以通过以下方式被发现 /.well-known/agent-card.json 并支持完整的A2A生命周期(任务、状态更新、取消)。

传统工具调用

对于简单的单步操作,您仍然可以使用传统的工具调用:

// Direct tool call
const files = await orchestrator.callTool('list_directory', { path: './' });

// With structured LLM output
const analysis = await orchestrator.llm.generateStructured({
  schema: z.object({ 
    summary: z.string(),
    fileCount: z.number()
  }),
  prompt: `Analyze these files: ${JSON.stringify(files)}`
});

何时使用每种方法

使用代码模式 使用传统工具调用
多步骤工作流 单个工具调用
复杂的数据转换 简单的操作
可用工具多 工具少
性能很重要(节省60-75%的代币) 实时交互

📖 看 docs/code-mode.md 用于全面的代码模式文档。

双电平LLM采样

图书馆支持 LLM采样的两个级别 通过模型上下文协议(MCP):

1.编排器级别采样

通过MCP直接进行LLM采样 sampling/createMessage 当MCP客户端支持时。

// Enable sampling with default options
const orchestrator = new MCPOrchestrator({
  servers: { /* your servers */ },
  llm: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
  samplingOptions: {
    maxTokens: 1000,
    temperature: 0.7,
    requireApproval: true, // Require user approval for sampling requests
    timeoutMs: 30000
  }
});

// Check sampling capabilities
const capabilities = orchestrator.getSamplingCapabilities();
console.log('Client supports sampling:', capabilities);

// Perform orchestrator-level sampling
const result = await orchestrator.sample(
  [
    { role: 'user', content: 'Analyze the benefits of MCP orchestration' }
  ],
  {
    systemPrompt: 'You are an expert in AI and distributed systems.',
    maxTokens: 500,
    origin: 'orchestrator'
  }
);

console.log('Sample result:', result);

2.通过代理进行子服务器采样

轻量级采样代理,将子服务器请求转发到编排器的LLM提供程序。

// Create sampling proxy for a sub-server
const expertProxy = orchestrator.createSamplingProxy('data-analyzer', {
  origin: 'data-expert',
  maxTokens: 300,
  requireApproval: false // Sub-server requests typically don't need approval
});

// Sub-server makes sampling request
const analysisResult = await expertProxy.createMessage({
  messages: [
    { role: 'user', content: 'Analyze this dataset for trends' },
    { role: 'assistant', content: 'I\'ll analyze the data for you.' }
  ],
  systemPrompt: 'You are a data analysis expert.',
  maxTokens: 400
});

// Structured sampling for type-safe results
const structuredResult = await expertProxy.createMessageStructured(
  {
    messages: [{ role: 'user', content: 'Provide analysis in JSON format' }],
    systemPrompt: 'Return structured analysis results.',
  },
  undefined,
  z.object({
    trends: z.array(z.string()),
    confidence: z.number(),
    recommendations: z.array(z.string())
  })
);

安全和信任功能

LLM采样的内置安全和信任管理:

import { SamplingSecurityManager, SecurityPolicy } from 'mcp-orchestrator/sampling';

// Configure security manager
const securityManager = new SamplingSecurityManager({
  maxQueueSize: 50,
  defaultRateLimit: {
    requestsPerMinute: 30,
    requestsPerHour: 500,
    requestsPerDay: 5000,
  }
});

// Add custom security policy
const costLimitPolicy: SecurityPolicy = {
  name: 'cost_limit_policy',
  description: 'Reject expensive requests',
  evaluate: async (request, options, context) => {
    const estimatedCost = estimateCost(request);
    if (estimatedCost > 1.00) {
      return { approved: false, reason: 'Cost exceeds limit' };
    }
    return { approved: true };
  }
};

securityManager.addPolicy(costLimitPolicy);

// Handle approval workflow (for UI integration)
securityManager.on('approval_requested', (approval) => {
  console.log('User approval needed:', approval.id);
  // Show approval dialog in your UI
});

// Check rate limits
const rateLimitStatus = securityManager.getRateLimitStatus('my-app');
console.log('Rate limit status:', rateLimitStatus);

// Access audit log
const auditLog = securityManager.getAuditLog({
  eventType: 'approved',
  startTime: Date.now() - 3600000 // Last hour
});

工具启用采样

当客户端和服务器都支持LLM时,支持LLM到工具的推理循环:

// Define available tools for sampling
const tools = [
  {
    name: 'search_database',
    description: 'Search the database for information',
    inputSchema: {
      type: 'object',
      properties: {
        query: { type: 'string' },
        limit: { type: 'number' }
      },
      required: ['query']
    }
  },
  {
    name: 'calculate_metrics',
    description: 'Calculate performance metrics',
    inputSchema: {
      type: 'object',
      properties: {
        data: { type: 'array' },
        operation: { type: 'string' }
      },
      required: ['data']
    }
  }
];

// Use tool-enabled sampling
const result = await orchestrator.sample(
  [
    { 
      role: 'user', 
      content: 'Find relevant data and calculate average performance' 
    }
  ],
  {
    tools,
    toolChoice: 'auto', // Let LLM choose which tools to use
    origin: 'analyst-expert'
  }
);

// The LLM will decide when to use tools and the system will handle the tool loop

类型生成

为您的工具生成TypeScript类型,以获得完整的IDE自动补全和类型安全。

1.创建配置文件

创建 mcp-config.json 定义服务器的文件。此文件同时支持 stdio (命令行工具)和 sse (远程HTTP)服务器。

{
  "servers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"]
    },
    "github": {
      "url": "https://api.github.com/mcp",
      "auth": {
        "token": "YOUR_GITHUB_TOKEN"
      }
    },
    "aws-tools": {
      "command": "node",
      "args": ["./dist/index.js"],
      "env": {
        "AWS_REGION": "us-east-1"
      }
    }
  }
}

2.运行发电机

运行CLI工具连接到服务器,发现工具,并生成带有接口的TypeScript文件。

npx mcp-orchestrator --config mcp-config.json --output src/types/mcp-tools.ts

3.使用生成的类型

导入生成的类型,以确保调用工具时的类型安全。

import { MCPOrchestrator } from 'mcp-orchestrator';
import './types/mcp-tools'; // Load type augmentations

const orchestrator = new MCPOrchestrator({ /* ... */ });

// TypeScript will now validate arguments and return types!
const result = await orchestrator.callTool('aws_ec2_run_instances', {
  instanceType: 't3.medium', // Type-checked
  region: 'us-east-1'
});

专家构图模式

该库提供辅助函数,将工具组合成复杂的工作流。

顺序执行

通过一系列步骤传递状态。

import { sequence } from 'mcp-orchestrator/patterns';

const result = await sequence([
  async (ctx) => {
    const data = await orchestrator.callTool('fetch_data', { id: ctx.id });
    return { ...ctx, data };
  },
  async (ctx) => {
    const analysis = await orchestrator.llm.generateStructured({
      schema: AnalysisSchema,
      prompt: `Analyze: ${JSON.stringify(ctx.data)}`
    });
    return { ...ctx, analysis };
  }
], { id: '123' });

并行执行

同时运行多个独立任务。

import { parallel } from 'mcp-orchestrator/patterns';

const [users, posts] = await parallel([
  () => orchestrator.callTool('get_users', {}),
  () => orchestrator.callTool('get_posts', {})
]);

重试逻辑

自动重试具有回退功能的瞬态故障。

import { retry } from 'mcp-orchestrator/patterns';

const result = await retry(
  () => orchestrator.callTool('flaky_api', {}),
  { 
    maxAttempts: 3, 
    backoff: 'exponential',
    initialDelay: 1000 
  }
);

最佳实践

取样注意事项

  • 成本管理:使用安全策略限制昂贵的请求
  • 用户批准:为敏感操作启用审批工作流
  • 速率限制:实施适当的费率限制,防止滥用
  • 回退策略:当MCP采样不可用时,始终提供回退

安全建议

  • 原产地追踪:使用不同组件的不同来源来跟踪使用情况
  • 审计日志:定期审查审计日志,以发现异常模式
  • 策略强制:实施内容过滤和成本控制策略
  • 超时处理:设置适当的超时以防止挂起请求

工具启用采样

  • 工具设计:保持工具模式简单且记录良好
  • 错误处理:为工具执行实施稳健的错误处理
  • 环路预防:设置合理的限制以防止无限的工具循环
  • 用户体验:使用工具启用的采样时提供明确的反馈

许可证

麻省理工学院

支持我的工作

你可以通过注册来支持我的工作;