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.
Port Discovery
Section titled “Port Discovery”list_serial_ports
Section titled “list_serial_ports”List available serial ports on the system. Call this first to discover what ports are available before opening one.
| Parameter | Type | Default | Description |
|---|---|---|---|
usb_only | bool | True | Only show USB serial devices. Set False to include legacy/phantom ttyS ports. |
grep | str | None | None | Regex 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 deviceslist_serial_ports()
# Include legacy ttyS portslist_serial_ports(usb_only=false)
# Find FTDI adapterslist_serial_ports(grep="FTDI")
# Match specific USB VID:PIDlist_serial_ports(grep="VID:PID=0403:6001")Connection Management
Section titled “Connection Management”open_serial_port
Section titled “open_serial_port”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.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path (/dev/ttyUSB0, COM3) or URL scheme (socket://, rfc2217://, loop://, spy://, cp2110://). See URL Schemes for details. |
baudrate | int | None | None | Baud rate. If None, auto-detect is attempted (recommended for unknown devices). Falls back to MCSERIAL_DEFAULT_BAUDRATE if detection fails. |
bytesize | Literal[5, 6, 7, 8] | 8 | Number of data bits. |
parity | Literal["N", "E", "O", "M", "S"] | "N" | Parity checking: None, Even, Odd, Mark, or Space. |
stopbits | Literal[1, 1.5, 2] | 1 | Number of stop bits. |
timeout | float | 1.0 | Read timeout in seconds. Default comes from MCSERIAL_DEFAULT_TIMEOUT. |
write_timeout | float | None | None | Write timeout in seconds. None means blocking writes. |
inter_byte_timeout | float | None | None | Timeout between bytes during read. None disables inter-byte timeout. |
xonxoff | bool | False | Enable software flow control (XON/XOFF). |
rtscts | bool | False | Enable hardware RTS/CTS flow control. |
dsrdtr | bool | False | Enable hardware DSR/DTR flow control. |
exclusive | bool | False | Request exclusive access (lock port from other processes). |
autobaud_probe | str | None | None | String to send during auto-detection (e.g., "UUUUU" for sync). |
autobaud_timeout | float | 0.3 | Timeout per rate during auto-detection in seconds. |
mode | Literal["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 rateopen_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 controlopen_serial_port(port="/dev/ttyUSB0", baudrate=9600, rtscts=true)
# Exclusive access prevents other processes from using the portopen_serial_port(port="/dev/ttyUSB0", baudrate=9600, exclusive=true)
# Auto-detect with sync probeopen_serial_port(port="/dev/ttyUSB0", autobaud_probe="UUUUU")
# Open a network serial portopen_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 modeopen_serial_port(port="/dev/ttyUSB0", baudrate=9600, mode="rs485")close_serial_port
Section titled “close_serial_port”Close an open serial port connection and release it for other processes.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port to close. |
Returns: Status dict with success, port, and message fields.
close_serial_port(port="/dev/ttyUSB0")set_port_mode
Section titled “set_port_mode”Switch a serial port between RS-232, RS-422, and RS-485 modes. Mode determines which mode-specific tools are available.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port to configure. |
mode | Literal["rs232", "rs485", "rs422"] | required | Target 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 communicationset_port_mode(port="/dev/ttyUSB0", mode="rs485")
# Switch to RS-422 mode for differential point-to-pointset_port_mode(port="/dev/ttyUSB0", mode="rs422")
# Switch back to RS-232set_port_mode(port="/dev/ttyUSB0", mode="rs232")get_connection_status
Section titled “get_connection_status”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()Writing Data
Section titled “Writing Data”write_serial
Section titled “write_serial”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.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port to write to. |
data | str | required | String data to send. |
encoding | str | "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 encodingwrite_serial(port="/dev/ttyUSB0", data="Hello", encoding="ascii")write_serial_bytes
Section titled “write_serial_bytes”Write raw bytes to an open serial port. Use this when you need to send binary data or specific byte sequences.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port to write to. |
data | list[int] | required | List 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 byteswrite_serial_bytes(port="/dev/ttyUSB0", data=[65, 84, 13, 10])
# Send a Modbus framewrite_serial_bytes(port="/dev/ttyUSB0", data=[0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A])Reading Data
Section titled “Reading Data”read_serial
Section titled “read_serial”Read data from an open serial port. Returns both decoded text and raw hex representation.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port to read from. |
size | int | None | None | Maximum bytes to read. None reads all available data. |
encoding | str | "utf-8" | Character encoding for decoding. |
timeout | float | None | None | Override 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 dataread_serial(port="/dev/ttyUSB0")
# Read exactly 10 bytesread_serial(port="/dev/ttyUSB0", size=10)
# Read with a longer timeoutread_serial(port="/dev/ttyUSB0", timeout=5.0)read_serial_line
Section titled “read_serial_line”Read a single line (until newline character) from an open serial port.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port to read from. |
encoding | str | "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_serial_lines
Section titled “read_serial_lines”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).
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port to read from. |
max_lines | int | 10 | Maximum number of lines to read. Must be 1-1000. |
encoding | str | "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 outputread_serial_lines(port="/dev/ttyUSB0", max_lines=50)read_until
Section titled “read_until”Read data until a specific terminator sequence is received. More flexible than read_serial_line because it supports any terminator string, not just newline.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port to read from. |
terminator | str | "\n" | Byte sequence to stop at. |
size | int | None | None | Maximum bytes to read. None means no limit (uses timeout). |
encoding | str | "utf-8" | Character encoding for the terminator and result. |
timeout | float | None | None | Override 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 characterread_until(port="/dev/ttyUSB0", terminator=">")
# Read until terminator with a size limitread_until(port="/dev/ttyUSB0", terminator="\r\n", size=256)
# Read with a custom timeout for slow devicesread_until(port="/dev/ttyUSB0", terminator=">", timeout=5.0)Transactions
Section titled “Transactions”transact
Section titled “transact”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).
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port (must be open). |
data | str | required | Command string to send. |
line_ending | str | None | None | Override line ending for this call. Accepts "cr", "lf", "crlf", "none", or a literal string. If None, uses the port’s default line ending. |
response_timeout | float | 1.0 | Max time in seconds to wait for a response. |
response_terminator | str | None | None | Stop reading when this sequence is received. |
response_length | int | None | None | Expected response length in bytes. Alternative to response_terminator. |
strip_echo | bool | False | Remove the echoed command from the start of the response. |
encoding | str | "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:
- Resolve line ending (explicit param > port default > none)
- Clear the input buffer for a clean read
- Encode and write the command
- Read response using terminator, length, or timeout fallback
# Simple command with timeout-based responsetransact(port="/dev/ttyUSB0", data="AT\r\n")
# With port default line ending set, no need for \r\ntransact(port="/dev/ttyUSB0", data="AT")
# Wait for a specific terminatortransact(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 responsetransact(port="/dev/ttyUSB0", data="VERSION", strip_echo=true, response_terminator="\r\n")
# Override line ending for a single calltransact(port="/dev/ttyUSB0", data="AT", line_ending="cr")Configuration
Section titled “Configuration”configure_serial
Section titled “configure_serial”Modify settings on an already-open serial port. Only the parameters you provide are changed; everything else stays the same.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port to configure. |
baudrate | int | None | None | New baud rate. None = no change. |
timeout | float | None | None | New read timeout in seconds. None = no change. |
write_timeout | float | None | None | New write timeout in seconds. None = no change. |
inter_byte_timeout | float | None | None | Timeout between bytes. None = no change. |
xonxoff | bool | None | None | Software flow control XON/XOFF. None = no change. |
rtscts | bool | None | None | Hardware RTS/CTS flow control. None = no change. |
dsrdtr | bool | None | None | Hardware DSR/DTR flow control. None = no change. |
rts | bool | None | None | Set RTS line state. None = no change. |
dtr | bool | None | None | Set DTR line state. None = no change. |
line_ending | str | None | None | Default 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 flyconfigure_serial(port="/dev/ttyUSB0", baudrate=115200)
# Increase read timeoutconfigure_serial(port="/dev/ttyUSB0", timeout=5.0)
# Enable hardware flow controlconfigure_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 endingconfigure_serial(port="/dev/ttyUSB0", line_ending="none")flush_serial
Section titled “flush_serial”Clear serial port input and/or output buffers. Discards any pending data.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port to flush. |
input_buffer | bool | True | Clear the input/receive buffer. |
output_buffer | bool | True | Clear 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 bufferflush_serial(port="/dev/ttyUSB0", input_buffer=true, output_buffer=false)Flow Control
Section titled “Flow Control”set_flow_control
Section titled “set_flow_control”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.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port. |
input_flow | bool | None | None | True sends XON (allow remote to send), False sends XOFF (tell remote to stop). None = no change. |
output_flow | bool | None | None | True 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_read
Section titled “cancel_read”Cancel any pending read operation on a serial port. Interrupts a blocking read by calling cancel_read() on the underlying pyserial connection.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port. |
Returns: Dict with success, port, and cancelled.
cancel_read(port="/dev/ttyUSB0")cancel_write
Section titled “cancel_write”Cancel any pending write operation on a serial port. Interrupts a blocking write by calling cancel_write() on the underlying pyserial connection.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port. |
Returns: Dict with success, port, and cancelled.
cancel_write(port="/dev/ttyUSB0")Diagnostics
Section titled “Diagnostics”set_low_latency_mode
Section titled “set_low_latency_mode”Enable or disable low-latency mode on a serial port. Reduces latency by changing how the kernel buffers data. Linux only.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port. |
enabled | bool | True | Enable or disable low latency mode. |
Returns: Dict with success, port, and low_latency.
# Enable low latency for time-critical communicationset_low_latency_mode(port="/dev/ttyUSB0", enabled=true)detect_baud_rate
Section titled “detect_baud_rate”Auto-detect baud rate using multiple heuristics: 0x55 sync pattern analysis, byte distribution analysis, ASCII readability scoring, and framing indicators.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path. Opened temporarily if not already open. If open, the baud rate is changed during testing and restored afterward. |
probe | str | None | None | String to send to trigger a response. Use "U" or "UUUUU" for sync-based detection on echo-enabled devices. |
timeout_per_rate | float | 0.5 | Seconds to wait for data at each baud rate. |
baudrates | list[int] | None | None | Custom 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_pattern | bool | True | Analyze 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 devicedetect_baud_rate(port="/dev/ttyUSB0")
# Use a sync probe for echo devicesdetect_baud_rate(port="/dev/ttyUSB0", probe="UUUUU")
# Test only common embedded ratesdetect_baud_rate(port="/dev/ttyUSB0", baudrates=[9600, 115200, 57600])
# Longer wait time for slow devicesdetect_baud_rate(port="/dev/ttyUSB0", timeout_per_rate=1.0)Logging
Section titled “Logging”configure_logging
Section titled “configure_logging”Configure server-wide logging behavior. Controls the minimum log level and buffer size for the in-memory log accessible via serial://log.
| Parameter | Type | Default | Description |
|---|---|---|---|
level | str | "INFO" | Minimum log level: DEBUG, INFO, WARNING, or ERROR. |
max_entries | int | 1000 | Maximum entries in the server log buffer (10-100000). |
clear | bool | False | Clear 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 loggingconfigure_logging(level="DEBUG")
# Reduce buffer size to save memoryconfigure_logging(max_entries=500)
# Clear logs and set to ERROR onlyconfigure_logging(level="ERROR", clear=true)enable_traffic_log
Section titled “enable_traffic_log”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.
| Parameter | Type | Default | Description |
|---|---|---|---|
port | str | required | Device path of the port to configure. |
enabled | bool | True | Enable or disable traffic logging. |
max_entries | int | 500 | Maximum traffic entries to keep (10-10000). |
clear | bool | False | Clear existing traffic log entries. |
Returns: Dict with success, port, traffic_log_enabled, max_entries, current_entries, and resource_uri.
# Enable traffic logging on a portenable_traffic_log(port="/dev/ttyUSB0")
# Enable with larger buffer for long sessionsenable_traffic_log(port="/dev/ttyUSB0", max_entries=2000)
# Clear and restart traffic captureenable_traffic_log(port="/dev/ttyUSB0", clear=true)
# Disable traffic loggingenable_traffic_log(port="/dev/ttyUSB0", enabled=false)