mxmcp — STM32CubeMX 的 MCP 服务器(也可完全独立运行)
交付物:
mxmcp/(服务器源码 + 自带数据包)、tests/(6 个测试脚本)、docs/(逆向记录、架构、数据模型、功能矩阵、独立模式、验收)、analysis/(机器可读逆向产物)、tools/(可复现的取证脚本)。
两种模式,同一个 MCP 接口:
- hybrid:装了 CubeMX 时驱动官方引擎(引脚/时钟/生成都是 ST 原版行为)。
- standalone:不需要任何 CubeMX 安装 —— 自带 9.1 MB 数据包 (2 019 颗 MCU / 245 083 引脚 / 274 套 IP 模式 / HAL Init 参数树), 自带校验引擎与 C 代码生成器。见 docs/STANDALONE.md。
项目状态 (.ioc) ←→ mxmcp (Python MCP server) ←→ CubeMX CLI (常驻 JVM,可选)
↑
自带数据包 cubemx-db.zip(离线选型/校验/生成)
1. 为什么这样做
- CubeMX 6.15.0 是 PE32 装载器 + 内嵌 ZIP 的 Java 应用(不是 native-image,
不需要脱壳):
java -jar STM32CubeMX.exe -q script.txt就是官方 headless 入口; 内嵌归档 54 774 条目、起始0x13000、中央目录0xD2F0A03(tools/rebuild_full_jar.py全量重建,0 失败)。 - 引擎内部有 267 条 CLI 注册(旧记录只有 89 条,因为旧提取漏了
com/st/components)、217 个插件 opcode;export script能把任意工程序列化成 可重放命令。 - 因此 MCP 不做“重新实现 CubeMX”,而是受控前端:写操作走官方解释器,
读操作读
.ioc/自带数据包;两者可交叉校验(verify/standalone_validate)。
完整逆向记录:ARCHITECTURE.md(总览)· REVERSE_ENGINEERING.md(过程)· DATA_MODEL.md(数据结构)· CLI_REGISTRY.md(267 条命令)· FEATURES.md(功能覆盖矩阵)· SECURITY_NETWORK.md(信任链与端点)· STANDALONE.md(独立模式)
2. 运行要求
- Python 3.9+(零第三方依赖,只用标准库)
- STM32CubeMX 可选:
- 装了 → hybrid 模式,用官方引擎(默认路径
C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeMX) - 没装 → standalone 模式,先建一次数据包
python -m mxmcp.bundle build --cubemx-root <安装目录>(需要一台装了 CubeMX 的机器)
- 装了 → hybrid 模式,用官方引擎(默认路径
- 注意:仓库不附带数据包(ST 派生内容,见 LICENSE)。
环境变量(可选):
| 变量 | 作用 | 默认 |
|---|---|---|
MXMCP_CUBEMX_ROOT |
CubeMX 安装目录 | C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeMX |
MXMCP_WORKSPACE |
工程状态目录 | ~/.mxmcp |
MXMCP_MAX_ENGINES |
同时驻留的 JVM 数(每个打开工程一个) | 3 |
3. 接入 MCP 客户端
stdio 传输、JSON-RPC 2.0(换行分隔,也接受 Content-Length 帧)。
{
"mcpServers": {
"stm32cubemx": {
"command": "python",
"args": ["-m", "mxmcp.server"],
"cwd": "C:\\path\\to\\mxmcp",
"env": { "MXMCP_WORKSPACE": "C:\\Users\\me\\.mxmcp" }
}
}
}
自检:
python -m mxmcp.server --list-tools
python -m mxmcp.server --selftest
python -m mxmcp.server --call catalog_index --args {}
4. 五分钟上手
project_create {name: "blink", mcu: "STM32F103C8T6", toolchain: "Makefile"}
-> project_id = blink
mcu_pin_functions {project_id: "blink", pin: "PA9"} # 看可选信号
pin_set {project_id: "blink", pin: "PC13", signal: "GPIO_Output"}
pin_set {project_id: "blink", pin: "PA9", signal: "USART1_TX"}
pin_set {project_id: "blink", pin: "PA10", signal: "USART1_RX"}
mode_set {project_id: "blink", peripheral: "USART1", mode: "Asynchronous"}
ip_param_set {project_id: "blink", ip: "USART1", param: "BaudRate", value: "115200"}
gpio_set {project_id: "blink", pin: "PC13", param: "GPIO_Label", value: "LED"}
clock_set {project_id: "blink", sysclk_hz: 72000000, pll_mul: "RCC_PLL_MUL9",
pll_source: "RCC_PLLSOURCE_HSE", sysclk_source: "RCC_SYSCLKSOURCE_PLLCLK",
apb1_div: "RCC_HCLK_DIV2"}
project_save {project_id: "blink"}
verify {project_id: "blink"}
project_generate {project_id: "blink", output_dir: "D:/work/blink", toolchain: "Makefile"}
project_generate 返回文件清单与警告;典型结果:913 个文件、Src/main.c、Drivers/、
Makefile、.ioc,耗时约 5–10 秒(引擎已热)。
5. 工具一览(113 个)
工程生命周期:project_create project_list project_get project_open
project_close project_save project_save_as project_delete project_diff
project_load_mcu project_load_board project_import_config project_export_script
project_options project_set_option project_report project_csv project_files
选型/资料(离线):catalog_index mcu_search mcu_info mcu_pin_functions
family_list family_mcus board_search board_list ip_library template_list
firmware_packages mode_catalog command_catalog product_db middleware_list
引脚 / 外设:pinout_get pin_functions pin_set pin_reset pin_clear_all
pin_lock pin_reserve gpio_params gpio_set peripheral_list mode_list
mode_set mode_reset mode_check sub_modes submode_state mode_pattern
ip_param_get ip_param_set ip_params_set ip_params_dump ip_user_name
value_check
中断 / DMA / 内存映射:nvic_read nvic_write dma_query dma_mutate
mdma_query mdma_mutate gic_query gic_mutate mmt lpbam
RTOS / 中间件:rtos_schema rtos_status rtos_objects rtos_object_write
rtos_config middleware_add
时钟:clock_get clock_set clock_resolve clock_param_possible_values
生成 / 校验:project_generate generate_code verify compliance
移植 / 比较 / 选择器:porting ioc_compare selectors
软件包:pack_status pack_enable pack_disable pack_validate swmgr
xcubedl login logout
独立模式(无安装):standalone_info standalone_create standalone_open
standalone_pin standalone_signals standalone_mode standalone_param
standalone_nvic standalone_view standalone_validate standalone_generate
standalone_mcu
.ioc 直写 / 兜底 / 运行时:ioc_get ioc_set ioc_delete ioc_import
ioc_export cli cli_batch cli_help runtime_props ide_bridge
cli / cli_batch 能执行 CLI_REGISTRY 里的任何命令
(267 条),所以 MCP 接口是 CubeMX CLI 的超集:即使某个能力没有专门工具,也不会丢。
完整的功能→命令→工具对照见 docs/FEATURES.md。
6. 关键行为与坑位(已在代码里处理)
load只认 db RefName:STM32F103C8T6会让解释器永久挂起;project_create会先用本地库把料号解析成STM32F103C(8-B)Tx。- 参数不登记不落盘:
ip_param_set/clock_set自动把参数名并入<IP>.IPParameters。 config save在无路径时挂起:只用saveas/saveext,并在保存后回读校验。- 引擎卡死会污染后续调用:会话引擎超时即杀进程,下次调用自动
config load恢复; 返回值里hung: true会明确告知。 - 固件包版本必须匹配:
.ioc里的FirmwarePackage与实际安装目录不一致时,project generate会尝试联网(无 UI 下可能挂起)。生成前会预检;缺包时自动 改用project setCustomFWPath指向已安装的同族包并重新固定版本,再生成。 - 首次生成可能只拷贝驱动:CubeMX 偶尔第一遍只做驱动拷贝;工具会检测 “有 Drivers 无 main.c”并自动再生成一次。
- GPIO 参数要完整引脚名:
PC13→PC13-TAMPER-RTC,工具会自动解析。 - HSE 时钟树:只设
PLLSourceVirtual=HSE而不复用 OSC 引脚时时钟树仍按 HSI 求解;clock_set会自动把OSC_IN/OSC_OUT复用成RCC_OSC_IN/OUT,并在结果里给出 warning。 - 派生时钟值要存两次:CubeMX 在 save 时才计算
PLLCLKFreq_Value等派生量。 可靠节奏是 写入 → save → reload → save(实测 8 MHz → 72 MHz),已固化在clock_set的多轮收敛里;手工用cli复现时务必照此顺序。 - 没有
.ioc时别依赖已启动的引擎:引擎被回收再启动是空工程,config saveas会抛Mcu.getDie()NPE。先project_save一次再继续。 - 中间件 IP 的
set mode不带引号:set mode FREERTOS CMSIS_V2;get modes对中间件返回 KO,mode_list会自动回退到db/mcu/IP/*_Modes.xml。 - RTOS 对象只在扩展保存里:
project_ext.ioc才有FREERTOS.Tasks01等; 读状态要合并视图,写完必须让引擎重新加载一次。
7. 目录
mxmcp/
├── mxmcp/ 服务器源码(零第三方依赖)
│ ├── server.py MCP 入口(stdio;--selftest/--list-tools/--call)
│ ├── rpc.py JSON-RPC 2.0 / MCP 协议
│ ├── engine.py CubeMX 会话引擎(-i 常驻 + 三种成帧)
│ ├── store.py 工程池、保存/加载、料号解析
│ ├── ioc.py .ioc 读写(含 project_ext.ioc 合并视图)
│ ├── catalog.py 安装目录索引(无安装时自动走数据包)
│ ├── bundle.py 数据包 build/info/verify + Pack 读取
│ ├── standalone.py 独立引擎(引脚/模式/参数/NVIC,真实校验)
│ ├── ipmodes.py IP 模式与参数 schema
│ ├── codegen.py 独立 C 代码生成
│ ├── firmware.py 固件包完整性扫描
│ └── tools_*.py 113 个 MCP 工具
├── tests/ 6 个测试脚本
│ ├── test_units.py 解析/参数/固件预检(含真实生成)
│ ├── test_e2e.py MCP 全流程(F1/F4/板卡)
│ ├── test_advanced.py dma/nvic/gic/mmt/porting/selectors/catalog
│ ├── test_rtos.py RTOS 对象读写与校验
│ ├── test_middleware.py 中间件集成
│ └── test_standalone.py 把安装路径指到不存在,验证独立模式
├── tools/ 取证与构建脚本(不是运行时依赖)
├── docs/ 逆向与使用文档
├── analysis/ 机器可读逆向产物(本地生成,不发布)
├── LICENSE CONTRIBUTING.md CHANGELOG.md pyproject.toml
└── .github/workflows/ci.yml lint + 测试 + 合规 + 打包
8. 测试
python -m pytest tests -q :: 单元测试(无需 CubeMX)
python tests\test_standalone.py :: 独立模式:把 MXMCP_CUBEMX_ROOT 指到不存在的目录
python tests\test_e2e.py :: ~70 s,MCP 全流程(需 CubeMX)
python tests\test_advanced.py :: 60+ 断言,覆盖新增命令族
python tests\test_rtos.py :: RTOS 对象增删改与唯一名约束
python tests\test_middleware.py :: 中间件启用与 active IP 报告
python tools\check_compliance.py :: 确认没有 ST 派生文件进入仓库
实测(2026-10-29,Windows + CubeMX 6.15.0):
| 脚本 | 结果 |
|---|---|
test_units.py |
通过(含 913 文件真实生成) |
test_e2e.py |
通过(F1 全流程、板卡工程、F4 时钟、CLI 桥) |
test_advanced.py |
ALL OK(93 工具时代) |
test_rtos.py |
通过(任务/队列/信号量 + 重复名拒绝) |
test_middleware.py |
通过(FREERTOS 集成 + verify) |
test_standalone.py |
通过(无安装:建工程→引脚→生成 6 文件) |
9. 许可
MIT(见 LICENSE)。注意:仓库不含任何 ST 派生数据——
数据包与反编译产物由使用者从自己的安装件本地生成(python -m mxmcp.bundle build),
不随仓库或发行物分发。详见 docs/OPEN_SOURCE.md。
STM32 / STM32CubeMX 是 STMicroelectronics 的商标,本项目与其无隶属关系。