adb-ai
<p align="center">
<img src="docs/img/brasil.gif" alt="Bandeira do Brasil / Flag of Brazil" width="640">
</p>
<p align="center">
π§π· <strong>Proudly made by Brazilians Β· Feito com orgulho por brasileiros</strong> π§π·
</p>
# ADB-AI π§π·
**Say it out loud. The room does the rest.**
> *"put on YouTube on the TV"*
> *"pause whatever is playing"*
> *"what's on the living-room screen?"*
> *"set an alarm for 7:30 on my phone"*
ADB-AI plugs the Android devices you already own β the TV, the TV box, the
phone, the tablet β into the AI agent you already use. You ask for something in
your own words; the device does it. No new hardware, no cloud account, no
vendor's app: just the debugging bridge your devices have shipped with for
fifteen years, wrapped so an agent can hold the remote.
It is the closest thing to a Jarvis for your living room that you can set up in
five minutes, on devices you already have.
[Install](docs/INSTALL.md) Β· [Tutorial](docs/TUTORIAL.md) Β· [What it can do](docs/RECIPES.md) Β· [Use with an AI agent](docs/AGENTS.md) Β· [How it works](docs/HOW-IT-WORKS.md) Β· [Troubleshooting](docs/TROUBLESHOOTING.md) Β· [Leia em portuguΓͺs](README.pt-BR.md)

### See it drive two devices at once
The agent searches YouTube for "eminem" on the TV while, on the phone, it opens
Termux, runs `pkg update`, and sets a 15-minute timer β all from one session.

One dependency-free Python package, identical on Windows, Linux, macOS and
Termux, with three ways in:
- an **MCP server** β for Claude, Codex, Cursor, or anything else that speaks
MCP. This is the one that makes the quotes above work.
- a **Claude Code skill** β the same thing for people who would rather their
agent drove the command line.
- a **CLI** you can use on its own: `adb-ai open netflix`. Scriptable, and
handy for checking something works before an agent touches it.
## It really works like that
A TV's launcher, a phone's calculator driven only by taps, and a timer set from
the command line β all captured through ADB-AI itself:
| | |
|---|---|
|  |  |
| The TV menu you drive with `home`, `down`, `ok` | `144 Γ· 12`, typed with `adb-ai tap` |
|  |  |
| `adb-ai timer 10m --label ADB-AI` | `adb-ai text` into a new note |
## Requirements
**Python 3.9+** and the **`adb` binary**. That is all β `requirements.txt` is
deliberately empty of packages, because everything here is standard library.
But **adb is not a Python package**, so `pip` cannot install it:
| System | Command |
|---|---|
| Termux | `pkg install android-tools` |
| Debian/Ubuntu | `sudo apt install adb` |
| Fedora | `sudo dnf install android-tools` |
| Arch | `sudo pacman -S android-tools` |
| macOS | `brew install android-platform-tools` |
| Windows | `winget install Google.PlatformTools` |
**Optional: `scrcpy`**, and only for `adb-ai mirror` and `adb-ai record` β
watching the screen live in a window. Nothing else needs it.
| System | Command |
|---|---|
| Debian/Ubuntu | `sudo apt install scrcpy` |
| Fedora | `sudo dnf install scrcpy` |
| Arch | `sudo pacman -S scrcpy` |
| macOS | `brew install scrcpy` |
| Windows | `winget install Genymobile.scrcpy` |
| Termux | **not supported** β see below |
**Optional: `ffmpeg`**, for agents. With it, a screenshot that would be
megabytes is scaled down before the model sees it β the picture arrives sooner
and says the same thing. `pkg install ffmpeg`, `sudo apt install ffmpeg`,
`brew install ffmpeg`, `winget install Gyan.FFmpeg`. Unlike scrcpy, it works on
Termux too. Without it nothing breaks: screenshots go full size, as before.
**scrcpy does not work from Termux.** It is not in the default repo, and the
X11 route does not get it running either; mirroring a phone onto the same phone
is not what it is for. `adb-ai` says so plainly instead of handing you an SDL
error, and everything else works there β on a phone, `adb-ai shot` is how you
see a screen. To mirror, run `adb-ai` from a desktop on the same network.
`adb-ai doctor` checks the lot at any time, and tells you how to fix whatever
is missing on your system:
```console
$ adb-ai doctor
adb-ai 0.1.0 on Linux (Linux-6.8.0-x86_64-with-glibc2.39)
[ok ] Python 3.12.3
[ok ] adb found
/usr/bin/adb
[ok ] Android Debug Bridge version 1.0.41
[warn] no devices connected
'adb-ai scan' looks for them on your network
[ok ] config: /home/you/.config/adb-ai/config.json
default device: none set | aliases: none
[ok ] scrcpy found - scrcpy 3.1
/usr/bin/scrcpy
ready to go.
```
If adb lives somewhere unusual, point `ADBAI_ADB` at the binary.
## Install
```bash
git clone https://github.com/cyberpunk2183/adb-ai
cd adb-ai
```
Then pick one:
```bash
./install.sh # Linux, macOS, Termux - installs what is missing, asks first
.\install.ps1 # Windows (PowerShell)
pip install . # if you already have adb and would rather do it yourself
```
Add `--check` (`-Check` on Windows) to see what is missing without changing
anything. No install at all is fine too β `python -m adbai ...` works straight
from the clone.
Step-by-step for each system, including turning on debugging on the device:
**[docs/INSTALL.md](docs/INSTALL.md)**.
## Plug it into your agent
This is the point of the project: one line, and your agent can drive your
devices.
**Claude Code**
```bash
claude mcp add adb-ai -- adb-ai mcp
```
**Claude Desktop** β `claude_desktop_config.json`
```json
{ "mcpServers": { "adb-ai": { "command": "adb-ai", "args": ["mcp"] } } }
```
**Codex CLI** β `~/.codex/config.toml`
```toml
[mcp_servers.adb_ai]
command = "adb-ai"
args = ["mcp"]
```
**Cursor** β `~/.cursor/mcp.json`
```json
{ "mcpServers": { "adb-ai": { "command": "adb-ai", "args": ["mcp"] } } }
```
Any other MCP client takes the same shape: run `adb-ai mcp`, talk JSON-RPC over
stdio. Twenty-two tools arrive β scan, connect, keys, taps and swipes, apps,
URLs, YouTube search, alarms, timers, volume, power, state, screenshots
(returned as an image the model can look at), a live mirror of the screen for
you to watch, and a full shell.
Then just ask, in whatever words you use at home:
> *put on YouTube on the TV*
> *pause whatever is playing*
> *what's on the living-room screen?*
> *set an alarm for 7:30 on my phone*
Using Claude Code and prefer it to drive the CLI directly? Copy the skill:
```bash
mkdir -p ~/.claude/skills && cp -r skills/adb-ai ~/.claude/skills/
```
Details, per-client paths and troubleshooting: **[docs/AGENTS.md](docs/AGENTS.md)**.
## Turn on debugging on the device
This is the step people get stuck on.
- **Android TV / TV box:** Settings β Device Preferences β About β click
*Build* seven times β back β Developer options β enable **Network debugging**
(sometimes *ADB debugging* / *USB debugging*).
- **Phone or tablet:** Settings β About β tap *Build number* seven times β
Developer options β enable **Wireless debugging**. Android 11 and newer want
a one-time pairing first, and the shortest way through it is the camera:
```bash
adb-ai pair # draws a QR; the phone scans it and pairs itself
adb-ai pair --mirror # the same, and the screen opens when it connects
```
On the phone: *Wireless debugging β Pair device with QR code*. Nothing to
type β no IP, no port, no six digits. It pairs and connects in one go.
(`adb-ai pair <ip>:<port> <code>` still does it the typed way.)
`--mirror` carries straight on into scrcpy, so a new phone goes from a QR
code to a window on your desk in one command. It works the same on
`adb-ai scan --mirror` and `adb-ai connect <ip> --mirror`. scrcpy is
optional, so when it is missing β and under Termux, where it cannot run at
all β the pairing is still reported and only the window is skipped.
- **USB first, wireless after:** plug it in, run `adb tcpip 5555`, unplug, then
`adb-ai scan`.
The first connection shows a dialog on the device asking you to allow this
computer. Say yes and tick *always allow*, or nothing will connect.
## Commands
```
adb-ai devices list what adb knows about
adb-ai scan [192.168.0.] find devices on the local network
--mirror connect to the one found and watch it
adb-ai pair pair an Android 11+ phone by QR code
--png code.png write the code to a file instead
--mirror open scrcpy the moment it connects
adb-ai connect <ip> [--alias tv] connect, optionally remember the name
--mirror open scrcpy once connected
adb-ai use <alias|serial> set the default device
adb-ai alias [name] [target] name a device, or list the names
adb-ai key home | ok | play | ... press keys, in order; -n repeats
--pace 120 one call per key, for menus that drop them
adb-ai keys list every key name
adb-ai text "hello there" type into the focused field
adb-ai apps [--all] installed packages
adb-ai open netflix launch by alias, package or fragment
adb-ai close netflix force-stop
adb-ai url <url> [--app <pkg>] open a URL or deep link
adb-ai youtube <query> search YouTube, no on-screen keyboard
adb-ai state [--json] foreground app, screen, playback
adb-ai shot [out.png] screenshot ('-' writes to stdout)
--max-size 1024 scale it down (needs ffmpeg)
adb-ai mirror [--view-only] watch the screen live (needs scrcpy)
adb-ai record [out.mp4] record the screen, no window
adb-ai volume up|down|mute|set N volume
adb-ai off | on sleep or wake the screen
adb-ai doctor check Python, adb, devices and config
adb-ai shell <cmd> raw adb shell, for anything not covered
adb-ai mcp run the MCP server on stdio
```
Every command takes `-d <alias|serial>`; without it, the default device is used.
`ADBAI_DEVICE` works too.
## Use it from an AI agent
### MCP server (Claude Desktop, Cursor, any MCP client)
```json
{
"mcpServers": {
"adb-ai": {
"command": "adb-ai",
"args": ["mcp"]
}
}
}
```
In Claude Code: `claude mcp add adb-ai -- adb-ai mcp`.
Twenty-two tools, including `adb_scan`, `adb_connect`, `adb_key`, `adb_tap`,
`adb_open_app`, `adb_mirror`,
`adb_youtube_search`, `adb_state`, `adb_screenshot` and `adb_volume`. The
screenshot comes back as an image the model can actually look at.
`adb_shell` runs **any** shell command on the device β `dumpsys`, `pm`, `am`,
`settings`, `content`, the lot β as the shell user, with no root. That is
deliberate: it is what makes an agent able to do the things the other tools
do not cover. It is also the one tool that can change a device in ways you did
not ask for, so if that is too much for your setup, switch it off:
```json
{ "mcpServers": { "adb-ai": {
"command": "adb-ai", "args": ["mcp"],
"env": { "ADBAI_NO_SHELL": "1" }
} } }
```
### Claude Code skill
```bash
mkdir -p ~/.claude/skills && cp -r skills/adb-ai ~/.claude/skills/
```
Then just ask: *"pause the TV"*, *"what's on the living-room screen?"*, *"open
Spotify and play something quiet"*. See [`skills/README.md`](skills/README.md).
## Why not just use `adb` directly?
Because the details bite:
- **DHCP moves your devices.** `adb-ai scan` finds them again with plain
sockets β no nmap, works the same on Windows and Termux.
- **Some devices corrupt their own screenshots.** Several Android TV builds
print driver noise on stdout before the PNG; a naively saved file is broken.
`adb-ai shot` always cuts to the PNG magic bytes.
- **Not every device has a working `grep`.** Output is parsed on your machine
in Python. `state` tries the device's own `grep` first, because it is the one
command an agent runs constantly, and silently falls back to parsing the full
dump when the device cannot do it β nothing *depends* on a device-side pipe.
- **Key codes and package names are not memorable.** `adb-ai key ok` beats
`adb shell input keyevent KEYCODE_DPAD_CENTER`, and `adb-ai open netflix`
finds `com.netflix.ninja` or `com.netflix.mediaclient`, whichever is there.
- **"Did it work?"** `adb-ai state` answers in one call: foreground app, screen
state, and whether media is actually playing.
## Scope, and a word of warning
This is a remote control, not a jailbreak. It drives devices **you own and have
enabled debugging on**, over your own network. It does not bypass licence
checks, paywalls or account restrictions.
It also cannot reach a device nobody opened up: ADB debugging lives behind a
hidden menu and a trust dialog that someone has to accept on the device's own
screen, in person.
That said β **any tool that controls devices over a network can be misused**,
and this one is no exception: `scan` sweeps a subnet, and controlling many
devices is this tool in a loop. The authors do not support that use and accept
no responsibility for it. Please read **[DISCLAIMER.md](DISCLAIMER.md)** before
using ADB-AI; the short version is:
- use it only on devices you own or are authorised to administer;
- **ADB over TCP is unauthenticated** once allowed β never expose port 5555 to
the internet, and turn debugging off when you are done;
- it comes with **no warranty**; you run it, you own the outcome.
**Pointing it at a phone is a bigger decision than pointing it at a TV.** ADB
access to a phone is the same reach you have when it is unlocked in your hand β
any app, any text field, a screenshot of anything on screen, one-time codes
included. See [Phones are not TVs](DISCLAIMER.md#phones-are-not-tvs).
Security policy and hardening checklist: **[SECURITY.md](SECURITY.md)**.
## Development
```bash
python -m unittest discover -s tests # 24 tests, no device needed
ruff check .
```
Pull requests welcome β especially app aliases for services outside Brazil and
the US, and fixes for device quirks like the screenshot one above.
## Licence
MIT Β© 2026 cyberpunk2183 π§π·
TDQS
Scored across 24 tools
Most tools have clearly distinct purposes, including separate pairing, connection, input, app, and device-state operations. Some overlap exists between convenience tools and lower-level ones, such as adb_scroll vs adb_swipe, adb_volume vs adb_key volume keys, and adb_power vs adb_key power/sleep/wake, but the descriptions generally clarify when to prefer each.
All tool names share a consistent adb_ prefix and snake_case formatting, making the set easy to scan. The main inconsistency is that many names are noun-style resource tools (adb_state, adb_screenshot, adb_volume) while others are verb-first actions (adb_open_app, adb_list_apps, adb_set_alarm).
At 24 tools, the surface is heavy and includes several convenience wrappers that could be folded into broader tools. The domain is broad enough to justify many operations, but this sits in the borderline 16-25 range rather than being tightly scoped.
The server covers device discovery, pairing, connection, input, app control, media/search, alarms/timers, screenshots, state inspection, power, volume, mirroring, and arbitrary shell access. Dedicated tools for file transfer, app install/uninstall, reboot, or screen recording are missing, but adb_shell provides a workaround for most gaps.