Skip to content

MCP 配置系统 ​

本文引用的源码文件

本文引用的文件

目录 ​

  1. 引言
  2. 项目结构与定位
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能与热重载特性
  8. 安全策略
  9. 配置模板与最佳实践
  10. 故障排查指南
  11. 结论

引言 ​

本文件面向 MCP(Model Context Protocol)配置子系统,聚焦 Agent 端如何持久化、校验、加载和运行 MCP Server 配置,以及扩展端如何通过 HTTP API 管理这些配置。文档覆盖以下目标:

  • 配置文件格式:服务器定义、传输协议、认证头、环境变量和工作目录。
  • 配置验证机制:必填字段检查、类型校验、依赖关系校验。
  • 配置热重载:增量更新、状态同步与连接生命周期。
  • 安全策略:命令白名单/黑名单、环境变量注入边界、网络访问控制。
  • 配置模板与最佳实践:多环境管理与敏感信息保护。
  • 完整示例与排障路径。

本项目为双进程架构:Chrome 扩展端(Manifest V3,src/)与独立本地代理端 Agent(Node.js,agent/src/server.js)。MCP 配置主要位于 Agent 端,扩展端通过 /api/mcp/* 接口进行增删改查和连接控制。

项目结构与定位 ​

MCP 配置相关代码集中在 Agent 端的 agent/src/mcp 目录,并由 agent/src/server.js 暴露 HTTP API;扩展端在设置页中提供 UI 并调用该 API。

graph TB
subgraph "扩展端"
Options["设置页<br/>src/options/toolbox-config.js"]
BackgroundConfig["后台配置读取<br/>src/background/config.js"]
LocalesEn["国际化文案<br/>src/shared/locales/en.js"]
end
subgraph "Agent 端"
Server["HTTP 路由与鉴权<br/>agent/src/server.js"]
Security["命令安全检查<br/>agent/src/security.js"]
McpConfig["MCP 配置持久化<br/>agent/src/mcp/mcp-config.js"]
Registry["MCP 注册表与工具发现<br/>agent/src/mcp/registry.js"]
Client["MCP 客户端与传输层<br/>agent/src/mcp/client.js"]
end
Options --> Server
BackgroundConfig --> Server
LocalesEn --> Options
Server --> Security
Server --> McpConfig
Server --> Registry
Registry --> Client

图示来源

章节来源

核心组件 ​

  • MCP 配置持久化模块:负责 mcp_servers.json 的读写、内存缓存、写入互斥锁、添加/删除/启用禁用服务器。
  • MCP 客户端模块:封装 Model Context Protocol SDK,根据配置创建 stdio/SSE/streamableHttp/websocket 传输层,完成握手、工具列表拉取、工具调用。
  • MCP 注册表模块:维护已连接的 McpClient 实例,提供初始化、状态查询、工具扁平化、连接/断开、关闭等能力。
  • HTTP 路由模块:将扩展端请求映射到 MCP 配置与注册表操作,并在 stdio 模式下对命令执行安全检查。
  • 命令安全检查模块:对 MCP stdio 命令做黑白名单与确认级拦截,防止 MCP 成为命令管控后门。
  • 扩展端设置页:提供 MCP 服务器管理界面,保存后通知 background 刷新工具列表。

章节来源

架构总览 ​

MCP 配置系统的运行时流程如下:

  1. 扩展端用户在设置页编辑 MCP 服务器配置。
  2. 设置页调用 Agent 的 /api/mcp/servers 接口保存配置。
  3. Agent 路由层先做参数校验与命令安全检查,再调用 MCP 配置模块持久化。
  4. 用户点击“连接”时,Agent 通过注册表创建 McpClient,选择传输层并建立连接。
  5. 连接成功后,注册表拉取工具列表,并向扩展端暴露工具元数据。
  6. 工具调用经由注册表转发到对应 McpClient,最终由 MCP SDK 与远端服务交互。
sequenceDiagram
participant UI as "扩展端设置页"
participant API as "Agent HTTP 路由"
participant SEC as "命令安全检查"
participant CFG as "MCP 配置模块"
participant REG as "MCP 注册表"
participant CLI as "MCP 客户端"
UI->>API : POST /api/mcp/servers
API->>SEC : 校验 command + argsstdio
SEC-->>API : deny / confirm / allow
API->>CFG : addMcpServer(server)
CFG-->>API : { success }
UI->>API : POST /api/mcp/servers/connect
API->>REG : connectMcpServer(id)
REG->>CLI : new McpClient(server)
CLI->>CLI : _createTransport()
CLI->>CLI : client.connect()
CLI-->>REG : { success, toolCount }
REG-->>API : { success, toolCount }
API-->>UI : 连接结果

图示来源

详细组件分析 ​

MCP 配置持久化模块 ​

该模块维护 ~/.ai-helper-agent/mcp_servers.json,结构为 { servers: Array }。每个 server 对象包含:

  • id:唯一标识。
  • name:显示名称。
  • transport:传输协议,支持 stdio、sse、streamableHttp、websocket。
  • url:SSE/streamableHttp/websocket 必需。
  • command、args:stdio 模式启动命令及参数。
  • env:stdio 模式的环境变量注入。
  • cwd:工作目录。
  • headers:HTTP 类传输的请求头。
  • enabled:是否启用。

关键行为:

  • 首次加载若文件不存在,会创建默认空配置。
  • 解析失败时降级为 { servers: [] }。
  • 所有写操作使用 Promise 链式写锁,避免并发覆盖。
  • 提供 addMcpServer、removeMcpServer、toggleMcpServer 等原子操作。
flowchart TD
Start(["调用 addMcpServer"]) --> Load["loadMcpConfig()"]
Load --> Find{"是否存在相同 id?"}
Find --> |是| Merge["合并字段:旧值 + 新值"]
Find --> |否| Push["追加新服务器"]
Merge --> Save["saveMcpConfig(config)"]
Push --> Save
Save --> WriteLock["withWriteLock 串行写入"]
WriteLock --> Persist["writeFileSync(mcp_servers.json)"]
Persist --> Cache["更新内存缓存与 mtime"]
Cache --> End(["返回 { success: true }"])

图示来源

章节来源

MCP 客户端与传输层 ​

McpClient 根据 server.transport 选择传输实现:

  • stdio:需要 command,可选 args、env、cwd。
  • sse:需要 url,可选 headers。
  • streamableHttp:需要 url,可选 headers。
  • websocket:需要 url。

连接过程:

  1. 创建传输层。
  2. 初始化 MCP SDK Client。
  3. 调用 client.connect()。
  4. 获取服务端版本与能力。
  5. 调用 listTools 拉取工具列表。
  6. 标记 connected = true。

工具调用:

  • 若未连接直接返回错误。
  • 调用 callTool,提取 text 内容作为统一文本输出。
  • 捕获异常并返回结构化错误。
classDiagram
class McpClient {
+string serverId
+string serverName
+object serverConfig
+boolean connected
+array tools
+object serverInfo
+connect() Promise
+callTool(toolName, args) Promise
+disconnect() Promise
+getStatus() object
-_createTransport() object
}

图示来源

章节来源

MCP 注册表 ​

注册表维护 Map<serverId, McpClient>,提供:

  • initializeMcpRegistry:启动时遍历启用的服务器并连接。
  • getMcpServersStatus:返回服务器状态、工具数量、工具详情。
  • getMcpTools:扁平化工具列表,可按 serverId 过滤。
  • callMcpTool:转发工具调用。
  • connectMcpServer / disconnectMcpServer:单服务器连接生命周期。
  • shutdownMcpRegistry:进程关闭时清理连接。
sequenceDiagram
participant Reg as "注册表"
participant Cfg as "配置模块"
participant Cli as "McpClient"
Reg->>Cfg : loadMcpConfig()
loop 遍历启用的服务器
Reg->>Cli : new McpClient(server)
Cli->>Cli : connect()
alt 连接成功
Reg->>Reg : clients.set(server.id, client)
else 连接失败
Reg->>Reg : failedServers.push(...)
end
end
Reg-->>Caller : { connected, failed }

图示来源

章节来源

HTTP 路由与配置入口 ​

Agent 的 HTTP 路由暴露以下 MCP 相关接口:

  • POST /api/mcp/servers:添加或更新服务器。
  • DELETE /api/mcp/servers:删除服务器。
  • POST /api/mcp/servers/connect:连接指定服务器。
  • POST /api/mcp/servers/disconnect:断开指定服务器。
  • POST /api/mcp/servers/toggle:启用/禁用服务器。
  • GET /api/mcp/servers:获取服务器状态。
  • GET /api/mcp/tools:获取工具列表。
  • POST /api/mcp/call:调用工具。

其中,添加服务器时对 stdio 模式的 command + args 执行命令安全检查,拒绝危险命令或要求确认。

flowchart TD
Req["HTTP 请求"] --> Route{"匹配 /api/mcp/*"}
Route --> Add["POST /api/mcp/servers"]
Route --> Del["DELETE /api/mcp/servers"]
Route --> Conn["POST /api/mcp/servers/connect"]
Route --> Disconn["POST /api/mcp/servers/disconnect"]
Route --> Toggle["POST /api/mcp/servers/toggle"]
Route --> List["GET /api/mcp/servers"]
Route --> Tools["GET /api/mcp/tools"]
Route --> Call["POST /api/mcp/call"]
Add --> CheckCmd["stdio 命令安全检查"]
CheckCmd --> Allow{"允许?"}
Allow --> |否| Deny["返回 403 或确认提示"]
Allow --> |是| Save["addMcpServer()"]

图示来源

章节来源

扩展端设置页与工具刷新 ​

设置页在保存 MCP 配置后,向 background 发送 RELOAD_MCP_TOOLS 消息以刷新工具列表。同时,设置页会根据 Agent 返回的状态计算启用/总数统计,并渲染 UI。

章节来源

依赖关系分析 ​

  • server.js 依赖 security.js 对 stdio 命令做安全检查。
  • server.js 依赖 mcp-config.js 做配置持久化。
  • server.js 依赖 registry.js 做连接与工具管理。
  • registry.js 依赖 client.js 做 MCP 协议通信。
  • 扩展端 toolbox-config.js 通过 HTTP API 与 Agent 交互,并通过 background 刷新工具。
graph LR
Server["server.js"] --> Security["security.js"]
Server --> McpConfig["mcp-config.js"]
Server --> Registry["registry.js"]
Registry --> Client["client.js"]
Options["toolbox-config.js"] --> Server

图示来源

章节来源

性能与热重载特性 ​

  • 内存缓存:mcp-config.js 使用 configCache 与 configCacheMtime,仅在文件 mtime 变化时重新读取磁盘。
  • 写入互斥锁:withWriteLock 保证并发写不会互相覆盖。
  • 增量更新:addMcpServer 按 id 合并字段,避免全量重建。
  • 状态同步:toggleMcpServer 在禁用时主动断开连接,确保工具立即可用/不可用。
  • 启动初始化:initializeMcpRegistry 在 Agent 启动时批量连接启用的服务器,并记录失败列表。

需要注意:当前 MCP 配置模块没有实现基于文件监听的热重载;热重载主要通过显式连接/断开与重启 Agent 进程生效。Agent 源码修改后必须重启进程,新接口才生效。

章节来源

安全策略 ​

MCP 配置系统的安全策略主要体现在以下方面:

命令白名单与黑名单 ​

  • 当 transport 为 stdio 时,Agent 路由层拼接 command + args,调用命令安全检查。
  • 检查结果可能为:
    • deny:直接拒绝,返回 403。
    • confirm:要求用户确认,返回确认提示。
    • allow:允许继续添加服务器。
  • 命令安全检查逻辑参考 Agent 的命令分级控制策略,包括破坏性命令、权限变更、网络外连等。

章节来源

环境变量注入边界 ​

  • env 仅用于 stdio 传输模式,传递给子进程。
  • 扩展端文案提示环境变量仅在 stdio 传输时需要,敏感值建议通过 shell 配置导出。
  • 建议在配置中避免硬编码密钥,优先使用外部密钥管理服务或受保护的 shell 环境变量。

章节来源

网络访问控制 ​

  • SSE/streamableHttp/websocket 传输通过 URL 发起网络请求。
  • 扩展端存在内网地址访问控制开关与白名单,但 MCP 传输层的网络访问控制需结合 Agent 的网络策略与部署环境评估。
  • RAG URL 导入的内网访问策略与 MCP 不同,注意区分。

章节来源

配置模板与最佳实践 ​

配置文件结构 ​

mcp_servers.json 的基本结构:

json
{
  "servers": [
    {
      "id": "example-server",
      "name": "示例 MCP 服务器",
      "transport": "stdio",
      "command": "node",
      "args": ["./mcp-server.js"],
      "env": {},
      "cwd": "/path/to/workspace",
      "headers": {},
      "enabled": true
    },
    {
      "id": "sse-server",
      "name": "SSE 服务器",
      "transport": "sse",
      "url": "https://example.com/mcp",
      "headers": {
        "Authorization": "Bearer ..."
      },
      "enabled": true
    }
  ]
}

传输协议选择 ​

  • stdio:适合本地脚本或二进制 MCP Server,支持 command、args、env、cwd。
  • sse:适合远程 SSE 服务,支持 url 与 headers。
  • streamableHttp:适合现代 Streamable HTTP 服务,支持 url 与 headers。
  • websocket:非官方标准传输,适合特定实现。

多环境配置管理 ​

  • 使用不同 id 区分开发、测试、生产环境。
  • 通过 enabled 控制当前环境启用的服务器。
  • 将敏感环境变量放在 shell 配置中,不在 JSON 中明文存储。

敏感信息保护 ​

  • 避免在 headers.Authorization 中硬编码长期有效密钥。
  • 优先使用短期 token 或代理网关鉴权。
  • 定期轮换密钥,并限制 MCP Server 的网络访问范围。

章节来源

故障排查指南 ​

常见问题与定位 ​

  • MCP 服务器未连接:
    • 检查 enabled 是否为真。
    • 检查 transport 与必填字段:stdio 需要 command,HTTP 类需要 url。
    • 查看 Agent 日志中的连接失败列表。
  • 工具列表为空:
    • 确认连接成功且 listTools 返回非空。
    • 检查 MCP Server 是否正确实现工具注册。
  • 命令被拒绝:
    • stdio 模式下,命令安全检查可能返回 deny 或 confirm。
    • 调整命令或确认后再添加服务器。
  • 环境变量未生效:
    • 确认使用 stdio 传输。
    • 检查 env 字段是否正确传递。
  • 网络访问失败:
    • 检查 URL 可达性与鉴权头。
    • 结合 Agent 部署环境的网络策略。

调试步骤 ​

  1. 打开 Agent 日志,观察 [MCP] 与 [MCP Registry] 输出。
  2. 使用 GET /api/mcp/servers 查看服务器状态。
  3. 使用 GET /api/mcp/tools 查看工具列表。
  4. 使用 POST /api/mcp/call 手动调用工具,观察返回内容。
  5. 对于 stdio 模式,检查命令安全检查结果。

章节来源

结论 ​

MCP 配置系统在 Agent 端实现了安全的配置持久化、传输层抽象、连接生命周期管理与工具发现能力。扩展端通过简洁的 HTTP API 管理 MCP 服务器,并在设置页中提供直观的配置界面。安全方面,stdio 命令经过严格检查,环境变量注入边界清晰,网络访问需结合部署策略。虽然当前未实现文件监听热重载,但通过显式连接/断开与进程重启可实现稳定更新。建议在生产环境中谨慎配置敏感信息,并使用最小权限原则管理 MCP Server 的能力范围。