Skip to main content
Glama

esp-runtime-mcp

MCP server for the runtime side of ESP-IDF development: what happens on the chip after flashing.

ESP-IDF 6.0 ships an official MCP server (idf.py mcp-server) with set_target, build_project, flash_project and clean_project. Other community servers cover the same build/flash ground. None of them let the agent read the console, so the agent can flash firmware but cannot see that it crashed. This server closes the loop:

edit -> build -> flash             (idf.py mcp-server)
     -> capture_log(reset, expect) (this server: did it boot and reach the expected state?)
     -> crash? decoded backtrace   (this server: file:line, inlining, fault address)
     -> fix -> ...

Tools

Tool

What it does

capture_log

Reads the console until all expect regexes have matched in order, a crash is caught, or the timeout expires. It can hard-reset the chip first. Any crash in the log is parsed and symbolised automatically, and passed gives a single boolean verdict for the run.

analyze_log

Parses a log the user pasted, or the last capture, without hardware.

decode_addresses

Runs addr2line on any text containing addresses, such as a Backtrace: line.

read_coredump

Runs esp-coredump on a core dump from flash, from a file, or from a base64 dump printed to UART in the last capture. Returns the crashed task and its stack frames.

reset_device

Sends an RTS→EN reset pulse, holding IO0 high so the chip boots the app.

list_serial_ports

Lists serial ports and flags the likely ESP bridges: Espressif USB, CP210x, CH340/CH9102 and FTDI.

Crash parser coverage

  • Guru Meditation on Xtensa (PC / EXCVADDR / PC:SP backtrace) and RISC-V (MEPC / RA / MTVAL). Includes IWDT and stack-canary debug exceptions.

  • abort(), assert failed (both the IDF ≥5 and newlib formats), and ESP_ERROR_CHECK with file, line, function and expression. A trailing abort() is merged into the same event.

  • FreeRTOS stack overflow hook, heap corruption and brownout.

  • Task WDT, keeping a separate backtrace for each CPU.

  • ROM reset reasons (rst:0xc (SW_CPU_RESET)) and reboot loops; each crash in a loop becomes its own event.

  • RISC-V without EH-frame backtraces: words from the stack dump that fall in code address ranges are offered as candidates and labelled as a heuristic.

Related MCP server: esp-idf-mcp

Design notes

  • Port I/O. pyserial is blocking, so the read loop runs in a worker thread behind an async API. Each port has its own lock, so two tools never read the same UART at once. Ports are opened with serial_for_url, which means rfc2217://host:port works for boards connected to another machine.

  • Line handling. Reads use a ring buffer, and the result reports how many lines were dropped. Chunked reads are split into lines correctly, and ANSI colour codes are stripped.

  • Stopping after a crash. The panic message is only the start of the crash output: the register dump and backtrace come after it. Capture therefore continues until Rebooting... or a 1.5 s grace period (for builds configured to halt on panic).

  • Symbolisation. The architecture comes from e_machine in the ELF header. The tool is then looked up in this order: xtensa-esp-elf-addr2line / riscv32-esp-elf-addr2line, then $IDF_TOOLS_PATH, then llvm-addr2line. Results are cached per ELF modification time, so a reboot loop costs a single addr2line call.

  • ESP-IDF conventions. The defaults follow $ESPPORT and $ESPBAUD. The ELF path is taken from build/project_description.json.

Install

pip install -e ".[coredump]"

Claude Code / Cursor config (run with ESP-IDF activated so the toolchain is on PATH):

{
  "mcpServers": {
    "esp-idf":     { "command": "eim", "args": ["run", "idf.py mcp-server"] },
    "esp-runtime": {
      "command": "esp-runtime-mcp",
      "env": { "ESPPORT": "/dev/ttyUSB0", "ESP_RUNTIME_PROJECT_DIR": "/path/to/project" }
    }
  }
}

Tests

pip install -e ".[dev]" && pytest

The tests need no hardware and no Espressif toolchain:

  • The parser is tested against recorded crash logs in tests/fixtures.

  • The capture loop is tested through pyserial's loop:// device, with data fed in chunks the way a real UART delivers it.

  • The addr2line path is tested end to end on a host-compiled ELF.

  • The MCP tools are tested through an in-memory MCP client.

License

MIT

Available Tools

6 tools
analyze_logC

Find crashes (Guru Meditation, abort, assert, ESP_ERROR_CHECK, stack overflow, TWDT, heap corruption, brownout) and reset reasons in a log, and symbolise backtraces against the ELF.

Inputs: elf, text, project_dir.

capture_logA

Read the device console until all expect patterns match, a crash is caught, or time runs out.

Crashes found in the log are parsed and symbolised automatically. Check passed: true only if every expect pattern matched and no crash was seen.

Inputs: elf, baud, port, reset, +5 more.

decode_addressesB

Symbolise code addresses (function, file:line, inlining) with the toolchain's addr2line. For a 'Backtrace: PC:SP PC:SP' line only the PCs are decoded.

Inputs: addresses (required), elf, project_dir.

list_serial_portsA

List serial ports; likely_esp marks Espressif USB, CP210x, CH340/CH9102 and FTDI bridges.

Inputs: no named parameters. Returns: result

read_coredumpC

Run esp-coredump info_corefile and return the crashed task, its stack frames and the full report.

Inputs: elf, port, source, core_file, +1 more.

reset_deviceA

Hard-reset the chip via the RTS->EN auto-reset circuit (app boot, not download mode).

Inputs: baud, port. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.5/5.0

    Scored across 6 tools

    Disambiguation4/5

    Tools target distinct actions: listing ports, capturing logs, analyzing logs, decoding addresses, resetting, reading coredumps. Slight overlap between capture_log (which also parses crashes) and analyze_log, but descriptions clarify the distinction.

    Naming Consistency5/5

    All tools follow a consistent snake_case verb_noun pattern (list_serial_ports, capture_log, analyze_log, decode_addresses, reset_device, read_coredump). No mixing of conventions.

    Tool Count5/5

    Six tools form a well-scoped set for ESP runtime debugging: port discovery, log capture, log analysis, address decoding, reset, and coredump reading. Each tool has a clear role without redundancy.

    Completeness4/5

    Core lifecycle for runtime debugging is covered: discovering ports, capturing/analyzing logs, decoding addresses, resetting, and reading coredumps. Minor gaps like device info query or serial write are not critical but could be useful.

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      A
      quality
      D
      maintenance
      A headless MCP server that enables AI tools (like Claude Code) to read and analyze serial logs from embedded boards (ESP32, STM32) for firmware debugging, with read-only tools for log retrieval and a built-in web viewer.
      6
      1
      -
    • A
      license
      A
      quality
      B
      maintenance
      Enables AI assistants to spawn and control persistent local shells, SSH sessions, REPLs, debuggers, and serial/UART devices with zero-loss output capture, timestamped history, and atomic expect matching for command execution and prompt synchronization.
      12
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      Enables local UART and serial-port debugging through MCP, providing persistent capture, log search, regex/event monitoring, HEX send/query, protocol parsing, and shell-like command sequences.
      15
      MIT