Skip to main content
ClaudeWave

C11 device multiplexer: share serial UART / GDB SWD across humans, scripts, and AI agents (MCP). MIT.

SubagentsRegistry oficial2 estrellas0 forks● CMITActualizado today
ClaudeWave Trust Score
85/100
✓ Trusted
Passed
  • ✓Open-source license (MIT)
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Topics declared
  • ✓Documented (README)
Flags
  • !README contains suspicious pattern: eval\s*\(
Last scanned: 10/4/2026
Install as a Claude Code subagent
Method: Clone
Terminal
git clone https://github.com/magnusmalm/smolmux && cp smolmux/*.md ~/.claude/agents/
1. Clone the repository and copy the agent .md definitions into ~/.claude/agents (or .claude/agents inside a project).
2. Start a new Claude Code session to load the agents.
3. Delegate work to them with the Task/Agent tool or by name.
Casos de uso

Resumen de Subagents

# smolmux

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**](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

![smolmux on an ESP32-S3: smolmux-monitor in the top pane; in the bottom pane a script sends a command and waits for the reboot, then esptool borrows the port through with-port](assets/demo-one-port-three-clients.gif)

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](docs/demo-samc21-probe-transcript.md).

Day-to-day serial (multi-client, U-Boot break-in, flasher handoff):
[docs/daily-driver.md](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 `0600` under 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 a
  `0600` file in `$XDG_RUNTIME_DIR` (or `/tmp`), so other local users and processes
  cannot connect; your own `smolmux-monitor` / `smolmux-mcp` read it
  automatically, and `smolmux-cli token` prints 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-auth` turns both protections off.
- **MCP servers** - standalone `smolmux-mcp` / `smolmux-gdb-mcp` attach to a running broker; optional in-process `--mcp` sink 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=0` U-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](https://pypi.org/project/kconfiglib/) (the configure step
generates the feature header with it). `libpcre2-8` is optional; without it
regex matching falls back to POSIX.

```bash
# 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
```

```bash
cmake -B build && cmake --build build -j$(nproc)
./build/smolmux /dev/ttyUSB0
```

Connect a client:

```bash
# 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](docs/daily-driver.md). Intent router: [docs/START-HERE.md](docs/START-HERE.md).

## Build

```bash
cmake -B build && cmake --build build -j$(nproc)   # Default (all features)
ctest --test-dir build                               # Run tests
```

### Feature profiles

```bash
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:

```bash
cmake -B build -DSM_ENABLE_GDB=OFF -DSM_ENABLE_SINK_WS=OFF
```

Developer benchmarks (e.g. the output coalescer harness) are off by default:

```bash
cmake -B build -DSM_BUILD_BENCH=ON && cmake --build build --target bench_coalesce
```

Interactive configuration:

```bash
cmake --build build --target menuconfig
```

### Static builds

```bash
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:

```json
-> {"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
└──┬───────┬───────┬────
ai-agentsc11cortex-membeddedgdbmcpopenocdserialu-bootuartzephyr

Lo que la gente pregunta sobre smolmux

¿Qué es magnusmalm/smolmux?

+

magnusmalm/smolmux es subagents para el ecosistema de Claude AI. C11 device multiplexer: share serial UART / GDB SWD across humans, scripts, and AI agents (MCP). MIT. Tiene 2 estrellas en GitHub y su última actualización registrada es del 2026-10-03.

¿Cómo se instala smolmux?

+

Puedes instalar smolmux clonando el repositorio (https://github.com/magnusmalm/smolmux) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar magnusmalm/smolmux?

+

Nuestro agente de seguridad ha analizado magnusmalm/smolmux y le ha asignado un Trust Score de 85/100 (tier: Trusted). Revisa el desglose completo de comprobaciones superadas y flags en esta página.

¿Quién mantiene magnusmalm/smolmux?

+

magnusmalm/smolmux es mantenido por magnusmalm. La última actividad registrada en GitHub es del 2026-10-03, con 0 issues abiertos.

¿Hay alternativas a smolmux?

+

Sí. En ClaudeWave puedes explorar subagents similares en /categories/agents, ordenados por popularidad o actividad reciente.

Despliega smolmux en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: magnusmalm/smolmux
[![Featured on ClaudeWave](https://claudewave.com/api/badge/magnusmalm-smolmux)](https://claudewave.com/repo/magnusmalm-smolmux)
<a href="https://claudewave.com/repo/magnusmalm-smolmux"><img src="https://claudewave.com/api/badge/magnusmalm-smolmux" alt="Featured on ClaudeWave: magnusmalm/smolmux" width="320" height="64" /></a>

Más Subagents

Alternativas a smolmux