adbmcp
Provides tools for interacting with Android devices through the Android Debug Bridge (adb), including listing devices, running shell commands, installing and uninstalling apps, reading logcat, taking screenshots, driving the UI with taps/swipes/typing/key events, querying system services with dumpsys, transferring files, forwarding ports, managing app permissions, and pairing/connecting over Wi-Fi.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@adbmcpscreenshot the screen of emulator-5554"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
adbmcp — Android Debug Bridge, as MCP tools
adbmcp is a Model Context Protocol server that exposes the
Android Debug Bridge (adb) to AI agents: list devices, run shell commands, install apps, read
logcat, take screenshots, drive the UI (tap/swipe/type/key events), query system services with
dumpsys, transfer files, forward ports, manage app permissions and pair/connect to devices over
Wi-Fi. It is a thin, predictable wrapper around the official
adb binary — no re-implemented adb protocol, no test framework, no extra state.
Multi-device first — every device-scoped tool takes an optional
deviceserial and every adb call is scoped withadb -s <serial>; ambiguity is an error listing the candidates.Failures an agent can act on — adb stderr/exit codes are mapped to typed causes (
NO_DEVICE,MULTIPLE_DEVICES,DEVICE_UNAUTHORIZED,DEVICE_OFFLINE,ADB_SERVER_CONFLICT,TIMEOUT,COMMAND_FAILED) with a hint for the next step.Safety by construction — full MCP annotations on every tool plus server-side guardrails that are enforced even if a host ignores annotations.
stdio transport — the client launches
adbmcpas a subprocess, the normal MCP deployment.
Implements the MVP plus v2.0 items 1–6 in docs/design/product-design-v0.md.
Install
Requires Node.js >= 20 and Android platform-tools (adb) on PATH — or ADB_PATH pointing at the
binary.
# from npm
npx -y @yhuangsh/adbmcp
# from a checkout
git clone https://github.com/yhuangsh/adbmcp.git && cd adbmcp
npm install
npm run build
node dist/index.js # speaks MCP on stdin/stdoutClaude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"adb": {
"command": "npx",
"args": ["-y", "adbmcp"],
"env": {
"ADB_PATH": "/Users/me/Library/Android/sdk/platform-tools/adb"
}
}
}
}Cursor (.cursor/mcp.json)
{
"mcpServers": {
"adb": {
"command": "node",
"args": ["/absolute/path/to/adbmcp/dist/index.js"],
"env": {
"ADBMCP_ALLOWED_DEVICES": "emulator-5554"
}
}
}
}Other clients work the same way: a command plus args, with ADB_PATH / ADBMCP_* environment
variables passed through. Diagnostics are written to stderr; stdout carries MCP traffic only.
Related MCP server: adb-tv-mcp
Tools
device is optional on every device-scoped tool and required when more than one device is connected.
Annotation columns: RO = readOnlyHint, D = destructiveHint, I = idempotentHint,
O = openWorldHint.
Tool | What it does | RO | D | I | O |
|
| ✅ | — | ✅ | — |
| Curated build properties (model, Android version, SDK, ABI) + screen size/density | ✅ | — | ✅ | — |
| Curated | ✅ | — | ✅ | — |
| Arbitrary | — | — | — | ✅ |
|
| ✅ | — | ✅ | — |
|
| — | — | — | — |
|
| — | ✅ | ✅ | — |
|
| — | ✅ | ✅ | — |
|
| — | ✅ | ✅ | — |
|
| — | ✅ | ✅ | — |
| Bounded | ✅ | — | ✅ | — |
| Start a long-lived | ✅ | — | — | — |
| Drain buffered output since the last read | ✅ | — | — | — |
| Stop the stream, return unread output | ✅ | — | ✅ | — |
|
| ✅ | — | ✅ | — |
|
| — | — | — | — |
|
| — | — | — | ✅ |
|
| — | — | ✅ | — |
|
| — | — | ✅ | — |
|
| — | — | ✅ | — |
|
| — | — | ✅ | — |
|
| ✅ | — | ✅ | — |
|
| ✅ | — | ✅ | — |
|
| — | — | ✅ | ✅ |
|
| — | — | ✅ | ✅ |
|
| — | — | ✅ | ✅ |
|
| — | — | — | — |
|
| — | — | ✅ | — |
|
| ✅ | — | ✅ | — |
|
| — | — | — | — |
|
| — | — | — | — |
|
| — | — | — | — |
|
| — | — | — | — |
|
| — | — | — | — |
Also shipped:
Resource
adb://devices— live device list as JSON (serial,state,model,allowed). State is never cached; re-read the resource to refresh.Prompts —
debug_crash,install_and_launch,capture_bug_report: step-by-step orchestrations of the tools above.
uninstall_package, grant_permission, revoke_permission and clear_app_data are the tools with
destructiveHint: true; shell, push_file, connect, disconnect and wireless_pair are the
openWorldHint: true tools. They are never merged with read-only tools, so hosts can auto-approve
reads and confirm writes.
Configuration
Variable | Default | Meaning |
|
| Path to the adb binary. Must match the version of any running adb server. |
| unset (all allowed) | Comma-separated serial allowlist. Operations on other serials are refused. |
|
| Comma-separated JavaScript regex sources tested against the whole |
| unset (no prefix restriction) | When set, a |
|
| Remote roots |
| unset (refuse every clear) | Comma-separated package allowlist for |
|
| Default subprocess timeout ( |
|
| Head+tail byte cap per call; the dropped middle is reported inline. |
|
| Ring-buffer cap per logcat stream; overflow is reported as |
Safety notes
Annotations are advisory, guardrails are authoritative. The host decides what to auto-approve;
adbmcpenforces its own limits regardless: blockedshellpatterns, the device allowlist, remote push roots, and the pull overwrite check.shellis arbitrary code execution on the device. It is annotated as not read-only and open-world, blocklisted by default, and documented as the escape hatch — keepshelldisabled or prefix-restricted (ADBMCP_SHELL_ALLOWED_PREFIXES) on shared or CI machines.uninstall_packagedeletes app data unlesskeep_data: true.clear_app_datadeletes app data permanently and is refused unless the package is listed inADBMCP_CLEAR_ALLOWED_PACKAGES(unset/empty refuses every clear).grant_permission/revoke_permissionchange an app's granted permissions. All four are markeddestructiveHint: true.Device scoping is explicit. With multiple devices connected, calls without
devicefail withMULTIPLE_DEVICESand the candidate serials instead of guessing.Filesystem writes are bounded.
pull_filenever overwrites silently;push_filerefuses writes outside the allowed remote roots and rejects..traversal and relative paths. Root containment is lexical: it does not resolve on-device symlinks, so a link pre-created inside an allowed root (e.g./data/local/tmp/x -> /data/system) can still redirect a push outside it.No privilege escalation.
adbmcpnever runsadb root/suitself and never retries a permission failure with elevation.The adb server is shared host state.
adbmcpnever kills or restarts it implicitly;adb_server_restartexists for the version-conflict case and says so in its description.Logcat streams are cleaned up. Streams are killed on
stop_logcat_stream, and all remaining streams are terminated on SIGINT/SIGTERM (server shutdown).
Development
npm install
npm run build # tsc -> dist/
npm test # vitest, no adb binary or device required
npm run typecheckTests drive a fake adb runner and a fake stream spawner, so the whole suite runs without platform-tools, a device or an emulator. Layout:
src/
index.ts stdio entrypoint (transport, signals)
server.ts assembles config + runner + tools/resources/prompts
config.ts env config, shell/device/push/clear guardrails
devices.ts device parsing, resolution rule, list_devices tool
adb/runner.ts subprocess per call: -s scoping, timeouts, head+tail caps
adb/errors.ts typed causes mapped from adb stderr/exit codes
streams/registry.ts long-running logcat handles + ring buffer
tools/ one module per tool group (34 tools, MVP + v2.0 items 1–6)
resources/devices.ts, prompts/index.ts
test/ vitest suites (fakes in test/helpers/)Status
Implements the MVP plus v2.0 items 1–6 from the design (§4.2): reverse port forwards and structured
forward/reverse listings, pm grant/revoke plus allowlist-gated clear_app_data, wireless
TCP/IP connect/disconnect/wireless_pair, first-class input injection (tap, swipe,
type_text, key_event — typed schemas that fix the input text quoting footgun, no DSL), and the
curated dumpsys_query. Not implemented: screenrecord, bugreport, Streamable HTTP transport,
iOS, emulator lifecycle management. Windows is best-effort (POSIX-first, like most of the
ecosystem).
This server cannot be deployed
Related MCP Connectors
Control real Android and iOS devices with LLM agents — tap, swipe, type, automate flows.
Cloud Android phones for AI agents: create a phone, read the screen, tap, type, install APKs, park.
Disposable cloud Android emulators for coding agents: run an APK or PR build, tap, type, screenshot.
Drive real devices from your AI Coding tool. Embed a client SDK (Unity, Godot, Flutter, iOS/macOS, Android, React Native, Web) in your app, then capture screenshots, traverse the UI tree, inject taps and key events, and run automated test tasks on the physical device over a secure relay.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables LLMs to control and manage Android devices via ADB, including app installation, UI interaction, and device monitoring.3512GPL 3.0
- AlicenseBqualityCmaintenanceEnables AI agents to control Android TV/Android devices through ADB, including screen capture, remote control, app management, and more.241 npm1MIT
- FlicenseBqualityCmaintenanceEnables AI assistants to observe, reason about, and control connected Android devices via ADB, providing tools for screenshots, UI hierarchy parsing, semantic element clicking, gestures, text input, and app lifecycle management.13-
- AlicenseAqualityCmaintenanceEnables AI agents to control, inspect, and automate Android devices, Waydroid containers, and AVD emulators over ADB. Provides tools for screenshots, UI-hierarchy text-based tapping, gestures, key presses, text input, app management, and raw shell commands.12MIT