a4api 自 0.2.2 起内置 MCP server 四端管理:把 Claude Code、Codex、dsh(DeepSeek Harness)与 ZCode 四端各自配置文件里的 MCP server 归一为统一视图(name / transport / command / args / env / url / headers),自动发现并聚合标注,支持跨端迁移(按传输能力矩阵严格校验)、快照回收站与迁移日志。密钥全程脱敏或用 DPAPI 加密,API 永不回传明文。本文章介绍 MCP 的发现与聚合、配置文件位置、传输能力矩阵、跨端迁移与回收站机制。
1. 功能概述
| 维度 | 说明 |
|---|---|
| 管理对象 | 四端配置文件中的 MCP server(stdio / sse / http 传输) |
| 统一视图 | { name, transport, command, args, env, url, headers, cwd } 归一 schema |
| 适用端 | Claude Code、Codex、dsh、ZCode(自 0.2.2 起) |
| 核心能力 | 发现聚合、跨端迁移、快照回收站、迁移日志 |
| 安全特性 | env / headers 一律脱敏;回收站快照 DPAPI 加密 |
1.1 与技能管理的差异
MCP 与 技能管理 管理骨架同构,但配置形态不同:skill 是独立目录,MCP server 是配置文件内的嵌套子结构,因此读写走各端的配置文件适配器,迁移语义为「配置片段复制」,冲突处理为「目标端同名先快照进回收站再写入」。
2. 配置文件位置
| 端 | 全局(用户级) | 项目级 | server 存放位置 |
|---|---|---|---|
| Claude Code | ~/.claude.json 顶层 mcpServers |
<项目>/.mcp.json |
mcpServers 对象 |
| Codex | ~/.codex/config.toml |
<项目>/.codex/config.toml |
[mcp_servers.*] 子表 |
| dsh | ~/.dsh/profiles/<profile>/cordis.patch.yml |
不支持(cordis 为全局 profile 层) | @deepseek-ai/dsh-mcp-client 插件的 insert 条目 |
| ZCode | ~/.zcode/cli/config.json |
<项目>/.zcode/config.json |
嵌套 mcp.servers(严格 schema 只写规范键) |
路径全部可通过环境变量覆盖(详见数据目录与日志说明);dsh 的 profile 默认 web,可用 A4API_DSH_MCP_PROFILE 指定。
3. 发现与聚合
「MCP 管理」页签加载时调用 /api/v1/mcp/discover,扫描四端全局与各项目级配置文件,把跨端同名的 server 聚合到一张卡片,并标注「已在 N 端存在」:
全局配置文件] --> D[归一 schema
按 name 聚合] B[扫描项目级
配置文件] --> D D --> E{同名?} E -->|是| F[合并到一张卡片
标注「已在 N 端存在」] E -->|否| G[单独一张卡片] F --> H[渲染卡片列表
env/headers 脱敏] G --> H style A fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style B fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style D fill:#ebdef0,stroke:#8e44ad,stroke-width:2px style E fill:#ebdef0,stroke:#8e44ad,stroke-width:2px style F fill:#d6eaf8,stroke:#1a6b8a,stroke-width:2px style G fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style H fill:#d5f5e3,stroke:#27ae60,stroke-width:2px
几个细节:
- 传输归一:各家对传输类型的命名不一(如 dsh 的
streamable-http、ZCode 省略 type 时按字段推断),统一归一为stdio/sse/http三种。 - 脱敏:server 详情的
env/headers只回显键名,API 永不回传明文密钥;迁移读写由后端直接基于配置文件进行,前端全程见不到真实值。 - 项目级识别:Claude Code 读
<项目>/.mcp.json,Codex 读<项目>/.codex/config.toml,ZCode 读<项目>/.zcode/config.json;dsh 无项目级 MCP。
4. 跨端迁移与传输能力矩阵
点击卡片的「迁移」选择源副本与目标位置(全局 / 项目),执行后把 server 的配置片段写入每个目标端:
- 源端保留:迁移是复制而非移动,源配置文件不变。
- 先快照再写入:目标端已有同名 server 时,旧片段先快照进回收站再写入新内容,绝不静默覆盖;写入前自动备份目标配置文件(滚动保留 5 份)。
- 严格校验:迁移按传输能力矩阵校验源传输类型是否被目标端支持,不兼容的组合整对失败并留日志,不静默降级:
含传输类型] --> B{目标端支持
该传输?} B -->|否| C[整对失败
写入迁移日志] B -->|是| D{目标端已有
同名 server?} D -->|是| E[旧片段快照
进回收站] D -->|否| F[直接写入] E --> G[写入目标配置文件
前先备份] F --> G G --> H[记录迁移日志] C --> H style A fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style B fill:#ebdef0,stroke:#8e44ad,stroke-width:2px style C fill:#fadbd8,stroke:#c0392b,stroke-width:2px style D fill:#ebdef0,stroke:#8e44ad,stroke-width:2px style E fill:#ffecd6,stroke:#e67e22,stroke-width:2px style F fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style G fill:#d6eaf8,stroke:#1a6b8a,stroke-width:2px style H fill:#d5f5e3,stroke:#27ae60,stroke-width:2px
4.1 传输能力矩阵
| 目标端 | 支持的传输 | 配置文件 | 项目级 |
|---|---|---|---|
| Claude Code | stdio / sse / http | ~/.claude.json |
支持 .mcp.json |
| Codex | 仅 stdio | ~/.codex/config.toml |
支持 |
| dsh | stdio / streamable-http | cordis.patch.yml |
不支持 |
| ZCode | stdio / sse / http | ~/.zcode/cli/config.json |
支持 |
4.2 各端写入细节
- dsh:MCP server 挂在
@deepseek-ai/dsh-mcp-client插件条目下,重写时保留该插件其他非管理条目与其余插件;条目 id 按 server 名安全化(仅保留字母数字与-/_)。 - ZCode:官方 schema 严格(未知键会被丢弃),a4api 只写规范字段(
type/command/args/cwd/env/url/headers/enabled/timeoutMs);type可省略,有command推断 stdio、有url推断 http/sse。迁移到 ZCode 的 server 会被客户端自动连接。 - Codex:仅 stdio——把 sse / http 传输的 server 迁到 Codex 会整对失败,改用本地桥接(如
npx起 stdio 包装)后再迁。
5. 回收站与安全
- 被替换 / 删除的 server 配置片段快照进回收站:磁盘快照存于数据目录
mcp_recycle\,数据库mcp_trash表记录原配置文件路径等恢复信息,30 天内可恢复原位或彻底删除,过期条目访问时惰性清理。 - 快照中的
env/headers用 DPAPI 加密落盘,恢复时解密写回——保证回收站这个"垃圾桶"里也没有明文密钥。 - 每次成功或失败的迁移写入
McpMigration日志(时间、server、传输类型、源、目标、结果),「迁移日志」弹窗按新到旧查看。 - 发现、内容预览、回收站接口对敏感字段全程脱敏。
6. 接口一览
| 接口 | 方法 | 用途 |
|---|---|---|
/api/v1/mcp/discover |
GET | 全量发现与聚合 |
/api/v1/mcp/migrate |
POST | 跨端迁移(源端保留,冲突先入回收站) |
/api/v1/mcp/migrations |
GET | 迁移日志(新到旧) |
/api/v1/mcp/delete |
POST | 删除某端某 server(配置片段移入回收站) |
/api/v1/mcp/content |
GET | 读取 server 详情(脱敏)供预览 |
/api/v1/mcp/trash |
GET | 回收站列表(含惰性清理提示) |
/api/v1/mcp/trash/{id}/restore |
POST | 恢复回收站条目到原位置 |
/api/v1/mcp/trash/{id} |
DELETE | 彻底删除回收站条目 |
7. 常见问题
问:迁移会把源端的 MCP server 移走吗?
答:不会。迁移把配置片段复制到目标端,源端配置文件保持不变;目标端已有同名 server 时旧片段先进回收站,不静默覆盖。
问:为什么把 sse 的 server 迁到 Codex 会失败?
答:Codex 的 MCP 客户端仅支持 stdio 传输,sse / http 组合不满足传输能力矩阵,整对失败并写入日志。想给 Codex 用,请在源端改用 stdio 桥接方式。
问:回收站快照里的密钥安全吗?
答:安全。快照由 mcp_recycle\ 目录承载,其中的 env / headers 在落盘前经 Windows DPAPI 加密,恢复时才解密写回;同时所有接口响应只回显键名,不返回任何明文。
问:mcp_trash 里的旧条目会不会一直占用磁盘?
答:不会。回收站条目超过 30 天后在下次访问回收站时惰性清理,并在返回结果中提示本次清理数量;也可随时对单条执行「彻底删除」。
举手提问