SSH and serial-port control for embedded devices, exposed as MCP tools. Log into a Raspberry Pi, talk to a UART, drive a USB-CDC console from your assistant.
Quick start · Tools · Workflows · Documentation
What is mcp-remote-access?
mcp-remote-access is an MCP server that exposes SSH (over paramiko)
and serial / UART (over pyserial) as MCP tools. Once it's running,
an agent can log into a host over SSH, run commands, transfer files,
open a serial console, send AT-style command sequences, and reset a
device over DTR/RTS.
It's deliberately thin: 26 tools, two transports, no orchestration language. Higher-level workflow logic lives in the agent's prompts, not in this server.
A few things it handles that are easy to get wrong by hand:
- Connect to a serial port by VID/PID/serial number/description
instead of guessing
/dev/ttyUSB0vs/dev/ttyUSB1(serial_connect_match). - Long-running SSH commands (builds,
tcpdump, test runs) don't block the MCP channel —ssh_execute_backgroundreturns a task ID,ssh_check_backgroundpolls it. serial_expect/serial_wait_forwait for a real pattern in the stream instead of a fixedsleep(), which avoids the usual "sent before the prompt was ready" race on login prompts and AT flows.- DTR/RTS control for hard-resetting MCUs over USB-serial, plus break-signal support.
- SSH passwords are held in memory only and cleared on disconnect; no on-disk session store.
Quick start
Install
git clone https://github.com/RFingAdam/mcp-remote-access.git
cd mcp-remote-access
uv pip install -e .
Run it
The server speaks MCP over stdio:
uv run --directory /path/to/mcp-remote-access mcp-remote-access
Add it to an MCP client
Codex CLI:
codex mcp add remote-access -- \
uv run --directory /path/to/mcp-remote-access mcp-remote-access
Claude Code:
claude mcp add remote-access -- \
uv run --directory /path/to/mcp-remote-access mcp-remote-access
Or add it to a client config file directly:
{
"mcpServers": {
"remote-access": {
"command": "uv",
"args": ["run", "--directory", "/path/to/mcp-remote-access", "mcp-remote-access"]
}
}
}
Then, from the assistant:
"Connect to my Pi at vpn-ap.local as
pi(passwordraspberry), rununame -a, thendmesg | tail -20."
That's ssh_connect followed by two ssh_execute calls.
Tools
26 MCP tools across two transports. Full reference in docs/tools.md.
SSH (9)
| Tool | Purpose |
|---|---|
ssh_connect |
Connect to a host via SSH (password or key auth) |
ssh_execute |
Run a command on a connected host (sync) |
ssh_execute_background |
Run a long-running command async, returns task_id |
ssh_check_background |
Check status / collect output of a background command |
ssh_list_background |
List all active background commands |
ssh_upload |
Upload a file via SFTP |
ssh_download |
Download a file via SFTP |
ssh_disconnect |
Close an SSH connection |
ssh_list_connections |
Show active SSH connections |
Serial / UART (17)
| Tool | Purpose |
|---|---|
serial_list_ports |
List available serial ports (with VID/PID, description, serial #) |
serial_connect |
Connect by port name |
serial_connect_match |
Connect by VID / PID / serial / description match |
serial_esp32_connect |
ESP32-aware connect (BOOT/RESET sequence, auto-baud) |
serial_send |
Send text data (with optional response read + configurable line ending) |
serial_send_bytes |
Send raw bytes as hex (binary protocols — Nordic DTM, HCI, etc.) |
serial_read |
Read available data |
serial_read_bytes |
Read raw bytes back as hex |
serial_wait_for |
Wait for a pattern in the incoming stream |
serial_expect |
Wait/send step sequences (login prompts, AT flows) |
serial_send_break |
Send a break signal |
serial_set_dtr |
Set DTR line state |
serial_set_rts |
Set RTS line state |
serial_reset_device |
Reset device via DTR/RTS sequence |
serial_flush |
Flush serial buffers |
serial_disconnect |
Close a serial connection |
serial_list_connections |
Show active serial connections |
Workflows
mcp-remote-access fits in the following eng-mcp-suite
workflow bundles:
lab-automation— pair withmcp-rs-spectrum-analyzer,mcp-rs-siggen,copper-mountain-vna-mcpto fully script a bench (DUT login over SSH or UART, lab gear over SCPI).embedded-bringup—serial_connect_match+serial_expect+ssh_uploadfor boot-loader interaction and image flashing.
Part of eng-mcp-suite.
Use in the lab-automation workflow bundle.
See the suite manifest for the full list of sibling MCPs and bundle definitions.
Documentation
- Quick Start — install through first call.
- Tool reference — every MCP tool, every argument.
- Usage examples — practical end-to-end walkthroughs.
- Architecture — how this MCP fits in eng-mcp-suite.
Part of eng-mcp-suite
This server is one piece of eng-mcp-suite, an umbrella of engineering MCP servers covering RF, EMC, PCB, signal integrity, EM simulation, and lab test. See the full catalog or jump to a sibling:
| Domain | Sibling MCPs |
|---|---|
| RF / Transmission lines | lineforge |
| EMC regulatory | mcp-emc-regulations |
| PCB / SI | mcp-pcb-emcopilot (private — public soon) |
| EM simulation | mcp-openems, mcp-nec2-antenna (private — public soon) |
| Diagrams | drawio-engineering-mcp |
| 3D / rendering | mcp-blender |
| Remote access | mcp-remote-access (this repo) |
| Lab gear | copper-mountain-vna-mcp, mcp-rs-spectrum-analyzer, mcp-rs-siggen, mcp-rs-cmw500 |
Security notes
- SSH passwords are kept in memory only and cleared on server restart.
- Connections are session-scoped; the server does not persist a session store on disk.
- Use SSH keys where possible.
- The MCP server runs over stdio — it only accepts connections from the local MCP client, never from the network.
Troubleshooting
SSH connection issues — verify the host is reachable
(ping vpn-ap.local), that SSH is listening on the target
(ssh [email protected] from the same shell), and that credentials are
correct.
Serial port issues — check port permissions
(ls -la /dev/ttyUSB*), add your user to the dialout group
(sudo usermod -a -G dialout $USER and re-login), and confirm the
device is present (dmesg | tail).
VID/PID match selects wrong device — serial_connect_match returns
the first hit; pair the match on description or serial_number to
disambiguate.
Contributing
Contributions are welcome.
- Pick a GitHub issue.
- Fork + branch (
feature/your-thingorfix/your-bug). - Run tests (
uv run pytest) if present. - Open a PR — link the issue, request review.
License
AGPL-3.0-or-later. Relicensed from Apache-2.0 in v0.2.0 to align with the eng-mcp-suite toolkit-wide AGPL move.
Acknowledgments
- paramiko — SSH transport.
- pyserial — serial / UART transport.
- The MCP working group — for the Model Context Protocol specification.
Part of eng-mcp-suite.
No comments yet
Be the first to share your take.