SkillAgentSearch skills...

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-mcp

If the server publishes to npm under a different name, use that package instead — check the repo README.

About this skill
🔌

MCP Server

Model Context Protocol server

Quality Score

78/100

Category

Automation

Supported Platforms

Claude Code
Claude Desktop

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.

Substance
29/30
Structure
20/20
Description
15/15
Adoption
4/20
Freshness
11/15

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.

SkillScoreStarsUpdatedFormat
android-mcp (this skill)by qalvinahmad78104mo agoMCP Server
Agent-Reachby Panniantong100102.4ktodayCLAUDE.md
headroomby headroomlabs-ai10077.8k1d agoCLAUDE.md
CowAgentby zhayujie10047.6ktodayCLAUDE.md
Scraplingby D4Vinci10089.7k3d agoMCP 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.

android-mcp

License: MIT Node.js 18+ 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 mobilecli binary 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 from ANDROID_HOME, ~/Library/Android/sdk (macOS), or %LOCALAPPDATA%\Android\Sdk (Windows), with PATH as 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:

  1. ANDROID_MCP_DEVICE environment variable
  2. The only online device, if exactly one is connected
  3. 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, type user@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 with fast-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 by input text, and non-ASCII input returns an actionable error instead of typing garbage.
  • Recording: adb shell screenrecord spawned in the background; stop sends SIGINT to the on-device process (killall -2 screenrecord), waits for the file to finalize, then adb pulls it.
  • Foreground app detection: dumpsys activity activities (ResumedActivity, covering both pre- and post-Android-13 formats) with dumpsys 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:

  1. Fork and create a feature branch.
  2. npm run build must pass with no TypeScript errors.
  3. Verify against a real device or emulator where possible (MCP Inspector makes this easy).
  4. Describe the behavior change in the PR.

License

MIT © Alvin Ahmad (@qalvinahmad)

Related Skills

View on GitHub
GitHub Stars10
CategoryAutomation
Updated3mo ago
Forks0

Languages

TypeScript

Trust signals

95/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

2 info