Android Control MCP Server
Enables 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.
README
Android Control MCP Server
A production-ready Model Context Protocol (MCP) server built in Node.js that enables AI assistants (such as Claude Desktop, Cursor, and custom agentic workflows) to observe, reason about, and control connected Android devices.
๐ Features
- ๐ Computer-Use Observation: High-resolution PNG screen capture returned directly as MCP image blocks alongside device metadata.
- ๐ UIAutomator Hierarchy Parsing: Intelligent XML dump parser that transforms verbose Android UI trees into compact, structured JSON.
- ๐ฏ Semantic Element Clicking: Click buttons and controls by their visible text, accessibility description, or resource ID without needing manual pixel calculations.
- โก Fast Gestures & Input: Pixel-accurate tapping, multi-coordinate swiping, directional scrolling, hardware key emulation, and shell-escaped text typing.
- ๐ฑ App Lifecycle Management: Launch applications by package name and inspect the currently focused foreground activity.
- ๐ก๏ธ Safety & Sandboxing: Input coordinate validation against actual screen bounds, strict allowlisted keycodes, argument sanitization, command timeouts, and strict
stderrlogging to guarantee stdio MCP stream integrity. - ๐ Multi-Device Support: Auto-detects connected devices or targets specific devices via
ANDROID_DEVICE_ID.
๐๏ธ Architecture
AI Client (Claude Desktop, Cursor, Agent)
โ
โ stdio transport (JSON-RPC)
โผ
Node.js MCP Server
โ
โโโ Stderr Structured Logger
โโโ Zod Schema Validation
โ
โโโ ADB Controller Layer
โ โโโ Device Resolver (auto-detect or target serial)
โ โโโ Input Engine (tap, swipe, keyevent, text, scroll)
โ โโโ Screenshot Manager (exec-out binary stream)
โ โโโ App Manager (launch, foreground inspection)
โ
โโโ UIAutomator Engine
โโโ XML Hierarchy Dump & Normalizer
โโโ Bounds & Center Coordinate Extractor
โโโ Semantic Element Finder & Click Resolver
โ
โผ
Android Device / Emulator
๐ Prerequisites
- Node.js:
v20.0.0or higher (node -v) - Android SDK Platform-Tools: ADB (
adb) installed and accessible in your systemPATH(or configured viaADB_PATH). - Android Device or Emulator:
- Physical Device: Connect via USB, enable Developer Options and USB Debugging.
- Emulator: Android Studio AVD, Genymotion, or headless emulator.
Verify Device Connection
adb devices -l
You should see your device listed as device:
List of devices attached
emulator-5554 device product:sdk_gphone64_arm64 model:sdk_gphone64_arm64
๐ Installation & Quick Start
# Clone or navigate to the repository
cd c:/Users/Abhishek/Code/mcp
# Install dependencies
npm install
# Run unit tests
npm test
# Start the MCP server
npm start
โ๏ธ Configuration
Create a .env file or pass environment variables:
# Target device ID (serial number). If omitted and 1 device is connected, it auto-selects.
ANDROID_DEVICE_ID=
# Custom path to ADB executable if not in PATH
# Windows: C:\Users\<user>\AppData\Local\Android\Sdk\platform-tools\adb.exe
# macOS: /Users/<user>/Library/Android/sdk/platform-tools/adb
ADB_PATH=adb
# Log level: debug | info | warn | error
LOG_LEVEL=info
# Default ADB timeout in milliseconds
ADB_TIMEOUT_MS=15000
๐ Connecting to MCP Clients
1. Claude Desktop Configuration
Add the following to your claude_desktop_config.json:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"android-control": {
"command": "node",
"args": ["C:/Users/Abhishek/Code/mcp/src/index.js"],
"env": {
"ANDROID_DEVICE_ID": "",
"ADB_PATH": "adb",
"LOG_LEVEL": "info"
}
}
}
}
2. Cursor / Windsurf MCP Configuration
In Cursor's Features > MCP Servers or Windsurf settings:
- Name:
android-control - Type:
command - Command:
node C:/Users/Abhishek/Code/mcp/src/index.js
๐ ๏ธ MCP Tools Reference
1. android_device_info
Get comprehensive device hardware and OS metadata.
- Parameters:
deviceId(optional string): Target device serial.
- Example Response:
{ "deviceId": "emulator-5554", "model": "Pixel 8", "manufacturer": "Google", "androidVersion": "15", "sdk": 35, "resolution": { "width": 1080, "height": 2400 }, "connectionState": "connected" }
2. android_screenshot
Capture the Android screen as an MCP Image Content Block (image/png).
- Parameters:
deviceId(optional string): Target device serial.
- Returns: PNG base64 image data block + dimension metadata.
3. android_ui_dump
Dumps the current screen UIAutomator hierarchy into a compact, AI-friendly JSON format.
- Parameters:
deviceId(optional string): Target device serial.
- Example Output:
{ "package": "com.android.settings", "activity": "com.android.settings.Settings", "totalElements": 24, "interactiveElementsCount": 8, "elements": [ { "index": 0, "text": "Network & internet", "resourceId": "android:id/title", "className": "TextView", "clickable": true, "bounds": [196, 340, 1016, 400], "center": [606, 370] } ] }
4. android_find_element
Search for UI elements matching specific criteria on the current screen.
- Parameters:
text(optional string): Visible text (exact or partial).contentDescription(optional string): Accessibility label.resourceId(optional string): Resource ID.className(optional string): Widget class name.clickable(optional boolean): Filter by clickability.exactMatch(optional boolean, defaultfalse): Exact string match.
5. android_click_element
Find an element and click its center point in a single step.
- Parameters:
text(optional string): Element text.contentDescription(optional string): Element content description.resourceId(optional string): Element resource ID.className(optional string): Element class.
6. android_tap
Tap at exact (x, y) coordinates with screen boundary validation.
- Parameters:
x(number): X coordinate.y(number): Y coordinate.
7. android_swipe
Perform a drag / swipe gesture between two points.
- Parameters:
x1,y1(numbers): Start coordinates.x2,y2(numbers): End coordinates.duration(optional number, default: 300): Duration in milliseconds.
8. android_type_text
Type text into the currently focused input. Handles space encoding (%s) and shell character escaping.
- Parameters:
text(string): Text to type.
9. android_press_key
Press a hardware or navigation key.
- Supported Keys:
HOME,BACK,ENTER,TAB,ESC,DELETE,SPACE,VOLUME_UP,VOLUME_DOWN,POWER,APP_SWITCH,CAMERA, etc. - Parameters:
key(string): Key name or numeric keycode.
10. android_scroll
Directional scrolling calculated against actual screen dimensions.
- Parameters:
direction(string:up|down|left|right)amount(optional number): Scroll distance in pixels.
11. android_launch_app
Launch an application by its package name.
- Parameters:
packageName(string): e.g.com.android.settings,com.google.android.youtube.activity(optional string): Specific activity name.
12. android_current_app
Inspect the currently focused foreground package and activity.
13. android_execute_action (Unified Computer-Use Tool)
Single unified action dispatcher supporting all actions: tap, swipe, type, press_key, click_element, scroll, launch_app.
{
"action": "click_element",
"text": "Wi-Fi"
}
๐ค Recommended AI Workflow: Observe โ Reason โ Act โ Verify
1. OBSERVE:
AI calls `android_screenshot` and `android_ui_dump`.
2. REASON:
AI inspects visual and UI structure to identify target elements.
3. ACT:
AI calls `android_click_element`, `android_type_text`, or `android_scroll`.
4. VERIFY:
AI captures another screenshot/dump to confirm desired state change.
๐งช Testing
Run the automated test suite:
npm test
Tests use Vitest and mock the ADB execution layer, allowing full unit verification without requiring a physical Android device attached during CI/CD.
๐ Security Best Practices
- No Arbitrary Shell Execution: The server does NOT expose raw
adb shellexecution tools. - Safe Process Invocation: All commands use
child_process.execFilewith explicit argument arrays to prevent shell injection. - Input Sanitization: Package names, keycodes, and coordinate parameters are strictly validated via Zod schemas and bounds checking.
- Stderr Isolated Logging: All logs are directed exclusively to
stderrto maintain strict JSON-RPC protocol compliance onstdout.
๐ License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.