A production-grade MCP (Model Context Protocol) server that gives any AI agent full control over Android devices via ADB, UIAutomator, Accessibility, and Vision (screenshots).
- 30+ MCP Tools — Device control, app management, UI automation, vision, testing
- Multi-Device Support — Control multiple Android devices simultaneously
- Smart Execution — UIAutomator → Accessibility → Vision → Coordinates fallback
- Security — Input sanitization, rate limiting, device allowlisting, destructive op protection
- Automation — Action recording/replay, test scenarios, state tracking
- Observability — Structured JSON logs, per-tool metrics, action history
- Node.js ≥ 18
- ADB installed and on PATH (Android SDK Platform Tools)
- An Android device or emulator connected via USB/WiFi
Verify ADB is working:
adb devices# Install dependencies
npm install
# Build TypeScript
npm run build
# Run the server
npm startAdd to claude_desktop_config.json:
{
"mcpServers": {
"android": {
"command": "node",
"args": ["repo_path/dist/mcp/server.js"],
"env": {
"ADB_PATH": "adb"
}
}
}
}Add to your Cursor MCP settings:
{
"mcpServers": {
"android": {
"command": "node",
"args": ["repo_path/dist/mcp/server.js"]
}
}
}node dist/mcp/server.jsThe server communicates via stdin/stdout using the MCP JSON-RPC protocol.
Create android-mcp.config.json in the project root (optional):
{
"adbPath": "adb",
"allowedDevices": [],
"maxActionsPerMinute": 120,
"commandTimeoutMs": 30000,
"maxRetries": 3,
"debug": false,
"screenshotDir": "./screenshots",
"recordingsDir": "./recordings",
"allowDestructiveOps": false
}Or use environment variables:
| Variable | Description |
|---|---|
ADB_PATH |
Path to adb binary |
ALLOWED_DEVICES |
Comma-separated device IDs |
MAX_ACTIONS_PER_MINUTE |
Rate limit per device |
COMMAND_TIMEOUT_MS |
ADB command timeout |
MAX_RETRIES |
Auto-retry count |
DEBUG |
Enable debug logging |
ALLOW_DESTRUCTIVE_OPS |
Allow uninstall etc. |
| Tool | Description |
|---|---|
list_devices |
List connected Android devices |
get_device_info |
Get device model, OS, screen size |
get_screen_size |
Get screen resolution |
| Tool | Description |
|---|---|
tap |
Tap at coordinates |
swipe |
Swipe between points |
long_press |
Long press at coordinates |
double_tap |
Double tap at coordinates |
input_text |
Type text into focused field |
press_key |
Press hardware/software key |
| Tool | Description |
|---|---|
list_apps |
List installed applications |
open_app |
Launch an app by package name |
close_app |
Force-stop an app |
install_apk |
Install an APK file |
uninstall_app |
Uninstall an app (requires config) |
get_current_app |
Get foreground app package |
| Tool | Description |
|---|---|
list_files |
List files on device |
pull_file |
Download file from device |
push_file |
Upload file to device |
| Tool | Description |
|---|---|
get_ui_tree |
Capture UI hierarchy |
find_element |
Find element by selector |
click_element |
Find and click element |
wait_for_element |
Wait for element to appear |
assert_element_exists |
Check if element exists |
| Tool | Description |
|---|---|
capture_screenshot |
Capture device screenshot |
analyze_screen |
Screenshot + UI tree analysis |
detect_elements_visually |
Detect interactive elements |
compare_screenshots |
Detect screen changes |
| Tool | Description |
|---|---|
smart_click |
Multi-strategy element click |
run_test_scenario |
Execute test steps |
start_recording |
Start recording actions |
stop_recording |
Stop and save recording |
replay_recording |
Replay recorded actions |
list_recordings |
List saved recordings |
get_device_state |
Get device state summary |
get_metrics |
Get performance metrics |
src/
├── mcp/
│ └── server.ts # MCP server entry point
├── controllers/
│ ├── device-tools.ts # Device MCP tools
│ ├── input-tools.ts # Input MCP tools
│ ├── app-tools.ts # App management MCP tools
│ ├── file-tools.ts # File system MCP tools
│ ├── ui-tools.ts # UIAutomator MCP tools
│ ├── vision-tools.ts # Vision MCP tools
│ └── automation-tools.ts # Automation MCP tools
├── adb/
│ ├── adb-executor.ts # Safe ADB command execution
│ ├── device-manager.ts # Device discovery & sessions
│ ├── input-controller.ts # Touch/key input
│ ├── app-manager.ts # App lifecycle
│ └── file-manager.ts # File operations
├── uiautomator/
│ ├── ui-tree-parser.ts # XML → JSON conversion
│ ├── element-finder.ts # Element search & interaction
│ └── element-cache.ts # LRU element cache
├── vision/
│ ├── screenshot.ts # Screenshot capture
│ ├── screen-diff.ts # Screenshot comparison
│ └── visual-analyzer.ts # AI-ready screen analysis
├── accessibility/
│ ├── accessibility-bridge.ts # Accessibility fallback
│ └── smart-executor.ts # Multi-strategy executor
├── automation/
│ ├── action-recorder.ts # Action recording
│ ├── action-replayer.ts # Action replay
│ ├── test-runner.ts # Test scenarios
│ └── state-tracker.ts # Device state memory
├── security/
│ ├── validator.ts # Input sanitization
│ └── rate-limiter.ts # Rate limiting
└── utils/
├── logger.ts # Structured logging
├── config.ts # Configuration
├── errors.ts # Error hierarchy
├── retry.ts # Retry logic
└── metrics.ts # Performance tracking
npm test
npm run test:coverage# Run in development mode (ts-node)
npm run dev
# Test with MCP Inspector
npx @modelcontextprotocol/inspector node dist/mcp/server.jsMIT