Transports
August 9, 2026 · View on GitHub
Every CLI command, web session, and MCP invocation talks to the Flipper through a pluggable transport. Select one with the serial.transport_url config field, or the --transport CLI flag (flag overrides config).
Schemes
| Scheme | Example | When to use |
|---|---|---|
serial:// | serial:///dev/ttyACM0?baud=230400 | Default. USB CDC-ACM. Fastest + most reliable. |
ble:// | ble://AA:BB:CC:DD:EE:FF (Linux/Windows) ble://e127efc1-05ec-... (macOS) | Wireless. No cable. Slower (~2–8 kB/s) but every tool works. |
mock:// | mock:///dev/pts/5 | Test harness pty slave. Used by internal/flipper/mock. |
http:// / https:// | https://gateway:8080/?send_path=/uart/send&recv_path=/uart/recv | Remote / cloud. Drives a Flipper hosted behind a FlipperHTTP-compatible gateway (POST /uart/send, GET /uart/recv). Supports a Bearer token; endpoint paths overridable via query string. |
Note
Marauder supports BLE as well as serial. Serial (/dev/ttyUSB0-style, CP210x) is the default. A standalone ESP32-Marauder devboard also exposes a BLE serial GATT service (Nordic UART): select it with marauder.transport: ble in config or --marauder-ble <addr> on the CLI, where marauder.port is reinterpreted as a BLE MAC / UUID / local name. (The Flipper-UART-bridged Marauder is a separate mode.)
Serial (USB)
- Connection: USB CDC ACM (
/dev/ttyACM0on Linux,/dev/cu.usbmodem*on macOS,COM*on Windows). - Baud rate: irrelevant for CDC ACM virtual serial (set to 230400 by convention).
- DTR: asserted automatically.
- Command terminator:
\r(CR, 0x0D). - Prompt:
>:with ANSI escape stripping for subshells like[nfc]>:. - File writes: use
storage write_chunk(not interactivestorage write).
BLE (wireless)
The ble:// URL accepts three forms — picked automatically by shape:
| Form | Example | Where it works |
|---|---|---|
| Hardware MAC | ble://80:E1:26:69:6E:55 | Linux, Windows |
| CoreBluetooth UUID | ble://e127efc1-05ec-ce53-014e-b79fee9117fa | macOS only — UUID is per-Mac |
| Device LocalName | ble://Unholy | Any platform; fallback when above are inconvenient |
To find the right identifier:
promptzero --ble-discover
Scans for ~8 s and prints visible peripherals with name, address, and RSSI. Suggests the strongest-signal Flipper as a copy-pasteable URL.
Pairing
Linux (BlueZ) — the adapter needs to know the device before PromptZero can connect:
bluetoothctl scan on # until you see your Flipper
bluetoothctl pair AA:BB:CC:DD:EE:FF
bluetoothctl trust AA:BB:CC:DD:EE:FF
macOS — pair once via System Settings → Bluetooth so CoreBluetooth caches the identifier UUID. Subsequent connects take the direct fast path (retrievePeripherals(withIdentifiers:)) — no scan, no MAC lookup.
macOS hides hardware BLE MACs from apps for privacy. The address PromptZero uses is the per-Mac CoreBluetooth identifier UUID — stable on this Mac for the life of the pairing, but different on every other Mac. Re-run
--ble-discoverif you move the config to another machine.
Windows — pair via Settings → Bluetooth & devices. PromptZero uses the hardware MAC.
Limitations
- WSL cannot do BLE. Windows doesn't pass Bluetooth through to the Linux guest. Use USB +
usbipd, or run PromptZero natively on Windows. - Throughput is ~10× slower than USB. A
log_streamor longsubghz rxcapture is less responsive — but every wrapper works (the CLI protocol is identical over Flipper's serial GATT service). - Range is Bluetooth Class 2 normal (~10 m in practice).
All registered tools work unchanged over BLE — capabilities detection, NFC subshell, loader close-via-back-button, everything. The transport is the only thing that changes.
macOS build note
The upstream tinygo.org/x/bluetooth package needs CGO. The release pipeline builds darwin/amd64 + darwin/arm64 binaries on macOS runners with CGO_ENABLED=1, so the standard install.sh does the right thing.
Building from source on macOS:
CGO_ENABLED=1 GOOS=darwin go build ./cmd/promptzero
Cross-compiled darwin binaries from a Linux host ship a stub that returns a clear "rebuild on macOS with CGO" error when BLE is attempted.
WSL2 USB passthrough
USB devices aren't passed through to WSL by default. Install usbipd-win on Windows, then from an admin PowerShell:
usbipd list
usbipd bind --busid <BUSID> # one-time
usbipd attach --wsl --busid <BUSID>
The Flipper then appears as /dev/ttyACM0 inside WSL.
Mock transport
mock:///dev/pts/N connects to a pseudo-terminal slave. Used by internal/flipper/mock for hermetic transport tests — not relevant to operators.