Skip to content

Common Tools

These 21 tools work in all three modes (RS-232, RS-422, and RS-485). They cover port discovery, connection management, reading and writing data, transactions, configuration, flow control, diagnostics, and logging.


List available serial ports on the system. Call this first to discover what ports are available before opening one.

ParameterTypeDefaultDescription
usb_onlyboolTrueOnly show USB serial devices. Set False to include legacy/phantom ttyS ports.
grepstr | NoneNoneRegex pattern to filter ports. Matches against device path, description, hardware ID, manufacturer, product, and serial number.

Returns: List of port objects with device, description, hwid, manufacturer, product, serial_number, and is_open fields. Sorted with USB ports (ttyUSB, ttyACM) first.

# List all USB serial devices
list_serial_ports()
# Include legacy ttyS ports
list_serial_ports(usb_only=false)
# Find FTDI adapters
list_serial_ports(grep="FTDI")
# Match specific USB VID:PID
list_serial_ports(grep="VID:PID=0403:6001")

Open a serial port connection with optional auto-baud detection. If baudrate is not specified, the server automatically detects the baud rate by analyzing incoming data patterns.

ParameterTypeDefaultDescription
portstrrequiredDevice path (/dev/ttyUSB0, COM3) or URL scheme (socket://, rfc2217://, loop://, spy://, cp2110://). See URL Schemes for details.
baudrateint | NoneNoneBaud rate. If None, auto-detect is attempted (recommended for unknown devices). Falls back to MCSERIAL_DEFAULT_BAUDRATE if detection fails.
bytesizeLiteral[5, 6, 7, 8]8Number of data bits.
parityLiteral["N", "E", "O", "M", "S"]"N"Parity checking: None, Even, Odd, Mark, or Space.
stopbitsLiteral[1, 1.5, 2]1Number of stop bits.
timeoutfloat1.0Read timeout in seconds. Default comes from MCSERIAL_DEFAULT_TIMEOUT.
write_timeoutfloat | NoneNoneWrite timeout in seconds. None means blocking writes.
inter_byte_timeoutfloat | NoneNoneTimeout between bytes during read. None disables inter-byte timeout.
xonxoffboolFalseEnable software flow control (XON/XOFF).
rtsctsboolFalseEnable hardware RTS/CTS flow control.
dsrdtrboolFalseEnable hardware DSR/DTR flow control.
exclusiveboolFalseRequest exclusive access (lock port from other processes).
autobaud_probestr | NoneNoneString to send during auto-detection (e.g., "UUUUU" for sync).
autobaud_timeoutfloat0.3Timeout per rate during auto-detection in seconds.
modeLiteral["rs232", "rs485", "rs422"]"rs232"Serial mode. "rs232" for point-to-point with modem control lines, "rs422" for full-duplex differential, "rs485" for half-duplex bus. Saves a separate set_port_mode call.

Returns: Connection status dict with success, port, mode, baudrate, bytesize, parity, stopbits, flow control settings, and resource_uri. When auto-baud is used, includes an autobaud object with detection details.

# Auto-detect baud rate
open_serial_port(port="/dev/ttyUSB0")
# Explicit baud rate with 8N1 (most common settings)
open_serial_port(port="/dev/ttyUSB0", baudrate=115200)
# RS-232 with hardware flow control
open_serial_port(port="/dev/ttyUSB0", baudrate=9600, rtscts=true)
# Exclusive access prevents other processes from using the port
open_serial_port(port="/dev/ttyUSB0", baudrate=9600, exclusive=true)
# Auto-detect with sync probe
open_serial_port(port="/dev/ttyUSB0", autobaud_probe="UUUUU")
# Open a network serial port
open_serial_port(port="socket://192.168.1.100:4001", baudrate=115200)
# Loopback for testing (no hardware needed)
open_serial_port(port="loop://", baudrate=9600)
# Open in RS-422 mode (full-duplex differential)
open_serial_port(port="/dev/ttyUSB0", baudrate=9600, mode="rs422")
# Open in RS-485 mode
open_serial_port(port="/dev/ttyUSB0", baudrate=9600, mode="rs485")

Close an open serial port connection and release it for other processes.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port to close.

Returns: Status dict with success, port, and message fields.

close_serial_port(port="/dev/ttyUSB0")

Switch a serial port between RS-232, RS-422, and RS-485 modes. Mode determines which mode-specific tools are available.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port to configure.
modeLiteral["rs232", "rs485", "rs422"]requiredTarget mode.

Returns: Status dict with success, previous_mode, current_mode, and mode_tools (list of tools available in the new mode).

# Switch to RS-485 mode for Modbus communication
set_port_mode(port="/dev/ttyUSB0", mode="rs485")
# Switch to RS-422 mode for differential point-to-point
set_port_mode(port="/dev/ttyUSB0", mode="rs422")
# Switch back to RS-232
set_port_mode(port="/dev/ttyUSB0", mode="rs232")

Get status of all open serial connections. Takes no parameters.

Returns: Dict with connections (map of port to status details) and count. Each connection includes is_open, mode, baudrate, bytesize, parity, stopbits, timeout, write_timeout, inter_byte_timeout, flow control flags, buffer counts (in_waiting, out_waiting), modem line states (cts, dsr, ri, cd, rts, dtr), and resource_uri.

get_connection_status()

Write string data to an open serial port. Data is encoded using the specified encoding before sending.

If a default line ending is configured (via configure_serial), it is automatically appended to every string sent through this tool. This eliminates the need to manually add \r\n to every command.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port to write to.
datastrrequiredString data to send.
encodingstr"utf-8"Character encoding for the data.

Returns: Dict with success, bytes_written, and port.

# Send an AT command (manual line ending)
write_serial(port="/dev/ttyUSB0", data="AT\r\n")
# With default line ending configured, just send the command
# (after configure_serial(port="/dev/ttyUSB0", line_ending="crlf"))
write_serial(port="/dev/ttyUSB0", data="AT")
# Send with specific encoding
write_serial(port="/dev/ttyUSB0", data="Hello", encoding="ascii")

Write raw bytes to an open serial port. Use this when you need to send binary data or specific byte sequences.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port to write to.
datalist[int]requiredList of byte values (0-255). Values outside this range return an error.

Returns: Dict with success, bytes_written, and port.

# Send AT\r\n as raw bytes
write_serial_bytes(port="/dev/ttyUSB0", data=[65, 84, 13, 10])
# Send a Modbus frame
write_serial_bytes(port="/dev/ttyUSB0", data=[0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A])

Read data from an open serial port. Returns both decoded text and raw hex representation.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port to read from.
sizeint | NoneNoneMaximum bytes to read. None reads all available data.
encodingstr"utf-8"Character encoding for decoding.
timeoutfloat | NoneNoneOverride the port’s read timeout for this call. None uses the port default.

Returns: Dict with success, data (decoded string), bytes_read, raw_hex, and port. Decoding errors are replaced rather than raising exceptions.

# Read all available data
read_serial(port="/dev/ttyUSB0")
# Read exactly 10 bytes
read_serial(port="/dev/ttyUSB0", size=10)
# Read with a longer timeout
read_serial(port="/dev/ttyUSB0", timeout=5.0)

Read a single line (until newline character) from an open serial port.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port to read from.
encodingstr"utf-8"Character encoding for decoding.

Returns: Dict with success, line (decoded string with trailing CR/LF stripped), bytes_read, and port.

read_serial_line(port="/dev/ttyUSB0")

Read multiple lines from an open serial port. Reads up to max_lines, stopping early if no more data is available (readline returns empty due to timeout).

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port to read from.
max_linesint10Maximum number of lines to read. Must be 1-1000.
encodingstr"utf-8"Character encoding for decoding.

Returns: Dict with success, lines (list of decoded strings), count, bytes_read, and port.

# Read up to 10 lines (default)
read_serial_lines(port="/dev/ttyUSB0")
# Read up to 50 lines of buffered output
read_serial_lines(port="/dev/ttyUSB0", max_lines=50)

Read data until a specific terminator sequence is received. More flexible than read_serial_line because it supports any terminator string, not just newline.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port to read from.
terminatorstr"\n"Byte sequence to stop at.
sizeint | NoneNoneMaximum bytes to read. None means no limit (uses timeout).
encodingstr"utf-8"Character encoding for the terminator and result.
timeoutfloat | NoneNoneOverride the port’s read timeout for this call. None uses the port default.

Returns: Dict with success, data (decoded string), bytes_read, raw_hex, port, and terminator_found (bool indicating whether the terminator was actually found or the read timed out).

# Read until "OK\r\n"
read_until(port="/dev/ttyUSB0", terminator="OK\r\n")
# Read until a prompt character
read_until(port="/dev/ttyUSB0", terminator=">")
# Read until terminator with a size limit
read_until(port="/dev/ttyUSB0", terminator="\r\n", size=256)
# Read with a custom timeout for slow devices
read_until(port="/dev/ttyUSB0", terminator=">", timeout=5.0)

Send a command and read its response in a single call. Combines write + flush + read into one atomic operation, eliminating the need for separate write_serial, flush_serial, and read_serial calls. Works in all three modes (RS-232, RS-422, and RS-485).

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port (must be open).
datastrrequiredCommand string to send.
line_endingstr | NoneNoneOverride line ending for this call. Accepts "cr", "lf", "crlf", "none", or a literal string. If None, uses the port’s default line ending.
response_timeoutfloat1.0Max time in seconds to wait for a response.
response_terminatorstr | NoneNoneStop reading when this sequence is received.
response_lengthint | NoneNoneExpected response length in bytes. Alternative to response_terminator.
strip_echoboolFalseRemove the echoed command from the start of the response.
encodingstr"utf-8"Character encoding for send and receive.

Returns: Dict with success, port, bytes_sent, data_sent, response (decoded string), response_bytes, and response_hex.

The transaction flow:

  1. Resolve line ending (explicit param > port default > none)
  2. Clear the input buffer for a clean read
  3. Encode and write the command
  4. Read response using terminator, length, or timeout fallback
# Simple command with timeout-based response
transact(port="/dev/ttyUSB0", data="AT\r\n")
# With port default line ending set, no need for \r\n
transact(port="/dev/ttyUSB0", data="AT")
# Wait for a specific terminator
transact(port="/dev/ttyUSB0", data="STATUS", response_terminator="\r\n>")
# Known response length (binary protocol)
transact(port="/dev/ttyUSB0", data="\x01\x03\x00\x00\x00\x01", response_length=7, encoding="latin-1")
# Strip echoed command from response
transact(port="/dev/ttyUSB0", data="VERSION", strip_echo=true, response_terminator="\r\n")
# Override line ending for a single call
transact(port="/dev/ttyUSB0", data="AT", line_ending="cr")

Modify settings on an already-open serial port. Only the parameters you provide are changed; everything else stays the same.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port to configure.
baudrateint | NoneNoneNew baud rate. None = no change.
timeoutfloat | NoneNoneNew read timeout in seconds. None = no change.
write_timeoutfloat | NoneNoneNew write timeout in seconds. None = no change.
inter_byte_timeoutfloat | NoneNoneTimeout between bytes. None = no change.
xonxoffbool | NoneNoneSoftware flow control XON/XOFF. None = no change.
rtsctsbool | NoneNoneHardware RTS/CTS flow control. None = no change.
dsrdtrbool | NoneNoneHardware DSR/DTR flow control. None = no change.
rtsbool | NoneNoneSet RTS line state. None = no change.
dtrbool | NoneNoneSet DTR line state. None = no change.
line_endingstr | NoneNoneDefault line ending for write_serial and transact. Accepts "cr", "lf", "crlf", "none" (to clear), or a literal string. When set, write_serial auto-appends this to every string. Does not affect write_serial_bytes. None = no change.

Returns: Dict with success, port, and all current settings (baudrate, timeout, write_timeout, inter_byte_timeout, xonxoff, rtscts, dsrdtr, rts, dtr, line_ending).

# Change baud rate on the fly
configure_serial(port="/dev/ttyUSB0", baudrate=115200)
# Increase read timeout
configure_serial(port="/dev/ttyUSB0", timeout=5.0)
# Enable hardware flow control
configure_serial(port="/dev/ttyUSB0", rtscts=true)
# Set DTR low (useful for reset sequences)
configure_serial(port="/dev/ttyUSB0", dtr=false)
# Set default line ending (auto-appended by write_serial and transact)
configure_serial(port="/dev/ttyUSB0", line_ending="crlf")
# Clear default line ending
configure_serial(port="/dev/ttyUSB0", line_ending="none")

Clear serial port input and/or output buffers. Discards any pending data.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port to flush.
input_bufferboolTrueClear the input/receive buffer.
output_bufferboolTrueClear the output/transmit buffer.

Returns: Dict with success, port, flushed_input, and flushed_output.

# Flush both buffers (default)
flush_serial(port="/dev/ttyUSB0")
# Flush only the input buffer
flush_serial(port="/dev/ttyUSB0", input_buffer=true, output_buffer=false)

Manually gate input/output flow control signals on a serial port. Flow control must already be enabled via configure_serial (set xonxoff=True or rtscts=True) for these signals to have effect.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port.
input_flowbool | NoneNoneTrue sends XON (allow remote to send), False sends XOFF (tell remote to stop). None = no change.
output_flowbool | NoneNoneTrue resumes outgoing data, False pauses it. None = no change.

Returns: Dict with success, port, changes (what was set), and flow_control_enabled (current xonxoff and rtscts state).

# Pause incoming data (send XOFF)
set_flow_control(port="/dev/ttyUSB0", input_flow=false)
# Resume incoming data (send XON)
set_flow_control(port="/dev/ttyUSB0", input_flow=true)

Cancel any pending read operation on a serial port. Interrupts a blocking read by calling cancel_read() on the underlying pyserial connection.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port.

Returns: Dict with success, port, and cancelled.

cancel_read(port="/dev/ttyUSB0")

Cancel any pending write operation on a serial port. Interrupts a blocking write by calling cancel_write() on the underlying pyserial connection.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port.

Returns: Dict with success, port, and cancelled.

cancel_write(port="/dev/ttyUSB0")

Enable or disable low-latency mode on a serial port. Reduces latency by changing how the kernel buffers data. Linux only.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port.
enabledboolTrueEnable or disable low latency mode.

Returns: Dict with success, port, and low_latency.

# Enable low latency for time-critical communication
set_low_latency_mode(port="/dev/ttyUSB0", enabled=true)

Auto-detect baud rate using multiple heuristics: 0x55 sync pattern analysis, byte distribution analysis, ASCII readability scoring, and framing indicators.

ParameterTypeDefaultDescription
portstrrequiredDevice path. Opened temporarily if not already open. If open, the baud rate is changed during testing and restored afterward.
probestr | NoneNoneString to send to trigger a response. Use "U" or "UUUUU" for sync-based detection on echo-enabled devices.
timeout_per_ratefloat0.5Seconds to wait for data at each baud rate.
baudrateslist[int] | NoneNoneCustom list of rates to try. Default tries common rates: 115200, 9600, 57600, 38400, 19200, 230400, 460800, 921600, 4800, 2400, 1200, 300, 500000, 576000, 1000000, 1500000.
use_sync_patternboolTrueAnalyze 0x55 sync patterns for improved detection accuracy.

Returns: Dict with success, port, detected_baudrate (or None if confidence is below 50), confidence (0-100 score), results (top 5 candidates with detailed scoring), and rates_tested.

# Detect baud rate on an active device
detect_baud_rate(port="/dev/ttyUSB0")
# Use a sync probe for echo devices
detect_baud_rate(port="/dev/ttyUSB0", probe="UUUUU")
# Test only common embedded rates
detect_baud_rate(port="/dev/ttyUSB0", baudrates=[9600, 115200, 57600])
# Longer wait time for slow devices
detect_baud_rate(port="/dev/ttyUSB0", timeout_per_rate=1.0)

Configure server-wide logging behavior. Controls the minimum log level and buffer size for the in-memory log accessible via serial://log.

ParameterTypeDefaultDescription
levelstr"INFO"Minimum log level: DEBUG, INFO, WARNING, or ERROR.
max_entriesint1000Maximum entries in the server log buffer (10-100000).
clearboolFalseClear existing log entries before applying new settings.

Returns: Dict with success, level, previous_level, max_entries, current_entries, cleared, and resource_uri.

Log levels filter what gets captured:

  • DEBUG: All events including TX/RX byte counts
  • INFO: Port open/close, configuration changes (default)
  • WARNING: Potential issues like sanitized filenames
  • ERROR: Failed operations only
# Set to DEBUG for detailed operation logging
configure_logging(level="DEBUG")
# Reduce buffer size to save memory
configure_logging(max_entries=500)
# Clear logs and set to ERROR only
configure_logging(level="ERROR", clear=true)

Enable or disable per-port traffic capture. When enabled, all TX/RX data on the port is captured to an in-memory buffer accessible via serial://{port}/log.

ParameterTypeDefaultDescription
portstrrequiredDevice path of the port to configure.
enabledboolTrueEnable or disable traffic logging.
max_entriesint500Maximum traffic entries to keep (10-10000).
clearboolFalseClear existing traffic log entries.

Returns: Dict with success, port, traffic_log_enabled, max_entries, current_entries, and resource_uri.

# Enable traffic logging on a port
enable_traffic_log(port="/dev/ttyUSB0")
# Enable with larger buffer for long sessions
enable_traffic_log(port="/dev/ttyUSB0", max_entries=2000)
# Clear and restart traffic capture
enable_traffic_log(port="/dev/ttyUSB0", clear=true)
# Disable traffic logging
enable_traffic_log(port="/dev/ttyUSB0", enabled=false)