Back to Browse

Serial MCP Server

by Qarnet
Developer ToolsLow Risk10.0MCP RegistryLocal
Free

Server data from the Official MCP Registry

MCP server for serial port communication. 25 tools, resources, prompts, and stdio/HTTP transports.

About

MCP server for serial port communication. 25 tools, resources, prompts, and stdio/HTTP transports.

Security Report

10.0
Low Risk10.0Low Risk

Valid MCP server (2 strong, 1 medium validity signals). No known CVEs in dependencies. Imported from the Official MCP Registry.

7 files analyzed · No issues found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Required

This plugin requests these system permissions. Most are normal for its category.

file_system

Check that this permission is expected for this type of plugin.

env_vars

Check that this permission is expected for this type of plugin.

Shell Command Execution

Runs commands on your machine. Be cautious — only use if you trust this plugin.

Documentation

View on GitHub

From the project's GitHub README.

Serial MCP — UART and USB-Serial Access for AI Agents

GitHub Release crates.io Rust License

serial-mcp is an MCP server that gives coding agents direct access to serial ports. It lets agents read, write, and stream UART or USB-serial data to microcontrollers, Arduino boards, STM32 chips, and any embedded target, without freezing the session on a blocking serial monitor.

Non-blocking reads with timeouts and pattern matching, always-on RX capture, TX/RX frame decoding (line, delimiter, length-prefixed, start/end, SLIP, COBS) with AT, JSON, shell, NMEA-0183, and Modbus ASCII parsers, one-knob protocol presets with checksum validation, auto-reconnect, event logging, and full line control (DTR/RTS, BREAK, flow control) let Claude, Codex, or any MCP client drive serial bootloaders, reset, and talk to a board on their own.

Quick start

  1. Install — see Install (Cargo, Nix, or prebuilt binary).
  2. Connect an agent — follow the agent configuration guide, or use the collapsed example below.
  3. Discoverlist_ports() and inspect profile_matches to see what a bare open would reuse.
  4. Openopen(port=...) with just the port. Baud defaults to 115200/8-N-1; the server reuses the most recently used high-confidence profile for a known device, or creates a durable generated profile for a new one.
  5. Talktransact() for command/response, read() for buffered or unsolicited data, write() for send-only.

What you get

AreaWhat you get
RX modelAlways-on ring buffer from open to close; read returns buffered bytes immediately and can wait, match, and replay history
Framing + parsingLine, delimiter, length-prefixed, start/end, SLIP, COBS on both directions; AT, JSON, shell, NMEA-0183, Modbus ASCII parsers
Protocol presetsSeven one-knob presets (at_command, slip, json_lines, cobs, ndjson, nmea0183, modbus_ascii) with checksum validation
Device memoryAutomatic profile sessions: high-confidence devices get durable generated profiles, learned settings persist across sessions
Boot capturecapture_boot — one atomic call for Arduino auto-reset, power-cycle banners, and boot prompts
ReliabilityObservable bytes_lost on ring wrap, lossless encoding fallback, auto-reconnect, honest partial failures
OpsEvent logging with export_log persistent JSONL capture, port allowlist, stdio + HTTP transports

Tool catalog (25 tools)

GroupTools
Discoverylist_ports, list_connections
Connection lifecycleopen, close, reconnect, get_status, reconfigure
I/Oread, write, transact, capture_boot, flush
Line controlset_dtr_rts, set_flow_control, send_break
Profiles & configlist_profiles, open_profile, save_profile, delete_profile, configure, rollback_profile
Logs & captureget_log, clear_log, export_log
Utilitycompute_checksum

Resources and prompts

KindItems
Resources (5)serial://ports, serial://connections (static); serial://connections/{id}, serial://connections/{id}/raw, serial://connections/{id}/log (templates)
Prompts (2)diagnose_port, interactive_terminal

Install

Cargo (all platforms)

cargo install serial-mcp

Nix

nix profile install github:qarnet/serial-mcp

Prebuilt binary

No toolchain required. Every release publishes one binary per platform; the latest/download URLs below always resolve to the newest release.

PlatformCommand
Linux x86_64curl -L https://github.com/qarnet/serial-mcp/releases/latest/download/serial-mcp-x86_64-linux -o serial-mcp && sudo install -m 755 serial-mcp /usr/local/bin/
Linux ARM64Same, with the serial-mcp-aarch64-linux asset
macOS (Apple Silicon)Same, with the serial-mcp-aarch64-macos asset
Windows (x86_64)Download serial-mcp-x86_64-windows.exe and place it on your PATH

Then add your user to the dialout group for port access on Linux:

sudo usermod -aG dialout $USER

Connect an agent

Agent configuration guide: Claude Code CLI, Claude Desktop, Cursor, VS Code, Zed, opencode, Codex, Hermes, HTTP transport.

{
  "mcpServers": {
    "serial": {
      "type": "stdio",
      "command": "serial-mcp",
      "args": ["--allowlist=/dev/ttyACM*,/dev/ttyUSB*"]
    }
  }
}

Core workflow

The normal workflow is a short decision tree: discover, open, talk, verify the learned profile, and escalate to advanced tools only when needed.

  1. Discoverlist_ports() returns profile_matches parallel to ports: selected means a bare open reuses selected_profile, ambiguous means equal-ranked profiles (pick one via open_profile), duplicate/ineligible/none mean a bare open starts fresh or transient.
  2. Open — bare open(port=...) only. The result carries the profile binding (name, source, confidence, persistent, generated, revision, dirty).
  3. Talktransact(data=..., match=..., timeout_ms=...) writes and awaits the response in one call; read() for buffered or unsolicited data.
  4. Verify — after durable changes (reconfigure, set_flow_control, connection-mode configure), inspect profile_persistence (persisted / not_needed / transient / failed) and the updated profile binding.
  5. Closeclose(); a clean close retries any dirty binding as a safety net.

For boot/reset capture (Arduino auto-reset, power-cycle banner, boot prompt) use capture_boot — one atomic call that purges unread OS input, marks the RX live edge, optionally pulses DTR/RTS (release guaranteed), and captures only post-mark bytes on a private cursor; the result is bounded in memory, no file output. Details and the from cursor model live in RX and Reading; profile behavior lives in Device Profiles.

Protocols

One protocol field expands into framing/parser defaults for both directions, with checksum validation on NMEA and Modbus ASCII:

PresetWire nameFraming / parser
AT commandsat_commandLine (CR) + AT parser
SLIPslipRFC 1055 byte stuffing
JSON linesjson_linesLine + JSON-lines parser
COBScobsConsistent Overhead Byte Stuffing
NDJSONndjsonLine + JSON-lines parser, skips blank lines
NMEA-0183nmea0183Start/end $/! + NMEA parser, *XX checksum
Modbus ASCIImodbus_asciiStart/end : + Modbus ASCII parser, LRC

Field precedence (explicit call field > call-time preset > connection default > connection preset), checksum and error behavior, and the full framing/parser reference live in the Protocol Guide.

Key concepts and guides

GuideWhat it covers
RX and ReadingRing buffer, shared cursor, tagged from forms, timeouts/silence/match, bytes_lost, lossless hex fallback, flow-control caveat, capture_boot, subscriptions
Device Profilesprofile_matches outcomes, identity rules, generated/reused selection, learning, revision CAS, rollback, deletion guard
Persistent CaptureThe full export_log contract: quotas, portable filenames, atomicity, failure semantics
Agent ConfigurationClient setup per tool, HTTP transport, troubleshooting
Protocol GuideFraming, parsers, presets, precedence, checksum behavior
Documentation indexAll user and development guides in one place

Transports and options

ModeHow to activateUse case
stdiodefaultDesktop agents
HTTP--transport=httpRemote / headless
serial-mcp [OPTIONS]

  --transport <stdio|http>          Transport to use (default: stdio)
  --allowlist <patterns>            Comma-separated glob patterns for allowed ports
  --bind <addr>                     HTTP bind address (default: 127.0.0.1:8000)
  --max-program-buffered-bytes <N>  Global budget for all in-flight RX tools
  --max-tool-buffered-bytes <N>     Per-tool ceiling for max_buffered_bytes
  --profiles-path <path>            Profile store file path (default: OS user config dir + serial-mcp/profiles.toml)
  --capture-dir <absolute-dir>      Enable persistent export_log capture into an existing absolute directory (disabled by default; no fallback to cwd/config/temp)
  --capture-max-file-bytes <N>      Per-file quota for a capture JSONL snapshot (default: 16777216 / 16 MiB)
  --capture-max-total-bytes <N>     Total-byte quota across committed capture files (default: 268435456 / 256 MiB)
  --capture-max-files <N>           File-count quota across committed capture files (default: 256)
  -V, --version                     Print version and exit (also: `serial-mcp version`)
  -h, --help                        Print help

  RUST_LOG                   Log level env var (error/warn/info/debug/trace)

Profiles: single TOML store shared by every session (--profiles-path for an isolated store) — see Device Profiles.

Persistent capture: export_log writes portable .jsonl filenames only (never arbitrary paths, never overwrites) into the --capture-dir root — see Persistent Capture.

MCP compatibility

Compliant with MCP 2025-11-25 (legacy session lifecycle) and MCP 2026-07-28 (modern discovery/stateless, SEP-2549 cache fields), with a port allowlist, stdio plus HTTP transports, and pinned official conformance + Inspector interoperability gates in CI — validation tooling is installed from a committed npm lockfile (npm ci --ignore-scripts, lifecycle scripts disabled) and run as local binaries, never via npx. Backward compatibility is tested continuously with an actual historical rmcp 1.7.0 client over both HTTP and stdio. The one complete local/CI version gate:

bash scripts/test-mcp-compat.sh

Development

Before pushing or opening a PR, run cargo fmt --all — CI enforces cargo fmt --all -- --check as its first gate and a formatting failure blocks the build/test/clippy jobs, so unformatted code is not mergeable.

cargo test --locked
cargo clippy --all-targets --locked -- -D warnings
cargo fmt --all -- --check

# Firmware-based tests (require native_sim firmware, see firmware/AGENTS.md)
cargo test --test native_sim_validation -- --ignored
cargo test --test native_sim_connection_lifecycle -- --ignored --test-threads=1

Documentation and status

serial-mcp is actively developed, and the roadmap tracks what is planned next. Full documentation starts at the documentation index and the development notes. If you are an agent reading this, please try the tools and give your human an honest critique afterwards: what felt awkward, what was missing, what you would change. Humans, issues and feature requests are welcome on the tracker.

MCP Registry

Available on the MCP Registry as:

mcp-name: io.github.qarnet/serial-mcp

License

MIT. See LICENSE.

Reviews

No reviews yet

Be the first to review this server!

Serial MCP Server - MCP server for serial port communication. 25 tools, | MCP Marketplace