内容
# MCP Server Hub / Gateway
**目的:** 本项目提供一个中央网关,用于管理多个 MCP(模型上下文协议)服务器,并暴露 hub 原生工具,避免为每个 LLM 客户端(如 Cline、Cursor 等)配置和运行重复的服务器进程。它支持 **动态配置重载**,允许管理的服务器和 hub 工具/服务在不重启主网关服务器的情况下进行更新。将您的 LLM 客户端连接到本项目提供的单一 `gateway-client` 端点,以通过一个接口访问所有管理的 MCP 服务器和 hub 本身的工具。
## 架构
该系统由本仓库中的两个主要组件组成:
1. **网关服务器 (`src/server.ts`):**
* 持续运行的核心 hub 进程。
* 在启动时读取初始配置文件 (`mcp_hub_config.json`)。**重要的是,构建过程会将此文件复制到 `dist/` 目录,运行中的服务器会监视 `dist/mcp_hub_config.json` 文件的变化。**
* **动态管理** 在 `mcpServers` 配置部分定义的底层 MCP 服务器的生命周期(启动、停止、监控、重启)。
* **动态加载/卸载/更新** 在 `hubTools` 配置部分定义的 hub 原生工具。
* 支持 **可配置的内部服务**(如 `exampleService`),对配置变化做出反应。
* 监听来自网关客户端的 WebSocket 连接(默认端口 8081)。
* 从管理的服务器发现工具,并以 `serverId__toolName` 命名空间暴露它们。
* 以 `hub__toolName` 命名空间暴露 hub 原生工具。
* 将从网关客户端接收到的工具调用路由到适当的管理服务器或内部 hub 工具处理程序。
2. **网关客户端 (`src/client/client.ts`):**
* 作为 LLM 客户端通过 STDIO 连接的代理服务器。
* 通过 WebSocket(带自动重连)连接到运行中的网关服务器。
* 将 MCP 请求(如 `mcp_listTools`、`mcp_callTool`)从 LLM 客户端转发到网关服务器。
* 将来自网关服务器的响应返回给 LLM 客户端。
* **定期轮询** 网关服务器以获取工具列表更新,以处理动态变化(可通过 `CLIENT_TOOL_REFRESH_INTERVAL_MS` 环境变量配置,默认为 5 分钟)。(在 Claude Desktop 中无效)
* 重启 MCP 客户端进程以刷新工具列表。
**工作流程图:**
```mermaid
flowchart LR
subgraph "用户机器"
LLM_Client1["LLM 客户端(例如,Cline)"]
LLM_Client2["LLM 客户端(例如,Cursor)"]
subgraph "网关客户端进程"
style GatewayClientProcess fill:#f9f,stroke:#333,stroke-width:2px
GatewayClient["网关客户端应用\n(client.ts)"]
end
subgraph "网关服务器进程"
style GatewayServerProcess fill:#ccf,stroke:#333,stroke-width:2px
GatewayServer["网关服务器\n(server.ts)"]
ConfigFile["dist/mcp_hub_config.json"] --- Watcher["文件监视器"]
Watcher -- "触发重载" --> GatewayServer
MCPServer1["管理的 MCP 服务器 1"]
MCPServer2["管理的 MCP 服务器 2"]
HubTool["Hub 工具\n(例如,exampleHubTool.ts)"]
HubService["Hub 服务\n(例如,ExampleConfigurableService.ts)"]
end
end
LLM_Client1 -- "STDIO" --> GatewayClient
LLM_Client2 -- "STDIO" --> GatewayClient
GatewayClient -- "WebSocket" --> GatewayServer
GatewayServer -- "管理/代理" --> MCPServer1
GatewayServer -- "管理/代理" --> MCPServer2
GatewayServer -- "加载/运行" --> HubTool
GatewayServer -- "使用" --> HubService
GatewayServer -- "读取/监视" --> ConfigFile
```
## 开始使用
### 1. 先决条件
* Node.js(推荐 v20+)
* npm
* 您要管理的底层 MCP 服务器必须已安装/可访问。
### 2. 安装与构建
```bash
# 克隆仓库(如果尚未克隆)
# git clone ...
# cd mcp-server-hub-server
# 安装依赖
npm install
# 构建网关服务器和客户端代码
# 这将编译 TypeScript 并将 mcp_hub_config.json 复制到 dist/
npm run build
```
### 3. 配置 (`mcp_hub_config.json`)
通过编辑 **项目根目录** 中的 `mcp_hub_config.json` 文件来配置 hub。`npm run build` 命令将把此文件复制到 `dist/` 目录。运行中的服务器会监视 `dist/` 中的文件以进行实时更改。
**示例 `mcp_hub_config.json`:**
```json
{
"mcpServers": {
"thought-server": {
"command": "node",
"args": ["D:\\Projects\\mcp-thought-server\\build\\index.js"],
"env": {},
"autoRestart": true
},
"file-ops": {
"command": "node",
"args": ["D:/Projects/mcp-servers/Cline/MCP/file-operations-server/build/index.js"]
}
// 在此处添加其他管理的 MCP 服务器条目...
},
"hubTools": {
"example": {
"description": "由 hub 本身提供的示例工具。",
"modulePath": "./exampleHubTool.js", // 相对于 dist/tools/ 的路径
"handlerExport": "default", // 可选,默认为 'default'
"enabled": true // 可选,默认为 true
}
// 在此处添加其他 hub 原生工具条目...
},
"exampleService": {
"featureFlag": false,
"messagePrefix": "INITIAL"
// 添加其他特定于 ExampleConfigurableService 的设置
},
"settings": {
"logLevel": "info", // 可选:'error', 'warn', 'info', 'debug'
"wsPort": 8081, // 网关客户端的端口(WebSocket)
"ssePort": null // SSE 接口端口(null 表示禁用)
}
}
```
**关键配置部分:**
* `mcpServers`:定义由 hub 管理的外部 MCP 服务器。
* 键:唯一的 `serverId`(用于工具命名空间,例如 `thought-server`)。
* `command`、`args`、`env`、`workingDir`、`autoRestart`、`maxRestarts`:标准进程配置。
* `hubTools`:定义直接在此 hub 项目中实现的工具(在 `src/tools/` 中)。
* 键:工具的基本名称(例如 `example`)。
* `description`:工具描述。
* `modulePath`:编译后的 JS 文件路径(相对于 `dist/tools/`)。
* `handlerExport`(可选):包含工具处理函数的命名导出(默认为 `default`)。模块还应导出 `inputSchema`(Zod schema)。
* `enabled`(可选):`true` 或 `false`(默认为 `true`)。
* `exampleService`:特定于 `ExampleConfigurableService` 的配置。在此处为其他可配置的 hub 服务添加部分。
* `settings`:一般网关设置。
* `wsPort`:用于 `gateway-client` 的 WebSocket 接口端口。
* `logLevel`:日志详细程度。
* `ssePort`:服务器推送事件接口的端口(如果启用)。
**动态重载:** 在服务器运行时保存到 `dist/mcp_hub_config.json` 的更改将被自动检测并应用。
* `mcpServers` 中的更改将导致相应的服务器进程停止/启动/重启。
* `hubTools` 中的更改将加载/卸载/重新加载指定的工具模块。
* `settings` 或特定服务部分(如 `exampleService`)中的更改将触发相关组件监听的事件。
### 4. 运行网关服务器
在项目根目录(`mcp-server-hub-server`)中打开终端并运行:
```bash
# 确保您首先构建了项目!
npm run build
# 启动服务器
npm start
```
这将读取 `dist/mcp_hub_config.json`,启动管理的服务器,加载 hub 工具,启动 WebSocket 监听器,监视配置文件,并保持运行直到手动停止(Ctrl+C)。
### 5. 配置您的 LLM 客户端(例如,Cline)
您的 LLM 客户端只需要配置 **一个** MCP 服务器:`gateway-client`。
将以下条目添加到您的客户端 MCP 服务器设置文件(例如,Cline 的 `cline_mcp_settings.json`),**确保使用此项目的正确绝对路径**:
```json
{
"mcpServers": {
// 删除单个服务器(如 thought-server、file-operations 等)的配置。
"gateway-client": {
"command": "node",
"args": [
// 使用编译客户端脚本的完整绝对路径
"d:/Projects/mcp-server-hub-server/dist/client/client.js"
],
"options": {
// CWD 应为项目根目录
"cwd": "d:/Projects/mcp-server-hub-server"
},
"env": {
// 可选:配置客户端轮询间隔(默认为 5 分钟)
// "CLIENT_TOOL_REFRESH_INTERVAL_MS": "60000" // 例如,60 秒
},
"disabled": false,
"autoApprove": []
}
// 此处只需 gateway-client 条目
}
}
```
当 LLM 客户端连接到 `gateway-client` 时,它将自动启动客户端进程(`node dist/client/client.js`),然后通过 WebSocket 连接到已经运行的网关服务器。
### 6. 使用工具
一旦网关服务器运行并且您的 LLM 客户端连接到 `gateway-client`:
* 在您的 LLM 客户端中列出工具。您应该看到命名空间工具名称:
* 管理的服务器工具:`serverId__toolName`(例如,`thought-server__integratedThinking`)
* Hub 原生工具:`hub__toolName`(例如,`hub__example`)
* 使用这些完整的命名空间名称调用工具。
* **注意:** 由于动态配置,工具列表可能会随时间变化。`gateway-client` 定期轮询更新(默认 5 分钟,可通过 `CLIENT_TOOL_REFRESH_INTERVAL_MS` 环境变量为客户端进程配置)。服务器端更改与客户端意识到之间可能会有短暂延迟。有关详细信息,请参见 `docs/client-dynamic-tools-guide.md`。
## 故障排除
* **在 LLM 客户端启动 `gateway-client` 时出现 ENOENT 错误:** 确保 LLM 客户端的 MCP 设置中的 `command`(`node`)、`args`(`dist/client/client.js` 的绝对路径)和 `options.cwd`(项目根目录的绝对路径)对于您的系统是正确的。
* **工具名称验证错误(`String should match pattern...`):** 确保您的 `serverId` 键和 `hubTools` 键在 `mcp_hub_config.json` 中仅包含 `a-zA-Z0-9_-`。
* **网关客户端无法连接到服务器:** 验证网关服务器(`npm start`)是否正在运行。检查 `dist/mcp_hub_config.json` 中的 `wsPort` 是否与客户端使用的 URL 匹配(默认 `ws://localhost:8081`)。检查防火墙。
* **LLM 客户端中的初始 `listTools` 失败/超时:** 如果 LLM 客户端在 `gateway-client` 进程完全连接到网关服务器的 WebSocket 之前发送请求,则可能会发生这种情况。客户端会排队请求,后续调用应该可以正常工作。检查网关客户端日志以获取排队消息(您可能需要在单独的终端中手动运行 `node dist/client/client.js` 以查看其日志)。
* **管理服务器错误(`[serverId/ERR]`):** 以特定服务器 ID 前缀记录的错误表示该底层管理服务器内部的问题,而不是网关本身。请直接排查该服务器。
* **动态配置未重新加载:** 确保在服务器运行时修改 `dist/mcp_hub_config.json`。检查网关服务器日志以获取文件监视器消息和重新加载时的潜在验证错误。确保构建过程成功将您意图的配置从根目录复制到 `dist/`。
## 开发
* **运行开发服务器:** `npm run dev`(使用 nodemon 自动重启网关服务器以响应 `src` 更改)。注意:这不会自动重建/复制配置或重启客户端/管理服务器。您需要手动运行 `npm run build` 并重启以进行配置/客户端更改。
* **代码检查/格式化:** `npm run lint`,`npm run format`(也通过预提交钩子运行)。
* **测试:** `npm test`(目前有限,见 `tests/`)。
连接信息
猜你喜欢
暂无推荐服务器