Skip to main content

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)
  • Browse recent live logs through MCP resources
  • Persist sessions in SQLite (WAL mode) for RAG-backed historical search
  • Local vector search (fastembed + LanceDB) over Datasheets, Error Code manuals, and KB articles
  • Analyse crash logs and run hardware sanity checks with guided prompts

Quick Start

pip install embpilot
embpilot --help

Install local RAG support only when needed:

pip install "embpilot[rag]"

EmbPilot is a stdio MCP server, so starting embpilot directly waits for an MCP client rather than opening an interactive terminal.

Command Line Interface

embpilot starts the stdio MCP server by default, and also exposes every MCP tool through a thin CLI that shares the exact same dispatch layer:

embpilot --help                    # server by default; subcommands for tools
embpilot tools                      # list available tools
embpilot tool connect_serial --json '{"port":"COM3","baudrate":115200}'
embpilot tool send_command --json '{"command":"help","line_ending":"crlf"}'
embpilot tool list_sessions
embpilot shell                      # interactive REPL with a persistent session
embpilot batch                      # scripted JSONL mode: one request per stdin line
embpilot serve                      # persistent daemon sharing one session across calls
embpilot serve --daemon             # detach into the background (writes daemon.pid)
embpilot --socket daemon.json tool list_sessions   # talk to a running daemon

Agent Harness Installation

Wire EmbPilot into the agents you use — MCP config where the harness supports it, plus a marker-fenced instructions block (and the pi skill) where it does not. Modeled on CodeGraph's installer; the block lists both the MCP tools and their CLI equivalents, so an agent whose MCP server fails to start falls back to the CLI automatically:

embpilot install                      # interactive: pick targets/scope, confirm files
embpilot install --target pi          # pi: AGENTS.md instructions + user skill
embpilot install --target claude      # Claude Code: .mcp.json + CLAUDE.md
embpilot install --target dsh         # DeepSeek Harness: MCP patch layer + instructions + skill
embpilot install --target agents      # project AGENTS.md (Cursor/Codex/Gemini/...)
embpilot install --target all --location global --yes   # non-interactive, no prompts
embpilot install --check              # report state, write nothing (exit 0/1)
embpilot install --print-config claude   # show the manual snippet, write nothing
embpilot uninstall --target pi        # remove only what install wrote

With no --target, install/uninstall run interactively: harnesses are detected and pre-checked, you pick targets and scope, and nothing is written until you confirm the exact file list. --yes skips every prompt for scripting.

Targets: claude (MCP + CLAUDE.md), zcode (MCP + skill + AGENTS.md), opencode (MCP + AGENTS.md), codex (TOML MCP + AGENTS.md, global), pi (CLI-only: AGENTS.md + skill copied into ~/.pi/agent/skills/), agents (project AGENTS.md), dsh (DeepSeek Harness: MCP bridge merged into the $DSH_HOME/cordis.patch.yml user patch layer that applies to every profile, instructions into $DSH_HOME/AGENTS.md / project AGENTS.md, and the skill copied into $DSH_HOME/skills/ globally or .dsh/skills/ locally; dsh exposes the tools as mcp__embpilot__<name>). --location local writes project files, --location global writes user-scope files; --check reports state without writing and exits 0 when everything selected is configured.

batch reads one request object per stdin line ({"tool": "connect_serial", "args": {"port": "COM3"}}) and prints one result envelope per stdout line, without any banner; add --fail-fast to stop at the first failing call. serve keeps a single session manager alive so connect survives across separate invocations: start it once, then pass --socket <daemon.json> (or a unix:PATH / tcp:HOST:PORT endpoint) to tool / tools / batch. POSIX uses a unix socket; Windows falls back to a TCP loopback bound to 127.0.0.1 because the standard library has no named-pipe server API. The daemon refuses to bind any non-loopback TCP address: it is a local-only, unauthenticated service — anything that can reach the socket can send commands to the attached device.

read_output observes device output without sending any bytes; it returns early when expect_regex matches or after duration_ms, which is how boot logs and periodic device output are captured passively.

Tool arguments also accept schema-driven flags instead of inline JSON:

embpilot tool connect_serial --port COM3 --baudrate 115200 --line-ending crlf
embpilot help connect_serial            # schema, examples, guidance for one tool

run connects, executes several commands, and disconnects in one call:

embpilot run --connect '{"port":"COM3"}' help version uname -a

search_history_logs accepts an optional session_id so closed sessions can be searched after disconnection (list_sessions shows the ids).

One-shot tool calls exit 0 on success, 1 on tool failure, and 2 on usage or argument errors. Pass --json-output to print the structured ok/data/error envelope instead of readable text. In the shell, connect once and then keep issuing tool calls against the same active session. monitor streams new device log lines (prefixed [log]) while commands stay usable (results prefixed [cmd]); type stop to leave monitor mode. Data path options (--data-dir, etc.) must appear before the subcommand:

embpilot --data-dir ./.embpilot-data tool list_sessions

MCP Client Configuration

Configure the client to start the installed executable; do not copy a developer-specific absolute path:

{
  "mcpServers": {
    "embpilot": {
      "command": "embpilot",
      "args": ["--data-dir", "./.embpilot-data"]
    }
  }
}

Prefer connect_serial, connect_ssh, or connect_telnet. Arguments are JSON objects, not JSON strings:

{"port":"COM3","baudrate":115200,"line_ending":"crlf"}
{"host":"192.168.1.10","username":"root","key_file":"~/.ssh/id_ed25519"}

send_command accepts line_ending, expect_regex, timeout_ms, and max_output_chars. Results contain structured ok, data, or error fields alongside readable text. SSH host-key verification is enabled by default.

Project Status

Alpha — active development.

Architecture

src/embpilot/
├── __main__.py        # CLI entry point
├── cli.py             # CLI subcommands: tools, one-shot tool calls
├── cli_shell.py       # Interactive REPL reusing the MCP dispatch layer
├── cli_format.py      # Terminal result formatting
├── config.py          # Configuration (XDG paths, framing timeout)
├── server.py          # MCP Tools / Resources / Prompts registration
├── core/
│   ├── engine.py      # Frame assembly, ring buffer, Expect engine
│   ├── commands.py    # Command line endings, expect, and output capture
│   ├── database.py    # SQLite WAL layer
│   ├── rag.py         # fastembed + LanceDB vector search
│   └── schema_*.sql   # Main/session DDL
└── drivers/
    ├── base.py        # Abstract device interface
    ├── serial_dev.py  # pyserial-asyncio
    ├── telnet_dev.py  # telnetlib3
    └── ssh_dev.py     # asyncssh

Agent routing guidance is bundled in .agents/skills/embpilot-device-debugging/.

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

embpilot-0.3.1.tar.gz (90.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

embpilot-0.3.1-py3-none-any.whl (77.6 kB view details)

Uploaded Python 3

File details

Details for the file embpilot-0.3.1.tar.gz.

File metadata

  • Download URL: embpilot-0.3.1.tar.gz
  • Upload date:
  • Size: 90.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.7

File hashes

Hashes for embpilot-0.3.1.tar.gz
Algorithm Hash digest
SHA256 31c961d44c16a1019812d4d27fed48606ce7f231f595fd6afe68c6fb0209bb25
MD5 e3b9d65d586ae8192eca2872e54d1c77
BLAKE2b-256 a48bca235d66c9a97780ba43e77ec6caa667f37efbddd0334e3c0ed5bc663668

See more details on using hashes here.

File details

Details for the file embpilot-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: embpilot-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 77.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.7

File hashes

Hashes for embpilot-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 dd8d3cc3685d2746f2ed9bd236163a93375ee04f7a418ce059d29e77bc17f7aa
MD5 078a075ae7e5a6eb8651d18372a1a76c
BLAKE2b-256 ae867a9ad2d6c371dfacbd64c96602bfa68a975668861554d62a393a1a12816e

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page