Skip to main content
Glama

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

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.

Related MCP server: serial-mcp

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

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 esc or -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 --mcp sink embeds MCP in-process.

  • smolmux-gdb-mcp - standalone MCP server for GDB debugging: 21 tools over a broker holding a --gdb link - 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 include smolmux-gdb://board-probing and probe_unknown_board. Built when SM_ENABLE_GDB is on; chip-ID validated on a SAM C21 Xplained Pro.

  • smolmux-watcher - daemon that monitors for anomalies and saves incident reports to disk

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

Available Tools

9 tools
serial_boot_statusA
Read-only

Report cold-boot progress: which boot stages the device has reached, the furthest stage, and whether the boot has stalled. Requires the device profile to declare boot_stages; otherwise reports none.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint=true, destructiveHint=false, openWorldHint=false), so the bar is lower. The description still adds real behavioral context beyond them: what information is returned and the graceful-degradation case when boot_stages is undeclared ('reports none'). No rate limits or auth details, but none are relevant for a local read.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with zero waste. The core purpose is front-loaded and the prerequisite is placed second, so the agent reads the important part first.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and discharges it by naming the three reported facts plus the fallback behavior. For a no-parameter, read-only query this is fully sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the schema has nothing to document and the baseline of 4 applies. The description correctly adds no parameter detail because there is nothing to describe.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb ('Report') and a narrowly scoped resource ('cold-boot progress'), then enumerates exactly what is reported: stages reached, furthest stage, and stall status. This is clearly distinct from siblings such as serial_port_status or serial_read, so an agent can select it without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states a concrete applicability condition: the device profile must declare boot_stages, otherwise the tool reports none. That tells the agent when this tool is meaningful, though it does not explicitly contrast with alternative tools or state when not to call it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

serial_generate_reportB
Read-only

Generate a status report for the serial device.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds only that the output is a "status report" for the serial device, without disclosing scope, contents, or whether the report is generated fresh or cached. With annotations carrying the behavioral burden, this is adequate but thin.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with the resource front-loaded and no filler. It is efficient, though the sentence is so terse that it sacrifices specificity rather than achieving tightness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description ideally should say what the report contains (port state, boot state, incidents?) — and it does not. With zero parameters and annotations covering safety, the definition is minimally viable but leaves the agent guessing about return content and sibling overlap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so per the baseline there is nothing for the description to compensate for. Schema coverage is 100% on an empty object, and the description correctly implies no input is required.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ("Generate") and resource ("status report for the serial device"), which is clear on its own. However, it does nothing to distinguish itself from closely related siblings such as serial_port_status, serial_boot_status, and serial_get_incidents, leaving ambiguity about what this report covers versus those.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus serial_port_status, serial_boot_status, or serial_get_incidents, nor any stated prerequisites or exclusions. The agent must infer the usage scenario entirely from the name and one-line description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

serial_get_incidentsB
Read-only

Get detected anomalies/crashes from the broker.

ParametersJSON Schema
NameRequiredDescriptionDefault
secondsNoIf > 0, only return incidents from the last N seconds.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered without description help. The description adds the useful fact that incidents are sourced "from the broker" and are pre-detected, but says nothing about ordering, caps, or empty-result behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence with no filler and the verb front-loaded. It is appropriately short for a single-parameter read tool, though the trailing "from the broker" is mildly ambiguous.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A simple read with one fully documented optional parameter and annotations covering safety. With no output schema, the description could have said what an incident record contains and whether results are bounded, so it is adequate but leaves a real gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the single optional 'seconds' parameter is fully documented in the schema itself. The description adds no filtering syntax or default behavior beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a clear verb+resource combination: retrieve detected anomalies/crashes. The scope word "detected" implies pre-filtered incidents rather than raw output, which usefully separates it from serial_read and serial_output_history. However, it never names a sibling or explains how it differs from those log-oriented tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no prerequisites, and no alternatives are named. An agent must infer from the name alone whether to call this instead of serial_output_history or serial_generate_report when investigating a crash.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

serial_list_portsB
Read-only

List serial ports with by-id and USB VID/PID when available. Bridge chips name the adapter, not the MCU.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint=false, and destructiveHint=false, which covers the safety profile. The description adds that by-id and USB VID/PID are provided when available, and explains that bridge chips name the adapter rather than the MCU. That is useful behavioral context beyond annotations, but it stops short of describing output shape or ordering. With annotations carrying the safety burden, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action. The second sentence is a useful caveat rather than filler, though it could be tightened. No waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-param read-only list tool with annotations covering safety, the description is adequate. It explains what the listing contains and a gotcha about bridge chips, but does not describe return format or ordering, which would help an agent consume the result. Without an output schema, some of that burden remains on the description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters, so baseline is 4. The description cannot add parameter meaning because there are none, and nothing about parameter semantics is missing or misleading.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb+resource: 'List serial ports'. The second sentence adds content about what data is included (by-id, USB VID/PID) and a caveat about bridge chips. It does not differentiate from siblings like serial_port_status, which could also enumerate ports — no explicit distinction is drawn.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this versus alternatives such as serial_port_status or serial_read. The agent has to infer that this is for discovery. There is no exclusion or selection criteria stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

serial_monitorB
Read-only

Monitor serial output for a duration, returning output and anomalies.

ParametersJSON Schema
NameRequiredDescriptionDefault
duration_secondsNoHow long to monitor (max 300 seconds, default 30).

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds that monitoring is time-bounded and that anomalies are surfaced, which is real behavioral context beyond the annotations, but it says nothing about how anomalies are detected, whether monitoring blocks, or what happens if the port is busy.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the verb and resource, with the return value appended. Nothing is padded or redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of describing the return, and 'output and anomalies' is too vague to know what an agent will actually receive or how to interpret anomalies. For a single-optional-param read tool with full annotations the rest is adequate, but the return contract is under-specified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single parameter is fully documented (max 300, default 30), so the baseline is 3. The description's phrase 'for a duration' merely restates the parameter without adding format or interaction detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('monitor') and resource ('serial output') and adds scope ('for a duration') plus the return payload ('output and anomalies'). It implicitly separates itself from serial_read (one-shot) and serial_wait_for (pattern wait), but never names a sibling, so an agent must infer the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no when-not-to-use, and no mention of alternatives among the eight serial_* siblings. An agent cannot tell from this text whether to pick serial_monitor, serial_read, or serial_wait_for for a given need.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

serial_output_historyA
Read-only

Non-destructive history. With since_seq: JSON cursor page. Without: prose by time/bytes. serial_read is drain-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
secondsNoIf > 0, return output from the last N seconds (prose).
max_bytesNoWith since_seq: max raw bytes in this page (default broker cap).
since_seqNoCursor from a prior history response: lossless page as JSON (cursor/dropped/has_more/chunks). Prefer this over serial_read.
last_bytesNoIf > 0, return the last N bytes of output (prose).

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds real behavioral value by disclosing the mode-dependent return shapes (JSON cursor page with cursor/dropped/has_more/chunks vs prose by time/bytes), which annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four front-loaded fragments with zero filler, and the non-destructive framing leads. It is dense to the point of being terse, but every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does the work of describing both return formats (JSON cursor page vs prose), and the four params are fully covered by the schema. Adequate for a read-only history tool, though it could note pagination/cursor-reuse behavior more explicitly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters in detail. The description only echoes the since_seq vs time/bytes split already present in the schema, adding no syntax or format nuance beyond it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (history) and a defining trait (non-destructive), and names the sibling it is not by noting 'serial_read is drain-only'. The agent can tell this retrieves past output rather than draining it, though the phrase 'Non-destructive history' never literally says 'serial output' and leans on the tool name for context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear mode-selection guidance: 'With since_seq' yields a cursor page while 'Without' yields prose by time/bytes. The contrast with serial_read ('drain-only') implies when to prefer this tool for non-destructive retrieval, but it stops short of an explicit when-not-to-use rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

serial_port_statusA
Read-only

Get the current status of the serial port and connected clients.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=false, and destructiveHint=false, so the safety profile is fully covered by structured data. The description adds only that 'connected clients' are part of the status, which hints at return content but says nothing about format, freshness, or error behavior on a disconnected port.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single eleven-word sentence that front-loads the verb and resource with no filler or redundancy. Nothing could be removed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no annotations beyond read-only flags, the description carries the burden of describing what 'status' actually returns. It names the two subjects (port, connected clients) but gives no field-level detail, so an agent cannot predict the response shape. Adequate but with a clear gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4 and there is nothing for the description to disambiguate. Schema coverage is also 100%, leaving no parameter gap to fill.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Get') and resource ('status of the serial port and connected clients'), so the agent knows exactly what operation it performs. It does not, however, distinguish itself from near-siblings like serial_boot_status or serial_list_ports, which an overloaded agent would have to disambiguate itself.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is only implied - reading current status - with no explicit when-to-use guidance, no exclusions, and no routing to alternatives such as serial_boot_status or serial_list_ports. The agent must infer selection from the name and sibling set.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

serial_readA
Read-only

Read buffered serial output without sending anything (session drain; prefer history for lossless capture).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint=true, destructiveHint=false, openWorldHint=false), so the bar is lower, and the description still adds real behavioral context: this is a 'session drain' whose contents are consumed, versus history which is lossless. That drain/loss nuance is not expressed anywhere in the structured fields and is the most decision-relevant thing an agent needs to know.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with the core action front-loaded and the alternative-route caveat tucked into a parenthetical. Every clause earns its place; nothing is padded or repeated from the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only tool with no output schema, the definition supplies the action, the consumption semantics, and the better alternative for lossless capture. It leaves the return format and whether the drain actually clears the buffer implicit, which is a minor gap given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate and the baseline of 4 applies. The absence of arguments is consistent with the description's claim that nothing is sent.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read buffered serial output') plus a scoping constraint ('without sending anything'), which is far more than a restatement of the name. It differentiates itself from serial_output_history by naming that sibling as the lossless alternative, though it does not distinguish itself from the other serial_* siblings (monitor, wait_for, status).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical 'prefer history for lossless capture' gives an explicit alternative and the condition that selects it, which is exactly the routing guidance an agent needs between two similar read tools. It stops short of a full when/when-not statement (e.g. no guidance relative to serial_monitor or serial_wait_for), so it is clear context rather than complete routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

serial_wait_forA
Read-only

Wait for a regex in serial output without sending. Works for observers. Ends early on critical anomaly (ABORTED).

ParametersJSON Schema
NameRequiredDescriptionDefault
patternYesRegex to match in device output (listen-only; no TX).
timeout_msNoMax wait in ms (default 30000, clamp 100–3600000).

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, destructiveHint and openWorldHint, so the safety profile is covered. The description adds a genuinely non-obvious behavioral trait — early termination on a critical anomaly (ABORTED) — which the annotations cannot express. It omits what happens on plain timeout, but the key runtime behavior is disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short, front-loaded sentences with no filler; the core purpose and the abnormal-exit condition both land immediately. Every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should say what a successful wait yields (matched text, boolean, incident?) and what a timeout returns, since that determines how the agent branches. Annotations cover safety and the schema covers inputs, but return semantics are left unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents the regex semantics (listen-only, no TX) and the timeout default and clamp range. The description's 'without sending' merely restates the schema's listen-only note, adding no new parameter meaning. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (wait) plus the resource and scope (a regex in serial output), and 'without sending' separates it from the write/monitor siblings. It does not name a specific sibling such as serial_read, so differentiation is implied rather than explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Works for observers' hints at the context in which this is appropriate, but there is no explicit when-to-use versus serial_read or serial_monitor, and no stated prerequisites or exclusions. Usage must be inferred from the name and the listen-only note.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 9 tool updatesv0.4.0
    • First observedserial_boot_status
    • First observedserial_generate_report
    • First observedserial_get_incidents
    • First observedserial_list_ports
    • First observedserial_monitor
    • First observedserial_output_history
    • First observedserial_port_status
    • First observedserial_read
    • First observedserial_wait_for

TDQS

A3.6/5.0

Scored across 9 tools

Disambiguation4/5

Most tools target distinct capabilities (read/drain, history, monitor, wait_for, incidents, boot, status, list, report), and descriptions explicitly differentiate read vs history vs monitor. However serial_read, serial_output_history, and serial_monitor all surface serial output and could still be confused, and serial_port_status vs serial_list_ports overlap somewhat.

Naming Consistency4/5

All tools share the predictable serial_ prefix, which makes the namespace cohesive. The suffix style varies (read, port_status, boot_status, wait_for, get_incidents, output_history, monitor, generate_report, list_ports), mixing noun_status and verb_noun forms, but it remains readable.

Tool Count5/5

Nine tools is well within the ideal 3-15 range and each maps to a distinct observation/reporting concern for a serial device debugger. No obvious filler or redundancy in count.

Completeness3/5

The observation side is thorough (read, history, monitor, wait, incidents, boot, status, report), but repeated phrasing 'without sending anything' strongly implies a serial write/send capability that is absent, leaving an obvious gap for interactive control. No config/session-management operations beyond status either.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Stateful MCP server for driving debug probes (J-Link) to flash, debug, and inspect embedded targets. Enables AI agents to perform flash, memory, breakpoint, and ELF/SVD-aware operations conversationally.
    41
    25 PyPI
    10
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    MCP server that lets LLMs talk to serial devices: microcontrollers, routers, modems, embedded Linux, anything with a UART.
    23
    50 PyPI
    7
    MIT