cynthion-mcp

cynthion-mcp

Drive a Cynthion USB test instrument from an LLM via the Model Context Protocol. Sniff, decode, and emulate USB devices over chat.

Category
访问服务器

README

cynthion-mcp

Drive a Cynthion USB test instrument from an LLM via the Model Context Protocol. Sniff, decode, and emulate USB devices over chat.

Cynthion is an open-source USB test instrument built around an ECP5 FPGA. It can passively capture Low/Full/High-speed USB traffic, or impersonate a USB device on its TARGET port. This project exposes those capabilities to LLMs (Claude Desktop, Claude Code, any MCP-aware client) as a set of stdio tools so the model can perform end-to-end USB reverse engineering workflows.

What it does

                  ┌─ switch_mode('analyzer') ──────┐
                  │  capture_start                  │
plug in target ───┤  (target enumerates)            │
                  │  capture_stop                   │
                  └─ convert_to_pcap ───────────────┘
                                │
                                ▼
                  ┌─ transaction_summary ──────────┐
                  │  dissect_packets(filter, …)    │  ← LLM analyses,
                  │  find_vendor_requests          │    extracts descriptors,
                  └────────────────────────────────┘    spots protocol patterns
                                │
                                ▼
                  ┌─ switch_mode('facedancer') ────┐
                  │  emulator_diagnose             │
                  │  emulate_from_descriptor(…)    │  ← clone the device,
                  │  emulate_device('ftdi') etc    │    fuzz responses,
                  │  disconnect_device             │    replay vendor reqs
                  └────────────────────────────────┘

Three capability groups; the FPGA can only run one bitstream at a time and switch_mode flips between them transparently.

Mode Bitstream What the LLM can do
Sniffer analyzer.bit Passively capture USB traffic on TARGET-C ↔ TARGET-A
Decoder (host-side) Turn captures into structured per-packet records via tshark
Emulator facedancer.bit Impersonate a USB device on TARGET-C (clone, fuzz, MITM)

Prerequisites

  • A Cynthion USB test instrument (any r0.x or r1.x).
  • macOS / Linux. (Windows likely works but is untested.)
  • Python ≥ 3.10.
  • tshark on $PATH (the decoder tools shell out to it).
    • macOS: brew install wireshark
    • Linux: apt install tshark / dnf install wireshark-cli
  • A working luna + cynthion Python install. The simplest setup is two source clones sharing a venv (see Setup below).

Setup

# 1. Clone the dependencies and this project side-by-side
git clone https://github.com/greatscottgadgets/luna.git
git clone https://github.com/greatscottgadgets/cynthion.git
git clone https://github.com/Oliver0804/cynthion-mcp.git

# 2. Create a venv and install everything into it
python3 -m venv .venv
./.venv/bin/pip install -e ./luna
./.venv/bin/pip install -e ./cynthion/cynthion/python
./.venv/bin/pip install -e ./cynthion-mcp

# 3. Copy Cynthion's prebuilt bitstreams + Moondancer firmware into the source tree.
#    Without these, `cynthion run …` can't load the FPGA. They ship inside the
#    PyPI wheel; the source clone doesn't include them.
./.venv/bin/pip download cynthion --no-deps -d /tmp/cynthion-wheel
unzip /tmp/cynthion-wheel/cynthion-*.whl 'cynthion/assets/*' -d /tmp/cynthion-extracted
cp -r /tmp/cynthion-extracted/cynthion/assets/* ./cynthion/cynthion/python/assets/

# 4. Verify the board is reachable
./.venv/bin/cynthion info

⚠️ facedancer==3.1.1 is pinned. facedancer 3.1.2 changed the libgreat-RPC protocol that the Moondancer SoC firmware shipped in cynthion 0.2.4 speaks. The emulator tools will hang on connect() if you upgrade. Don't bump facedancer unless cynthion also ships a new firmware.

Register with Claude Code

claude mcp add -s user cynthion /absolute/path/to/.venv/bin/cynthion-mcp

Restart Claude Code (/exit and reopen). Seventeen tools appear under the mcp__cynthion__* namespace.

Register with Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "cynthion": {
      "command": "/absolute/path/to/.venv/bin/cynthion-mcp"
    }
  }
}

Restart Claude Desktop.

Tool reference

Hardware (3)

  • get_status() — current bitstream + USB enumeration state.
  • switch_mode(applet)"analyzer" / "facedancer" / "selftest". Handles JTAG-stuck recovery via Apollo soft_reset.
  • recover() — software unstick for handoff timeouts / USB glitches.

Sniffer (5)

  • capture_start(speed)"auto" (HS/FS/LS auto-detect on r0.6+), "high", "full", "low".
  • capture_stop() — returns byte count + duration.
  • capture_status() — peek at running capture's progress.
  • list_captures() — enumerate stored captures (~/.cynthion-mcp/captures/).
  • read_capture(capture_id, offset, length) — slice raw bytes as hex (debugging mainly).

Decoder (4) — tshark-backed

  • convert_to_pcap(capture_id) — Cynthion native .binLINKTYPE_USB_2_0 pcap. Idempotent.
  • dissect_packets(capture_id, display_filter, limit) — structured per-packet records. display_filter accepts full Wireshark display-filter syntax (usbll.pid == 0x96, usbll.device_addr == 16, etc).
  • transaction_summary(capture_id) — PID counts + device address counts at a glance.
  • find_vendor_requests(capture_id, limit) — preset filter for vendor-class SETUP packets — high-value targets when reversing proprietary protocols.

Emulator (5) — Facedancer

  • emulator_diagnose() — probe the Moondancer SoC's libgreat-RPC. Always call before other emulator tools.
  • emulate_device(device_type, vendor_id?, product_id?) — built-in templates: "ftdi" / "keyboard" ⚠️ / "vendor". The keyboard flavour injects keystrokes — only use intentionally.
  • emulate_from_descriptor(device_descriptor_hex, configuration_descriptor_hex?, strings?)device cloning: stand up an emulation built from raw descriptor bytes you pulled out of a capture. The closed-loop pairing with dissect_packets.
  • disconnect_device() — stop active emulation.
  • inject_serial(text) — push UTF-8 out an active FTDI emulation's bulk-IN endpoint.

Example session

A round-trip "clone an unknown USB device" prompt for Claude:

1. switch to analyzer mode
2. start a capture in auto speed
3. tell me when I should plug in the target — I'll do it after you say go
4. capture for 5 seconds after I plug it in, then stop
5. summarise the bus activity and list all unique device addresses you observed
6. dissect the DATA0/DATA1 packets that followed GET_DESCRIPTOR setups
   and pull out the 18-byte device descriptor and the config descriptor
7. switch to facedancer mode, diagnose, then emulate from those descriptors
8. tell me when the clone is up

What works on which devices

Cynthion's analyzer captures USB 1.1 / 2.0 (Low / Full / High speed). SuperSpeed (USB 3.x) lanes are not teed — but virtually every USB 3.x device falls back to USB 2.0 HS when only D+/D- is wired, so most still work.

Device class Sniff Clone via emulate_from_descriptor
HID — mouse / keyboard / gamepad 🟢 simple (descriptor + report)
Serial — FTDI / CH340 / CDC-ACM 🟢 built-in template
Mass storage (flash drive) ✅ — falls back to HS 🟡 needs SCSI command emulation (facedancer.devices.umass)
Webcam (UVC) ✅ HS 🔴 isochronous + complex descriptors
Audio (UAC) 🔴 isochronous
Printer / network adapter (CDC-ECM/RNDIS) 🟡 protocol-dependent
Vendor proprietary protocols 🟡 needs a vendor-request handler
Pure SuperSpeed-only (rare)

⚠️ Flash-drive caveat: a busy HS bulk transfer (~30–60 MB/s) overruns Cynthion's internal FIFO and the gateware emits CAPTURE_STOP_FULL. For RE work, sniff the enumeration phase only — re-plug the target, then immediately stop the capture once it's connected; don't actually read/write large files while capturing.

Known limitations / non-goals

  • Higher-layer dissection (HID, MSC, UVC class) only kicks in once the capture includes the device's enumeration. Re-plug the target while capturing for the richest tshark output.
  • SuperSpeed (USB 3.x) is out of scope — the analyzer applet doesn't observe SS lanes.
  • The HID keyboard emulator will inject keystrokes into whatever host is connected to TARGET-C. If that's the same machine running the MCP server, those keystrokes land in whichever app has focus. Use sparingly.

Architecture

cynthion-mcp/
├── pyproject.toml
└── src/cynthion_mcp/
    ├── server.py        # FastMCP entrypoint (17 tools)
    ├── hardware.py      # Apollo MCU + bitstream switching, JTAG-stuck recovery
    ├── capture.py       # analyzer.bit USB driver (vendor reqs + bulk drain)
    ├── decoder.py       # Cynthion native frame format → pcap LINKTYPE_USB_2_0
    ├── tshark.py        # tshark JSON wrapper + USB PID name table
    └── emulator.py      # Facedancer integration (diagnose, template + descriptor emulation)

The capture path drives the analyzer applet directly through libusb (vendor requests 0–4, bulk endpoint 0x81). Capture bytes are streamed to ~/.cynthion-mcp/captures/<id>.bin in the gateware's native frame format (big-endian 16-bit words, 4-byte event records and 4-byte packet headers, 16-bit-aligned). decoder.py re-frames those into a standards-compliant pcap so tshark's USB dissectors (and Wireshark / Packetry) can read them directly.

The emulator path goes through facedancer's Moondancer backend, which talks libgreat-RPC to the SoC firmware running on the FPGA.

Proof of working

See docs/HARDWARE-TEST-LOG.md for a detailed bring-up log: an LLM driving cynthion-mcp through the full reverse-engineering loop on a Cynthion r1.4 — sniffing a Logitech wireless receiver, identifying an unknown Edimax Bluetooth dongle from its descriptors alone (VID/PID/MAC), and emulating an FTDI device that macOS IOKit registers.

License

BSD 3-Clause — see LICENSE. Same as the upstream Cynthion / LUNA / facedancer projects.

Related projects

  • Cynthion — the hardware + host tools this builds on
  • LUNA — the Amaranth HDL USB gateware library
  • Facedancer — the USB device-emulation framework
  • Packetry — GUI viewer for Cynthion-format captures (consumes the same pcaps convert_to_pcap produces)

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选