Metadata-Version: 2.4
Name: openocd-mcp
Version: 0.1.0
Summary: MCP server to debug microcontrollers from Claude through OpenOCD (flash, halt/step, memory/registers, breakpoints, variables and peripheral registers by name).
Project-URL: Homepage, https://github.com/microhenrio/openocd-mcp
Author: Hexentronics
License: MIT
License-File: LICENSE
Keywords: arm,debugging,embedded,mcp,openocd,stm32,swd
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Debuggers
Classifier: Topic :: Software Development :: Embedded Systems
Requires-Python: >=3.10
Requires-Dist: cmsis-svd>=0.6
Requires-Dist: mcp>=1.9.0
Requires-Dist: pyelftools>=0.31
Description-Content-Type: text/markdown

<!-- mcp-name: io.github.microhenrio/openocd-mcp -->

# OpenOCD MCP Server

Debug microcontrollers directly from Claude. This is an [MCP](https://modelcontextprotocol.io)
server that drives [OpenOCD](https://openocd.org/), letting Claude flash firmware,
control execution, and inspect a running target — and read your variables and
peripheral registers **by name** instead of raw addresses.

## Description

Once connected to a target through a debug probe (ST-Link, J-Link, CMSIS-DAP, …),
Claude can:

- **Flash firmware** — program and verify `.elf` / `.bin` / `.hex` images
- **Control execution** — halt, resume, single-step, reset
- **Inspect state** — read/write CPU registers and memory
- **Set breakpoints** — add/remove/list hardware & software breakpoints
- **Read variables by name** — from your firmware's `.elf` symbols (e.g. `read_variable uart_rx_count`)
- **Read peripheral registers by name** — from a CMSIS-SVD file, decoded into named bitfields (e.g. `RCC.CR`, `GPIOA.MODER`)

The server is **chip-agnostic** — it works with any target OpenOCD supports; you
point it at your chip's config and (optionally) SVD/ELF. It can also **start
OpenOCD for you** and **download OpenOCD automatically** for your platform, so
there's nothing else to install by hand.

## Installation

**Prerequisites:** Python 3.10+, [Claude Code](https://claude.com/claude-code),
and a debug probe connected to your target.

Clone and install the package into a virtual environment:

```bash
git clone https://github.com/microhenrio/openocd-mcp
cd openocd-mcp
python -m venv .venv
```

Install it (creates the `openocd-mcp` command):

```bash
# Windows
.venv\Scripts\python -m pip install -e .

# macOS / Linux
.venv/bin/python -m pip install -e .
```

Register the server with Claude Code (user scope makes it available in every
project):

```bash
# Windows
claude mcp add --scope user openocd -- "%CD%\.venv\Scripts\openocd-mcp.exe"

# macOS / Linux
claude mcp add --scope user openocd -- "$PWD/.venv/bin/openocd-mcp"
```

> **Windows shortcut:** instead of the steps above you can just run `setup.bat`,
> which creates the environment, installs the package, and registers it.

Then **restart Claude Code** so it loads the server. Verify with:

```bash
claude mcp list      # openocd: ... ✓ Connected
```

**OpenOCD** is obtained automatically: a build for your OS/architecture is
downloaded and cached on first connect (checksum-verified). You can also fetch it
ahead of time with `openocd-mcp install-openocd`, or use an existing install by
setting the `OPENOCD_BIN` environment variable.

## How to work with it

### 1. Point it at your chip

Each firmware project tells the server which target it's debugging. Create an
`openocd-mcp.json` in your project root (a template is in
[`openocd-mcp.example.json`](openocd-mcp.example.json)):

```json
{
  "target_cfg": "target/stm32g0x.cfg",
  "svd_file": "path/to/STM32G0B0.svd",
  "elf_file": "path/to/build/firmware.elf"
}
```

- `target_cfg` / `interface_cfg` — OpenOCD configs (relative to its scripts dir).
  Defaults to an ST-Link probe; set `target_cfg` for your chip.
- `svd_file` — CMSIS-SVD file for the chip (enables peripheral registers by name).
- `elf_file` — your firmware build output (enables variables by name).

Or simply tell Claude the chip you're using and it will configure the session for
you. `show_config` reports the active settings at any time.

### 2. Talk to Claude

With the board plugged in, describe what you want — Claude picks the right tools:

| You say… | What happens |
|---|---|
| "connect and halt the target" | Starts OpenOCD if needed, attaches, halts the CPU |
| "what's the status?" | Reports running/halted and the current program counter |
| "read the variable `sensor_value`" | Looks it up in the `.elf` and reads it off the chip |
| "set `motor_enabled` to 1" | Writes the variable by name |
| "read `GPIOA.MODER`" | Reads the register and decodes its named bitfields |
| "list the `RCC` registers" | Lists registers from the SVD |
| "break at `0x08001234`, then reset and run" | Sets a breakpoint and resets |
| "flash `build/firmware.elf` and run it" | Programs, verifies, and restarts |
| "dump 64 bytes of RAM at `0x20000000`" | Reads memory |

You don't call tools by name — describe the goal and Claude maps it to the
underlying tools.

> The target must be **halted** to read registers, memory, or variables — Claude
> halts first when needed. The first `connect` of a session starts OpenOCD
> automatically.
