FlipperTalk
# FlipperTalk
Talk to your **Flipper Zero** from Claude Code — or any [MCP](https://modelcontextprotocol.io)
client. Storage, app deployment, screen capture, button automation, **JavaScript
execution on the device**, and honest answers about what is nearby.
The possibilities are endless as this gives your AI instance full Flipper capabilities.
**Momentum-first**, with Unleashed, RogueMaster and official firmware supported.
One third-party dependency. No network access. Destructive operations hidden by
default.
```
"Deploy my app and show me the settings screen."
-> flipper_deploy_fap (upload, md5-verify, launch)
-> flipper_input_sequence ["DOWN","DOWN","OK"] screenshot: true
-> [the actual device screen comes back as an image]
```
## Why this exists
qFlipper is the official desktop app, and it has not shipped a feature since
**November 2023** (its last commit, June 2024, was *"Fixing windows build"*).
Firmware reached **1.4.3** in December 2025. In that gap it gained a JavaScript
engine, dynamic app loading, a rewritten NFC stack, self-update, and a much
larger CLI. qFlipper exposes none of it, and has no IPC, socket or daemon to
attach to anyway.
FlipperTalk targets the **firmware** instead, speaking both protocols the device
actually offers over USB serial:
1. **The text CLI** — the interactive `>: ` shell
2. **The protobuf RPC** — screen capture, binary-safe transfer, synthetic input
`qFlipper-cli` is invoked only for DFU/bootloader recovery, the one thing it
still uniquely does.
> **The serial port is exclusive.** The qFlipper desktop app holds it while
> connected, so the two cannot use the device at once. Close qFlipper if a tool
> reports the port is busy, and call `flipper_disconnect` to hand it back.
## Custom firmware is a first-class target
The forks are not skins — each maintains its own protobuf and diverges from
official firmware (whose `Main.content` tops out at tag 75):
| Firmware | Protobuf divergence | What FlipperTalk does with it |
|---|---|---|
| **Momentum** | `gui_send_ascii_event_request` @100; `ScreenFrame` gains `bg_color`/`fg_color` | `flipper_type_text` types strings directly; screenshots use your actual theme colours |
| **RogueMaster** | identical to Momentum (it tracks *Momentum's* protobuf, not Unleashed's) | same as Momentum |
| **Unleashed** | `PB_Network` (TCP/HTTP/WebSocket) and `PB_Gps`, tags 76–90 | GPS position in sensing; network tools exist but are **off by default** |
All three dialects are merged into one schema — the tag ranges do not collide —
so decoding is correct whatever is attached. Firmware detection then decides
which *tools* you are offered, so you never see one your device cannot honour.
Momentum's JavaScript engine is also materially bigger, adding `subghz`,
`blebeacon`, `i2c`, `spi`, `usbdisk`, `widget` and `vgm` on top of the official
module set.
## Install
Requires Python 3.10+ and a Flipper Zero on USB with a data-capable cable.
```bash
git clone https://github.com/ReconGrunt/FlipperTalk
cd FlipperTalk
python -m venv .venv
.venv/Scripts/activate # Windows
# source .venv/bin/activate # macOS / Linux
pip install --require-hashes -r requirements.lock
pip install -e . --no-deps
```
`--require-hashes` pins every artifact by SHA-256. See [SECURITY.md](SECURITY.md).
```bash
python -m flippertalk_mcp --list-tools # see what your config exposes
```
### Claude Code
```bash
claude mcp add flippertalk --scope user -- /absolute/path/to/.venv/bin/python -m flippertalk_mcp
```
### Claude Desktop / any `mcpServers` client
```jsonc
{
"mcpServers": {
"flippertalk": {
"command": "/absolute/path/to/.venv/bin/python",
"args": ["-m", "flippertalk_mcp"]
}
}
}
```
On Windows use `C:\path\to\.venv\Scripts\python.exe`.
## Running JavaScript on the device
The most flexible thing here. Firmware 1.0+ embeds mJS, and — critically —
*"all output from `print()` is sent to the CLI, not the device screen"* when a
script is launched this way. So Claude can write code, run it, and read results.
```
flipper_run_js { source: 'print("battery: " + require("flipper").getBatteryCharge());' }
```
Scripts reach GPIO, UART, notifications, BadUSB, GUI and storage — plus Momentum's
extra modules. Call `flipper_js_probe` first; it reports which modules actually
resolve on the attached firmware rather than assuming.
## "What's nearby?" — and what that honestly means
`flipper_scan_nearby` sweeps every source the hardware genuinely supports and
returns structured results plus a plain-language summary.
**It will not pretend.** Sources that could not run are reported as *not
checked, with a reason* — never as "nothing found":
| Source | Reality |
|---|---|
| Sub-GHz | genuine over-the-air; Momentum/Unleashed widen the tunable range |
| NFC / RFID / iButton | **contact range** — the card must be on the reader |
| i2c / 1-Wire | wired to the GPIO header |
| GPS | Unleashed only |
| **BLE** | **no firmware can scan for it.** Stock `bt` is `hci info`; Momentum's `blebeacon` transmits. Needs a scanner app or an ESP32 devboard |
| **WiFi** | **no radio on the device.** Needs an ESP32 devboard |
Summaries state observations, not conclusions — *"strong signal at 433.92 MHz"*,
never *"someone is tracking you"*. Run `flipper_sense_capabilities` to see the
limits for your specific device.
## Tools
66 by default across seven groups. `flipper_cli` remains the escape hatch to any
firmware command.
**core** · devices, info, storage, upload/download, app launch and deploy,
screenshot, screen record, input, typing, virtual display, asset packs, clock
**js** · run/save/list scripts, module probe
**sense** · scan nearby, sense capabilities, app reports
**radio** · subghz, nfc, rfid, ibutton, infrared
**hw** · gpio, i2c, 1-Wire, led, vibro, buzzer, notify, BadUSB *(gated)*
**dev** · capabilities, diagnostics, log, Momentum settings
**firmware** · qFlipper-cli status/backup, native SD update, plus gated
flash/erase/wipe/restore
**network** · Unleashed HTTP, TCP connect/send/close, GPS — **off unless
explicitly enabled**
Device paths are absolute, starting `/ext` (SD card) or `/int` (internal).
### Trimming the surface
66 tools costs context in every session. Groups are selectable:
```bash
FLIPPERTALK_TOOLSETS=core,js,dev # 46 tools — app development
FLIPPERTALK_TOOLSETS=core # 38 tools — essentials only
FLIPPERTALK_TOOLSETS=all # everything, including network
```
Nothing is lost by trimming — `flipper_cli` still reaches every firmware command.
## For app developers
`flipper_deploy_fap` is the inner loop: upload a freshly built `.fap`, verify it
by md5, launch it.
```
ufbt
-> flipper_deploy_fap { local_path: "dist/myapp.fap" }
-> flipper_screen_record { frames: 8, keys: ["DOWN","OK"] }
```
Because screenshots return the real framebuffer, a model can *look at* what a UI
change renders instead of inferring it from source. `flipper_screen_record`
extends that to animations and transitions.
## Safety
Destructive operations are **hidden, not merely refused** — omitted from
`tools/list` entirely, so a model that never sees them cannot call them.
| Variable | Default | Effect |
|---|---|---|
| `FLIPPERTALK_TOOLSETS` | all but `network` | Which tool groups are exposed |
| `FLIPPERTALK_ALLOW_DESTRUCTIVE` | off | Firmware flash, erase, wipe, restore, recursive delete, DFU reboot |
| `FLIPPERTALK_READ_ONLY` | off | Withholds every mutating tool |
| `FLIPPERTALK_LOCAL_ROOTS` | unset | Confines host file access to an allowlist |
| `FLIPPERTALK_DIALECT` | auto | Force a firmware family if detection is wrong |
| `FLIPPERTALK_WRITE_CHUNK` | `512` | Bytes per storage-write chunk (64–4096) |
| `FLIPPERTALK_IDLE_TIMEOUT` | `120` | Seconds before an idle connection is released |
| `QFLIPPER_CLI` | auto | Explicit path to `qFlipper-cli` |
`QFLIPPER_MCP_*` names from v0.1 still work for one version.
Granting this server to a model is equivalent to handing over the device. Use
`FLIPPERTALK_READ_ONLY=1` if you only need inspection.
## Development
```bash
PYTHONPATH=src python -m unittest discover -s tests -v
```
278 tests, no hardware required. They cover the protobuf codec against
hand-computed golden byte vectors (including zigzag `sint32`, which Unleashed's
GPS coordinates need and which decodes silently wrong if mishandled), PNG output
decoded back and compared pixel by pixel, a full MCP handshake over stdio against
the server as a subprocess, the RPC layer against a fake device speaking the real
wire protocol, fork detection — including that RogueMaster must *not* be
misdetected as Unleashed — and the sensing rule that an unrun source is never
reported as empty.
`proto/{official,momentum,unleashed}/` are vendored from each fork's own repo as
reference for the field numbers in `pb.py`. They are never compiled or executed.
## Compatibility
Official 1.x, Momentum, Unleashed and RogueMaster. Unknown fields are skipped on
decode, so a firmware that adds messages still parses cleanly. Screen capture
assumes the standard 128x64 display.
## License
MIT — see [LICENSE](LICENSE).
Independent of Flipper Devices Inc. A clean-room implementation speaking a
documented wire protocol; it neither links nor derives from qFlipper's source.
TDQS
Scored across 66 tools
Most tools have clear, distinct purposes, but there is some overlap between file writing tools (upload vs write_file) and between notification tools (notify vs buzzer/vibro/led). However, overall agents can distinguish them with careful reading.
All tools use the consistent prefix 'flipper_' and snake_case. Most follow a verb_noun pattern, but a few like 'flipper_nfc' or 'flipper_subghz' are just nouns, creating minor inconsistency. Still, the naming is predictable and readable.
At 66 tools, the server is quite large. The scope justifies many tools given the Flipper Zero's versatility, but the count is above the typical sweet spot, making navigation heavier. A more consolidated approach could improve discoverability.
The tool set comprehensively covers all major Flipper Zero operations: hardware interfaces (NFC, RFID, iButton, Sub-GHz, Infrared, GPIO, I2C, 1-Wire), file management, app life cycle, scripting, diagnostics, and device information. There are no obvious gaps for the device's known capabilities.