EmbPilot
Embedded device debugging via the Pilot (MCP) protocol.
EmbPilot is an MCP (Model Context Protocol) server that lets LLM agents connect to, control, and debug physical embedded devices over Serial, Telnet, or SSH.
Features
- Connect to devices via Serial UART, Telnet, or SSH
- Send commands and capture output with regular-expression interception (Expect)
- Reset targets by issuing a reboot to the connected device
- Guard risky operations with dangerous-command confirmation, delete confirmation, redacted audit history, rate limiting, and bounded exports
- Expose active-session resources through MCP, including
device://live_loganddevice://session_info - Persist sessions in SQLite (WAL mode) with FTS5-backed historical search
- Search and export recorded sessions (by session id, keyword, or full export)
- Local vector search tools (optional
embpilot[rag]) over Datasheets, Error Code manuals, and KB articles - Analyse crash logs and run hardware sanity checks with guided prompts
Quick Start
pip install embpilot # core: Serial/Telnet/SSH MCP server
pip install embpilot[rag] # + optional local RAG (fastembed + LanceDB)
embpilot install # detect and configure supported agent harnesses
embpilot --help
embpilot install follows the explicit installer model used by agent tooling
such as CodeGraph. It detects supported harnesses, lets you select targets and
global/local scope, then idempotently installs MCP config and a marker-fenced
EmbPilot routing block plus a detailed embpilot-device-debugging skill where
the harness supports them. The short, always-loaded hook routes relevant tasks;
the skill supplies the full workflow and safety contract only when needed.
Existing instructions and other MCP servers are preserved. Run
embpilot uninstall to remove only content still owned by EmbPilot. A skill
edited by the user is left in place while its MCP entry and routing hook are
still removed.
Run embpilot doctor for
environment diagnostics (Python, core/RAG deps, drivers, storage, serial ports).
The plain embpilot command starts the MCP stdio server and waits for an MCP
client; it is not an interactive shell.
To configure another project without changing directories:
embpilot install --project-dir path/to/project
Non-interactive examples:
embpilot install --target claude,codex,zcode,opencode --location global
embpilot install --target claude,opencode --location local --project-dir .
embpilot install --yes # auto-detect targets, global scope
Supported installation surfaces:
| Harness | Global | Local project |
|---|---|---|
| Claude Code | ~/.claude.json, ~/.claude/CLAUDE.md, ~/.claude/skills/embpilot-device-debugging/SKILL.md |
.mcp.json, .claude/CLAUDE.md, .claude/skills/embpilot-device-debugging/SKILL.md |
| Codex | ~/.codex/config.toml, ~/.codex/AGENTS.md, ~/.codex/skills/embpilot-device-debugging/SKILL.md |
Not supported |
| ZCode | ~/.zcode/cli/config.json + registered embpilot-device-debugging skill |
Not supported |
| OpenCode | ~/.config/opencode/opencode.jsonc, AGENTS.md, skills/embpilot-device-debugging/SKILL.md |
opencode.jsonc, AGENTS.md, .opencode/skills/embpilot-device-debugging/SKILL.md |
OpenCode follows XDG_CONFIG_HOME when set. ZCode installs its confirmed MCP
entry plus an enabled embpilot-device-debugging skill; because no verified
global instruction path is available, it does not receive a separate marker
hook.
MCP Client Configuration
Configure your agent to start EmbPilot as an MCP server:
{
"mcpServers": {
"embpilot": {
"command": "embpilot",
"args": ["--data-dir", "./.embpilot-data"]
}
}
}
Agents should use EmbPilot before raw ssh, telnet, or serial clients. Pick
the protocol-specific tool and pass an actual JSON object, not an encoded JSON
string or a nested config object:
{"port":"COM3","baudrate":115200}
{"host":"192.168.1.10","username":"root","key_file":"~/.ssh/id_ed25519"}
{"host":"192.168.1.10","port":23}
These map to connect_serial, connect_ssh, and connect_telnet. Then use
send_command; set expect_regex, timeout_ms, or line_ending when the
target requires them. Connection successes and runtime failures include
structured JSON for agents as well as readable text. Invalid arguments remain
MCP invalid-parameter errors so clients can repair the call.
An empty command with line_ending="as-is" or "none" is rejected before it
reaches a transport. To send only Enter/a blank line, use line_ending="lf",
"crlf", or "cr" as required by the target.
Current resource direction:
device://live_logexposes the active session's recent log snapshot and is currently a snapshot resource. EmbPilot does not advertise subscriptions until it sends MCPnotifications/resources/updatedevents.device://session_infoexposes honest session metadata for the current connection instead of pretending EmbPilot can issue one generic sysinfo probe across all targets.
Safety defaults:
- SSH uses AsyncSSH host-key defaults unless
known_hosts: nullis explicitly passed in the connection config. - Destructive actions such as
reset_target, dangerous commands, session deletion, and RAG document deletion require explicit confirmation flags. - Operation audit export redacts sensitive config keys and inline command secrets such as passwords, tokens, Authorization headers, and AT Wi-Fi passwords.
- Safety limits can be tuned from the CLI with flags such as
--command-timeout-max-ms,--export-limit-max, and--tool-rate-limit-per-minute; MCP tool schemas are generated from those configured limits.
Project Status
Alpha — active development.
Architecture
src/embpilot/
├── __main__.py # Python module entry point
├── cli.py # CLI argument parsing and startup wiring
├── mcp_app.py # MCP app assembly and stdio server runner
├── config.py # Configuration (XDG paths, framing timeout, retention)
├── server.py # Compatibility wrapper over the new MCP runner
├── runtime/
│ ├── __init__.py
│ ├── models.py # SessionInfo plus canonical log/ring exports
│ ├── pipeline.py # Dispatcher-based log fan-out and framing
│ ├── expect.py # Command windows and expect matching
│ ├── resources.py # device://live_log and device://session_info payloads
│ └── session.py # Session lifecycle and active connection state
├── core/
│ ├── engine.py # Canonical LogLine/RingBuffer types
│ ├── database.py # SQLite WAL layer and schema loading
│ ├── rag.py # fastembed + LanceDB vector search
│ ├── schema_main.sql
│ └── schema_session.sql
└── drivers/
├── base.py # Abstract device interface
├── serial_dev.py # pyserial-asyncio
├── telnet_dev.py # telnetlib3
└── ssh_dev.py # asyncssh
mcp_app.pyowns MCP protocol registration and delegates runtime behavior to theruntime/package.runtime/pipeline.pynow uses explicit dispatcher fan-out instead of the old implicit multi-consumer queue description.- Driver implementations expose a byte-oriented runtime contract. Text-mode
transports such as Telnet and SSH adapt their library streams internally, so
the log pipeline always receives bytes before frame assembly.
send_commandaccepts an explicitline_endingstrategy (as-is,none,lf,crlf,cr) for targets which require a specific terminator. - Session logs store inferred
levelandtagmetadata and are indexed through SQLite FTS5 for historical search.search_history_logsdefaults tomode="fts"and also supportsmode="substring"for literal partial-token searches such as register names, paths, and abbreviated error fragments.
License
MIT
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 embpilot-0.1.1.tar.gz.
File metadata
- Download URL: embpilot-0.1.1.tar.gz
- Upload date:
- Size: 56.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c17e1dcffbbb104b33f5c6adc68a88ac553bcfa42ea5d9bac5b8f8a915b256e
|
|
| MD5 |
6302bca995791afe71b56295a5e1a8ce
|
|
| BLAKE2b-256 |
0982408ec1bff3c60207d46bbf331c2f9c3f80d4faf58697048450dd831d21a1
|
File details
Details for the file embpilot-0.1.1-py3-none-any.whl.
File metadata
- Download URL: embpilot-0.1.1-py3-none-any.whl
- Upload date:
- Size: 55.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b027e83db3f88af36f25d06fb939666423f8b509d827cab1f1b1508c361558cf
|
|
| MD5 |
bee73a6069de650a5ab755e431089104
|
|
| BLAKE2b-256 |
76b0f0affade18ac6cb79975661dae1071623280d961752549a68d6ada1d6ec0
|