Skip to main content

Multi-client debug-probe broker MCP server — session lifecycle, probe operations, ITM/SWO trace, and lane supervision over three concurrent transports

Project description

brontes-probe-mcp

A Model Context Protocol (MCP) server that gives AI assistants direct access to a debug probe — flash firmware, halt/resume, read memory, and stream ITM trace, all without leaving the conversation.

Status: 0.2.1 — fully operational. Session lifecycle, probe operations, ITM/SWO trace, and lane supervision over three concurrent transports (stdio MCP, Unix socket, loopback TCP).

Quick start

Three steps: configure, start the probe agent (macOS / pip only), connect.


Step 1 — Configure

Pick your deployment. Each section below includes a prompt you can paste directly into Claude Code to write .mcp.json automatically, or add it manually if you prefer.

Docker on Linux (recommended)

Paste into Claude Code:

Add brontes-probe-mcp to .mcp.json in this project, creating it if needed:

{
  "mcpServers": {
    "brontes-probe-mcp": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "--device=/dev/bus/usb",
        "-v", "${HOME}/.brontes-probe-mcp:/run/brontes-probe-mcp",
        "-v", "${HOME}/.brontes-probe-mcp/packs:/packs",
        "-e", "PROBE_BROKER_TRANSPORTS=stdio,socket",
        "-e", "CMSIS_PACK_ROOT=/packs",
        "ghcr.io/cms-pm/brontes-probe-mcp@sha256:TBD"
      ]
    }
  }
}

Then pull the image:
docker pull ghcr.io/cms-pm/brontes-probe-mcp@sha256:TBD

Then tell me to restart Claude Code to load the new server.

Replace sha256:TBD with the digest from CHANGELOG.md.

Docker on macOS (Docker Desktop)

Docker Desktop cannot pass USB devices into containers. First install the host CLI:

pip install brontes-probe-mcp

Paste into Claude Code:

Add brontes-probe-mcp to .mcp.json in this project, creating it if needed:

{
  "mcpServers": {
    "brontes-probe-mcp": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-v", "${HOME}/.brontes-probe-mcp:/run/brontes-probe-mcp",
        "-v", "${HOME}/.brontes-probe-mcp/packs:/packs",
        "-e", "PROBE_BROKER_TRANSPORTS=stdio,socket",
        "-e", "CMSIS_PACK_ROOT=/packs",
        "-e", "PROBE_BROKER_GDB_HOST=host.docker.internal",
        "ghcr.io/cms-pm/brontes-probe-mcp@sha256:TBD"
      ]
    }
  }
}

Then tell me to restart Claude Code to load the new server.

pip install (no Docker, all platforms)

Requires arm-none-eabi-gdb on PATH (install via your OS package manager or ARM toolchain download).

pip install brontes-probe-mcp

Paste into Claude Code:

Add brontes-probe-mcp to .mcp.json in this project, creating it if needed:

{
  "mcpServers": {
    "brontes-probe-mcp": {
      "command": "brontes-probe-mcp-cli",
      "args": ["serve"]
    }
  }
}

Then tell me to restart Claude Code to load the new server.

Step 2 — Start the probe agent (macOS and pip only)

Docker on Linux users skip this step — the container manages pyocd internally.

Run this once before each session (keep it running in the background):

# Auto-detects probe and target if exactly one probe is connected
brontes-probe-mcp-cli probe-agent start

If auto-detection fails (multiple probes, or board not recognised by pyocd):

brontes-probe-mcp-cli probe-agent start --target stm32g474 --probe-uid <uid>

session_start auto-discovers the running agent — no extra configuration needed. session_stop removes the Brontes session but leaves the agent running for reuse.


Step 3 — Connect

After restarting Claude Code (or running /mcp to reload), paste this into the conversation:

Call probe_discover to list connected debug probes. Use any board or chip
information from the results to call target_suggest and find the pyocd
target string. If target_suggest returns no matches, call pack_update to
refresh the pack index, then pack_search to find the right CMSIS pack name,
then pack_install (may take a minute), then retry target_suggest. Once you
have the target string, call session_start — omit probe_uid if only one
probe is connected, otherwise pass the uid from probe_discover.

If you already know your target string:

Call session_start with target="stm32g474".

What it does

  • Probe discoveryprobe_discover, target_suggest, pack_search, pack_install, pack_update
  • Session lifecyclesession_start, session_stop, session_status (reports image_digest, image_tag, protocol_version).
  • Probe operationsprobe_program (elf / bin / hex), probe_halt, probe_resume, probe_reset (soft / hard), probe_mem_read, probe_blackbox_export.
  • ITM / SWO traceitm_stream_start, itm_stream_stop, recent_lines.
  • Lane supervisionlane_status, lane_release, lane_resume.

Three transport adapters bind concurrently over one shared BrokerCore instance, controlled by PROBE_BROKER_TRANSPORTS:

Transport Default Use case
stdio MCP stdio — one AI client
socket Unix-domain socket — local tool access
tcp Loopback TCP with bearer token — sandbox / Docker Desktop

CLI

The brontes-probe-mcp-cli console script manages the server and probe agent:

brontes-probe-mcp-cli --version
brontes-probe-mcp-cli --config-dump            # print resolved config as JSON

# Start all configured transports (MCP server entry point for pip install)
brontes-probe-mcp-cli serve

# Probe agent — manages the host-side pyocd gdbserver daemon
brontes-probe-mcp-cli probe-agent start [--target TARGET] [--port PORT] [--probe-uid UID]
brontes-probe-mcp-cli probe-agent status       # prints JSON; exits 1 if not healthy
brontes-probe-mcp-cli probe-agent stop [--force]

If --target is omitted, probe-agent start auto-detects from a connected probe. If multiple probes are attached, specify --target and --probe-uid.

Configuration

All configuration is via PROBE_BROKER_* environment variables:

Variable Default Description
PROBE_BROKER_TRANSPORTS stdio,socket Comma-separated active transports
PROBE_BROKER_SOCKET_PATH ~/.brontes-probe-mcp/probe.sock Unix socket path
PROBE_BROKER_TCP_HOST 127.0.0.1 TCP bind address
PROBE_BROKER_TCP_PORT 7172 TCP port
PROBE_BROKER_LANES swd,itm_swo Active probe lanes
PROBE_BROKER_BACKEND pyocd Debug backend (pyocd or openocd)
PROBE_BROKER_GDB_HOST 127.0.0.1 GDB server host — set to host.docker.internal to connect to a host-side probe agent
PROBE_BROKER_DEFAULT_PACK (none) Default CMSIS pack path — used by target_suggest and session_start when no pack= argument is supplied
PROBE_BROKER_AGENT_STATE_DIR ~/.brontes-probe-mcp Directory where probe-agent start writes its state file and where session_start looks for a running agent. If probe-agent start --state-dir is set to a non-default path, set this variable to match
PROBE_BROKER_DIGEST_CHECK enforce Image digest verification (enforce, warn, skip)

Flash memory snapshot (probe_blackbox_export)

Capture a binary snapshot of the target's flash for archiving or diff:

{
  "tool": "probe_blackbox_export",
  "arguments": {
    "out": "/tmp/snapshot.bin"
  }
}

Defaults to 0x080000000x08080000 (512 KB). Requires an active session. Response includes bytes_written and snapshot_at (UTC ISO-8601).

See docs/tutorials/blackbox-export.md for custom address ranges, error cases, and snapshot comparison examples.

Advanced deployment

Docker Compose (socket, auto-restart)

curl -fsSL https://raw.githubusercontent.com/cms-pm/brontes-probe-mcp/main/docker-compose.yml \
  -o docker-compose.yml
docker compose up -d

TCP loopback (sandbox / Docker Desktop without probe-agent)

docker run -d --name brontes-probe-mcp \
  -e PROBE_BROKER_TRANSPORTS=stdio,tcp \
  -e PROBE_BROKER_TOKEN=your-token-here \
  -p 127.0.0.1:7172:7172 \
  --device=/dev/bus/usb \
  ghcr.io/cms-pm/brontes-probe-mcp:0.2.1

Pinning by digest

Pin by digest for production — the digest is the binary-level reproducibility contract:

ghcr.io/cms-pm/brontes-probe-mcp@sha256:<digest>

Digests are published in CHANGELOG.md for each release.

Client configuration

Configure your AI client to launch the server via the MCP stdio transport.

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (Linux: ~/.config/Claude/claude_desktop_config.json):

{
  "brontes-probe-mcp": {
    "command": "docker",
    "args": [
      "run", "--rm", "-i",
      "--device=/dev/bus/usb",
      "-v", "${HOME}/.brontes-probe-mcp:/run/brontes-probe-mcp",
      "-v", "${HOME}/.brontes-probe-mcp/packs:/packs",
      "-e", "PROBE_BROKER_TRANSPORTS=stdio,socket",
      "-e", "CMSIS_PACK_ROOT=/packs",
      "ghcr.io/cms-pm/brontes-probe-mcp@sha256:TBD"
    ]
  }
}

macOS users: omit --device=/dev/bus/usb and add "-e", "PROBE_BROKER_GDB_HOST=host.docker.internal" after running brontes-probe-mcp-cli probe-agent start on the host.

Claude Code

Add to .mcp.json in your project root (or ~/.claude.json for global config):

{
  "mcpServers": {
    "brontes-probe-mcp": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "--device=/dev/bus/usb",
        "-v", "${HOME}/.brontes-probe-mcp:/run/brontes-probe-mcp",
        "-v", "${HOME}/.brontes-probe-mcp/packs:/packs",
        "-e", "PROBE_BROKER_TRANSPORTS=stdio,socket",
        "-e", "CMSIS_PACK_ROOT=/packs",
        "ghcr.io/cms-pm/brontes-probe-mcp@sha256:TBD"
      ]
    }
  }
}

Codex

Add to ~/.codex/config.json:

{
  "mcpServers": {
    "brontes-probe-mcp": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "--device=/dev/bus/usb",
        "-v", "${HOME}/.brontes-probe-mcp:/run/brontes-probe-mcp",
        "-v", "${HOME}/.brontes-probe-mcp/packs:/packs",
        "-e", "PROBE_BROKER_TRANSPORTS=stdio,socket",
        "-e", "CMSIS_PACK_ROOT=/packs",
        "ghcr.io/cms-pm/brontes-probe-mcp@sha256:TBD"
      ]
    }
  }
}

OpenCode

Add to opencode.json in your project root:

{
  "mcp": {
    "servers": {
      "brontes-probe-mcp": {
        "type": "stdio",
        "command": "docker",
        "args": [
          "run", "--rm", "-i",
          "--device=/dev/bus/usb",
          "-v", "${HOME}/.brontes-probe-mcp:/run/brontes-probe-mcp",
          "-v", "${HOME}/.brontes-probe-mcp/packs:/packs",
          "-e", "PROBE_BROKER_TRANSPORTS=stdio,socket",
          "-e", "CMSIS_PACK_ROOT=/packs",
          "ghcr.io/cms-pm/brontes-probe-mcp@sha256:TBD"
        ]
      }
    }
  }
}

Replace sha256:TBD with the pinned digest from CHANGELOG.md.

Why "Brontes"

Brontes ("Thunderer") is one of the cyclops smiths in Hephaestus's forge — the worker who hammers metal at the master's direction. The metaphor maps onto the broker's role: client code directs the operation, the broker performs the probe work.

Changelog

See CHANGELOG.md.

License

Apache-2.0. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

brontes_probe_mcp-0.2.1.tar.gz (42.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

brontes_probe_mcp-0.2.1-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

File details

Details for the file brontes_probe_mcp-0.2.1.tar.gz.

File metadata

  • Download URL: brontes_probe_mcp-0.2.1.tar.gz
  • Upload date:
  • Size: 42.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for brontes_probe_mcp-0.2.1.tar.gz
Algorithm Hash digest
SHA256 1aa632e91f193093921c30c65b5b4cbfb071c33b409dffa504de7beb3fe029ea
MD5 232aeb22a4d81516813a1a39be7eedf5
BLAKE2b-256 c2677fa1a7108d5e2a0e15abf4ff1b5c0b7f4a5a20883d2df63f94f377fcd092

See more details on using hashes here.

Provenance

The following attestation bundles were made for brontes_probe_mcp-0.2.1.tar.gz:

Publisher: publish.yml on cms-pm/brontes-probe-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file brontes_probe_mcp-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for brontes_probe_mcp-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 71365793f25e74195e85242715ed9544380a6df41c036b2b7c719f331394577b
MD5 6e751a1e8614675896e1035ddcceb41b
BLAKE2b-256 e30e8dfb82ca3281b07e86669bd3763c0252b27a3a0f34077dd4a9e6312578ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for brontes_probe_mcp-0.2.1-py3-none-any.whl:

Publisher: publish.yml on cms-pm/brontes-probe-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page