# @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
```
