STM32-MCP
About
Access STM32CubeIDE and debug tools
Details
- Author
- shieldyguy
- Categories
- Developer Tools, Infrastructure, Other
Jump to
Setup
Install STM32-MCP in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/shieldyguy/stm32-mcp
Follow the installation instructions in the repository README, then restart your MCP client.
stm32-mcp is pretty specific to how I tend to approach hardware development, but it is likely useful to others, too! It could be massaged to fit lots of workflows, but this is laser focused on mine (stlink-v3 mini, VCP on that header, STM32 microcontroller).
claude:two unnamed probes connected to two unnamed PCBs
me:k ask them who they are and give them a nickname based on their response
claude:got it, do you want to nickname the probes too? your boards are 'doorbell A' and 'synthesizer B'
me:yep, I put paint marker on those probes. call doorbell's 'blue' and the synth's 'red'
me:give them both VCP commands so they can talk to each other, then have the doorbell ask the synth on a date
claude:thinking...done, synth declined. plenty of fish in the sea, doorbell!
[!WARNING] This server gives an AI direct access to your compiler, debug probe, and serial ports. It can flash firmware, overwrite memory, and send arbitrary data to your hardware. This is powerful and useful, but it is not a sandbox. Know what's connected before you let it rip.
- STM32CubeIDEinstalled at/Applications/STM32CubeIDE.app(macOS) or/opt/st/stm32cubeide_*(Linux)
- Python 3.10+
- OpenOCD(brew install open-ocd) — for flash, memory read/write, and live monitoring
- open-source stlink tools(brew install stlink) — for probe enumeration
- ST-Linkconnected via USB (for flash/board info)
- Serial portavailable (ST-Link VCP or USB-UART adapter)
git clone https://github.com/shieldyguy/stm32-mcp.git cd stm32-mcp python3 -m venv .venv source .venv/bin/activate pip install -e .
claude mcp add stm32 -- /path/to/stm32-mcp/.venv/bin/python -m stm32_mcp.server
Add to your project's.claude/settings.jsonor.claude.json:
{ "mcpServers": { "stm32": { "command": "/path/to/stm32-mcp/.venv/bin/python", "args": ["-m", "stm32_mcp.server"] } } }
bin/contains four thin wrappers over the same code the MCP tools use
export PATH="/path/to/stm32-mcp/bin:$PATH"
Probe nicknames and board nicknames resolve.
Builds share the MCP's headless CubeIDE workspace lock, so astm32-build/stm32-bfracing an agent-driven build will queue behind it.
Board nicknames follow the physical MCU (persist across probe swaps). Probe nicknames follow the ST-Link hardware. Use nicknames in anyprobeparameter across all tools.
serial_sequenceschedules multiple steps (serial send, delay, webcam capture, and SWD memory read/write) in one tool call. delays use atime.sleep()in the executor thread. Claude can't reliably time individual tool calls, so this allows tight timing of commands and expectations.
[ { "send": "SIM_LEFT", "to": "/dev/cu.usbmodem11202" }, { "delay_ms": 500 }, { "send": "GET_BLINK_STATE", "to": "/dev/cu.usbmodem11402", "expect": "BLINK" }, { "capture": true, "label": "post_brake" }, { "mem_write": true, "address": "0x48000418", "value": "0x40", "probe": "yellow" }, { "delay_ms": 1000 }, { "mem_read": true, "address": "0x48000400", "count": 2, "probe": "yellow", "label": "gpio_post" } ]
- Send step:{send, to, expect?, read_timeout?, line_ending?}—tois the port path fromserial_connect
- Delay step:{delay_ms}— realtime.sleep(), not tool-call round-trips
- Capture step:{capture: true, label?, device_index?}— PNG saved to/tmp/stm32-captures/
- Memory write step:{mem_write: true, address | symbol + elf_path, value, probe, width?}
- Memory read step:{mem_read: true, address | symbol + elf_path, probe, count?, width?, label?}
- probeaccepts ST-Link SN, probe nickname, or board nickname
- addressis hex (e.g."0x48000418"); alternatively usesymbol+elf_pathto resolve by name
- widthis 8/16/32 bits, defaults to 32 (auto-detected from symbol size when usingsymbol)
- Each memory op currently launches a fresh OpenOCD process (~tens of ms overhead per op), so inter-memory-op timing below ~50ms is approximate. Delays themselves are accurate.
- on_failure:"continue"(default) runs all steps regardless."stop"aborts on first failure.
- filter_responses:Whentrue,expectpatterns match only>-prefixed VCP response lines (ignores debug noise).
Step 1 [/dev/cu.usbmodem11202] SEND: SIM_LEFT Response: >OK:SIM_LEFT Step 2 DELAY: 500ms Step 3 [/dev/cu.usbmodem11402] SEND: GET_BLINK_STATE Response: >BLINK_STATE:BLINK Expect "BLINK": PASS Step 4 [yellow] MEM_WRITE: Wrote 0x00000040 to 0x48000418 Step 5 DELAY: 1000ms Step 6 [yellow] MEM_READ: gpio_post 0x48000400: 0xabffdfff 0x00000080 Summary: 2/2 sends OK, 1/1 assertions PASS, 1/1 mem_writes OK, 1/1 mem_reads OK
Monitor firmware variables in real time via SWD, without modifying firmware or using serial. OpenOCD runs as a persistent subprocess and polls variables over its built-in TCL socket.
live_memory_start( variables='["blink", "ts"]', # symbol names from ELF elf_path="/path/to/firmware.elf", probe="taillight", # board/probe nickname interval_ms=500 # min 250ms )
- Symbol names(strings):"blink"— resolved from the ELF viaarm-none-eabi-nm
- Dicts with symbol + type:{"symbol": "temperature", "type": "float"}— interprets 32-bit value as IEEE 754
- Dicts with raw address:{"address": "0x20000304", "name": "x", "width": 32}
live_memory_read(session_id="abc123", last_n=10)
Returns recent entries from an in-memory ring buffer (max 100 entries). Full history is written to the JSONL output file.
{ "t": 1709830123.456, "elapsed_s": 1.002, "values": { "blink": 65539 } }
live_memory_stop(session_id="abc123")
Returns stats: duration, read count, error count, output file path.
- One session per probe— this is a hardware constraint (single SWD connection)
- Stop before flashing—live_memoryholds the SWD connection;stm32_flashandstm32_read/write_memorywill fail if a session is active
- TCL port 6666— OpenOCD's default. Stop other OpenOCD instances first if there's a conflict
- Baud rate:115200
- Line ending:LF (\n)
- Read polling:50ms inter-byte sleep, 200ms silence break
- Buffer limits:4096 bytes max read
source .venv/bin/activate mcp dev src/stm32_mcp/server.py
Serial tools can be tested without hardware using pyserial's loopback:
import serial ser = serial.serial_for_url("loop://", baudrate=115200, timeout=0.1) ser.write(b"PING\n") print(ser.read(100)) # b'PING\n'
This is a web browser that enables your coding agent, such as Claude Code, to visit websites on your behalf and assist you in identifying bugs or creating UI test cases.
Policy-gated MCP tools that let coding agents build, flash, stimulate and observe real embedded hardware (OpenOCD, pyOCD, STM32CubeProgrammer, serial, CAN).
Clean and audit messy MCP setups: stale servers, unused tools, context-heavy MCPs, outdated packages, and safe repair plans.
LSP-Claw is an MCP server that lets an AI agent safely build, run, and debug Lua/LSP web apps inside a controlled Mako/Xedge/BAS lab, including on embedded or RTOS devices.
All Azure MCP tools in a single server. The Azure MCP Server implements the MCP specification to create a seamless connection between AI agents and Azure services. Azure MCP Server can be used alone or with the GitHub Copilot for Azure extension in VS Code.
Flag features, manage company data, and control feature access using Bucket.
Enable AI Agents to fix build failures from CircleCI.
interacts with ConfigCat feature flag platform. Supports managing feature flags, configs, environments, products and organizations. Helps to integrate ConfigCat SDK, implement feature flags or remove zombie (stale) flags.
Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning with Cycode.
Turn your favourite AI tool into a feature management assistant. DevCycle's MCP works with your favourite coding assistant so you can create and monitor feature flags using natural language right in your workflow.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.





