Skip to main content
Glama
galderic
by galderic

serial-mcp

An MCP server that lets Claude (or any MCP client) read the serial output of a device.

Why this exists

Reading serial logs is a blocking, long-running operation that streams output indefinitely. An AI agent cannot simply open a serial port and wait for it to close, because it never closes. The agent would hang, unable to do anything else while the port is open.

This MCP server solves the problem by opening the serial port in the background via pyserial-asyncio, buffering output line-by-line, and letting the agent poll for new lines on demand. The agent can start monitoring, go do other work, and come back to read the logs whenever it needs to — checking for crash backtraces, boot messages, sensor readings, or any other serial output.

Related MCP server: embedded-serial-mcp

Installation

pip install -e ".[dev]"

Requires Python 3.10+.

Configuration

Environment variable

Default

Description

SERIAL_MCP_MAX_BUFFER

unlimited

Maximum number of lines kept in the buffer. When exceeded, the oldest lines are discarded first.

MCP Tools

The server exposes three tools over stdio transport:

start_buffering(device, baudrate=115200)

Opens the serial port at the given path (e.g. /dev/ttyUSB0) and baud rate. If a monitor is already running, it is stopped first and replaced. Output begins accumulating in memory immediately.

next_chunk(nlines=50, pattern=None)

Returns the next batch of buffered lines the agent hasn't seen yet. Each response includes a status header:

[lines=12 remaining=0 running=true]
I (324) cpu_start: Starting scheduler on PRO CPU.
I (330) main_task: Started on CPU0
...
  • lines — number of lines in this response (when filtered, shows matched/total)

  • remaining — unread lines still in the buffer after this batch

  • running — whether the serial reader is still alive

The optional pattern parameter filters output using a regular expression. Only lines matching the pattern are returned. This is useful for reducing token consumption when dealing with verbose output:

# Only show ERROR lines
next_chunk(100, pattern="ERROR")

# Show temperature readings
next_chunk(50, pattern=r"Temperature: \d+\.\d+")

Call this repeatedly to drain all output. When there is nothing new, it returns (no new output).

stop_buffering()

Closes the serial port. The buffer is preserved, so next_chunk can still be called to read any remaining output.

Usage with Claude Code

Add the server to your MCP configuration (e.g. .mcp.json in your project):

{
  "mcpServers": {
    "serial-mcp": {
      "command": "serial-mcp"
    }
  }
}

Then Claude can use it as part of a natural workflow:

  1. Start the monitor via start_buffering("/dev/ttyUSB0")

  2. Do other work — edit source files, review code, build, flash, etc.

  3. Poll for logs via next_chunk() to check what the device printed

  4. Stop the monitor via stop_buffering() when done

Running tests

pytest tests/ -v

All tests use mocked serial connections — no hardware required.

How it works

  • The serial port is opened via pyserial-asyncio using open_serial_connection(url=device, baudrate=baudrate).

  • A background asyncio.Task reads the port line-by-line and appends to an in-memory list.

  • next_chunk() is a simple cursor-based read — it slices the list from where the agent last left off and advances the cursor. No locking is needed because everything runs in a single-threaded asyncio event loop.

  • UTF-8 decoding uses errors="replace" to handle garbled serial data gracefully.

Available Tools

3 tools
next_chunkB

Return the next batch of buffered serial output lines.

Args: nlines: Maximum number of lines to return (default 50) pattern: Optional regex pattern to filter lines (only matching lines are returned)

ParametersJSON Schema
NameRequiredDescriptionDefault
nlinesNo
patternNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full behavioral burden. It reveals the output comes from a buffer, but says nothing about whether returned lines are consumed/removed from the buffer, whether the call blocks waiting for new output, or any rate/ordering behavior. For a chunked-stream-read tool this is a notable gap.

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?

The purpose sentence is front-loaded and the argument list is compact and waste-free. The Args block is slightly redundant with the schema but efficient.

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?

An output schema exists, so return-value structure needn't be described. However, the description omits the buffering prerequisite, consumption semantics, and empty-buffer behavior, leaving real gaps for a tool that coordinates with start_buffering/stop_buffering.

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?

Schema description coverage is 0% (bare types only), so the description must compensate, and it largely does: it explains nlines as a maximum line count with default 50 and pattern as an optional regex filter that limits results to matching lines. It doesn't clarify interaction between pattern filtering and the nlines cap, but the semantics are substantially covered.

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 and resource ('Return the next batch of buffered serial output lines'), which is clear and unambiguous. It doesn't explicitly differentiate itself from the siblings start_buffering/stop_buffering, though the distinction is inferable from the name and wording.

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 call this versus alternatives. Critically, it never states the obvious prerequisite that buffering must be active (via start_buffering) before chunks can be returned, nor what happens when the buffer is empty.

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

start_bufferingB

Start (or restart) the serial monitor on the given device.

Args: device: Serial port path, e.g. /dev/ttyUSB0 or /dev/ttyACM0 baudrate: Baud rate for the serial connection (default 115200)

ParametersJSON Schema
NameRequiredDescriptionDefault
deviceYes
baudrateNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full behavioral burden. It discloses the meaningful restart semantics in '(or restart)', but says nothing about what happens to an already-running monitor, failure modes (invalid/busy port, missing device), permissions, or whether the stream must be drained via next_chunk.

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?

Front-loaded with the core action in the first sentence, then a compact Args block with one line per parameter. No filler, though the docstring-style Args formatting is slightly redundant with the schema's parameter list.

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?

An output schema exists, so return values need not be described, and both parameters are covered. What is missing for a hardware I/O tool is the operational context: relationship to next_chunk/stop_buffering and behavior on error or on an already-active monitor.

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?

Schema description coverage is 0%, so the description must compensate, and it largely does: it gives a concrete format/example for device ('/dev/ttyUSB0 or /dev/ttyACM0') and states the baudrate meaning and its default value. It adds real meaning beyond the bare schema types.

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+resource ('start (or restart) the serial monitor') and names the target device, so the agent knows exactly what the tool does. It does not explicitly differentiate itself from siblings next_chunk or stop_buffering, which is the only gap.

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 is only implied: starting the monitor is obviously the setup step before next_chunk and the counterpart to stop_buffering, but the description never says when to call it vs. those siblings or what preconditions (device present, no running monitor) apply. No explicit when/when-not guidance.

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

stop_bufferingA

Stop the serial monitor. Buffered output remains readable via next_chunk.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It discloses the important non-obvious trait that stopping does not discard buffered output and that next_chunk remains valid afterwards — a real behavioral detail beyond the name. It does not cover side effects on an in-progress monitor session or auth/state requirements, keeping it short of a 5.

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 short sentences, zero waste, with the primary action front-loaded and the follow-up capability second. Every sentence earns its place.

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 an output schema present, return values need not be explained, and the description covers the key post-stop behavior. It is essentially complete for a zero-parameter control tool, with only minor room to state whether the monitor session itself is torn down.

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 to disambiguate; baseline 4 applies. The description correctly avoids inventing parameter detail.

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?

States a specific verb and resource ('Stop the serial monitor') and immediately contrasts with the sibling workflow by noting buffered output stays readable via next_chunk. An agent can distinguish this from start_buffering and next_chunk without opening any schema.

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 description gives clear context for post-call behavior and implicitly routes the agent to next_chunk if buffered data is still needed. It lacks an explicit 'use this when...' clause or stated exclusions, but the workflow positioning is unambiguous.

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. 3 tool updatesv0.1.0
    • First observednext_chunk
    • First observedstart_buffering
    • First observedstop_buffering

TDQS

A3.7/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: start_buffering initiates monitoring, next_chunk reads buffered output, and stop_buffering terminates it. No overlap or ambiguity in selecting the right tool.

Naming Consistency4/5

All names use snake_case, but start_buffering and stop_buffering follow a verb_noun pattern while next_chunk uses an adjective_noun pattern, creating a minor inconsistency. The deviation is small and still readable.

Tool Count4/5

Three tools are sufficient for basic serial monitoring (start, read, stop), earning their place. However, a tool to list available serial ports or check status would make the set feel more complete without being excessive.

Completeness4/5

The surface covers the core lifecycle of starting, reading, and stopping a serial monitor. Minor gaps exist, such as no tool to list available serial devices or to write to the port, but these may be outside the stated monitoring purpose.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • 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
    80 PyPI
    5
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A professional MCP server for serial port communication, enabling AI assistants to list, connect, send/receive data, and manage serial connections with embedded systems, IoT devices, and hardware debugging hardware.
    1
    MIT
  • F
    license
    A
    quality
    B
    maintenance
    A headless MCP server that enables AI tools (like Claude Code) to read and analyze serial logs from embedded boards (ESP32, STM32) for firmware debugging, with read-only tools for log retrieval and a built-in web viewer.
    6
    -