Read-only Cortex-M live-attach MCP for DWARF variables, symbols, memory and registers.
Debug_Mcp is a JSON-lines stdio server that lets an MCP client inspect a running Cortex-M target through pyOCD. It is designed for firmware diagnosis when opening a debug session must not reset the target or change its run state.
The attach path is non-intrusive: connect_mode=attach is used with auto_unlock=false and no reset or halt on connect. A small number of inspection operations have a different target-state contract: read_registers and snapshot may briefly halt a running target, read coherent core state, and resume it.
Safety boundary: this server exposes no variable-write, memory-write, flash, erase, breakpoint, reset, or run-control tools. Read-only does not mean non-halting for every operation; see Target-state semantics.
Firmware engineers often need live values, symbols, memory and register state while a device is already running. This project puts those reads behind a small, explicit interface that can be used from Claude Desktop, Claude Code, or another MCP client without requiring the client to drive a full debug workflow.
- Non-resetting attach through pyOCD using SWD or JTAG.
- DWARF-based C variable resolution for globals, members, arrays, pointers and selected bitfields/enums.
- ELF symbol-table fallback when DWARF type information is unavailable.
- Memory and register inspection with bounded reads.
- Coherent snapshot mode for reading registers and multiple variables together.
- AXF/ELF/OUT discovery under a project directory.
- JSON-lines stdio protocol with structured success and error responses.
- Toolchain coverage for debug artifacts produced by Keil MDK, GCC and IAR, subject to compatible debug information.
| Operation | May halt a running target? | Notes |
|---|---|---|
attach |
No | Uses attach mode; no reset or halt is requested on connect. |
status |
No | Reports the current target state. |
read_memory |
No explicit halt | Reads a bounded raw memory range. |
resolve_symbol |
No | Resolves an address from the debug artifact only. |
read_symbol / read_variable / read_variables |
No explicit halt | Resolve metadata, then read target memory. |
read_registers |
Yes, briefly | Halts only when the target is running, reads core registers, then resumes. |
snapshot |
Yes, briefly | Halts only when the target is running, reads registers and variables, then resumes. |
detach / shutdown |
No explicit reset or run-control | Closes the probe session. |
The server does not expose a write path. However, a memory read can still be inappropriate for some peripheral addresses, and a halted/resumed target can affect timing-sensitive firmware. Select addresses and operations with the target's safety requirements in mind.
| Operation | Description |
|---|---|
attach |
Select a pyOCD probe and attach via SWD/JTAG. |
detach |
Close the pyOCD session and release the probe. |
status |
Return the connection state and target run state. |
read_memory |
Read raw bytes from target memory; limited to 256 bytes per request. |
resolve_symbol |
Look up a linker symbol address and size from the AXF/ELF/OUT file. |
read_symbol |
Resolve a symbol and read its stored bytes from target memory. |
read_variable |
Read one C variable or supported member/array/pointer expression. |
read_variables |
Batch-read up to 64 C variables. |
read_registers |
Read core registers; may briefly halt and resume a running target. |
snapshot |
Read registers and variables coherently; may briefly halt and resume. |
find_axf |
Recursively find .axf, .elf and .out files under a directory. |
shutdown |
Detach and exit. |
The DWARF resolver supports expressions such as:
symbol
symbol.member
symbol.arr[5]
symbol.member[2].subfield
ptr->field
*ptr
Function calls, address-of expressions, casts and arbitrary arithmetic are rejected. Pointer expressions require a live target-memory read.
- Python 3.10+
pyocd>=0.45.0pyelftools>=0.33cmsis-pack-manager>=0.6.0pylink-square>=1.7.0- A supported debug probe, such as J-Link, ST-Link or CMSIS-DAP
- A Cortex-M target and a matching debug artifact with symbols:
.axf,.elfor.out
Install the Python dependencies from requirements.txt.
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txtOn Windows PowerShell, activate the environment with:
.\.venv\Scripts\Activate.ps1python -m pyocd listRecord the probe serial number, for example 000123456789.
The server speaks JSON-lines over stdin/stdout. A minimal client configuration is:
{
"mcpServers": {
"debug-mcp": {
"command": "python",
"args": ["C:/path/to/Debug_Mcp/live_attach.py"]
}
}
}The pre-built DebugMcp.exe in the repository can also be used on Windows. For reproducible deployments, prefer a versioned GitHub Release artifact with a checksum once releases are enabled.
{"id":1,"operation":"attach","arguments":{"probe_serial":"000123456789","protocol":"swd","clock_hz":2000000}}
{"id":2,"operation":"read_variable","arguments":{"axf_file":"C:/firmware/project.axf","expression":"g_bms.pack[2].soc"}}
{"id":3,"operation":"read_registers","arguments":{}}
{"id":4,"operation":"shutdown","arguments":{}}The exact values returned by reads depend on the selected probe, target state and matching debug artifact. A failed read is returned as an error; callers must not interpret a failed read as zero.
live_attach.py JSON-lines server and DWARF resolver
requirements.txt Runtime dependencies
DebugMcp.exe Pre-built Windows artifact kept for convenience
LICENSE MIT license
The repository can support host-side checks such as Python syntax compilation without a connected target. End-to-end validation is environment-dependent and requires all of the following:
- A supported debug probe and driver installation.
- A running Cortex-M target with a compatible SWD/JTAG connection.
- The exact matching AXF/ELF/OUT artifact, including usable symbols or DWARF data.
- A client that sends the JSON-lines protocol and checks both success and error responses.
The current repository includes a lightweight static syntax check in GitHub Actions. Hardware attach, target reads, halt/resume behavior and end-to-end protocol coverage are intentionally not claimed by that check.
read_registersandsnapshotcan briefly halt a running target; do not use them where that timing disturbance is unacceptable.- Expression support is intentionally narrower than a full C evaluator.
- Peripheral memory reads may have target-specific side effects even though the server does not write.
- Debug-artifact and target compatibility must be checked by the caller; a source-level match alone is not sufficient.
See CONTRIBUTING.md for the change and verification boundary, and SECURITY.md for handling sensitive firmware/debug data.
MIT - see LICENSE.