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.2 — 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:61e4d0423085ac734a938b2a45a984e5197e1803326547f5d13d519e67798e91"
      ]
    }
  }
}

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

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

Replace sha256:61e4d0423085ac734a938b2a45a984e5197e1803326547f5d13d519e67798e91 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:61e4d0423085ac734a938b2a45a984e5197e1803326547f5d13d519e67798e91"
      ]
    }
  }
}

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.2

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:61e4d0423085ac734a938b2a45a984e5197e1803326547f5d13d519e67798e91"
    ]
  }
}

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:61e4d0423085ac734a938b2a45a984e5197e1803326547f5d13d519e67798e91"
      ]
    }
  }
}

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:61e4d0423085ac734a938b2a45a984e5197e1803326547f5d13d519e67798e91"
      ]
    }
  }
}

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:61e4d0423085ac734a938b2a45a984e5197e1803326547f5d13d519e67798e91"
        ]
      }
    }
  }
}

Replace sha256:61e4d0423085ac734a938b2a45a984e5197e1803326547f5d13d519e67798e91 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.2.tar.gz (42.8 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.2-py3-none-any.whl (33.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: brontes_probe_mcp-0.2.2.tar.gz
  • Upload date:
  • Size: 42.8 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.2.tar.gz
Algorithm Hash digest
SHA256 20d1c7f97e65454ad8f57a8067bc81538aec65a3a986d56ad46730d9e8de0a1d
MD5 c636db537e7bb4ac57d6b2af044e6810
BLAKE2b-256 3976fc341b66263c985dd4d711a08a73f142cbf43359e2855b38f8da47f75a2b

See more details on using hashes here.

Provenance

The following attestation bundles were made for brontes_probe_mcp-0.2.2.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.2-py3-none-any.whl.

File metadata

File hashes

Hashes for brontes_probe_mcp-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6b9fb0127b78f69cfc7b82553eb0096b6ba562cbbacc08cb15df89b6dcbe0b7b
MD5 d1c99ec8fa68ef1b9b83e17eb12d5220
BLAKE2b-256 53d43839d9a1cabee2577cb88072468b8e80ad7dbb5fa2db5af4b2bc3033dac5

See more details on using hashes here.

Provenance

The following attestation bundles were made for brontes_probe_mcp-0.2.2-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