Debug_Mcp
by xhw949
README.md
# Debug_Mcp
**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](https://github.com/pyocd/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](#target-state-semantics).
## Why this project
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.
## Features
- **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.
## Target-state semantics
| 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.
## Operations
| 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. |
## C-expression support
The DWARF resolver supports expressions such as:
```text
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.
## Requirements
- Python 3.10+
- `pyocd>=0.45.0`
- `pyelftools>=0.33`
- `cmsis-pack-manager>=0.6.0`
- `pylink-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`, `.elf` or `.out`
Install the Python dependencies from [`requirements.txt`](requirements.txt).
## Quick start
### 1. Install dependencies
```bash
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
```
On Windows PowerShell, activate the environment with:
```powershell
.\.venv\Scripts\Activate.ps1
```
### 2. Check available probes
```bash
python -m pyocd list
```
Record the probe serial number, for example `000123456789`.
### 3. Register the server in an MCP client
The server speaks JSON-lines over stdin/stdout. A minimal client configuration is:
```json
{
"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.
### 4. Example requests
```json
{"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.
## Project layout
```text
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
```
## Verification boundary
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:
1. A supported debug probe and driver installation.
2. A running Cortex-M target with a compatible SWD/JTAG connection.
3. The exact matching AXF/ELF/OUT artifact, including usable symbols or DWARF data.
4. 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.
## Known limitations
- `read_registers` and `snapshot` can 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.
## Contributing and security
See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the change and verification boundary, and [`SECURITY.md`](SECURITY.md) for handling sensitive firmware/debug data.
## License
MIT - see [`LICENSE`](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues