@voyager-0x/agent-mcp
Version:
Voyager MCP Agent - A powerful Model Context Protocol agent
608 lines (478 loc) • 15.3 kB
Markdown
# @voyager-0x/agent-mcp
🤖 一个基于 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) 的可扩展 AI Agent 基础框架,支持浏览器和 Node.js 双环境运行。
## ✨ 特性
- 🌐 **跨平台支持**:同时支持浏览器和 Node.js 环境
- 🔌 **可扩展架构**:支持 MCP DSL 模块和外部 MCP 服务器
- 🎯 **类型安全**:完整的 TypeScript 支持
- 🔄 **实时通信**:支持流式对话和智能缓存
- ⚙️ **灵活配置**:支持多种 AI 模型配置
- 🛠️ **工具集成**:支持 MCP 工具和资源管理
- 🔗 **多协议支持**:支持 HTTP/HTTPS/WebSocket 连接
- 📦 **模块化设计**:易于扩展和维护
## 📦 安装
```bash
npm install @voyager-0x/agent-mcp
```
## 🚀 快速开始
### 基础用法
```typescript
import { WebMcpAgent, AIModelConfig } from "@voyager-0x/agent-mcp";
// 配置 AI 模型
const config: AIModelConfig = {
apiKey: "your-api-key",
baseURL: "https://api.openai.com/v1",
model: "gpt-4",
debug: true,
};
// 创建 Agent 实例
const agent = new WebMcpAgent(config);
// 设置消息监听
agent.onReply(
(message) => console.log("AI回复:", message),
() => console.log("对话结束")
);
// 开始对话
await agent.chat("你好,请介绍一下你自己");
```
## 🔌 MCP 模块扩展
### 1. 创建 DSL 模块
```typescript
import { createMcpDslModule } from "@voyager-0x/agent-mcp";
// 创建自定义工具模块
const calculatorModule = createMcpDslModule(
{
title: "计算器模块",
description: "提供基础数学计算功能",
},
(mcpServer) => {
// 注册计算工具
mcpServer.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;
if (name === "calculator") {
const { operation, a, b } = args;
let result;
switch (operation) {
case "add":
result = a + b;
break;
case "subtract":
result = a - b;
break;
case "multiply":
result = a * b;
break;
case "divide":
result = b !== 0 ? a / b : "Error: Division by zero";
break;
default:
result = "Error: Unknown operation";
}
return {
content: [
{
type: "text",
text: `计算结果: ${result}`,
},
],
};
}
});
// 注册工具列表
mcpServer.setRequestHandler("tools/list", async () => {
return {
tools: [
{
name: "calculator",
description: "执行基础数学计算",
inputSchema: {
type: "object",
properties: {
operation: {
type: "string",
enum: ["add", "subtract", "multiply", "divide"],
description: "计算操作类型",
},
a: { type: "number", description: "第一个数字" },
b: { type: "number", description: "第二个数字" },
},
required: ["operation", "a", "b"],
},
},
],
};
});
}
);
```
### 2. 连接外部 MCP 服务器
```typescript
import { createMcpServerModule, McpServerConfig } from "@voyager-0x/agent-mcp";
// 连接到外部 MCP 服务器
const serverConfig: McpServerConfig = {
title: "文件系统服务器",
description: "提供文件操作功能",
serverUrl: "ws://localhost:8080/mcp",
connectionParams: {
timeout: 5000,
retryAttempts: 3,
auth: {
token: "your-auth-token",
},
},
};
const fileSystemModule = await createMcpServerModule(serverConfig);
```
### 3. HTTP/HTTPS 服务器连接
```typescript
// 连接到 HTTP MCP 服务器
const httpServerConfig: McpServerConfig = {
title: "API 服务器",
description: "提供 REST API 访问",
serverUrl: "https://api.example.com/mcp",
connectionParams: {
requestInit: {
headers: {
Authorization: "Bearer your-token",
"Content-Type": "application/json",
},
},
reconnectionOptions: {
initialReconnectionDelay: 1000,
maxReconnectionDelay: 30000,
maxRetries: 5,
},
},
};
const apiModule = await createMcpServerModule(httpServerConfig);
```
## 🛠️ 模块管理
### 管理 MCP 模块
```typescript
import { mcpModulesManager } from "@voyager-0x/agent-mcp";
// 列出所有模块
const modules = mcpModulesManager.listMcpModules();
console.log("已加载的模块:", modules);
// 获取特定模块
const module = mcpModulesManager.getMcpModule({ uuid: "module-uuid" });
// 移除模块
await mcpModulesManager.removeMcpServerModule({ uuid: "module-uuid" });
// 更新模块配置
const updatedModule = await mcpModulesManager.updateMcpServerModule({
uuid: "module-uuid",
config: newServerConfig,
});
```
### 获取工具和资源
```typescript
// 获取所有可用工具
const tools = await mcpModulesManager.getTools({
uuids: ["module-1-uuid", "module-2-uuid"],
});
// 获取所有可用资源
const resources = await mcpModulesManager.getResources({
uuids: ["module-1-uuid", "module-2-uuid"],
});
// 按模块来源筛选
const dslModuleUuids = mcpModulesManager.getModuleUuidsBySource("user-dsl");
const externalModuleUuids =
mcpModulesManager.getModuleUuidsBySource("external-http");
```
## ⚙️ 配置管理
### AI 模型配置
```typescript
import {
setAIConfig,
getAIConfig,
updateAIConfig,
onAIConfigChange,
AIModelConfig,
} from "@voyager-0x/agent-mcp";
// 设置配置
const config: AIModelConfig = {
apiKey: "sk-...",
baseURL: "https://api.openai.com/v1",
model: "gpt-4-turbo",
debug: false,
};
setAIConfig(config);
// 监听配置变化
const unsubscribe = onAIConfigChange((newConfig) => {
console.log("配置已更新:", newConfig);
});
// 更新部分配置
updateAIConfig({ model: "gpt-4o" });
// 取消监听
unsubscribe();
```
### 支持的 AI 模型
- **OpenAI**: `gpt-4`, `gpt-4-turbo`, `gpt-3.5-turbo`
- **自定义模型**: 通过 `baseURL` 配置支持兼容 OpenAI API 的模型
## 🎯 高级用法
### 自定义事件处理
```typescript
const agent = new WebMcpAgent(config);
// 获取底层 agent 实例
const mcpAgent = agent.getAgent();
// 监听会话事件
mcpAgent.session.on("reply", (message) => {
console.log("新消息:", message);
});
mcpAgent.session.on("finish", () => {
console.log("对话结束");
});
mcpAgent.session.on("error", (error) => {
console.error("发生错误:", error);
});
```
### 获取对话历史
```typescript
// 获取当前会话的所有消息
const messages = agent.getChatMessages();
console.log("对话历史:", messages);
```
### 取消对话
```typescript
// 取消当前进行中的对话
agent.cancelChat();
```
## 🌐 跨环境支持
### 浏览器环境
```html
<script type="module">
import { WebMcpAgent } from "@voyager-0x/agent-mcp";
const agent = new WebMcpAgent({
apiKey: "your-key",
baseURL: "https://api.openai.com/v1",
model: "gpt-4",
});
</script>
```
### Node.js 环境
```javascript
// ESM
import { WebMcpAgent } from "@voyager-0x/agent-mcp";
// CommonJS
const { WebMcpAgent } = require("@voyager-0x/agent-mcp");
```
## 📚 API 参考
### WebMcpAgent
| 方法 | 描述 | 参数 | 返回值 |
| ------------------------------ | ---------------- | -------------------- | --------------- |
| `constructor(config)` | 创建 Agent 实例 | `AIModelConfig` | `WebMcpAgent` |
| `updateConfig(config)` | 更新 AI 配置 | `AIModelConfig` | `void` |
| `createChat()` | 创建新的聊天会话 | - | `McpAgent` |
| `chat(message)` | 发送消息 | `string` | `Promise<void>` |
| `getChatMessages()` | 获取对话历史 | - | `Message[]` |
| `cancelChat()` | 取消当前对话 | - | `void` |
| `onReply(onMessage, onFinish)` | 设置回复监听器 | `Function, Function` | `void` |
### AIModelConfig
```typescript
interface AIModelConfig {
apiKey: string; // API 密钥
baseURL: string; // API 基础 URL
model: string; // 模型名称
debug?: boolean; // 调试模式
}
```
### McpServerConfig
```typescript
interface McpServerConfig {
title: string; // 服务器标题
description: string; // 服务器描述
serverUrl: string; // 服务器 URL (支持 ws://, wss://, http://, https://)
}
```
### McpModule
```typescript
interface McpModule {
title: string; // 模块标题
description: string; // 模块描述
uuid: string; // 唯一标识符
client: Client; // MCP 客户端实例
source: McpModuleSource; // 模块来源类型
config?: McpServerConfig; // 服务器配置(仅外部模块)
}
type McpModuleSource =
| "builtin" // 内置模块
| "user-dsl" // 用户 DSL 模块
| "external-http" // 外部 HTTP/WebSocket 服务器
| "external-stdio"; // 外部标准输入输出服务器
```
### McpModulesManager
模块管理器提供以下方法:
| 方法 | 描述 | 参数 | 返回值 |
| --------------------------------------- | ------------------- | ----------------------------------------- | ---------------------------- |
| `createMcpDslModule(config, callback)` | 创建 DSL 模块 | `{title, description}, Function` | `McpModule` |
| `createMcpServerModule(config, uuid?)` | 创建服务器模块 | `McpServerConfig, string?` | `Promise<McpModule>` |
| `removeMcpServerModule({uuid})` | 删除服务器模块 | `{uuid: string}` | `Promise<boolean>` |
| `updateMcpServerModule({uuid, config})` | 更新服务器模块 | `{uuid: string, config: McpServerConfig}` | `Promise<McpModule \| null>` |
| `listMcpModules()` | 列出所有模块 | - | `McpModule[]` |
| `getMcpModule({uuid})` | 获取指定模块 | `{uuid: string}` | `McpModule` |
| `getModuleUuidsBySource(source)` | 按来源获取模块 UUID | `McpModuleSource` | `string[]` |
| `getTools({uuids})` | 获取工具列表 | `{uuids: string[]}` | `Promise<Tool[]>` |
| `getResources({uuids})` | 获取资源列表 | `{uuids: string[]}` | `Promise<Resource[]>` |
## ⚠️ 错误处理
### 常见错误类型
```typescript
try {
const agent = new WebMcpAgent(config);
await agent.chat("Hello");
} catch (error) {
if (error.message.includes("AI配置未初始化")) {
console.error("请先设置 AI 配置");
} else if (error.message.includes("连接到MCP服务器失败")) {
console.error("MCP 服务器连接失败,请检查服务器状态");
} else {
console.error("未知错误:", error);
}
}
// 模块连接错误处理
try {
const module = await createMcpServerModule({
title: "Test Server",
description: "Test",
serverUrl: "ws://localhost:8080/mcp",
});
} catch (error) {
console.error("模块连接失败:", error.message);
// 可以尝试重连或使用备用服务器
}
```
### 连接重试机制
```typescript
// 内置重试机制(最多3次)
const module = await createMcpServerModule(config);
// 自定义重试逻辑
async function createModuleWithRetry(config: McpServerConfig, maxRetries = 5) {
for (let i = 0; i < maxRetries; i++) {
try {
return await createMcpServerModule(config);
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
```
## 💡 最佳实践
### 1. 配置管理
```typescript
// ✅ 推荐:使用环境变量
const config: AIModelConfig = {
apiKey: process.env.OPENAI_API_KEY || "",
baseURL: process.env.OPENAI_BASE_URL || "https://api.openai.com/v1",
model: process.env.OPENAI_MODEL || "gpt-4",
debug: process.env.NODE_ENV === "development",
};
// ❌ 避免:硬编码敏感信息
const config = {
apiKey: "sk-hardcoded-key", // 不要这样做
// ...
};
```
### 2. 模块生命周期管理
```typescript
// ✅ 推荐:及时清理资源
class MyApp {
private modules: McpModule[] = [];
async addModule(config: McpServerConfig) {
const module = await createMcpServerModule(config);
this.modules.push(module);
return module;
}
async cleanup() {
// 清理所有模块
for (const module of this.modules) {
await mcpModulesManager.removeMcpServerModule({ uuid: module.uuid });
}
this.modules = [];
}
}
```
### 3. 错误边界
```typescript
// ✅ 推荐:设置全局错误处理
const agent = new WebMcpAgent(config);
agent.onReply(
(message) => {
try {
// 处理消息
handleMessage(message);
} catch (error) {
console.error("消息处理错误:", error);
}
},
() => {
console.log("对话完成");
}
);
```
## 🔧 开发
### 构建
```bash
# 构建所有环境版本
npm run build
# 构建特定环境
npm run build:browser # 浏览器版本
npm run build:node # Node.js 版本
npm run build:types # 类型声明
```
### 测试
```bash
# 运行测试
npm test
# 监视模式
npm run test:watch
# 覆盖率报告
npm run test:coverage
```
### 开发模式
```bash
npm run dev
```
## 🐛 故障排除
### 常见问题
**Q: 提示 "AI 配置未初始化" 错误**
A: 确保在使用 Agent 前调用了构造函数或 `updateConfig()` 方法设置配置。
**Q: MCP 服务器连接失败**
A: 检查服务器 URL 是否正确,服务器是否正在运行,网络连接是否正常。
**Q: 工具调用失败**
A: 确保 MCP 模块正确实现了 `tools/list` 和 `tools/call` 处理器。
**Q: 浏览器环境下无法连接 WebSocket**
A: 检查 CORS 设置和 WebSocket 服务器配置。
### 调试模式
```typescript
// 启用调试模式
const config: AIModelConfig = {
// ...
debug: true,
};
// 查看详细日志
import { log } from "@voyager-0x/agent-mcp";
log.setLevel("debug");
```
## 📚 相关资源
- [Model Context Protocol 官方文档](https://modelcontextprotocol.io/)
- [OpenAI API 文档](https://platform.openai.com/docs)
- [项目示例](../examples/)
## 📄 许可证
MIT License
## 🤝 贡献
欢迎提交 Issue 和 Pull Request!
### 贡献指南
1. Fork 项目
2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 打开 Pull Request
### 开发环境设置
```bash
# 克隆项目
git clone https://github.com/your-org/web-mcp-agent.git
# 安装依赖
npm install
# 运行测试
npm test
# 启动开发模式
npm run dev
```