embedded-debugger-mcp
A Model Context Protocol server for embedded debugging with probe-rs - supports ARM Cortex-M, RISC-V debugging via J-Link, ST-Link, and more
Documentation
Embedded Debugger MCP Server
Embedded Debugger MCP is a Rust server for embedded debugging through either
probe-rs (native) or OpenOCD (via the GDB Remote Serial Protocol). It exposes a
single MCP tool set for AI assistants — probe discovery, target control, memory,
breakpoints, flash, RTT, and AI-facing crash diagnosis — plus a small CLI and
bundled skill for a command-driven workflow without setting up an MCP client
first.
Language versions: English | 中文
What It Provides
- One MCP tool set over two interchangeable backends (probe-rs native, or
OpenOCD via GDB RSP), chosen at connect. Validated on real ESP32-S3.
- MCP tools for probe discovery, target connection, core control, memory access,
breakpoints, flash programming, RTT communication, and crash diagnosis
(`diagnose_fault`, `unwind_exception`).
- CLI commands for environment checks, configuration inspection, probe listing,
MCP serving, and skill prompt handoff.
- A Codex/Claude Code compatible skill at `skills/embedded-debugger`.
- Release checks covering rustfmt, clippy, tests, docs, packaging, and the STM32
demo build.
Architecture
MCP client or CLI
|
v
embedded-debugger-mcp (one MCP tool set)
|
v
DebugBackend: probe-rs (native) | OpenOCD (GDB RSP)
|
v
debug probe / openocd -> target MCURequirements
- Rust stable toolchain.
- A probe-rs compatible debug probe such as ST-Link, J-Link, DAPLink, Black
Magic Probe, or a supported FTDI-based probe. Alternatively, a running
`openocd` exposing its GDB port (e.g. openocd-esp32 for ESP32) to use the
`openocd` backend.
- A supported target chip and working SWD/JTAG wiring for hardware operations.
- Nightly Rust plus `rust-src` for the bundled STM32 demo firmware check.
Build
git clone https://github.com/adancurusul/embedded-debugger-mcp.git
cd embedded-debugger-mcp
cargo build --releaseThe binary is `target/release/embedded-debugger-mcp`.
MCP Mode
Run the server explicitly:
embedded-debugger-mcp serveFor compatibility, running `embedded-debugger-mcp` without a subcommand also
serves MCP over stdio.
Example MCP client configuration:
{
"mcpServers": {
"embedded-debugger": {
"command": "/path/to/embedded-debugger-mcp/target/release/embedded-debugger-mcp",
"args": ["serve"],
"env": {
"RUST_LOG": "info"
}
}
}
}On Windows, use the `.exe` path and Windows path separators.
CLI And Skill Mode
CLI mode is useful for setup checks, automation, and agent workflows before an
MCP client is configured.
embedded-debugger-mcp doctor
embedded-debugger-mcp doctor --json
embedded-debugger-mcp probes list
embedded-debugger-mcp probes list --json
embedded-debugger-mcp config generate
embedded-debugger-mcp config validate
embedded-debugger-mcp config show
embedded-debugger-mcp skill print-prompt
embedded-debugger-mcp skill install --target bothThe bundled skill lives in:
skills/embedded-debugger/It is written as a plain Codex skill and is also packaged for Claude Code with
`.claude-plugin/plugin.json`. The skill starts with CLI checks and uses MCP
tools only when an MCP client is available.
Install the skill for Codex and Claude Code:
embedded-debugger-mcp skill install --target bothPreview or automate the install with JSON:
embedded-debugger-mcp skill install --target both --dry-run --json
embedded-debugger-mcp skill install --target both --force --json`--target` accepts `codex`, `claude`, or `both`. The command installs the Codex
skill under `~/.codex/skills/embedded-debugger`, the Claude Code skill under
`~/.claude/skills/embedded-debugger`, and a local Claude plugin-dir package under
`~/.claude/plugins/local/embedded-debugger-mcp`. Existing directories are not
replaced unless `--force` is passed.
Trigger the Codex skill with a prompt such as:
Use $embedded-debugger to inspect my embedded target setup.Load the installed Claude Code plugin package:
claude --plugin-dir ~/.claude/plugins/local/embedded-debugger-mcp --print '/embedded-debugger inspect my embedded target setup'For skill-only environments, the same `skills/embedded-debugger` directory can
also be copied to a local skills directory.
Validate the skill package:
python3 .github/scripts/validate_skill.py skills/embedded-debugger
python3 ~/.codex/skills/.system/skill-creator/scripts/quick_validate.py skills/embedded-debugger
claude plugin validate .
embedded-debugger-mcp skill install --target both --home /tmp/embedded-debugger-skill-home --force --jsonThe first command validates the repository skill metadata, the second validates
the standard `SKILL.md` layout when the Codex skill creator validator is
installed, and the third validates the Claude Code plugin manifest.
Backends
The tools run over one of two interchangeable engines, selected at `connect`:
- `backend: "probe-rs"` (default) — native probe-rs; full flash and RTT support.
- `backend: "openocd"` (experimental) — connects to an already-running `openocd`
over its GDB port (`openocd_address`, default `127.0.0.1:3333`) using the GDB
Remote Serial Protocol. Intended for targets probe-rs does not cover (e.g.
Xtensa ESP32 via openocd-esp32). Memory access and halt/run/step/reset are
validated on real ESP32-S3; flash and RTT are probe-rs only. Register reads
currently use ARM gdb register numbers, so PC/SP are wrong on Xtensa (known
limitation); `diagnose_fault` and `unwind_exception` are Cortex-M specific.
Start openocd with `gdb_memory_map disable`, otherwise it probes flash on the
GDB connect, fails, and rejects the connection — e.g.
`openocd -f board/esp32s3-builtin.cfg -c "gdb_memory_map disable"`.
The AI sees the same tool set for both; only `connect` arguments change.
MCP Tool Set
Probe management:
| Tool | Purpose |
|---|---|
| `list_probes` | Discover connected debug probes. |
| `connect` | Open a probe session for a target chip. |
| `probe_info` | Show active session information. |
Target control:
| Tool | Purpose |
|---|---|
| `halt` | Halt core execution. |
| `run` | Resume execution. |
| `reset` | Reset the core. Only the implemented hardware-style reset path is accepted. |
| `step` | Single-step one instruction. |
| `get_status` | Read core/session status. |
| `disconnect` | Drop the session and clean up resources. |
Memory and breakpoints:
| Tool | Purpose |
|---|---|
| `read_memory` | Read target memory with configured size/range limits. |
| `write_memory` | Write target memory when enabled by configuration. |
| `set_breakpoint` | Set a hardware breakpoint. |
| `clear_breakpoint` | Clear a hardware breakpoint. |
Diagnostics:
| Tool | Purpose |
|---|---|
| `diagnose_fault` | Read the Cortex-M SCB fault registers (CFSR/HFSR/MMFAR/BFAR/SHCSR/CPUID) plus PC/SP/LR in one call and return a compact structured evidence bundle with the set fault bits. Reports raw evidence; it does not assert a root cause. Halt the target first. |
| `unwind_exception` | Unwind the stack after a crash and map each frame to a source line. On the probe-rs backend, returns a full DWARF backtrace (function + file:line per frame) via probe-rs's own unwinder; on the OpenOCD backend, reads the Cortex-M exception stack frame and maps the faulting PC / caller LR to source lines. Needs `elf_path` to firmware built with debug info (`.debug_line`). |
Flash:
| Tool | Purpose |
|---|---|
| `flash_erase` | Erase flash when erase permissions are enabled. |
| `flash_program` | Program ELF, HEX, or BIN files through probe-rs flash algorithms. |
| `flash_verify` | Compare raw expected data with target flash contents. |
| `run_firmware` | Erase, program, reset/run, and optionally attach RTT. |
RTT:
| Tool | Purpose |
|---|---|
| `rtt_attach` | Attach to a SEGGER RTT control block. |
| `rtt_detach` | Detach RTT. |
| `rtt_channels` | List discovered RTT channels. |
| `rtt_read` | Read from an up channel with max byte and timeout limits. |
| `rtt_write` | Write to a down channel. |
Crash Diagnosis
After a crash, halt the core and let the model reason over the evidence:
1. `halt`, then `diagnose_fault` — reads the Cortex-M SCB fault registers
(CFSR/HFSR/MMFAR/BFAR/SHCSR/CPUID) plus PC/SP/LR in one call and returns a
compact structured bundle with the set fault bits. It reports evidence; it
does not assert a root cause.
2. `unwind_exception` with `elf_path` — maps the crash to source lines. On the
probe-rs backend this is a full DWARF backtrace (function + `file:line` per
frame); on the OpenOCD backend it reads the exception stack frame and maps
the faulting PC / caller LR.
Both are Cortex-M specific (SCB registers, ARM exception frame) and do not apply
to Xtensa (ESP32) targets. The firmware must be built with debug info
(`.debug_line`) for source mapping.
Safety Notes
- Flash erase is disabled unless `security.allow_flash_erase` or
`flash.allow_erase` is enabled.
- Memory writes are controlled by `security.allow_memory_write`.
- Optional memory range restriction uses target memory regions in the
configuration.
- Firmware file paths are canonicalized, checked against
`security.allowed_file_paths` when configured, and checked against size
limits.
- Sector erase by arbitrary address is rejected until target-specific sector
mapping is implemented.
- `flash_verify` supports raw data comparison. Use raw BIN files or hex data for
file-based verification.
Generate a starting configuration:
embedded-debugger-mcp config generate > embedded-debugger.toml
embedded-debugger-mcp --config embedded-debugger.toml config validateSTM32 Demo
The STM32 RTT demo is in `examples/STM32_demo`.
cd examples/STM32_demo
CARGO_TARGET_DIR=/tmp/embedded-debugger-mcp-stm32-target cargo +nightly check --lockedThe demo firmware shows multi-channel RTT communication and is intended as a
hardware validation aid. See examples/STM32_demo/README.md.
Release Checks
Run these before cutting a release:
cargo fmt --all -- --check
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo test --locked --all-targets --all-features
RUSTDOCFLAGS="-D warnings" cargo doc --locked --all-features --no-deps
cargo package --locked
python3 .github/scripts/validate_skill.py skills/embedded-debugger
claude plugin validate .
embedded-debugger-mcp skill install --target both --home /tmp/embedded-debugger-skill-home --force --json
(cd examples/STM32_demo && CARGO_TARGET_DIR=/tmp/embedded-debugger-mcp-stm32-target cargo +nightly check --locked)Acknowledgments
License
This project is licensed under the MIT License. See LICENSE.
Frequently asked questions
What is embedded-debugger-mcp?
embedded-debugger-mcp is A Model Context Protocol server for embedded debugging with probe-rs - supports ARM Cortex-M, RISC-V debugging via J-Link, ST-Link, and more
How do I install embedded-debugger-mcp?
Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.
Is embedded-debugger-mcp open source?
Yes — it is hosted on GitHub at https://github.com/adancurusul/embedded-debugger-mcp and has 13 stars.
Related MCP tools
An open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM for the Model Context Protocol. Enhance AI
The official Rust SDK for the Model Context Protocol Trusted by 2500+ developers. Trusted by 2500+ developers. Trusted by 2500+ developers.
🌍 Terraform Model Context Protocol (MCP) Tool - An experimental CLI tool that enables AI assistants to manage and operate Terraform environments.
Search infrastructure for AI
🙌 OpenHands: Code Less, Make More for the Model Context Protocol. Enhance AI assistants with powerful integrations. Python-based implementation.
The all-in-one Desktop & Docker AI application with built-in RAG, AI agents, No-code agent builder, MCP compatibility, and more.
Run your own MCP server? See who uses it and what to fix.
Measure it with TrackMCP