stmctl-mcp
STM32 Flashing & Hardware Control MCP Server (stmctl-mcp)
A production-grade Model Context Protocol (MCP) server wrapping STM32CubeCLT (STM32_Programmer_CLI.exe). This MCP server enables any AI coding assistant or agent framework (Antigravity, Claude Desktop, Cursor, custom Node.js/Python agents) to perform hardware flashing, memory dumps, option byte modification, chip erase, board resets, and live SWO printf log tracing.
Hardware & Software Requirements
1. Host Computer Requirements
Node.js: v18.0.0 or higher
Operating System: Windows 10 / 11, Linux, or macOS
2. Platform Installation Scripts (scripts/)
Automated installer & environment setup scripts are provided in the scripts/ folder:
Windows:
scripts/install_win.batLinux:
scripts/install_linux.sh(Includes ST-LINK USBudevpermission rules setup)macOS:
scripts/install_mac.sh(Includes Homebrewstlinkfallback check)
Flexible Path Configuration & Dynamic Resolution Hierarchy
To accommodate different computers, OS environments, and version numbers (e.g., STM32CubeCLT_1.17.0, 1.22.0, 2.0.0), stmctl-mcp resolves STM32_Programmer_CLI.exe using the following priority sequence:
Priority 1: Local Configuration File (stmctl_config.json)
You can manually specify any custom path in stmctl_config.json in the server root directory:
{
"cli_path": "C:\\MyCustomPath\\STM32_Programmer_CLI.exe",
"default_port": "SWD",
"default_mode": "HOTPLUG"
}Priority 2: Environment Variable
Set STM32_PROGRAMMER_CLI_PATH in your environment or MCP launcher configuration:
STM32_PROGRAMMER_CLI_PATH=C:\ST\STM32CubeCLT_1.22.0\STM32CubeProgrammer\bin\STM32_Programmer_CLI.exePriority 3: Automatic Dynamic Version Scanning (C:\ST\STM32CubeCLT_*)
If no manual path is specified, stmctl-mcp automatically scans C:\ST\ for **any installed version number** (sorting highest version first) to locate:
C:\ST\STM32CubeCLT_<version>\STM32CubeProgrammer\bin\STM32_Programmer_CLI.exe
Priority 4: Standard Program Files Directories
Scans standard Program Files, Program Files (x86), /usr/local/STMicroelectronics/..., /opt/st/..., and /Applications/... directories.
Priority 5: System PATH Fallback
Tries executing STM32_Programmer_CLI directly from system environment PATH.
Capabilities & Tools Exposed
stm32_list_probes: Discover connected ST-LINK, J-Link, UART COM ports, USB devices.stm32_connect_info: Query chip ID, Flash/RAM size, revision ID, CPU core.stm32_flash_firmware: Program.bin,.hex,.elf,.srecfiles with automatic erase, verification, reset, and run flags.stm32_erase_memory: Perform full chip mass erase or sector/page erase.stm32_read_memory: Read raw memory addresses or dump to.bin/.hexfiles.stm32_write_memory: Write bytes/words to specific memory addresses or peripheral registers.stm32_read_option_bytes: Read RDP protection level, BOR level, Watchdog, and Boot flags.stm32_write_option_bytes: Modify Option Bytes (e.g.RDP=0xAA,nBOOT0=1).stm32_reset_mcu: Hardware (HWrst), Software (SWrst), or Core (Crst) reset.stm32_run_mcu: Start or resume program execution at specified address.stm32_start_swv_trace: Stream/capture live SWO Serial Wire Viewer printf logs.stm32_raw_cli: Direct passthrough for any customSTM32_Programmer_CLIflags.
Installation & Build
1. Install Dependencies
npm install2. Build TypeScript Source
npm run buildThis compiles TypeScript files into ./dist/index.js.
How to Integrate stmctl-mcp into Any Agent
Method 1: Desktop IDEs & Apps (Antigravity, Claude Desktop, Cursor, VS Code)
Add the JSON configuration block below to your application's MCP settings file (e.g., claude_desktop_config.json or .vscode/mcp.json):
{
"mcpServers": {
"stmctl-mcp": {
"command": "node",
"args": [
"c:/Users/kunur/OneDrive/Documents/Smarttrak/Firmware_Agent/STMCTL_MCP/dist/index.js"
]
}
}
}Method 2: Custom Node.js / TypeScript Agent
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
async function main() {
const transport = new StdioClientTransport({
command: "node",
args: ["c:/Users/kunur/OneDrive/Documents/Smarttrak/Firmware_Agent/STMCTL_MCP/dist/index.js"],
});
const client = new Client({ name: "firmware-agent-host", version: "1.0.0" }, { capabilities: {} });
await client.connect(transport);
const probeResult = await client.callTool({
name: "stm32_list_probes",
arguments: {},
});
console.log("Probes Result:", probeResult.content[0].text);
}
main().catch(console.error);Method 3: Custom Python Agent (LangChain / LlamaIndex / CrewAI / AutoGen)
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def run_firmware_agent():
server_params = StdioServerParameters(
command="node",
args=["c:/Users/kunur/OneDrive/Documents/Smarttrak/Firmware_Agent/STMCTL_MCP/dist/index.js"],
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("stm32_list_probes", arguments={})
print("Probe Result:", result.content[0].text)
asyncio.run(run_firmware_agent())Method 4: Interactive Web Browser Debugging (MCP Inspector)
npm run inspectorThis opens the MCP Inspector UI at http://localhost:5173.