MCP server for CP210x USB-UART bridge customization
Project description
mcp210x-uart
It's MCP. It's CP210x. It was right there the whole time.
An MCP server for customizing Silicon Labs CP210x USB-UART bridge devices — product strings, serial numbers, power config, GPIO port config, baud rate tables, udev rules, and device locking — through natural language in Claude Code.
Built on FastMCP with Python ctypes bindings to all 45 functions in Silicon Labs' native libcp210xmanufacturing library. Covers the full CP210x family: CP2101, CP2102, CP2102N, CP2103, CP2104, CP2105, CP2108, and CP2109.
The problem
You plug in three CP2102 boards. They all enumerate as:
Bus 001 Device 004: ID 10c4:ea60 Silicon Labs CP2102 USB to UART Bridge Controller
Bus 001 Device 005: ID 10c4:ea60 Silicon Labs CP2102 USB to UART Bridge Controller
Bus 001 Device 006: ID 10c4:ea60 Silicon Labs CP2102 USB to UART Bridge Controller
Which one is which? Unplug, replug, guess. /dev/ttyUSB0 becomes /dev/ttyUSB2 after a reboot. You write udev rules that match on nothing unique. The Silicon Labs GUI customization tool is 32-bit only and hasn't been updated since 2015.
The fix
> What CP210x devices are connected?
Two devices found:
[0] RYLR998 0033001104645C0B00001130 (serial: 0001)
[1] RYLR998 0033001104645C0B00000D27 (serial: 0001)
> Set up a udev rule for device 0 so it always appears at /dev/rylr998-1130
Each device gets a unique product string baked into its USB descriptor EPROM. Udev rules match on that string to create stable symlinks. Devices survive reboots, port reordering, and hub changes.
Tools
Read-only (no confirmation)
| Tool | Description |
|---|---|
list_devices |
List all connected CP210x devices |
get_device_info |
Full device details — part number, VID/PID, strings, power, lock state, firmware version (CP2102N), flush config, device mode |
get_firmware_version |
Firmware version (CP2102N only) |
get_flush_buffer_config |
Flush buffer configuration (CP2104/CP2105/CP2108) |
get_device_mode |
Device mode — ECI/SCI assignment (CP2105 only) |
get_interface_string |
USB interface string (CP2105/CP2108 only) |
get_baud_rate_config |
Baud rate alias table (32 entries) |
get_port_config |
GPIO port configuration (auto-detects CP2103/4/5/8) |
get_raw_config |
Raw EPROM configuration blob (hex string) |
create_hex_file |
Dump device config to Intel HEX file |
reset_device |
USB disconnect/reconnect to apply changes |
Normal writes (elicitation → fallback to proceed)
| Tool | Description |
|---|---|
set_product_string |
Write USB product string (max 126 chars) |
set_manufacturer_string |
Write USB manufacturer string (max 45 chars) |
set_serial_number |
Write USB serial number (max 63 chars) |
set_max_power |
Set max USB power draw in mA (0–500, rounded to nearest 2) |
set_self_powered |
Toggle self-powered vs bus-powered reporting |
set_device_version |
Set device version (bcdDevice field) |
set_interface_string |
Set USB interface string (CP2105/CP2108 only) |
set_flush_buffer_config |
Set flush buffer configuration (CP2104/CP2105/CP2108) |
set_device_mode |
Set device mode (CP2105 only) |
set_baud_rate_config |
Set full 32-entry baud rate alias table |
set_baud_rate_alias |
Modify a single baud rate alias entry (read-modify-write) |
set_port_config |
Set GPIO port configuration (auto-detects CP2103/4/5/8) |
setup_udev_rule |
Generate and install a udev rule for a stable /dev/ symlink |
Strict writes (elicitation required — hard-refuses without it)
| Tool | Description |
|---|---|
set_vid |
Set USB Vendor ID (can break driver matching) |
set_pid |
Set USB Product ID (can break driver matching) |
set_raw_config |
Write raw configuration blob to EPROM |
update_firmware |
Update device firmware (CP2102N only) |
lock_device |
Permanently freeze device configuration |
Safety model
CP210x descriptor EPROM is one-time-programmable with limited write cycles. Writes can't be undone. Locks are permanent. The server enforces a tiered confirmation model:
| Tier | Behavior | Tools |
|---|---|---|
| None | No confirmation | All get_*, list_devices, reset_device, create_hex_file |
| Normal | Elicitation if client supports it; proceeds otherwise | String setters, power, baud config, port config, setup_udev_rule |
| Strict | Elicitation required; returns error without it | set_vid, set_pid, set_raw_config, update_firmware, lock_device |
The strict gate isn't a warning — it returns an error and does not proceed if the MCP client can't present a confirmation dialog.
Part-number support
Different CP210x parts expose different features. The server auto-gates tools to supported parts:
| Feature | Supported parts |
|---|---|
| Core (strings, power, baud) | All CP210x |
| Flush buffer config | CP2104, CP2105, CP2108 |
| Device mode | CP2105 |
| Interface strings | CP2105, CP2108 |
| Port config | CP2103, CP2104 |
| Dual port config | CP2105 |
| Quad port config | CP2108 |
| Firmware version/update | CP2102N |
Requirements
- Linux x86_64
libcp210xmanufacturing.so— Silicon Labs CP210x manufacturing library- Python 3.10+
- uv
Installation
1. Native library
Arch Linux (AUR package included):
cd aur/cp210xmanufacturing
makepkg -si
This installs the shared library, headers, and udev rules for non-root USB access.
From source:
cd AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing
make LIB_ARCH=64
sudo make install
sudo ldconfig
You'll also need udev rules for non-root device access — copy aur/cp210xmanufacturing/SiliconLabs.rules to /usr/lib/udev/rules.d/ and reload.
2. MCP server
uv tool install .
3. Claude Code
claude mcp add cp210x -- uvx mcp210x-uart
For development (runs from source):
claude mcp add cp210x-local -- uv run --directory /path/to/this-repo mcp210x-uart
Architecture
Claude Code ──stdio──▶ FastMCP server (server.py)
│
▼
Python ctypes (bindings.py)
│
▼
libcp210xmanufacturing.so
│
▼
libusb ──▶ CP210x device
The native library uses libusb for device access, separate from the kernel's cp210x serial driver. Both coexist — you can read/write UART data over /dev/ttyUSB0 while customizing USB descriptors through this server.
Project structure
mcp210x-uart/
├── src/mcp210x_uart/
│ ├── server.py # FastMCP tool definitions, elicitation, part-number dispatch
│ ├── bindings.py # ctypes: structs, prototypes, bitmask helpers, device wrapper
│ └── __init__.py
├── aur/cp210xmanufacturing/
│ ├── PKGBUILD # Arch Linux package for the native library
│ └── SiliconLabs.rules # udev rules for non-root USB access
├── AN721SW/ # Silicon Labs toolkit (library source)
├── docs/ # Datasheets and application notes
└── pyproject.toml
Complementary tools
This server handles device customization (USB descriptors, power config, GPIO, baud tables). For serial communication (sending/receiving data over UART), use mcserial.
Reference
- CP2102 Datasheet
- AN721: Device Customization Guide — source for
libcp210xmanufacturing - AN197: Serial Communication Guide
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp210x_uart-0.2.0.tar.gz.
File metadata
- Download URL: mcp210x_uart-0.2.0.tar.gz
- Upload date:
- Size: 2.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74ab0e3955cf042e10a05e052de3899cca27dc0037c1ceb4e0e1ee6f450ca18b
|
|
| MD5 |
423df85e3336f604870a87c8d0cf84a2
|
|
| BLAKE2b-256 |
c061f3ec8a27882d79afab66d42b35f48af50e29df811096c3651db62e118c91
|
File details
Details for the file mcp210x_uart-0.2.0-py3-none-any.whl.
File metadata
- Download URL: mcp210x_uart-0.2.0-py3-none-any.whl
- Upload date:
- Size: 19.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
33373d5bdc0634dcaae8e7bc8c734cede836ddf1456a3837dbf72ade64a21565
|
|
| MD5 |
5ba1f9677910396596e878431f501264
|
|
| BLAKE2b-256 |
22191eee8d11c267d9be8ad63abda505781f9a8d27d50bf0a9f526d258031306
|