05 — 多协议服务架构:MCP / HTTP-SSE / ACP
多协议服务架构:MCP / HTTP-SSE / ACP
学习目标
理解 CodeWhale 的三种服务模式:MCP stdio 服务器、HTTP/SSE 运行时 API、ACP 编辑器适配器,以及它们的复用基础与隔离边界。
前置知识
- MCP 协议与生态集成 — Model Context Protocol 的传输层与客户端架构
- ACP JSON-RPC 路由 — Agent Client Protocol 的适配器模式
下文假设你已理解上述概念,直接聚焦 CodeWhale 的具体实现。
项目实践
三种模式对比
| 维度 | serve --mcp | serve --http | serve --acp |
|---|---|---|---|
| 协议 | MCP stdio | HTTP/SSE JSON-RPC | ACP stdio |
| 用例 | 供其他 MCP 客户端调用的工具服务器 | 应用直接消费的运行时 API | Zed/自定义编辑器的 Agent |
| 配置 | ~/.codewhale/mcp.json 条目 | 直接 URL 连接 | 编辑器 agent_servers 自定义命令 |
| 生命周期 | 每客户端会话生成子进程 | 长期守护进程 | 每编辑器 Agent 会话生成 |
| 入口点 | codewhale-tui serve --mcp 或 codewhale mcp-server | codewhale serve --http | codewhale serve --acp |
复用基础
三种模式共享同一个 TUI 运行时引擎:
每种协议模式将外部请求映射为内部引擎操作,将引擎响应映射为协议特定的响应格式。
MCP stdio 服务器
启动方式:
codewhale-tui serve --mcp# 或等价的调度器入口codewhale mcp-server自注册为 MCP 服务器:
codewhale-tui mcp add-self这解析当前二进制路径,生成运行 codewhale-tui serve --mcp 的配置条目,写入 MCP 配置文件。这样其他 MCP 客户端(包括其他 CodeWhale 会话)可以调用本实例的工具。
工具命名:遵循 mcp_<server>_<tool> 约定。自注册服务器名为 codewhale,所以 shell 工具变为 mcp_codewhale_shell。
HTTP/SSE 运行时 API
启动方式:
codewhale serve --http # HTTP/SSE API 服务器codewhale serve --mobile # LAN 移动端控制页(默认 token 门控)端点结构:
/v1/threads— 线程管理(创建/列出)/v1/threads/{id}/turns— turn 管理(开始/停止)/v1/threads/{id}/events?since_seq=<n>— 事件回放(客户端重放历史)/v1/tasks— 后台任务管理
安全边界:
- 绑定 localhost——仅供可信本地访问
- EdgeOne 不用于暴露
/v1/*(即使配置了公共 HTTPS 边缘) - 移动端模式使用 token 门控
运行时线程时间线:
- API/TUI 创建或恢复线程
- Turn 在线程上启动
- 引擎事件映射为 item 生命周期事件(
item.started/item.delta/item.completed) - 中断/转向操作仅应用于活跃 turn
- 压缩/清除作为特殊 item 生命周期发出
- 客户端通过
since_seq参数回放历史并恢复
ACP 编辑器适配器
启动方式:
codewhale serve --acpZed 集成:
{ "agent_servers": { "DeepSeek": { "type": "custom", "command": "codewhale", "args": ["serve", "--acp"], "env": {} } }}当前功能限制:
- 第一个 ACP 切片支持新会话和提示响应
- 通过现有的 DeepSeek 配置/API 密钥
- 工具支持的编辑和检查点回放尚未通过 ACP 暴露
社区适配器:acp-codewhale-adapter 桥接 codewhale exec --auto 到 cc-connect,用于需要在内置 Zed 切片之外使用工具支持 ACP 工作流的用户。
问题与规避
陷阱:HTTP API 暴露到公网
HTTP/SSE API 设计为 localhost 访问。如果通过反向代理暴露到公网,没有额外的认证层会很危险。
规避:
--mobile模式有 token 门控- 文档明确说 “EdgeOne is not used to expose
/v1/*” - 生产部署应在反向代理后添加认证层
陷阱:MCP 自注册导致循环调用
A 会话将 B 会话注册为 MCP 服务器,B 又调用 A——可能导致循环。
规避:每个 MCP 会话是独立的子进程,有自己的配置和 API 密钥。循环调用在实际中不太可能自然发生,但用户应避免手动配置相互调用。
陷阱:ACP 功能不完整
ACP 适配器当前仅支持基本会话和提示响应,不支持工具编辑和检查点回放。
规避:对于需要完整 ACP 工作流的用户,使用社区维护的 acp-codewhale-adapter。
设计取舍
为什么三种模式共享同一引擎
- 代码复用:核心 Agent 循环、工具系统、会话管理不需要为每个协议重写
- 一致性:无论通过哪个协议访问,行为一致
- 维护成本:只需维护一个引擎实现
代价:
- 引擎与协议层的耦合可能导致某协议的变更影响其他协议
- 引擎的启动路径需要适配三种不同的生命周期(子进程/守护进程/编辑器会话)
为什么 ACP 功能受限
ACP 适配器是后加的集成层,核心引擎最初只为 TUI 和 CLI 设计。工具编辑和检查点回放需要:
- 编辑器特定的 UI 协议(如 diff 展示、接受/拒绝变更)
- 检查点状态在编辑器与 Agent 之间的同步
这些需要额外的工作,不在第一个 ACP 切片的范围内。
参考来源
docs/MCP.md— MCP 集成文档docs/RUNTIME_API.md— HTTP/SSE API 文档crates/tui/src/runtime_api.rs— HTTP/SSE 运行时 API 实现(~4368 行)crates/tui/src/acp_server.rs— ACP 适配器实现crates/mcp/— MCP 客户端和 stdio 服务器