JTAG/SWD MCP Server for hardware debugging via OpenOCD
Project description
mcjtag
JTAG/SWD MCP Server for hardware debugging via OpenOCD.
Gives LLMs the ability to interact with JTAG/SWD debug probes — read/write memory, inspect registers, flash firmware, scan JTAG chains, and decode SVD peripheral registers.
Install
uvx mcjtag
Or install permanently:
uv pip install mcjtag
Requirements: Python 3.11+, OpenOCD installed on your system.
Quick Start
# Auto-spawn OpenOCD with a config file
OPENOCD_CONFIG=openocd-daplink-swd.cfg uvx mcjtag
# Connect to an already-running OpenOCD
OPENOCD_HOST=localhost OPENOCD_PORT=6666 uvx mcjtag
# Add to Claude Code
claude mcp add mcjtag -- uvx mcjtag
# Add to Claude Code with auto-spawn
claude mcp add mcjtag -- env OPENOCD_CONFIG=/path/to/config.cfg uvx mcjtag
A typical first session:
probe_diagnostics()— verify probe, target, and connection healthjtag_scan()— enumerate the JTAG chain, read IDCODEstarget_state()— check if the target is halted or runningread_memory("0x08000000", count=4)— read the vector tableread_registers()— inspect all CPU registers
Tools
17 tools across 9 categories:
| Category | Tools | Purpose |
|---|---|---|
| Connection | connect, start_openocd, disconnect |
Session lifecycle |
| Diagnostics | probe_diagnostics |
9-point health check |
| Target | target_state, target_control |
Halt, resume, step, reset |
| Memory | read_memory, write_memory, search_memory |
Read, write (SRAM-safe), search |
| Registers | read_registers, write_register |
CPU register access |
| Flash | flash_info, flash_program |
Bank info, program firmware |
| JTAG | jtag_scan, jtag_shift |
Scan chain, IR/DR shift |
| SVD | svd_inspect |
Peripheral register decoding |
| Raw | raw_command |
Direct OpenOCD TCL access |
Resources
7 MCP resources for polling target state without tool calls:
| URI | Description |
|---|---|
jtag://target/state |
Execution state and program counter |
jtag://registers/all |
All CPU register values |
jtag://flash/banks |
Flash bank topology |
jtag://jtag/chain |
JTAG scan chain with TAPs |
jtag://svd/peripherals |
Loaded SVD peripheral list |
jtag://svd/{peripheral} |
Decoded register values for a peripheral |
jtag://transport/info |
Active transport and adapter info |
Prompts
5 pre-built prompt templates for common workflows:
| Prompt | Purpose |
|---|---|
identify_chip() |
JTAG scan and chip identification |
debug_crash() |
HardFault diagnosis via registers and stack |
reverse_engineer_peripheral(peripheral) |
SVD-based register decoding |
flash_and_verify(image_path) |
Complete flash programming workflow |
memory_map() |
Build memory map from vector table |
Environment Variables
| Variable | Default | Description |
|---|---|---|
OPENOCD_HOST |
localhost |
OpenOCD TCL server hostname |
OPENOCD_PORT |
6666 |
OpenOCD TCL server port |
OPENOCD_CONFIG |
— | Path to .cfg file; auto-spawns OpenOCD if set |
OPENOCD_SVD |
— | SVD file path; auto-loaded on connection |
MCJTAG_SAFE_WRITE_RANGES |
0x20000000-0x20100000 |
Allowed write ranges (comma-separated hex). Set to none for unrestricted |
MCJTAG_MAX_SEARCH_RANGE |
1048576 |
Maximum search_memory range in bytes |
MCJTAG_ALLOW_RAW |
false |
Set true to disable raw_command deny-list |
Safety
mcjtag ships with conservative defaults for use alongside safety-critical firmware:
- Write restrictions —
write_memoryonly allows SRAM by default (0x20000000-0x20100000). Flash, peripheral, and system writes are blocked unless you expand the ranges. - Raw command deny-list —
raw_commandblocks destructive OpenOCD commands (flash erase, memory writes, reset, shutdown). Use dedicated tools instead, or setMCJTAG_ALLOW_RAW=true. - Flash validation —
flash_programchecks file existence, extension, and size before writing. - Input validation — Hex parsing rejects negatives, alignment is enforced for writes, values are range-checked against width.
Hardware
Tested with:
- Probe: Treedix DAP-Link V1 (CMSIS-DAP)
- Target: STM32F103C8T6 (Blue Pill)
- Transport: SWD and JTAG
Shipped OpenOCD configs:
openocd-daplink-swd.cfg— DAP-Link over SWD (2-wire, recommended)openocd-daplink-jtag.cfg— DAP-Link over JTAG (4-wire, chain scanning)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcjtag-2026.2.18.tar.gz.
File metadata
- Download URL: mcjtag-2026.2.18.tar.gz
- Upload date:
- Size: 318.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"EndeavourOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dfbbfa7e4504148a4a59aedc2103880ed441a50665b1f12a34b07099b159c4a7
|
|
| MD5 |
427db4a2ca985d802512def1a817e8d0
|
|
| BLAKE2b-256 |
6326ed8b53e16f7fac1fd80c9824b089e26c78e3c149b352a8dcd82c85a96c26
|
File details
Details for the file mcjtag-2026.2.18-py3-none-any.whl.
File metadata
- Download URL: mcjtag-2026.2.18-py3-none-any.whl
- Upload date:
- Size: 42.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"EndeavourOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63623e864678e822cd91e519efc8d1a795db26382e1f5a59525bc42e604d4c26
|
|
| MD5 |
33c549f2c78163ad29ba7fd43107e0fb
|
|
| BLAKE2b-256 |
6bb13b0cceec1bc8c45a287740ee9b32e137981e10a16e00e2d9fc8b6f40358b
|