Skip to content

Network Serial Ports

Serial devices are not always physically attached to the machine running mcserial. Serial device servers, terminal servers, and networked test equipment expose serial ports over TCP. mcserial supports these through URL schemes passed to open_serial_port — the same read, write, configure, and file transfer tools work regardless of how the port is connected.

All of the operations described in this guide are performed through your MCP client. Ask the assistant to open a network serial port by providing the URL scheme, and all subsequent tool calls work identically to a local port.

  • Serial device servers (Digi, Moxa, Lantronix) bridge RS-232/RS-485 ports to your LAN
  • Remote equipment in server rooms, factory floors, or field sites
  • Terminal servers providing shared console access to routers, switches, and PDUs
  • Virtual serial ports for testing and development without physical hardware

All URL schemes are passed directly to open_serial_port in the port parameter. Once opened, the connection is used identically to a local serial port.

The simplest network serial option. Bytes are forwarded as-is between the TCP socket and your tools, with no protocol framing, baud rate control, or flow control signals.

Full serial port emulation over a Telnet connection (RFC 2217 / Telnet COM Port Control). The remote device server translates baud rate changes, flow control, and modem line signals into commands that control the physical serial port.

// Connect to a Digi PortServer on port 4001
// open_serial_port(
// port="socket://192.168.1.100:4001",
// baudrate=115200
// )
{
"success": true,
"port": "socket://192.168.1.100:4001",
"mode": "rs232",
"baudrate": 115200,
"url_scheme": "socket",
"hint": "Opened via URL handler. Some features (exclusive, auto-baud) are not available."
}

Characteristics:

  • No baud rate negotiation — the device server must be pre-configured to match
  • No flow control or modem line signals
  • Lowest overhead; good for simple byte-stream forwarding
  • Works with any serial-to-ethernet bridge

After opening, all tools work the same way:

// write_serial(port="socket://192.168.1.100:4001", data="AT\r\n")
{
"success": true,
"bytes_written": 4,
"port": "socket://192.168.1.100:4001"
}
// read_serial_lines(port="socket://192.168.1.100:4001", max_lines=5)
{
"success": true,
"lines": ["OK"],
"count": 1,
"port": "socket://192.168.1.100:4001"
}

The spy:// scheme wraps another serial connection and logs all traffic. It works with local ports and other URL schemes.

// Debug a local serial port
// open_serial_port(port="spy:///dev/ttyUSB0", baudrate=9600)
{
"success": true,
"port": "spy:///dev/ttyUSB0",
"baudrate": 9600,
"url_scheme": "spy"
}
// Debug a network connection
// open_serial_port(port="spy://socket://192.168.1.100:4001", baudrate=115200)

All reads and writes are logged to stderr in the mcserial server process. Check the server’s stderr output to see the traffic.

Silicon Labs CP2110 chips present as USB HID devices rather than standard serial ports. They do not appear as /dev/ttyUSB* devices, so normal serial access does not work.

// open_serial_port(port="cp2110://", baudrate=9600)
{
"success": true,
"port": "cp2110://",
"baudrate": 9600,
"url_scheme": "cp2110"
}

This requires the hidapi package. Install it with the optional extra:

Terminal window
uv pip install mcserial[cp2110]

If hidapi is not installed and you try to open a cp2110:// port, mcserial returns a clear error:

{
"error": "cp2110:// requires the hidapi package. Install with: pip install mcserial[cp2110]",
"success": false
}

hwgrep:// opens the first serial port whose hardware information matches a pattern. This is useful when device paths change between reboots or when multiple adapters are connected.

// Find and open an FTDI device by USB VID:PID
// open_serial_port(port="hwgrep://VID:PID=0403:6001", baudrate=115200)
{
"success": true,
"port": "hwgrep://VID:PID=0403:6001",
"baudrate": 115200,
"url_scheme": "hwgrep"
}
// Find by description string
// open_serial_port(port="hwgrep://FTDI", baudrate=9600)
// Find by manufacturer
// open_serial_port(port="hwgrep://Silicon Labs", baudrate=9600)

The pattern is matched against the port’s device path, description, hardware ID, manufacturer, product, and serial number. The first matching port is opened.

The loop:// scheme creates a virtual loopback port where everything written is immediately available to read. No hardware is needed. This is useful for testing and development.

// open_serial_port(port="loop://", baudrate=9600)
// write_serial(port="loop://", data="hello")
// read_serial(port="loop://")
{
"success": true,
"data": "hello",
"bytes_read": 5,
"port": "loop://"
}

URL-opened ports differ from local device ports in a few ways:

FeatureLocal portURL port
Auto-baud detectionYesNo (not applicable)
Exclusive access lockYesNo
Low-latency modeYes (Linux)No
set_rs485_mode hardware ioctlYesNo
Read/write/configureYesYes
File transfersYesYes

Baud rate auto-detection is skipped for URL ports because it requires reopening the port at different speeds, which does not apply to TCP or virtual connections. For socket://, the baud rate parameter is informational only — the device server must be configured separately.

For rfc2217://, baud rate and serial parameters are sent to the remote device server, which applies them to the physical port.