Install
$ agentstack add mcp-okhsunrog-flashprobe-mcp ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
flashprobe-mcp
An MCP server for flashing and monitoring embedded targets from any MCP client (Claude Code, Claude Desktop, …). It covers the whole bench from one tool surface, over two backends:
- probe-rs — JTAG/SWD flashing + RTT capture. Any
probe-rs-supported chip: ESP (Xtensa + RISC-V), STM32, nRF, RP2040/RP2350, …
- espflash — UART flashing + serial capture for ESP32-family chips.
Output is decoded as defmt when the firmware uses it (defmt-rtt, rtt-target, or esp-println's defmt-espflash) and plain text otherwise — detected automatically from the ELF.
Why a server instead of the CLI
The win for an agent is bounded, early-exiting capture. probe-rs run / espflash monitor never terminate on their own — an agent either forgets a timeout and hangs, or sets one and burns the whole window every time. This server stops the instant an expected line (or defmt error) appears — the programmatic equivalent of watching the log and pressing Ctrl-C — and returns a compact, cleaned result.
Build
cargo build --release
# binary at: target/release/flashprobe-mcp
probe-rs is a default-on feature. For a lean espflash-only (serial) build with a much smaller dependency tree:
cargo build --release --no-default-features
The server speaks MCP over stdio.
Configure your MCP client
claude mcp add flashprobe -- /absolute/path/to/target/release/flashprobe-mcp
Or generic mcpServers JSON:
{
"mcpServers": {
"flashprobe": {
"command": "/absolute/path/to/target/release/flashprobe-mcp"
}
}
}
Serial access needs your user in the dialout/uucp group; probe access needs the probe-rs udev rules.
Choosing a backend (required)
Every flash/monitor call takes an explicit backend: "probe-rs" or "espflash". Both work on ESP chips, and the right one depends on where the firmware emits output — RTT (probe-rs) vs UART (espflash). Picking the wrong one flashes fine but shows no logs, so the server asks rather than guessing.
- defmt-rtt / rtt-target firmware →
probe-rs - esp-println / UART firmware →
espflash - any non-ESP chip →
probe-rs
Auto-detection
Everything except the backend is derived from the project on disk (no config file, no state) and can be overridden per call:
| Derived | From | Override | |---------|------|----------| | ELF / file to flash | cargo metadata build artifact | file_path / elf, project_dir, bin | | chip (probe-rs) | .cargo/config.toml runner --chip | chip | | serial port (espflash) | the sole USB serial port | port | | defmt vs text | the ELF's .defmt section | — (reliable) |
So from a project directory, flash_monitor { "backend": "probe-rs", "stop": "ready" } flashes the built artifact to the detected chip and decodes defmt — nothing else to pass.
Tools
All flash/monitor/device tools work on both backends (each using its native mechanism); only list_ports is serial-specific.
| Tool | Purpose | Backend notes | |------|---------|---------------| | flash | Flash an ELF/binary (no monitor) | espflash: IDF format / raw flash_address; probe-rs: flash-algo | | flash_monitor | Flash, then capture from boot | | | rerun | Reset (no reflash) + capture; repeat > 1 for flaky-bug runs | | | monitor | Attach + capture only | | | reset_device | Reset the device | espflash: DTR/RTS; probe-rs: core reset | | erase_flash / erase_region | Erase flash (destructive) | espflash: ROM erase (4 KiB-aligned region); probe-rs: flash-algo (sector-covering) | | read_flash | Read a memory/flash region to a file | espflash: ROM read; probe-rs: debug-port memory read | | chip_info | Device/target info | espflash: ESP type/revision/MAC/crystal/flash; probe-rs: target name + cores + memory map | | checksum_md5 | MD5 of a region | espflash: on-device ROM MD5; probe-rs: read + host-side hash | | list_ports | Discover serial ports | espflash/serial only |
Capture
flash_monitor, monitor, and rerun capture until the first of:
stop— an unanchored regex on the rendered line (RESULT (PASS|FAIL),
panic|abort). Plain text is a valid pattern.
stop_on_level— defmt only: stop on the first frame at/above a level
(e.g. error) — the "did it panic?" button.
idle_ms— no new data for this long (default4000).timeout_s— max wall-clock window (default5).max_bytes— byte cap; stops early and marks the output truncated
(default 65536).
Show filters: grep (regex, both modes), context (N lines around the stop match), and defmt-only level (minimum to show) / module (regex on the module path). In defmt mode a suppressed-by-level count reports what a looser level would reveal. In text mode, ROM/bootloader boot noise (strip_boot_noise) and ANSI codes (strip_ansi) are stripped by default.
defmt note
defmt decode needs the exact ELF that's running — version skew yields garbage, not an error. It's free in the flash-then-monitor flow (just built it); for bare monitor/rerun, make sure the auto-detected (or passed) ELF matches. The server surfaces a warning when a non-empty stream decodes to zero frames.
License
MIT — see [LICENSE](LICENSE).
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: okhsunrog
- Source: okhsunrog/flashprobe-mcp
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.