android-mcp
MCP server for Android device automation over ADB - screenshots, UI hierarchy, taps, app management, logcat, and screen recording. No companion APK, no telemetry.
Install / Use
claude mcp add qalvinahmad -- npx -y github:qalvinahmad/android-mcpIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
AutomationSupported Platforms
Our assessment of android-mcp
android-mcp scores 78/100 on our quality scale, 2568th of 2,903 Automation skills we index.
Its MCP Server is 11 KB long, well organised into 23 sections with 7 code examples: a thorough specification that gives an agent plenty to work with.
It has 10 GitHub stars, so there is little community track record yet; judge it on its content.
Maintenance, license and trust
- The repository was last updated about 4 months ago. That is recent enough to be usable, but agent tooling moves fast, so check the instructions against your agent's current version.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 95/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
android-mcp compared with similar skills
All 4 of these similar skills score higher than android-mcp; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| android-mcp (this skill)by qalvinahmad | 78 | 10 | 4mo ago | MCP Server |
| Agent-Reachby Panniantong | 100 | 102.4k | today | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 77.8k | 1d ago | CLAUDE.md |
| CowAgentby zhayujie | 100 | 47.6k | today | CLAUDE.md |
| Scraplingby D4Vinci | 100 | 89.7k | 3d ago | MCP Server |
Frequently asked questions
- How do I install android-mcp?
- Run
claude mcp add qalvinahmad -- npx -y github:qalvinahmad/android-mcp. The install tabs above show the steps for each supported agent. - Which AI agents does android-mcp work with?
- It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
- Is android-mcp safe to use?
- It is MIT-licensed and scores 95/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is android-mcp still maintained?
- The repository was last updated about 4 months ago. That is recent enough to be usable, but agent tooling moves fast, so check the instructions against your agent's current version.
Skill content
View source on GitHubandroid-mcp
An MCP (Model Context Protocol) server that gives AI agents full control of Android devices and emulators through plain ADB — no companion APK, no extra daemon, no telemetry.
With this server, agents like Claude Code, Claude Desktop, or Cursor can see the screen (screenshots + UI hierarchy) and act on it (tap, swipe, type, launch apps, read logs, record video) on any device that adb can reach.
You: "Open Settings, turn on dark mode, and show me a screenshot"
Agent: launches the app, navigates by reading the UI hierarchy,
taps the right elements, and returns a screenshot — hands-free.
Why another Android MCP?
This project merges the best ideas of two excellent servers into one dependency-light TypeScript implementation:
| Inspiration | What was adopted | |---|---| | mobile-mcp | App management, uiautomator-based element listing, screenshots, screen recording, orientation control | | Android-MCP | WiFi ADB + mDNS auto-discovery, selector-based taps, wait-for-element, smart default-device selection |
Differences by design:
- ADB only. No uiautomator2 server APK on the device, no
mobileclibinary on the host. - Zero telemetry. Nothing is phoned home, ever.
- Android-first. No iOS code paths to carry around.
- Agent-friendly errors. Failures return actionable messages that tell the agent what to try next.
Requirements
- Node.js 18+
- Android platform-tools (
adb) — auto-detected fromANDROID_HOME,~/Library/Android/sdk(macOS), or%LOCALAPPDATA%\Android\Sdk(Windows), withPATHas fallback - An Android device with USB debugging or wireless debugging enabled, or a running emulator
Installation
git clone https://github.com/qalvinahmad/android-mcp.git
cd android-mcp
npm install
npm run build
Claude Code
claude mcp add android -- node /path/to/android-mcp/dist/index.js
Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"android": {
"command": "node",
"args": ["/path/to/android-mcp/dist/index.js"]
}
}
}
Cursor / other MCP clients
Any client that speaks MCP over stdio works the same way: run node /path/to/android-mcp/dist/index.js as the server command.
Environment variables (all optional)
| Variable | Purpose |
|---|---|
| ANDROID_MCP_DEVICE | Default device id used when a tool call omits device |
| ANDROID_MCP_ALLOW_UNSAFE_URLS | Set to 1 to allow non-http(s) URLs (e.g. deep links) in android_open_url |
| ANDROID_HOME | Android SDK location, used to locate adb |
Device selection
Every tool accepts an optional device parameter. When omitted, the server resolves the target in this order:
ANDROID_MCP_DEVICEenvironment variable- The only online device, if exactly one is connected
- The first physical device (USB or WiFi preferred over emulators)
android_list_devices also auto-connects wireless-debugging peers advertised via mDNS (adb mdns services) when the device list is empty — devices on the same network appear without any manual adb connect.
Capabilities — 26 tools
Device management
| Tool | Description | Key parameters |
|---|---|---|
| android_list_devices | List connected devices with name, Android version, connection type (usb/wifi/emulator), and state. Auto-discovers mDNS wireless peers. | — |
| android_connect_wifi | Connect over WiFi ADB. Port defaults to 5555. | host |
| android_device_info | Model, Android version, SDK level, screen size, orientation, battery level, foreground app. | device? |
App management
| Tool | Description | Key parameters |
|---|---|---|
| android_list_apps | List installed apps that have a launcher activity. | device? |
| android_launch_app | Launch an app by package name. | packageName |
| android_terminate_app | Force-stop a running app. | packageName |
| android_install_app | Install an APK, optionally granting all runtime permissions. | apkPath, grantPermissions? |
| android_uninstall_app | Uninstall an app. | packageName |
Screen observation
| Tool | Description | Key parameters |
|---|---|---|
| android_take_screenshot | Screenshot returned inline as an image the agent can see. | device? |
| android_save_screenshot | Screenshot saved to a local .png file. | saveTo |
| android_list_elements | UI hierarchy: element type, text, accessibility label, resource id, focus/clickable state, and center tap coordinates. | device? |
| android_wait_for_element | Poll until an element appears — use instead of fixed sleeps for dynamic content. | selector, timeout? |
Interaction
| Tool | Description | Key parameters |
|---|---|---|
| android_tap | Tap at pixel coordinates. | x, y |
| android_tap_element | Find an element by selector and tap its center. Waits up to timeout (default 5 s) for it to appear. | selector, index?, timeout? |
| android_double_tap | Double-tap at coordinates. | x, y |
| android_long_press | Long-press at coordinates. | x, y, duration? |
| android_swipe | Directional swipe from screen center or from given coordinates. | direction, x?, y?, distance?, duration? |
| android_drag | Drag and drop between two points. | fromX, fromY, toX, toY, duration? |
| android_type_text | Type into the focused field (ASCII), optionally clearing it first and/or submitting with ENTER. | text, submit?, clear? |
| android_press_key | Press a key: BACK, HOME, ENTER, APP_SWITCH, VOLUME_UP, any KEYCODE_* name, or a numeric keycode. | key |
| android_open_url | Open an http(s) URL in the default browser. | url |
| android_open_notifications | Expand the notification shade. | device? |
System
| Tool | Description | Key parameters |
|---|---|---|
| android_set_orientation | Force portrait/landscape (disables auto-rotate). | orientation |
| android_start_recording | Start background screen recording (max 180 s, Android limit). | timeLimit? |
| android_stop_recording | Stop recording, pull the .mp4 to this computer. | saveTo? |
| android_logcat | Read recent logs with buffer selection (main/system/crash/events/all) and substring filter. Great for debugging Flutter/React Native crashes. | lines?, buffer?, filter? |
Element selectors
android_tap_element and android_wait_for_element accept any combination of:
| Selector | Matching |
|---|---|
| text | Exact visible text |
| textContains | Substring of visible text, case-insensitive |
| resourceId | Full id (com.app:id/btn_login) or short id (btn_login, auto-expanded using the foreground app package) |
| contentDesc | Substring of accessibility label, case-insensitive |
| className | Full class (android.widget.Button) or suffix (Button) |
Usage examples
Prompts you can give an agent once the server is connected:
- "List my devices and take a screenshot of the current screen."
- "Open the Settings app and toggle dark mode."
- "Install ~/Downloads/app-release.apk with all permissions granted, launch it, and check logcat for errors."
- "Fill in the login form: tap the field with resource id
email, typeuser@example.com, then tap the Login button." - "Record the screen while you walk through the onboarding flow, then save the video to my desktop."
- "My Flutter app crashed — read the crash buffer and tell me why."
How it works (spec)
┌──────────────┐ stdio (JSON-RPC / MCP) ┌─────────────┐ adb CLI ┌─────────────┐
│ MCP client │ ◄────────────────────────► │ android-mcp │ ◄─────────► │ device / │
│ (Claude, ...) │ │ (Node.js) │ │ emulator │
└──────────────┘ └─────────────┘ └─────────────┘
- Transport: stdio, stateless — one server process per client session.
- Screenshots:
adb exec-out screencap -p, returned as PNG (inline base64 image or file). - UI hierarchy:
adb exec-out uiautomator dump /dev/tty, parsed withfast-xml-parser, retried up to 10× when the bridge returns a null root. Elements with no size or no useful text/id are filtered out. - Input:
adb shell input(tap/swipe/text/keyevent/draganddrop). Text is shell-escaped; only ASCII is supported byinput text, and non-ASCII input returns an actionable error instead of typing garbage. - Recording:
adb shell screenrecordspawned in the background; stop sendsSIGINTto the on-device process (killall -2 screenrecord), waits for the file to finalize, thenadb pulls it. - Foreground app detection:
dumpsys activity activities(ResumedActivity, covering both pre- and post-Android-13 formats) withdumpsys window(mFocusedApp) as fallback. - Safety rails: package names validated against
[a-zA-Z0-9_.], output paths must be absolute with allowed extensions, URLs restricted to http(s) unless explicitly overridden.
Project layout
src/
├── index.ts entry point — stdio transport
├── server.ts MCP server + 26 tool registrations
├── adb.ts adb discovery/execution, device resolution, WiFi + mDNS connect
└── ui.ts uiautomator dump parsing, selector matching, wait-for-element
Development
npm run watch # rebuild on change
npm run inspector # test tools interactively with MCP Inspector
Troubleshooting
| Symptom | Fix |
|---|---|
| adb not found | Install Android platform-tools and/or set ANDROID_HOME. |
| No Android devices connected | Enable USB debugging (or wireless debugging), accept the RSA prompt on the device, check adb devices. |
| Screenshot is black | The screen is off — send android_press_key with WAKEUP first. |
| Failed to dump UI hierarchy | The foreground screen is secure (password field, DRM). Use android_take_screenshot instead. |
| Non-ASCII text fails | adb shell input text is ASCII-only. Type the ASCII portion or use the device keyboard. |
| WiFi connect fails | Ensure wireless debugging or adb tcpip 5555 is active and the host is reachable. |
Contributing
Issues and pull requests are welcome. Keep changes small and focused:
- Fork and create a feature branch.
npm run buildmust pass with no TypeScript errors.- Verify against a real device or emulator where possible (MCP Inspector makes this easy).
- Describe the behavior change in the PR.
License
MIT © Alvin Ahmad (@qalvinahmad)
Related Skills
Agent-Reach
102.4kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
77.8kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
CowAgent
47.6kOpen-source personal AI assistant & Agent Harness. Plans tasks, runs tools and skills, self-evolves with memory and knowledge. Multi-agent, multi-model, multi-channel. Lightweight, extensible, one-line install.
Scrapling
89.7k🕷️ A Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
