系统总览
本章是 30,000 英尺高度的视角:一次构建请求怎么从你的键盘(或浏览器)
走到一个编译好的 .bin,再走回来。后面三章会拉近镜头,看每一层。
角色
| 组件 | 在哪里运行 | 做什么 |
|---|---|---|
| 你的客户端 | 你的笔记本 | 支持 MCP 的 AI 客户端(Claude Code、Cursor、…)或 esphome.cloud 浏览器向导。 |
espctl mcp serve | 你的笔记本或构建机器 | MCP 服务。把 MCP 工具调用翻译为本地计划,或者通过 WebRTC 翻译为远程构建请求。 |
| 构建服务器 | 一台公开的 Linux 主机 | 颁发构建许可,代理 WebRTC 连接建立,把任务分配给构建机器。从不接触构建本身。 |
| 构建机器 | 一台带 IDF 工具链的私有 Linux 主机 | 在沙箱里跑实际构建。通过 WebRTC 数据通道与你的客户端通信。 |
| store | 构建机器上的硬盘 | 装着所有已安装的 IDF 版本和工具链的目录。 |
一次构建怎么流动
┌────────────────┐
│ 你的客户端 │
│ (IDE 或浏览器) │
└────┬───────────┘
│ ① "给我编译一个 esp32s3 固件"
▼
┌────────────────┐ ② 许可请求 ┌─────────────────┐
│ MCP 服务 │───────────────────────────►│ 构建服务器 │
│ (espctl) │◄───────────────────────────│ - 颁发许可 │
└────┬───────────┘ ③ 许可 + ICE 服务 │ - 挑构建机器 │
│ └─────────┬───────┘
│ ④ SDP offer (POST /signaling/.../offer) │
│ │ ⑤ 事件
│ ▼ 流
│ ┌─────────────┐
│ │ 构建机器 │
│ └────┬────────┘
│ ⑥ WebRTC 点对点连接 │
│ ◄──────────────────────────────────────────────►
│
│ ⑦ BuildRequest 在 espctl 通道上
│ ⑧ 日志流式在 pty 通道上
│ ⑨ 固件字节在 firmware 通道上
▼
┌────────────────┐
│ 结果: .bin │
│ + 尺寸报告 │
│ + 清单 │
└────────────────┘
编号步骤:
- 你向 AI 客户端发问(或在浏览器向导中点按钮)。
- MCP 服务(或浏览器)向构建服务器 POST 一个构建许可请求: “我想要一个
构建会话,带
espctl、pty、firmware通道,最长 30 秒。” (长会话用单独的、更长有效期的许可。) - 构建服务器返回一个签名的许可,挑出一个或多个有能力跑这个任务的 候选构建机器,并附上 STUN/TURN ICE 服务列表用于 WebRTC 握手。
- MCP 服务向连接建立端点 POST 一个 SDP offer。
- 被选中的构建机器 —— 它一直在定期查看构建服务器有没有新任务 —— 通过 实时推送抓到许可,准备接收 offer。
- WebRTC ICE 协商发生。两边通过构建服务器交换候选(构建服务器纯粹做 转发,它从不看 SDP 体的内容),最终聚合到要么直接点对点连接、要么 TURN 中继的连接。
- 数据通道开了之后,客户端在
espctl通道上发送BuildRequest。 构建机器在本地验证许可签名,开始构建。 - 随构建进行,构建机器在
pty通道上流回idf.py的 stdout/stderr, 在espctl通道上发结构化的流水线事件。 - 构建成功后,构建机器把固件二进制分块,在
firmware通道上流回, 最后再发一个 SHA-256 用于校验。
构建本身在构建机器上的沙箱里运行 —— 它无法读或写构建机器为它准备的 工作区目录之外的任何东西。
三层,三个职责
这是后面架构章节展开的三层模型:
- 构建服务器与连接建立 —— 公开、无状态,知道谁但不知道 什么。颁发许可。转发 SDP。永远没有解密任何东西的权限。
- WebRTC 构建机器与数据通道 —— 私有,跑构建,逐客户端 执行通道白名单和带宽限制。拥有完整的代码执行权限,但仅限沙箱内。
- 构建许可与安全 —— 把上述两者绑在一起的密码学协议。 许可是一个签名 token,说“这个用户在这段时间里能用这些通道“。
为什么是这种形状?
架构的设计理念是让公开面(构建服务器)无状态且不可信。攻陷 构建服务器让你拿到颁发许可的能力,但许可没有构建机器配合就没用 —— 而构建机器会用编译时嵌入的、它信任的公钥在本地校验许可签名。
反过来,攻陷一个构建机器让你拿到当前在沙箱里跑的代码,但构建机器无法 冒充其他用户或颁发许可。构建机器本质上是“在沙箱里跑不可信代码的昂贵 机器“ —— 这正是沙箱被设计用来对付的威胁模型。
数据通道本身尽可能直接点对点,所以构建日志和固件二进制不会 经过构建服务器。这意味着运营构建服务器的人即使想读你的构建日志或固件 镜像,也无法做到。