io.github.microhenrio/openocd-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| OPENOCD_BIN | No | Path to an existing OpenOCD binary. If not set, the server will automatically download a pre-built version. |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| configureA | Set the chip/project settings for this session. Only non-empty arguments are applied; the rest keep their current values. interface_cfg : debug-probe OpenOCD config, e.g. 'interface/stlink.cfg' or 'interface/jlink.cfg' target_cfg : chip OpenOCD config, e.g. 'target/stm32g0x.cfg' transport : 'swd' or 'jtag' — set 'swd' for J-Link on Cortex-M (else it picks JTAG) svd_file : path to the chip's CMSIS-SVD file (peripheral registers) elf_file : path to the firmware .elf (variables by name) Alternatively, put these in an 'openocd-mcp.json' file in your project so they load automatically. Loading a new SVD/ELF takes effect on next use. |
| show_configA | Show the current effective project settings and where they came from. |
| set_permissionsA | Adjust safety permissions for this session (only provided args change). read_only : master switch — blocks all writes/flash/erase/raw allow_memory_write : write_memory / write_variable / write_register / write_peripheral_register allow_flash : flash_write (program) allow_flash_erase : flash_erase_sector (destructive; off by default) allow_raw_command : run_command escape hatch flash_max_bytes : reject flashing files larger than this (0 = no limit) For persistent settings, put a "permissions" object in openocd-mcp.json. (flash_allowed_paths is set there, not here.) |
| install_openocdA | Download and cache OpenOCD for this OS/architecture (if not already present), so the server can run without a separate OpenOCD install. Verifies a pinned SHA-256. Needed only when OpenOCD isn't bundled or on PATH (e.g. a pip install). |
| start_openocdA | Start OpenOCD as a subprocess (so you don't have to launch it manually). Detects an already-running instance and won't start a duplicate. interface_cfg : debug-probe config (default: project setting, else ST-Link) target_cfg : chip config, e.g. 'target/stm32f4x.cfg' (default: project setting) Leave both empty to use the configured project settings (see configure / openocd-mcp.json). A target_cfg must be set somewhere or this errors. |
| stop_openocdA | Stop the OpenOCD process this server started. |
| statusA | Report current debug state: whether OpenOCD is running, whether the target is halted or running, and the current program counter (PC) if halted. Does not disturb execution. |
| connectA | Connect to OpenOCD. Call this first. If nothing is listening and auto_start is True, the server launches OpenOCD itself using the configured project settings (probe + target) and connects. Set auto_start=False to require an already-running OpenOCD. |
| haltA | Halt the target CPU so registers and memory can be inspected. |
| resumeA | Resume CPU execution. Optionally resume from a specific address. If conditional breakpoints are set, this skips past those whose condition is false and stops at the first one whose condition is true (or on any other halt). |
| resetA | Reset the target. mode: 'halt' — reset and immediately halt (good for debugging) 'run' — reset and start running 'init' — reset and run init scripts With 'run' and conditional breakpoints set, this honors those conditions (skipping false ones) just like resume. |
| stepB | Execute a single instruction and halt again. |
| read_registersA | Dump all CPU registers (r0-r15, pc, sp, lr, xpsr, etc.). |
| read_registerA | Read a single CPU register by name. Examples: 'r0', 'pc', 'sp', 'lr', 'xpsr', 'msp', 'psp' |
| write_registerC | Write a value to a CPU register. value: hex string, e.g. '0x20001000' |
| read_memoryB | Read memory from the target. address : hex address, e.g. '0x20000000' count : number of units to read width : unit size in bits — 8, 16, or 32 |
| write_memoryB | Write a value to a memory address. address : hex address, e.g. '0x20000000' value : hex value, e.g. '0xDEADBEEF' width : 8, 16, or 32 |
| read_peripheralB | Read memory-mapped peripheral registers. base_address : peripheral base, e.g. '0x40020000' for GPIOA on STM32 count : number of 32-bit registers to read (default 16) |
| add_breakpointB | Add a breakpoint. address : hex address, e.g. '0x08001234' hardware : True for hardware breakpoint (recommended for flash); False for software |
| remove_breakpointC | Remove the breakpoint at the given address. |
| add_watchpointC | Add a data watchpoint. address : hex address to watch length : size in bytes (usually 1, 2, or 4) type : 'r' (read), 'w' (write), or 'a' (access/any) value : optional hex value to match (hardware dependent) mask : optional hex mask for the value match |
| remove_watchpointC | Remove the watchpoint at the given address. |
| list_breakpointsA | List all currently set breakpoints and watchpoints. |
| remove_all_breakpointsA | Remove every breakpoint and watchpoint that is currently set. |
| add_conditional_breakpointA | Add a conditional breakpoint. The target halts at address : hex address for the breakpoint condition : a TCL expression/block. Use get_reg and get_mem ?width?. It is evaluated when the breakpoint is hit; non-zero = halt. Examples: 'expr {[get_reg r0] > 100}' 'expr {[get_mem 0x20000000] == 0xdeadbeef}' 'incr ::hit_count; expr {$::hit_count >= 5}' |
| remove_conditional_breakpointB | Remove the conditional breakpoint at the given address. |
| flash_writeA | Program a firmware file onto the target flash. path : full path to .elf, .bin, or .hex file verify : read back and verify after programming (recommended) reset_after : reset and run the new firmware after flashing |
| flash_infoB | Display information about the flash bank (size, sectors, erase state). |
| flash_erase_sectorA | Erase a range of flash sectors. bank : flash bank index (usually 0) first : first sector number to erase last : last sector number to erase (inclusive) |
| load_elfA | Load variable names and addresses from a firmware .elf file, so you can read and write variables by name. Build the firmware with debug symbols. path: full path to the .elf (defaults to the configured elf_file if set). |
| read_variableB | Read a global/static variable by name (requires load_elf first). Scalars (1/2/4 bytes) are decoded to hex and decimal; larger objects (arrays, structs) are dumped as words. |
| write_variableA | Write a scalar global/static variable by name (requires load_elf first). value: hex (e.g. '0x2A') or decimal. Use write_memory for arrays/structs. |
| list_variablesA | List known variable names, optionally filtered by a substring. |
| watch_variablesA | Live-watch one or more variables WITHOUT halting the CPU: sample them repeatedly while the target runs and return a time-series table. names : comma- or space-separated variable names (requires load_elf). samples : number of snapshots, 1-200. interval_ms : delay between snapshots in milliseconds. Works for RAM globals/statics (read live via background memory access). CPU registers need a halt and aren't supported here. Multi-word values are read non-atomically, so a >4-byte value may be momentarily inconsistent. This tool is one-shot and returns a flat text table. For an open-ended,
auto-refreshing GUI window with expandable structs/arrays, there is a
separate standalone program called |
| load_svdA | Load peripheral register definitions from a CMSIS-SVD file. Loaded automatically on first use from the configured svd_file; call this only to use a different SVD. path defaults to the configured svd_file. |
| read_peripheral_registerA | Read a peripheral register by name (e.g. 'RCC.CR', 'GPIOA.MODER') and decode its named bitfields. The target should be halted for a stable read. |
| write_peripheral_registerA | Write a 32-bit value to a peripheral register by name (e.g. 'GPIOA.ODR'). |
| list_peripheral_registersA | With no argument: list all peripheral names. With a peripheral name (e.g. 'RCC'): list that peripheral's registers. |
| run_commandA | Run any raw OpenOCD TCL command and return its output. Use this for anything not covered by the other tools. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/microhenrio/openocd-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server