mcpField
E
ESP-IDF MCP

ESP-IDF MCP

本地服务
github.com/Maty403开发工具16 天前更新

关于 ESP-IDF MCP

ESP-IDF MCP 是供 Agent 在连接的硬件上构建和测试 ESP-IDF 固件的本地 MCP 服务,涵盖编译、串口烧录与监控、芯片信息及硬件在环测试。

主要功能

  1. 01构建和清理 ESP-IDF 项目
  2. 02烧录固件并监控串口日志
  3. 03读取连接设备的芯片和闪存信息
  4. 04创建项目并浏览随附示例
  5. 05管理组件依赖并运行硬件测试

适用场景

  1. 01构建 ESP-IDF 项目固件
  2. 02向开发板烧录并检查启动输出
  3. 03查看已连接芯片的信息
  4. 04在真实硬件上运行 pytest-embedded 测试

MCP 相关

该服务向 MCP 客户端提供 ESP-IDF 项目、串口设备和硬件测试工具,还提供列出已连接串口的 project://devices 资源。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"maty403-esp-idf": {
"command": "uvx",
"args": [
"esp-idf-mcp"
]
}
}
}
启动命令uvx esp-idf-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiesp-idf-mcp1.1.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

esp-idf-mcp

License Platform Python Protocol

一个 Model Context Protocol(MCP)服务,可让 AI Agent 在真实硬件上构建、烧录和监控 ESP-IDF 项目——端到端覆盖从源代码到启动日志的完整流程。

Agent 不再只能 编写 固件代码,这个服务还打通了整个流程:编译 → 通过串口烧录 → 捕获启动日志 → 运行 pytest-embedded 硬件测试——全程无需离开 Agent 的工具集。

快速开始(Windows + Codex)

要求: ESP-IDF、Python 3.9 或更高版本,以及支持 MCP 的 Codex 客户端。只有烧录、串口监控和硬件在环测试需要连接开发板。

  1. 克隆此仓库,并将其安装到 Codex 将使用的 Python 环境中:

    git clone https://github.com/Maty403/esp-idf-mcp.git
    cd esp-idf-mcp
    python -m pip install .
    
  2. 将服务添加到 Codex。桌面应用、命令行和 IDE 扩展共用 MCP 配置。在终端中运行:

    codex mcp add esp-idf -- esp-idf-mcp
    codex mcp list
    

    如果 esp-idf-mcp 不在 PATH 中,请打开 %USERPROFILE%\.codex\config.toml 并添加以下内容,替换其中的两个路径。请使用运行 pip install . 时所用的同一个 Python 环境:

    [mcp_servers.esp-idf]
    command = "C:\\path\\to\\python.exe"
    args = ["C:\\path\\to\\esp-idf-mcp\\esp_idf_mcp.py"]
    
  3. 重启 Codex,打开一个 ESP-IDF 项目,然后询问:“构建这个 ESP-IDF 项目。” 在桌面应用中,检查 设置 → MCP 服务,或输入 /mcp 确认服务已连接。

演示工作流

打开 ESP-IDF 项目并连接开发板后,试试以下操作:

  1. “读取已连接芯片的信息并列出串口设备。”
  2. “构建这个项目。”
  3. “将这个项目烧录到 COM3,然后监控启动日志并总结应用程序的输出。”

请将 COM3 替换为你机器上显示的正确端口。烧录前请确认目标开发板和端口。

此服务的定位

一个由社区构建的本地 MCP 服务,适用于 ESP-IDF 硬件工作流。可用它让 AI Agent 在同一工作流中构建固件、与串口连接的开发板交互,并运行硬件在环测试。

功能对比

与 Espressif 的内置 ESP-IDF Tools MCP 服务相比(文档检查于 2026-10-26):

工作流内置 ESP-IDF Tools MCPesp-idf-mcp
设置目标、构建、烧录、清理支持支持
创建项目示例模板最简模板或捆绑的 ESP-IDF 示例
监控设备等待预期输出;保存完整串口日志持久的读取/发送/关闭会话、增量和完整日志视图、波特率检测,以及 USB 重连处理
项目和设备上下文项目配置、构建状态、已连接设备资源已连接设备资源,以及芯片型号、版本、晶振、MAC 和闪存详情
组件和硬件测试未列于内置 Tools MCP 工具集浏览捆绑的示例、添加/移除组件依赖项,并运行 pytest-embedded 硬件测试

此表对比的是本地 Tools MCP 服务与本项目。Espressif 的独立 Documentation MCP 和 Component Registry MCP 服务提供文档和组件发现功能;它们可以与任一本地工具服务搭配使用。

功能

  • ESP-IDF 零配置发现 — 自动定位 IDF 根目录、工具目录和 Python 虚拟环境(优先使用环境变量,否则选择 D:\esp、C:\esp 或 ~/esp 下最新的安装);工具链路径按版本通配符匹配,因此升级 ESP-IDF 或工具链时无需编辑脚本。
  • 通过 idf.py build 构建 — 与手动构建使用完全相同的路径,不会额外改写配置。因此,sdkconfig 和 sdkconfig.defaults 保持官方上游语义:默认文件用于初始化新的 sdkconfig(通用的 sdkconfig.defaults,以及通用文件存在时的 sdkconfig.defaults.<target>),而后续构建时,sdkconfig 中已有的值优先。对 sdkconfig 的手动编辑会通过官方 ninja RERUN_CMAKE 流程生效。
  • 一次调用完成烧录和自动监控 — 使用 esptool 烧录(读取 build/flash_args),等待硬复位启动完成,然后在该端口上打开持久监控会话并立即返回——开发板会复位,因此会话只保留最新的启动日志;使用 monitor_read 轮询。目标端口就是你传入的端口(省略时会自动检测,但只有在恰好连接了一个非 COM1 端口时才会检测——否则调用会拒绝执行并列出候选端口);烧录前只会关闭该端口的监控会话(若没有会话则跳过),不会影响其他开发板。
  • 从真实硬件读取芯片信息 — read_chip_info 通过 esptool 报告芯片型号、版本、特性、晶振、MAC 地址,以及闪存厂商、设备和容量,然后硬复位开发板,使其重新进入运行中的应用。
  • 自动检测波特率 — 每次串口采集都会从项目的 sdkconfig 读取 CONFIG_ESP_CONSOLE_UART_BAUDRATE(不使用硬编码默认值),因此日志不会乱码。
  • 基于会话的串口监控 — monitor_open / monitor_read / monitor_send / monitor_close:创建持久、非阻塞的会话,只需轮询获取新增行。monitor_close(session_id) 只会释放你指定的会话,或者指定端口上的所有会话。每次烧录后,flash_project 都会自动打开一个会话,因此启动日志随时可供轮询。会话会自动释放:在 idle_release 秒(默认 30,可在每次调用时覆盖)内没有读写操作后,端口就会释放,因此被遗弃的会话不会一直占用 COM 端口。
  • 应用层日志视图 — monitor_read 从运行时标记 main_task: Returned from app_main() 开始输出:此前的所有内容(启动 ROM、引导加载程序和组件日志,以及你的 app_main() 初始化输出)都会折叠,并在标题中汇总为 N lines folded before app start;标记及其后的所有行(你的任务、wifi、mqtt、普通 printf)则逐行打印。不包含标记的增量内容若为普通续行,会原样打印;若仍处于启动阶段,则会折叠。
  • full 应急选项 + 持久化完整日志 — monitor_read(full=True) 会原样转储缓冲区中保留的所有内容(不拆分层级、不折叠、不改动时间戳),且不会消耗增量读取游标——两种读取模式互不影响。此外,每行串口日志都会写入会话日志文件(<project>/.esp_monitor_full.log),因此即使缓冲区淘汰日志、USB 重新枚举、开发板复位或会话关闭,历史记录也会保留。读取不会丢失信息——所有折叠内容都会在标题中计数,被淘汰的内容则保存在文件中。
  • 便于 Agent 使用的输出 — 在源头去除 ANSI 颜色转义,将相邻重复行合并为 <first line> *N,让重复内容紧邻其计数显示(比较时忽略行首的 I (12345) 前缀,因此不同毫秒记录的行也会合并);仅保留长输出中相关的尾部内容,并在标题中报告被淘汰或跳过的数量,而不是静默丢弃行。
  • 可应对 USB 重新枚举 — 复位后,端口可能会消失再重新出现(ESP32-S2/USB-OTG);读取循环会在最多 10 s 内尝试重新连接,并清除过期的缓冲日志。
  • 硬件在环测试 — 使用 pytest-embedded 测试套件对真实开发板运行测试。 其中包含针对 Windows usbser.sys 的变通方案(仅 RTS 的控制传输需要重新断言 DTR),因此在 USB-CDC 端口和 CH340 风格的适配器上都能正常复位。

工具

工具用途
build_projectidf.py build(与手动构建相同,不会重写配置)
flash_project使用 esptool 烧录;省略 port 时会自动检测(仅当恰好连接一个非 COM1 端口时才会自动检测——否则调用会拒绝执行并列出候选端口);烧录前仅关闭该端口的监视器会话,然后在该端口上打开一个持久监视器会话(波特率取自 sdkconfig),供 monitor_read 使用
read_chip_info芯片型号、修订版、特性、晶振、MAC、闪存厂商/设备/容量
set_targetidf.py set-target(esp32、esp32s3、esp32c2……)
create_project / list_examples创建新项目(最小模板或打包的官方示例);浏览已安装 IDF 随附的示例
add_dependency / remove_dependency管理 idf_component.yml 中的 ESP 组件管理器依赖项
clean_project增量清理或完全清理
monitor_open / monitor_read / monitor_send / monitor_close持久交互式串口会话;monitor_read 从 Returned from app_main() 开始(此前的所有内容折叠为一个计数),将相邻重复项折叠为 <first line> *N,提供 full=True,用于不受游标影响地转储所有保留内容;提供 timestamp=True 以保留毫秒前缀,并将每一行写入 <project>/.esp_monitor_full.log;monitor_close(session_id)(或直接传入端口名称)会释放且仅释放对应会话/端口;会话在 idle_release 秒(默认 120 秒)内没有读/写操作后会自动释放
run_pytest运行 pytest-embedded 硬件测试
project://devices(资源)列出已连接的串口
工具参考

每个工具向 Agent 完整公开的描述:

build_project(project_dir, timeout=600) — 通过 idf.py build 构建 ESP-IDF 项目(与手动构建相同)。timeout 限制整个构建过程的秒数(默认 600);超时后会终止进程树,并返回包含提取出的错误行的失败结果。每次调用都会明确给出 ✅/❌ 结果。完整输出始终写入 <project_dir>/.esp_build.log,每次运行都会重写该文件。配置不会被修改:sdkconfig.defaults 用于初始化新的 sdkconfig,而 sdkconfig 中已有的值优先。

flash_project(project_dir, port=None, monitor=True, wait_after_flash=2.0, timeout=600) — 直接使用 esptool 烧录已构建的项目(读取 build/flash_args)。烧录前会自动关闭目标端口上的监视器会话——无需手动调用 monitor_close。省略 port 时会自动检测,但仅当恰好连接一个非 COM1 端口时才会检测;若连接了多个端口,调用会拒绝执行并列出这些端口,因此绝不会将固件烧录到错误的开发板上。monitor=True 会在烧录后打开持久会话(波特率取自 sdkconfig);wait_after_flash 会等待硬复位启动完成后再打开监视器,从而让会话获取干净的启动日志。timeout 限制整个烧录过程的秒数(默认 600)。完整输出始终写入 <project_dir>/.esp_flash.log,每次运行都会重写该文件。

create_project(path, example='') — 在绝对路径 path 下创建新的 ESP-IDF 项目(该路径必须不存在或为空)。设置 example 后(例如 'get-started/hello_world'),项目会从已安装 IDF 随附的官方示例复制而来——使用 list_examples 浏览这些示例;如果找到根目录中的 project(),会将其名称改为新目录的名称。未设置 example 时,会通过 idf.py create-project 创建最小模板项目。两种方式都完全离线;若要将注册表组件引入新项目,请之后调用 add_dependency(组件会在下一次构建时下载)。 list_examples(category='') — 列出已安装 IDF 中附带的 ESP-IDF 官方示例。不带参数时,列出类别(get-started、wifi、peripherals 等);指定类别时,列出其中的示例,路径可直接用于 create_project(example=…)。

read_chip_info(port=None, baud=115200) — 通过 esptool 获取芯片型号、修订版本、功能、晶振频率、MAC 地址以及闪存厂商、设备和容量信息。开发板会短暂进入下载模式,之后硬件复位并恢复运行应用。此处无法获取 PSRAM 详情——请改用 monitor_open 读取启动日志。

monitor_open(port, reset=True, project_dir=None, idle_release=120, baud=0) — 打开持久串口监视器会话并立即返回(非阻塞)。reset=True 会先清空缓冲区,再对开发板进行硬件复位,因此会话从全新启动开始。baud > 0 时会直接使用指定波特率并跳过自动检测;默认 baud=0 时,会从 project_dir 的 sdkconfig(CONFIG_ESP_CONSOLE_UART_BAUDRATE,回退到 115200)自动检测波特率。project_dir 还会将会话的完整日志写入 <project_dir>/.esp_monitor_full.log(每次打开会话时都会从头重写;在会话期间,每行到达时都会立即写入,因此即使缓冲区淘汰、重新连接或开发板复位,历史记录也会保留;未指定项目目录时,会话不会保存完整日志文件)。会话 ID 为 PORT@BAUD(例如 COM17@115200)。idle_release 设置会话在没有 monitor_read/monitor_send 操作时的存续秒数(默认 120):超过此时长后,会话会自行停止并释放端口,因此即使客户端遗弃会话(MCP 客户端通常会让服务进程继续运行,而不关闭 stdio 管道),也不会一直占用 COM 端口——包括 USB 拔出后重新插入的情况,因为否则读取循环可能会再次占用端口。每次调用 monitor_read/monitor_send 都会重置计时器;若要跨越较长时间的暂停,请传入更大的值,或在完成后显式调用 monitor_close。如果调用报告 No session,只需再次调用 monitor_open——完整历史记录保存在日志文件中。

monitor_read(session_id, full=False, timestamp=False, max_lines=0, match='') — 读取自上次读取以来到达的行。输出从运行时标记 main_task: Returned from app_main() 开始:此标记之前的所有内容(启动日志和 app_main() 初始化信息)都会合并计数,报告为 N lines folded before app start;标记及之后的每一行都会逐行打印。相邻的重复行会合并为 <first line> *N,因此重复内容始终会与计数一起显示(比较时会忽略前缀 I (12345) ,因此即使行日志记录在不同毫秒,也会合并)。没有标记的增量内容,如果是普通的延续内容,则会按原样打印;如果仍处于启动阶段,则会被合并。full=True 会切换到与游标无关的完整转储:逐字输出环形缓冲区中保留的所有行(不合并、不分层,保留时间戳),且不会推进增量游标,因此合并视图和完整视图互不影响。max_lines 限制返回的尾部行数(0 = 返回所有保留内容)。适用时,标头会报告 M evicted by buffer cap 和 K older skipped (showing last T),并显示完整日志文件路径——从环形缓冲区淘汰的行不会丢失,而是保存在文件中。timestamp=True 会保留毫秒前缀(默认会将其移除,显示为 TAG: msg)。 match 按正则表达式筛选输出(不区分大小写,匹配去掉级别/毫秒前缀后的行文本;| 用于分隔多个选项,例如 match='heap|wifi|dhcp')。设置此参数后,会跳过应用启动日志折叠,仅返回匹配的行,适合从嘈杂的日志中提取某个主题。对诊断至关重要的行始终会通过筛选,即使它们没有匹配项:所有 ESP_LOG 错误级别行(E (…)),以及不带日志级别前缀的 panic 处理程序输出(Guru Meditation / panic'ed、abort() was called、assert failed、Backtrace:、堆栈金丝雀、看门狗和 brownout 触发信息、CORRUPT HEAP、核心转储、重置原因、Rebooting…)——筛选视图绝不会隐藏崩溃。未通过筛选的行仍会由增量游标读取;将 match 与 full=True 结合使用,可使用相同的筛选条件重新扫描缓冲区中保留的所有内容。

monitor_send(session_id, data, press_enter=True) — 向设备的串行输入端写入文本(shell 命令、菜单选项);press_enter 会追加 CRLF。

monitor_close(session_id) — 释放一个会话(COM17@115200),或释放裸端口上的所有会话(COM17)。没有全部释放模式。

set_target(project_dir, target) — 对 esp32 / esp32s3 / esp32c2 / … 执行 idf.py set-target。请注意,idf.py 会将现有的 sdkconfig 重命名为 sdkconfig.old,并为新目标生成一个全新的文件。

add_dependency(project_dir, dependency, component=None, path=None) / remove_dependency(project_dir, dependency) — 管理 ESP 组件管理器清单 idf_component.yml;组件会在下次构建时获取或移除。

clean_project(project_dir, full=False) — 执行 idf.py clean 或 fullclean(仅处理构建产物;绝不会修改 sdkconfig)。

run_pytest(project_dir, ...) — 针对真实开发板运行 pytest-embedded 硬件测试(烧录 + 交互 + 断言串行输出)。

资源 project://devices — 已连接串行端口的 JSON 列表。

要求

  • ESP-IDF(在 Windows 上基于 v6.1 开发;只要自动检测或以下环境变量能找到安装位置,其他目录布局也适用)
  • Python ≥ 3.9,需安装 mcp 和 pyserial
  • 任意 MCP 客户端(Claude Desktop、Cursor、VS Code 等)

设置

选项 A — 安装为软件包
pip install .
选项 B — 直接运行单个文件

只需将 MCP 客户端指向 esp_idf_mcp.py,并使用安装了 mcp + pyserial 的任意 Python(ESP-IDF 虚拟环境很适用)。

注册到 MCP 客户端
{
  "mcpServers": {
    "esp-idf": {
      "command": "python",
      "args": ["C:\\path\\to\\esp_idf_mcp.py"]
    }
  }
}

(如果通过 pip 安装,也可以不带参数,使用 "command": "esp-idf-mcp")

配置

启动时会自动定位 ESP-IDF:首先检查环境变量,然后查找 D:\esp\<ver>\esp-idf、C:\esp\<ver>\esp-idf 或 ~/esp/<ver>/esp-idf 下最新的安装版本。工具目录的备用位置依次为 C:\Espressif\tools 和 D:\espressif\tools。所有路径都可以从外部覆盖:

环境变量含义
IDF_PATHESP-IDF 框架根目录(覆盖自动检测结果)
IDF_PYTHON_ENV_PATHESP-IDF Python 虚拟环境(默认:<tools>\python\*\venv 下最新的环境)
IDF_TOOLS_PATHEspressif 工具目录(默认:C:\Espressif\tools,然后是 D:\espressif\tools)
ESP_IDF_VERSION版本标签——从 IDF 目录名中提取并去掉开头的 v(v6.1 → 6.1),以便组件管理器解析
IDF_COMPONENT_MANAGER强制设为 1,以便 idf.py add-dependency 和托管组件正常解析

工具路径下的工具链目录(xtensa/riscv GCC、CMake、Ninja、ccache、idf-exe、esp-rom-elfs)会根据版本通配符匹配,并添加到 PATH 的前面。启动时会向 stderr 打印一行诊断信息(IDF_PATH=… TOOLS=… PYENV=…)。

典型 Agent 工作流

read_chip_info → set_target(esp32s3) → build_project → flash_project(port="COM17")
→ monitor_read(session_id) → iterate on code → run_pytest

支持

如果这个服务帮你减少了固件调试的反复折腾,请点个星,或请作者喝杯咖啡:

支付宝Binance Pay
README 配图README 配图
扫码支付在 Binance 应用中扫码
USDT(TRC-20)USDT(BEP-20 / BSC)
README 配图README 配图
扫码,或复制地址:
TL4j1mRbfjQBEGpqBbRTEYHvJABxCi3tkQ
扫码,或复制地址:
0x1572a9a6ce3da8b55c6cfc67e5b0557f3f10d423

USDT:仅可通过 BSC / BEP-20 转账——使用任意 EVM 钱包扫描该地址,或直接复制地址。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。