主题
消息格式与通信协议
本文引用的源码文件
本文引用的文件
目录
引言
本文面向 MCP 工具扩展、命令执行流式输出、以及扩展端与本地 Agent 之间的 HTTP/WebSocket 通信,给出完整的消息格式、连接握手、心跳与断线重连、错误码与重试策略、状态管理机制说明,并配套序列图与流程图帮助理解整体交互。
本项目为双进程架构:
- Chrome 扩展端(Manifest V3,版本 2.3.1)通过
src/background/local-agent-client.js发起 HTTP 请求与 WebSocket 连接。 - 独立本地代理端 Agent(Node.js,入口
agent/src/server.js,npm 包名 ai-helper-agent,版本 2.3.1)提供 HTTP API、WebSocket 命令输出通道、MCP 工具注册与调用、长期记忆与 RAG 能力。
两端版本号始终保持同步;Agent 源码修改后必须重启进程新接口才生效。
项目结构与通信边界
扩展端与 Agent 端的通信契约是系统核心:
- 扩展端经本地 HTTP/WebSocket 端点调用 Agent 的文件读写、命令执行、长期记忆与 RAG 能力。
- MCP 工具由 Agent 侧自动发现与调用,扩展端仅暴露统一 REST 接口。
- 所有需认证的请求均携带 Bearer Token;WebSocket 认证优先使用 Authorization Header,回退到 URL query token。
graph TB
subgraph "Chrome 扩展端"
BG["background/local-agent-client.js<br/>HTTP + WebSocket 客户端"]
SC["background/stream-controller.js<br/>SSE 解析与节流"]
end
subgraph "本地 Agent 端"
S["agent/src/server.js<br/>HTTP 路由 + WebSocket 服务器"]
E["agent/src/executor.js<br/>命令执行 + WS 广播"]
M["agent/src/mcp/*<br/>MCP 客户端与注册表"]
end
BG --> |HTTP /api/*| S
BG --> |WebSocket /ws/exec/{execId}?token=...| S
S --> E
S --> M
SC -.-> BG
图示来源
- src/background/local-agent-client.js#L399-L443
- src/background/local-agent-client.js#L662-L728
- agent/src/server.js#L2087-L2153
- agent/src/executor.js#L198-L206
章节来源
核心组件与职责
- 扩展端 HTTP 客户端:封装带认证的 fetch 请求、超时控制、可达性缓存、多代理配置管理。
- 扩展端 WebSocket 客户端:创建命令执行实时输出通道,透传 JSON 或原始文本。
- Agent HTTP 服务器:统一路由、CORS、鉴权、文件操作、RAG/Memory/Skill/MCP 分发。
- Agent 命令执行器:维护进程生命周期、超时、WS 广播 stdout/stderr/exit/error。
- SSE 流控制器:解析 OpenAI 兼容 SSE,聚合 tool_calls、usage,节流推送。
- MCP 客户端与注册表:支持 stdio/sse/streamable-http/websocket 传输,统一管理工具发现与调用。
章节来源
- src/background/local-agent-client.js#L399-L443
- src/background/local-agent-client.js#L662-L728
- agent/src/server.js#L417-L553
- agent/src/executor.js#L198-L206
- src/background/stream-controller.js#L36-L53
- agent/src/mcp/client.js#L35-L45
- agent/src/mcp/registry.js#L19-L20
架构总览
扩展端通过 local-agent-client.js 向 Agent 发起两类通信:
- HTTP:用于配对、状态查询、文件操作、MCP 工具列表与调用、Skill/RAG 管理等。
- WebSocket:用于命令执行的实时输出流。
Agent 侧 server.js 同时承载 HTTP 路由与 WebSocket 升级;命令执行委托给 executor.js,MCP 工具通过 mcp/registry.js 与 mcp/client.js 管理。
sequenceDiagram
participant FE as "扩展端 background"
participant AC as "local-agent-client.js"
participant AG as "agent/src/server.js"
participant EX as "agent/src/executor.js"
FE->>AC : "发起命令执行"
AC->>AG : "POST /api/exec {command,cwd,timeoutMs}"
AG->>EX : "executeCommand(...) 返回 execId/wsUrl"
AG-->>AC : "{success : true, execId, wsUrl}"
AC->>AG : "WebSocket /ws/exec/{execId}?token=..."
AG->>EX : "addWsClient(execId, ws)"
EX-->>AG : "stdout/stderr/exit/error 事件"
AG-->>AC : "JSON 消息 {type,data,...}"
图示来源
- src/background/local-agent-client.js#L600-L612
- agent/src/server.js#L2089-L2153
- agent/src/executor.js#L198-L206
详细组件分析
一、HTTP 请求/响应消息结构
通用约定:
- 头部:
Authorization: Bearer <token>:除/api/pair、/api/status等免认证接口外均需携带。Content-Type: application/json:JSON 请求体。Accept-Language:语言偏好。
- 响应体:
- 成功:
{ success: true, ... } - 失败:
{ success: false, error: "<i18n key or message>" } - 部分扩展端会附加
httpStatus字段以区分网络/HTTP 状态与业务错误。
- 成功:
常用端点摘要(节选):
- 认证与会话:
POST /api/pair:配对,返回 token。GET /api/status:健康检查(无认证)。GET /api/status/detail:详细状态(需认证)。GET /api/heartbeat:心跳(需认证)。
- 文件系统:
POST /api/fs/read、/api/fs/write、/api/fs/list、/api/fs/delete、/api/fs/search_files、/api/fs/search_content、/api/files/upload、/api/fs/download-stream等。
- 命令执行:
POST /api/exec:启动命令,返回{ execId, wsUrl }。POST /api/exec/stop:停止运行中的命令。POST /api/exec/detach:显式 daemon 化。
- MCP:
GET /api/mcp/tools、POST /api/mcp/call、GET /api/mcp/servers、POST /api/mcp/servers、DELETE /api/mcp/servers、POST /api/mcp/servers/connect、POST /api/mcp/servers/disconnect、PUT /api/mcp/servers/toggle。
- Skill/RAG/审计日志/回收站等:见客户端注释汇总。
错误码与语义:
- HTTP 层:400/401/403/404/409/429/500/503 等。
- 业务层:统一
success:false+error字符串;具体含义由 i18n key 表达。 - 扩展端在
agentRequest中会把 HTTP 状态码附加到返回对象的httpStatus,便于上层区分“文件不存在”和“Agent 离线”。
章节来源
- src/background/local-agent-client.js#L43-L93
- src/background/local-agent-client.js#L399-L443
- agent/src/server.js#L474-L553
- agent/src/server.js#L987-L1599
- agent/src/server.js#L2050-L2075
二、WebSocket 连接建立与消息传输协议
连接建立流程:
- 扩展端构造 URL:
ws[s]://{host}:{port}/ws/exec/{execId}?token=<token>。 - Agent 侧在
upgrade事件中校验路径与 token,通过后升级为 WebSocket。 - 认证成功后,服务端将 ws 加入对应 execId 的监听列表,并开启心跳检测。
消息格式(命令执行通道):
- 标准 JSON 消息:
{ type: "stdout", data: "...", execId }{ type: "stderr", data: "...", execId }{ type: "exit", exitCode: number, execId, killed: boolean, timedOut: boolean }{ type: "error", error: string, execId }
- 非 JSON 数据:扩展端会降级为
{ type: "raw", data: event.data }。
心跳机制:
- 服务端每 30 秒 ping 一次,若未收到 pong 则 terminate 连接,触发断开清理逻辑。
- 客户端不主动发送 ping/pong,浏览器会自动响应 ping。
断线重连:
- 客户端本身不做指数退避重连;上层(如工具执行器)负责 Promise 超时、取消与资源清理。
- 服务端在进程已结束场景下,对晚到的 WS 连接回放全部历史输出并立即关闭。
sequenceDiagram
participant C as "扩展端 WebSocket"
participant S as "Agent server.js"
participant X as "Agent executor.js"
C->>S : "HTTP Upgrade /ws/exec/{execId}?token=..."
S->>S : "verifyToken(token)"
alt 认证成功
S->>X : "addWsClient(execId, ws)"
S->>C : "ping (每30s)"
C-->>S : "pong"
X-->>S : "stdout/stderr/exit/error"
S-->>C : "转发 JSON 消息"
else 认证失败
S-->>C : "403 Forbidden"
end
图示来源
- src/background/local-agent-client.js#L662-L728
- agent/src/server.js#L2089-L2153
- agent/src/executor.js#L429-L479
章节来源
- src/background/local-agent-client.js#L662-L728
- agent/src/server.js#L2089-L2153
- agent/src/executor.js#L429-L479
三、SSE 流式输出与工具调用
扩展端还消费模型服务商的 SSE 流(非 Agent WebSocket),由 StreamController 负责:
- 解析
data:行,识别[DONE]、choices.delta.content、choices.delta.tool_calls、usage。 - 节流合并内容增量,避免 UI 抖动。
- 当检测到
finish_reason === 'tool_calls'时,提前通知前端工具卡片,随后继续读取 usage。 - 空闲超时保护:持续无数据超过阈值即中断流,释放底层 reader。
flowchart TD
Start(["开始读取SSE"]) --> Parse["逐行解析 data: 行"]
Parse --> DoneCheck{"[DONE]?"}
DoneCheck --> |是| Finish["finish() 发送 STREAM_DONE"]
DoneCheck --> |否| Usage["提取 usage若有"]
Usage --> Choice{"存在 choices[0] ?"}
Choice --> |否| Ignore["忽略该行"]
Choice --> |是| Delta["处理 delta.content / reasoning_content / tool_calls"]
Delta --> ToolCalls{"finish_reason === 'tool_calls' ?"}
ToolCalls --> |是| Notify["发送 STREAM_TOOL_CALL 并返回"]
ToolCalls --> |否| Content{"delta.content ?"}
Content --> |是| Throttle["节流合并并发送 STREAM_CHUNK"]
Content --> |否| Accumulate{"delta.tool_calls ?"}
Accumulate --> |是| Accum["累积参数,等待 finish_reason"]
Accumulate --> |否| Next["继续下一行"]
Throttle --> Next
Notify --> End(["结束本轮"])
Finish --> End
Ignore --> Next
Next --> Parse
图示来源
章节来源
- src/background/stream-controller.js#L36-L53
- src/background/stream-controller.js#L59-L168
- src/background/stream-controller.js#L287-L409
四、MCP 工具消息与状态
MCP 工具通过 Agent 内部注册表统一管理:
- 扩展端调用
/api/mcp/tools获取扁平化工具列表(含 serverId、name、inputSchema)。 - 扩展端调用
/api/mcp/call传入 serverId、toolName、args,由注册表定位已连接的 McpClient 并转发。 - McpClient 支持多种传输:stdio、SSE、streamable-http、websocket。
classDiagram
class McpClient {
+string serverId
+string serverName
+boolean connected
+Array tools
+connect()
+callTool(toolName, args)
+disconnect()
+getStatus()
}
class Registry {
+initializeMcpRegistry()
+getMcpServersStatus()
+getMcpTools(serverId?)
+callMcpTool(serverId, toolName, args)
+connectMcpServer(serverId)
+disconnectMcpServer(serverId)
+shutdownMcpRegistry()
}
Registry --> McpClient : "管理实例"
图示来源
- agent/src/mcp/client.js#L35-L45
- agent/src/mcp/client.js#L96-L127
- agent/src/mcp/client.js#L129-L158
- agent/src/mcp/registry.js#L26-L55
- agent/src/mcp/registry.js#L89-L128
章节来源
- agent/src/mcp/client.js#L35-L45
- agent/src/mcp/client.js#L96-L127
- agent/src/mcp/client.js#L129-L158
- agent/src/mcp/registry.js#L26-L55
- agent/src/mcp/registry.js#L89-L128
五、状态管理机制
- 会话状态:
- 扩展端通过
sessionId、callId关联流式消息与工具调用结果。 StreamController维护fullContent、reasoningContent、usage、toolCalls。
- 扩展端通过
- 工具状态:
- MCP 工具通过
serverId与toolName标识;注册表维护已连接 client 的工具清单。
- MCP 工具通过
- 连接状态:
- 扩展端按 agentId 维护可达性缓存
_agentReachability,不可达时直接短路请求。 - Agent 侧 WebSocket 维护每个 execId 的活跃客户端集合,心跳检测半开连接。
- 命令执行支持受管模式:调用方显式传
timeoutMs接管超时权威,断连不解除定时器。
- 扩展端按 agentId 维护可达性缓存
章节来源
- src/background/stream-controller.js#L36-L53
- src/background/stream-controller.js#L222-L280
- src/background/local-agent-client.js#L100-L140
- agent/src/executor.js#L198-L206
- agent/src/executor.js#L429-L479
依赖关系分析
local-agent-client.js依赖shared/logger.js、shared/i18n.js、shared/secret.js。server.js依赖auth.js、security.js、executor.js、logger.js、memory/routes.js、rag/*、skill/*、mcp/*。executor.js依赖config.js、security.js、logger.js。stream-controller.js依赖shared/logger.js。mcp/client.js依赖@modelcontextprotocol/sdk各传输实现。mcp/registry.js依赖mcp/client.js、mcp/mcp-config.js、i18n.js。
graph LR LAC["local-agent-client.js"] --> SJS["server.js"] SJS --> EXE["executor.js"] SJS --> MCP_REG["mcp/registry.js"] MCP_REG --> MCP_CLI["mcp/client.js"] LAC --> SC["stream-controller.js"]
图示来源
- src/background/local-agent-client.js#L1-L4
- agent/src/server.js#L1-L37
- agent/src/executor.js#L198-L206
- agent/src/mcp/registry.js#L1-L5
- agent/src/mcp/client.js#L1-L6
章节来源
- src/background/local-agent-client.js#L1-L4
- agent/src/server.js#L1-L37
- agent/src/executor.js#L198-L206
- agent/src/mcp/registry.js#L1-L5
- agent/src/mcp/client.js#L1-L6
性能与网络异常处理
- 请求超时:
- HTTP:
agentRequest默认 60s,agentGet默认 30s;上传默认 60s;下载默认 120s;RAG ingest 放宽至 600s。 - WebSocket:空闲超时由调用方(工具执行器)Promise 超时统一管理,避免双重超时冲突。
- SSE:空闲超时 120s,持续无数据即中断 reader 并释放连接。
- HTTP:
- 流量与内存:
- 大文件采用流式上传/下载,避免 base64 膨胀与全量内存占用。
- ZIP 打包分块写入,降低峰值内存。
- 并发与限流:
- Agent 操作冷却时间(如重启/更新)防止频繁调用。
- 搜索最大结果数限制。
- 健壮性:
- 全局捕获未处理异常与未拒绝 Promise,记录日志但不退出进程。
- 优雅关闭:终止子进程、关闭 MCP 连接、强制销毁活跃 socket,10s 兜底退出。
章节来源
- src/background/local-agent-client.js#L399-L443
- src/background/local-agent-client.js#L516-L550
- src/background/local-agent-client.js#L600-L612
- src/background/stream-controller.js#L9
- src/background/stream-controller.js#L287-L409
- agent/src/server.js#L2239-L2308
故障排查指南
常见问题与定位要点:
- 无法连接 Agent:
- 检查扩展端是否已配对且 activeAgentId 有效。
- 检查
_agentReachability是否为 false,若是则跳过请求。 - 确认 Agent 服务端口未被占用,查看
server_error日志。
- WebSocket 连接失败:
- 检查 URL 中 execId 是否存在,token 是否正确。
- 服务端会在认证失败时返回 403 并关闭连接。
- 若进程已结束,服务端会回放历史输出后立即关闭。
- 命令执行卡住:
- 检查工具执行器的 Promise 超时与 detach 策略。
- 受管模式下,断连不会解除超时;只有显式 detach 才会豁免。
- MCP 工具不可用:
- 检查 MCP Server 是否 enabled 且已 connect。
- 查看注册表日志,确认工具列表加载成功。
- SSE 流中断:
- 关注 StreamIdleTimeout 日志,检查上游服务商是否长时间无数据。
- 确认
streamEnabled配置未被禁用。
章节来源
- src/background/local-agent-client.js#L100-L140
- src/background/local-agent-client.js#L662-L728
- agent/src/server.js#L2089-L2153
- agent/src/executor.js#L429-L479
- agent/src/mcp/registry.js#L26-L55
- src/background/stream-controller.js#L287-L409
结论
本通信协议以扩展端 HTTP/WebSocket 客户端与 Agent 端 HTTP+WebSocket 服务器为核心,结合 SSE 流控制器与 MCP 工具注册表,形成可扩展、可观测、可恢复的命令执行与工具调用体系。通过统一的认证、错误码、心跳与超时策略,确保在 MV3 Service Worker 生命周期约束与网络异常环境下仍能稳定工作。实际集成时,请严格遵循本文的消息格式、状态管理与异常处理建议,并在 Agent 源码变更后重启进程以确保接口生效。