trackmcp
Back to directory
adancurusul

embedded-debugger-mcp

View on GitHub

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

13 stars RustAI & Machine Learning Updated Sep 12, 2025

Documentation

Embedded Debugger MCP Server

Rust
RMCP
License

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

text
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 MCU

Requirements

  • 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

bash
git clone https://github.com/adancurusul/embedded-debugger-mcp.git
cd embedded-debugger-mcp
cargo build --release

The binary is `target/release/embedded-debugger-mcp`.

MCP Mode

Run the server explicitly:

bash
embedded-debugger-mcp serve

For compatibility, running `embedded-debugger-mcp` without a subcommand also

serves MCP over stdio.

Example MCP client configuration:

json
{
  "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.

bash
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 both

The bundled skill lives in:

text
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:

bash
embedded-debugger-mcp skill install --target both

Preview or automate the install with JSON:

bash
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:

text
Use $embedded-debugger to inspect my embedded target setup.

Load the installed Claude Code plugin package:

bash
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:

bash
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 --json

The 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:

ToolPurpose
`list_probes`Discover connected debug probes.
`connect`Open a probe session for a target chip.
`probe_info`Show active session information.

Target control:

ToolPurpose
`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:

ToolPurpose
`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:

ToolPurpose
`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:

ToolPurpose
`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:

ToolPurpose
`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:

bash
embedded-debugger-mcp config generate > embedded-debugger.toml
embedded-debugger-mcp --config embedded-debugger.toml config validate

STM32 Demo

The STM32 RTT demo is in `examples/STM32_demo`.

bash
cd examples/STM32_demo
CARGO_TARGET_DIR=/tmp/embedded-debugger-mcp-stm32-target cargo +nightly check --locked

The 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:

bash
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

  • probe-rs for embedded debug probe support.
  • rmcp for the Rust MCP SDK.
  • tokio for the async runtime.

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

Run your own MCP server? See who uses it and what to fix.

Measure it with TrackMCP