Vscode_cube_mcp
全部由 deepseek-v4-flash 生成
- GitHub: https://github.com/h666zhang/vscode-cube-mcp
- PyPI: https://pypi.org/project/vscode-cube-mcp/
MCP(Model Context Protocol) server,封装 STM32CubeMX 官方命令行脚本模式(-q),
让 AI 助手可以直接加载 .ioc 工程、改引脚/外设配置、生成 HAL 代码、导出引脚表。
每次调用:命令序列写入临时脚本 → 启动 STM32CubeMX -q → 超时强杀
→ 过滤 log4j 噪音 → 检测 KO 失败标记 → 返回干净输出。
技术栈
| 层 | 技术 |
|---|---|
| 语言 | Python >= 3.10 |
| MCP 框架 | mcp SDK 2.x(官方 Model Context Protocol Python SDK,stdio 传输) |
| 交互对象 | STM32CubeMX 6.x(-q 脚本模式,外部工具,运行时 subprocess 调用) |
| 打包发布 | setuptools + build + twine(PyPI) |
| 测试 | unittest(标准库,零依赖) |
| 配套构建链 | CMake + Ninja + arm-none-eabi-gcc(STM32CubeMX 生成的工程采用 CMakePresets 配置,由 Ninja 构建,arm-none-eabi 工具链链接) |
| 目标平台 | Windows(主);跨平台可用(含 os.name 分支的通用探测) |
功能
| 工具 | 说明 |
|---|---|
cubemx_script |
任意 CubeMX 脚本命令序列(逃生通道) |
cubemx_load |
加载 .ioc 并回读关键配置(只读) |
cubemx_configure |
加载 .ioc,执行 set 命令序列,saveas 写回 |
cubemx_generate |
加载 .ioc 并 project generate 生成 HAL 工程 |
cubemx_export_pinout |
导出引脚配置 CSV(只读) |
cubemx_new_project |
从零生成新工程(模板 + set 命令 + generate,无需预先 .ioc) |
cubemx_remove_peripheral |
从 .ioc 移除外设(文本方式,解决 set noparam 无效) |
cubemx_add_source |
把自定义源文件加入 CMake 源列表(generate 覆盖后可重补) |
要求
- Python >= 3.10,安装依赖
mcp>=2.0 - STM32CubeMX(ST 专有软件,请从 ST 官网免费下载并自行遵守其许可)—— 本工具仅运行时调用其命令行,不包含、不修改其任何代码
安装
pip install vscode-cube-mcp # 从 PyPI
# 或本地开发安装
pip install -e .
配置(环境变量)
| 变量 | 默认 | 说明 |
|---|---|---|
ST_CUBEMX_EXE |
PATH 中的 STM32CubeMX / 常见 Windows 安装位置 |
STM32CubeMX 可执行文件完整路径 |
ST_CUBEMX_ALLOWED_ROOTS |
当前工作目录 | .ioc 允许访问的根目录,os.pathsep 分隔(; for Windows) |
ST_CUBEMX_TIMEOUT |
240 |
CubeMX 子进程超时秒数 |
示例(Windows PowerShell):
$env:ST_CUBEMX_EXE = "C:\MINE\STM\STM\STM32CubeMX.exe"
$env:ST_CUBEMX_ALLOWED_ROOTS = "C:\MINE\STM32Project\STM32VScode"
安全设计:所有 .ioc / 生成路径都必须在
ST_CUBEMX_ALLOWED_ROOTS白名单内, 白名单外的路径会被拒绝(路径校验见_check_path)。
使用(接入 MCP 客户端)
把 server 注册到支持 MCP 的客户端(如 Reasonix / Claude Desktop 等), stdio 方式启动:
{
"mcpServers": {
"Vscode_cube_mcp": {
"command": "python",
"args": ["-m", "cubemx_mcp"]
}
}
}
或直接用 console 入口:
vscode-cube-mcp
开发
python -m unittest test_cubemx_mcp -v # 运行单元测试(不依赖 CubeMX)
测试覆盖:_cleanup 噪音过滤、_check_path 白名单校验、_find_cubemx /
_allowed_roots 配置解析、_run_script(mock 子进程)的 KO 检测与超时路径。
许可与依赖声明
- 本工具代码:MIT License(见
LICENSE) - mcp SDK(唯一 Python 依赖):MIT License(modelcontextprotocol/python-sdk)
- STM32CubeMX:ST 专有软件,运行时外部调用,需用户自备并遵守其许可条款
实践经验(2026-08-05,OLED_MCP 项目踩坑记录)
用 cubemx_generate 生成的新工程,在 VSCode 里用 STM32 VS Code Extension 打开时可能遇到:
Run and Debug 迟迟不出现 / ST 扩展识别工程很慢 / 报 OLED_MCPsettings\ide.store.json 之类 ENOENT。
根因:CubeMX CLI 生成的新工程缺少 ST 扩展识别工程所需的文件:
| 文件 | 作用 |
|---|---|
.settings/ide.store.json |
声明 sourceType=STM32CubeMX、device、core(扩展识别硬件的关键) |
.settings/bundles.store.json、bundles-lock.store.json |
bundles(工具链)版本锁定 |
.vscode/settings.json |
cube-cmake / clangd 配置 |
.vscode/c_cpp_properties.json |
compile_commands.json 索引 |
.clangd |
clangd 配置 |
正确做法(对齐实例工程,如 OLED_HAL):
- 生成新工程后,不要手写 launch.json(实例工程没有,ST 扩展会自动提供调试配置);
- 在 VSCode 里重新加载窗口(Reload Window),扩展会识别工程并自动补齐上述文件(device 名取自
.ioc,如STM32F103C8T6); - 若扩展没自动补齐,可从同芯片的实例工程复制
.settings/、.vscode/、.clangd(注意核对ide.store.json里的device是否一致)。
其他教训:
- 若确实要手写 launch.json,ST 扩展的调试器类型是
stlinkgdbtarget,deviceName必须与.settings/ide.store.json的device一致(如STM32F103C8T6,不是STM32F103C8Tx),否则扩展可能解析异常; - 本机 STM32 VS Code Extension 全家桶调试类型:
stlinkgdbtarget(ST-Link)/jlinkgdbtarget(J-Link)/stgdbtarget(通用 GDB); cubemx_generate的project path对已存在目录返回 KO 是正常现象,generate 默认在 .ioc 同目录生成,结果不受影响。
从零配置时钟实战(2026-08-06,Blink_PB13:HSE 8MHz + PLL ×9 = 72MHz)
目标:生成一个新的 .ioc(芯片 STM32F103C8T6,外部晶振 8MHz,PLL ×9 到 72MHz,PB13 输出翻转)。 正确做法不是手写 RCC 键,而是基于 6.18 原生 .ioc 改造 + set 命令,让 CubeMX 自己写时钟树:
流程(全部通过 MCP 脚本/configure,无需 GUI)
- 准备基底:复制一个 6.18 原生生成的 .ioc(如 OLED_MCP.ioc)作为工作副本;
- 启用 HSE(关键!):
→ CubeMX 自动补全整个时钟树派生频率(AHBFreq 72M / APB1 36M / TimSys 72M 等);set pin PD0-OSC_IN RCC_OSC_IN set pin PD1-OSC_OUT RCC_OSC_OUT - 配 PLL 与系统时钟源:
(set ip parameters RCC PLLSourceVirtual RCC_PLLSOURCE_HSE set ip parameters RCC PLLMUL RCC_PLL_MUL9 set ip parameters RCC SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK set ip parameters RCC APB1CLKDivider RCC_HCLK_DIV2set ip parameters <IP> <参数> <值>是 6.18 设置 IP 参数的唯一入口) - 改引脚/外设:
set pin PB13 GPIO_Output+set gpio parameters PB13 GPIO_Label LED; 移除多余外设:set noparam I2C1、set pin PB8 GPIO_Input(再手动删掉 Mcu.Pin 残留行); - saveas 写回 → 加载验证(脚本 OK + csv pinout 核对)。
关键坑(血泪教训)
| 坑 | 说明 |
|---|---|
| HSE 靠引脚启用,不是键 | 6.18 的 F1 里 HSE 用 PD0-OSC_IN/PD1-OSC_OUT 的 HSE-External-Oscillator 模式表达,set pin ... RCC_OSC_IN/OUT 即可;不存在 RCC.HSEState 键,手写会被静默删除 |
| 手写旧格式键会被删 | HSEState/HSE_VALUE 等手写键,6.18 不认识,saveas 时静默清理 → 时钟树悬空 → GUI 弹 "Resolve Clock Issues" |
set rcc 语法不存在 |
set 命令只有 mode/pin/gpio/ip/... 类别,没有 set rcc;RCC 参数必须走 set ip parameters RCC ... |
set gpio parameters 是空格分隔 |
set gpio parameters PB13 GPIO_Label LED,不是 = 连接 |
| 时钟树自动补全 | 一旦 HSE 引脚生效,PLLCLKFreq_Value/HCLK/APB 派生值全部由 CubeMX 自动算出,不要手填 |
| 弹窗根因 | 时钟源未启用或键无效 → 时钟树无法自洽 → GUI 弹 "Resolve Clock Issues"(点 Yes 会让求解器洗白文件) |
| set pin 不写 Mode 行 | set pin 只写 Signal;PD0-OSC_IN.Mode=HSE-External-Oscillator 这类显示属性由 GUI/文本补,脚本加载不依赖它 |
从零生成:能力说明(2026-08-06 新增)
cubemx_new_project 提供"从零生成"能力:无需预先准备 .ioc,指定芯片型号 + 工程名 + set 命令即可生成完整 HAL 工程。
cubemx_new_project(
project_name = "Blink",
project_dir = "C:/MINE/STM32Project/NewProj",
mcu = "STM32F103C8T6", # 匹配 templates/{mcu}.ioc
commands = ["set pin PB13 GPIO_Output",
"set gpio parameters PB13 GPIO_Label LED"],
template = "", # 可选,直接指定模板 .ioc 路径
)
流程:templates/ 选 6.18 原生模板(或显式 template)→ 复制到 project_dir 并改写 ProjectName/ProjectFileName → config load + 依次执行 set 命令 + saveas → project generate。
内置模板库(templates/ 目录,按芯片型号命名):
| 模板文件 | 内容 |
|---|---|
STM32F103C8T6.ioc |
F103C8,HSE 8MHz + PLL ×9 = 72MHz,SWD,PB13=LED(GPIO_Output) |
STM32F103C8T6_tim_template.ioc |
上面全部 + TIM2(ETR 外部时钟,PA0)+ TIM3(内部时钟,1s)+ I2C1(PB8/PB9) |
STM32F103C8T6_tim2_internal.ioc |
上面全部但 TIM2 为内部时钟(1s),无 TIM3/ETR——需要 TIM2 内部时钟秒表时首选 |
新增芯片:把 6.18 原生生成的 .ioc 复制到
templates/{芯片型号}.ioc即可;模板必须是 6.18 原生文件(否则 6.18 加载会报错)。
配套工具:
| 工具 | 用途 |
|---|---|
cubemx_remove_peripheral |
从 .ioc 移除外设(文本方式,解决 set noparam 无效) |
cubemx_add_source |
把自定义源文件加入 CMake 源列表(generate 覆盖后可重补) |
TIM 内部时钟:首选
STM32F103C8T6_tim2_internal.ioc模板;脚本模式无法把 ETR TIM 改成内部时钟,cubemx_new_project内置借壳法(_tim_make_internal_clock)作兜底,详见templates/README.md。
📚 各外设的配置命令、实测状态与坑:见
templates/README.md(GPIO/I2C/TIM/时钟的 set 命令与注意事项)。
能力边界:已验证范围与未验证外设
cubemx_new_project 已实现"从零生成",但只验证了部分配置:
已验证 ✅(本机实测通过):
- 时钟:HSE 8MHz + PLL ×9 = 72MHz(含 APB 分频、SWD 调试口)
- GPIO:输出引脚(PB13=LED,含 GPIO_Label)
- I2C1:PB8=SCL / PB9=SDA(经
set pin+set mode I2C1 I2C,生成 i2c.c + main.c 调用) - TIM2/TIM3 + NVIC:经
template=TIM2.ioc生成,MX_TIM2_Init/MX_TIM3_Init+NVIC.TIMx_IRQn正确(tim.c 生成)
未验证 ⚠️(机制上应可用,但尚未实测):
- 外设:USART / SPI / ADC / DAC / DMA 等
- 中断:除 TIM 外的其它外设中断
- 高级时钟:PLL 其它倍频、MCO 输出等
已知坑(实测发现):
set mode TIM2 <mode>对 TIM 无效(枚举名不可得,一律 KO),TIM 激活需靠 "原生模板已带 TIM 配置"(template参数直接指 TIM2.ioc 这类样板)或 GUI 生成的种子;set ip parameters TIM2 ...在 TIM2 未激活时会被静默忽略(不报错也不生效)。
实现机制(伪从零):CubeMX 的 -q 脚本模式没有 new project 命令,实际流程是
复制 templates/{芯片型号}.ioc(6.18 原生种子)→ 改工程名 → set 命令 → generate。
模板必须是 6.18 原生 .ioc,手写/非原生文件 6.18 会报错;新增芯片需先用 GUI
从空白建一次该芯片工程,把 .ioc 存入 templates/ 后即可脚本化复用。
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vscode_cube_mcp-0.2.0.tar.gz.
File metadata
- Download URL: vscode_cube_mcp-0.2.0.tar.gz
- Upload date:
- Size: 28.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
972098ae4475effe349af27946e4319d3e1c345c09049d74d035ec0d7ab2a861
|
|
| MD5 |
082d1559caef501c9456bbf0917f19e6
|
|
| BLAKE2b-256 |
2646421764c28a3c8ad05a7eb11812d0c88bdc2243e5ccd041f52112f4e60ee6
|
File details
Details for the file vscode_cube_mcp-0.2.0-py3-none-any.whl.
File metadata
- Download URL: vscode_cube_mcp-0.2.0-py3-none-any.whl
- Upload date:
- Size: 26.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30dcf5e2b280499e3b379cfd9b165f1592ccd35dfca232c9823dedc9967ac249
|
|
| MD5 |
29a88529192f3dcdb27a30ab06183505
|
|
| BLAKE2b-256 |
8db8a164233657ac86932a0e0a534d1fa1449257dbefdc8bf55c94fab42f2070
|