About smolmux-gdb-mcp
smolmux-gdb-mcp is an MCP server for embedded developers debugging ARM Cortex-M boards through a smolmux broker. It exposes GDB operations and board-probing tools, including fault decoding and profile generation.
Key features
- 01Set and inspect breakpoints
- 02Step through execution and inspect backtraces
- 03Read registers, memory, and peripherals
- 04Evaluate expressions and decode fault registers
- 05Identify boards and generate GDB profiles
Use cases
- 01Debug firmware on an ARM Cortex-M board
- 02Inspect memory and peripheral state over SWD
- 03Decode a fault and review its register values
- 04Probe an unknown board and create a starter profile
MCP support
Connects to a running smolmux broker holding a GDB link and exposes debugging tools, resources, and prompts to MCP clients.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.
Tools
Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.
Details
From the project READMEsmolmux
A portable C11 device multiplexer. Holds a device connection open (serial UART, GDB stub) and multiplexes access to multiple clients over Unix sockets using newline-delimited JSON.
Single static binary, low latency, small footprint - built for daily serial and GDB bring-up on Linux.
New here? docs/START-HERE.md is a one-screen router - find your intent (run it, bring up a new board with an AI agent, understand the architecture, hack on the code) and it points you to the right doc.
One port, three clients

One broker holds an ESP32-S3's UART. The monitor (top) watches it live. In the
bottom pane a script sends temp and gets the reply on the same wire, resets
the board and waits for its prompt, then esptool reads the flash ID through
with-port: the broker suspends, esptool runs, the broker resumes, and the
monitor never loses the port.
Example: probe an unknown board
One broker holds SWD; smolmux-gdb-mcp runs probe_unknown_board. On a
SAM C21 Xplained Pro that path decoded Cortex-M0+ from CPUID, named the
part via SAM DSU DID, rejected a false STM32 match, and wrote a starter
*.gdb-profile.json. Tools, register values, and profile shape:
docs/demo-samc21-probe-transcript.md.
Day-to-day serial (multi-client, U-Boot break-in, flasher handoff): docs/daily-driver.md.
Features
- Serial UART, GDB MI, and serial-over-TCP (telnet + RFC2217) device links via vtable polymorphism
- Multiple concurrent clients over Unix sockets with role-based access (observer/controller/takeover)
- Expect engine - concurrent regex matching on the device byte stream with timeouts
- Anomaly detection - pattern-based crash/error detection with cooldown and incident tracking
- Output history - timestamped ring buffer for replay by late-joining clients
- Structured logging - JSONL I/O log + human-readable text log with rotation
(the I/O log records everything sent to and from the device, including
anything typed at a login prompt — it is created
0600under your private state directory, and smolmux refuses to write it through a symlink or to a file owned by another user) - Network sinks - TCP and WebSocket for remote access (loopback by default).
The wire protocol is cleartext, and any client that completes the handshake
gets full control of the device — console writes, pins, BREAK, SysRq, GDB.
On loopback without
--auth-token, the broker generates a token into a0600file in$XDG_RUNTIME_DIR(or/tmp), so other local users and processes cannot connect; your ownsmolmux-monitor/smolmux-mcpread it automatically, andsmolmux-cli tokenprints it. For remote use, keep the bind on loopback and reach it over an SSH tunnel or WireGuard rather than exposing the port; smolmux refuses to serve a non-loopback TCP bind with no--auth-token.--insecure-no-authturns both protections off. - MCP servers - standalone
smolmux-mcp/smolmux-gdb-mcpattach to a running broker; optional in-process--mcpsink for single-process stdio - Boot tracking & autoresponder - ordered boot stages, stall events, standing expect->send rules
- Autoboot interrupt - broker-side key flood (and optional DTR/RTS reset) for
bootdelay=0U-Boot - Device profiles / board manifests - JSON configs for prompts, anomalies, multi-wire boards
- Auto-reconnect - exponential backoff recovery on USB-serial disconnect
- Build-time feature selection - Kconfig-based; UART-only builds carry no GDB/TCP/WebSocket code
Quick start
Prerequisites: Linux, a C11 compiler, CMake 3.21+, Python 3 with
kconfiglib (the configure step
generates the feature header with it). libpcre2-8 is optional; without it
regex matching falls back to POSIX.
# Debian/Ubuntu
sudo apt install build-essential cmake python3 python3-pip libpcre2-dev
pip install kconfiglib # or in a venv; Debian's system Python may need
# --break-system-packages
cmake -B build && cmake --build build -j$(nproc)
./build/smolmux /dev/ttyUSB0
Connect a client:
# Needs a running broker (above). Auto-discovers the socket from the port name.
./build/smolmux-monitor /dev/ttyUSB0
Day-to-day workflows (profiles, logs, U-Boot break-in, multi-wire boards): docs/daily-driver.md. Intent router: docs/START-HERE.md.
Build
cmake -B build && cmake --build build -j$(nproc) # Default (all features)
ctest --test-dir build # Run tests
Feature profiles
cp configs/defconfig.minimal .config && cmake -B build # UART only, no sinks/watcher
cp configs/defconfig.uart .config && cmake -B build # UART + MCP sink + watcher
cp configs/defconfig.embedded .config && cmake -B build # Embedded target profile
cp configs/defconfig.full .config && cmake -B build # Everything (GDB, TCP, WS, MCP, watcher)
Or toggle features directly:
cmake -B build -DSM_ENABLE_GDB=OFF -DSM_ENABLE_SINK_WS=OFF
Developer benchmarks (e.g. the output coalescer harness) are off by default:
cmake -B build -DSM_BUILD_BENCH=ON && cmake --build build --target bench_coalesce
Interactive configuration:
cmake --build build --target menuconfig
Static builds
cmake -B build -DSM_MUSL_STATIC=ON # Fully static musl binary (zero runtime deps)
cmake -B build -DSM_STATIC=ON # Static linking (except glibc)
Usage
smolmux <port> [options]
Options:
-b, --baud <rate> Baud rate (default: 115200)
-s, --socket <path> Unix socket path
-l, --log-dir <dir> I/O log directory
(default: $XDG_STATE_HOME/smolmux or
~/.local/state/smolmux)
-t, --text-log-dir <dir> Text log directory
-p, --profile <path> Device profile JSON file
--board <name> Group this wire under a board (for discovery)
--role <label> This wire's role on the board (console, swd, ...)
--gdb Use GDB MI link instead of UART
--gdb-path <path> Path to gdb binary (default: gdb)
--gdb-target <spec> GDB target (e.g., localhost:3333)
--serial-tcp <host:port> Connect to a serial-over-TCP device server
(ser2net, socat, terminal server; telnet +
RFC2217 baud/DTR/RTS/break control)
--mcp Enable in-process MCP stdio sink (prefer standalone
smolmux-mcp against a daemon broker for daily use)
--tcp-port <port> Enable TCP sink (default: 5555)
--tcp-bind <addr> TCP bind address (default: 127.0.0.1)
--auth-token <token> Require token in hello from TCP clients
(prefer env SMOLMUX_AUTH_TOKEN - hidden from ps)
--auth-token-file <path> Read the token from a file
--insecure-no-auth Serve TCP/WS with no token. Without it, a
loopback listener gets a generated token
(0600 file; smolmux-cli token prints it) and
a non-loopback --tcp-bind is refused.
--ws-port <port> Enable WebSocket sink (default: 5556)
--no-text-log Disable text log
--no-io-log Disable JSONL I/O log
--no-reconnect Don't auto-reconnect on disconnect
--wait-device <seconds> Wait for the device path before open
--gdb-allow-shell Permit GDB shell/python/eval (off by default)
--list-ports List available serial ports and exit
--list-profiles List available device profiles and exit
--help-protocol Show wire protocol documentation
-v, --verbose Enable debug logging
-V, --version Show version
-h, --help Show this help
Wire protocol
Newline-delimited JSON over Unix sockets (also TCP/WS sinks). Binary data is base64-encoded. Message set covers session control, expect, history, anomaly, boot stages, autoboot flood, and autoresponder.
Full reference: ./build/smolmux --help-protocol (always matches this binary).
Client -> Broker: hello, send, send_expect, takeover, release, status, pin_control, set_baud, suspend, resume, history_request, incidents_request, configure_anomaly, interrupt_autoboot, configure_autoresponder, autoresponders_request
Broker -> Client: welcome, output, input_echo, expect_result, status_response, error, history_response, incidents_response, anomaly, autoboot_result, boot_stage, boot_stall, autoresponders_response, autoresponder_fired, suspended, resumed, link_down, link_up
Example session:
-> {"type":"hello","name":"my-tool","role":"controller","protocol_version":1}
<- {"type":"welcome","broker_version":"x.y.z","protocol_version":1,"port":"/dev/ttyUSB0","baud":115200,"your_role":"controller"}
-> {"type":"send","id":"1","data":"dW5hbWUgLWEK"}
<- {"type":"output","data":"TGludXggNC4xOS4w...","timestamp":1709654321.123}
Architecture
┌───────────┐ ┌───────────┐
│ uart link │ │ gdb link │ <- device-facing, compiled in/out via Kconfig
└─────┬─────┘ └─────┬─────┘
│ │
▼ ▼
┌──────────────────────────────┐
│ smolmux core │ <- epoll event loop, message bus,
│ history · logging · anomaly │ role enforcement, expect engine
└──┬───────┬───────┬───────┬───┘
│ │ │ │
▼ ▼ ▼ ▼
┌──────┐┌─────┐┌─────┐┌──────┐
│ unix ││ tcp ││ ws ││ mcp │ <- sinks, also compiled in/out
│socket││sink ││sink ││ sink │
└──────┘└─────┘└─────┘└──────┘
See DESIGN.md for full architecture documentation.
Dependencies
Required: cJSON (vendored, single file)
Auto-detected: PCRE2 (libpcre2-8). Used as the regex engine when
present, because it bounds backtracking internally; the build falls back to
POSIX ERE automatically when it is absent, so it is never required. Force
either way with -DSM_ENABLE_PCRE2=ON (error if missing) or
-DSM_ENABLE_PCRE2=OFF.
Core has zero required external dependencies beyond POSIX + cJSON.
Companion tools
- smolmux-cli - command-line client (send commands, read output;
with-port <cmd>suspends the port, runs an external tool like a flasher, then always resumes) - smolmux-monitor - interactive terminal client with escape sequences (prefix key then a command; prefix defaults to Ctrl-], change with
-e, e.g.-e escor-e ^A) - smolmux-mcp - standalone MCP server: connects to a running broker and exposes serial tools (
serial_send_command,serial_read,serial_boot_status,serial_add_autoresponder, ...). Alternative: broker--mcpsink embeds MCP in-process. - smolmux-gdb-mcp - standalone MCP server for GDB debugging: 21 tools over a
broker holding a
--gdblink - breakpoints, stepping, backtrace, name-labeled registers, memory, expression eval, fault-register decode (where the core has them), peripheral reads,gdb_interrupt, and unknown-board probing on ARM Cortex-M today (gdb_identify_target/gdb_generate_profile; other architectures are planned). Resources and prompts includesmolmux-gdb://board-probingandprobe_unknown_board. Built whenSM_ENABLE_GDBis on; chip-ID validated on a SAM C21 Xplained Pro. - smolmux-watcher - daemon that monitors for anomalies and saves incident reports to disk
Related Documentation
- Start here - One-screen intent router (daily use, new board, architecture, hacking).
- MCP setup - Register
smolmux-mcp/smolmux-gdb-mcpwith Claude Code, Claude Desktop, or Cursor. - Daily driver - Recommended build, runtime flags, U-Boot break-in, boot stages, boards, coexistence with flashers.
- Board Exploration Workflow - Runbook for a fresh board (manually or with an AI agent): wires, SWD identify, console, peripherals.
- Board Bring-up Template - Copy-per-board fact-capture template.
- Persistent Serial Device Names - Stable names for UART dongles (
/dev/serial/rpi-consoleetc.). - Hardware validation matrix - What is validated on real hardware vs not yet proven.
- DESIGN.md / CLAUDE.md - Architecture and contributor map.
Free vs Pro
Everything in this repository is MIT-licensed - full source, wire protocol, generic device profiles, build system. Build it yourself and you have the complete product.
smolmux Pro is convenience, not a feature gate: prebuilt static binaries
(x86_64 + aarch64, musl, zero runtime dependencies), the curated profile pack
with per-profile notes, and 6 months of email support. One-time purchase
($79). MCP setup for zip paths is docs/MCP-SETUP-FULL.md (also in
this public tree).
Buy smolmux Pro - $79 one-time - download includes current static binaries and the profile pack.
License
MIT. cJSON is vendored under its own MIT license
(deps/cJSON/LICENSE).
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.