davidgin/mcp-android-server
If you are the rightful owner of mcp-android-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
The MCP Android Server is a comprehensive Model Context Protocol server designed to automate Android devices using uiautomator2, enabling AI agents and MCP-compatible clients to control Android devices through natural language commands.
MCP Android Server
A comprehensive Model Context Protocol (MCP) server for automating Android devices using uiautomator2. This server enables AI agents and MCP-compatible clients to control Android devices through natural language commands, making Android automation accessible and intuitive.
Table of Contents
- Features
- Prerequisites
- Quick Start
- Installation
- Usage
- MCP Tools Reference
- Configuration
- Testing
- Troubleshooting
- Examples
- Contributing
- License
Features
Device Management
- Connect to Android devices via ADB
- Get device information (manufacturer, model, version, battery, etc.)
- Screen power control (on/off/unlock)
- Hardware key simulation (home, back, menu, volume)
App Management
- Start and stop applications by package name
- List installed applications with version info
- Get current foreground application
- Clear application data and cache
- Wait for specific activities to appear
UI Automation
- Click, long click, and double-click UI elements
- Text input with automatic keyboard handling
- Gesture support (swipe, scroll, drag)
- Element discovery by text, resource ID, or description
- Wait for elements to appear/disappear
- Screenshot capture and UI hierarchy analysis
Advanced Features
- Toast message retrieval
- Scrollable container navigation
- Element bounds and property inspection
- Async operations with proper timeout handling
- Comprehensive error handling and logging
Prerequisites
System Requirements
- Python: 3.10 or higher (3.13 recommended)
- Operating System: Linux, macOS, or Windows
- Android SDK: ADB (Android Debug Bridge) installed
Android Device Requirements
- Android Version: 4.4+ (API level 19+)
- USB Debugging: Enabled in Developer Options
- Connection: USB cable or wireless ADB connection
- Permissions: Allow computer debugging when prompted
Quick Start
-
Clone and Setup
git clone https://github.com/your-repo/mcp-android-server.git cd mcp-android-server python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate pip install -r requirements.txt -
Connect Android Device
# Enable USB debugging on your Android device # Connect via USB cable adb devices # Should show your device -
Start the Server
python server.py # MCP stdio mode # OR uvicorn server:app --host 0.0.0.0 --port 8000 # HTTP mode -
Test Connection
python -c "from server import mcp_health, connect_device; print(mcp_health()); print(connect_device())"
Installation
Method 1: Using pip
# Clone repository
git clone https://github.com/your-repo/mcp-android-server.git
cd mcp-android-server
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
Method 2: Using Poetry
# Clone repository
git clone https://github.com/your-repo/mcp-android-server.git
cd mcp-android-server
# Install with Poetry
poetry install
poetry shell
Method 3: Using uv (Recommended for speed)
# Clone repository
git clone https://github.com/your-repo/mcp-android-server.git
cd mcp-android-server
# Install with uv
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
uv pip install -r requirements.txt
Android SDK Setup
Option 1: Install Android Studio
- Download Android Studio
- Install and run Android Studio
- Open SDK Manager and install "Android SDK Platform-Tools"
- Add ADB to PATH:
- Linux/macOS: Add
~/Android/Sdk/platform-toolsto PATH - Windows: Add
%LOCALAPPDATA%\Android\Sdk\platform-toolsto PATH
- Linux/macOS: Add
Option 2: Standalone ADB Installation
Ubuntu/Debian:
sudo apt update
sudo apt install adb
macOS:
brew install android-platform-tools
Windows:
- Download Platform Tools
- Extract to a folder (e.g.,
C:\platform-tools) - Add the folder to system PATH
Device Setup
-
Enable Developer Options
- Go to Settings > About phone
- Tap "Build number" 7 times
- Developer options will appear in Settings
-
Enable USB Debugging
- Go to Settings > Developer options
- Enable "USB debugging"
- Enable "Stay awake" (recommended)
-
Connect and Verify
adb devices # Should show: device_id device
Usage
Running the Server
MCP stdio Mode (For AI Agents)
python server.py
This mode uses stdin/stdout for MCP communication, suitable for integration with AI agents.
HTTP Mode (For Web Integration)
uvicorn server:app --host 0.0.0.0 --port 8000
Access at http://localhost:8000 for REST API usage.
Background Mode
nohup python server.py > server.log 2>&1 &
MCP Client Integration
Example: MCP Client Configuration
{
"mcpServers": {
"mcp-android": {
"type": "stdio",
"command": "python",
"args": ["/path/to/mcp-android-server/server.py"],
"cwd": "/path/to/mcp-android-server"
}
}
}
Example: VS Code Integration
Create .vscode/mcp.json:
{
"servers": {
"mcp-android": {
"type": "stdio",
"command": "bash",
"args": ["-c", "cd /path/to/mcp-android-server && source venv/bin/activate && python server.py"]
}
}
}
Direct Python Usage
from server import connect_device, start_app, click, screenshot
# Connect to device
device_info = connect_device()
print(f"Connected to {device_info['manufacturer']} {device_info['model']}")
# Launch an app
start_app("com.android.settings")
# Interact with UI
click("Wi-Fi", selector_type="text")
screenshot("/tmp/screenshot.png")
MCP Tools Reference
Device Management
| Tool | Description | Parameters |
|---|---|---|
mcp_health | Check server health | None |
connect_device | Connect to device and get info | device_id (optional) |
get_device_info | Get detailed device information | device_id (optional) |
check_adb_and_list_devices | Check ADB status and list devices | None |
screen_on | Turn screen on | device_id (optional) |
screen_off | Turn screen off | device_id (optional) |
unlock_screen | Unlock device screen | device_id (optional) |
press_key | Press hardware key | key, device_id (optional) |
App Management
| Tool | Description | Parameters |
|---|---|---|
get_installed_apps | List all installed apps | device_id (optional) |
get_current_app | Get current foreground app | device_id (optional) |
start_app | Start app by package name | package_name, device_id (optional), wait |
stop_app | Stop app by package name | package_name, device_id (optional) |
stop_all_apps | Stop all running apps | device_id (optional) |
clear_app_data | Clear app data/cache | package_name, device_id (optional) |
wait_activity | Wait for specific activity | activity, timeout, device_id (optional) |
UI Automation
| Tool | Description | Parameters |
|---|---|---|
click | Click on UI element | selector, selector_type, timeout, device_id |
long_click | Long click on element | selector, selector_type, duration, device_id |
send_text | Send text to focused field | text, clear, device_id |
get_element_info | Get element information | selector, selector_type, timeout, device_id |
wait_for_element | Wait for element to appear | selector, selector_type, timeout, device_id |
swipe | Perform swipe gesture | start_x, start_y, end_x, end_y, duration, device_id |
scroll_to | Scroll to element | selector, selector_type, device_id |
drag | Drag element to position | selector, selector_type, to_x, to_y, device_id |
screenshot | Take screenshot | filename, device_id |
dump_hierarchy | Get UI hierarchy as XML | compressed, pretty, max_depth, device_id |
get_toast | Get last toast message | device_id |
Selector Types
text: Match by visible textresourceId: Match by Android resource IDdescription: Match by content description
Key Names for press_key
home,back,menu,search,volume_up,volume_downpower,camera,focus,enter,delete,recentvolume_mute,page_up,page_down,escape,forward_del
Configuration
Environment Variables
# Optional: Override default ADB path
export ADB_PATH=/custom/path/to/adb
# Optional: Default device ID
export ANDROID_DEVICE_ID=emulator-5554
# Optional: Default timeout (seconds)
export DEFAULT_TIMEOUT=30
Server Configuration
Edit server.py to modify default settings:
# Default timeouts
DEFAULT_ELEMENT_TIMEOUT = 10.0
DEFAULT_ACTIVITY_TIMEOUT = 30.0
# Default screenshot format
SCREENSHOT_FORMAT = "PNG"
# Logging level
import logging
logging.getLogger().setLevel(logging.INFO)
Testing
Test Suite Overview
The project includes comprehensive tests:
- Unit Tests: 55+ tests with mocking (87% coverage)
- Integration Tests: Real device testing
- Test Runner: Automated test execution
Running Tests
# Install test dependencies
pip install pytest pytest-cov pytest-asyncio
# Run all tests
python run_tests.py
# Unit tests only (no device required)
python run_tests.py --unit-only
# Integration tests only (requires device)
python run_tests.py --integration-only
# With coverage report
python run_tests.py --coverage --unit-only
Manual Testing
# Test basic functionality
python -c "from server import mcp_health; print(mcp_health())"
# Test device connection
python -c "from server import connect_device; print(connect_device())"
# Test screenshot
python -c "from server import screenshot; screenshot('/tmp/test.png')"
Android Emulator for Testing
# Set Android SDK environment
export ANDROID_SDK_ROOT=/path/to/android-sdk
# Create emulator (one-time)
$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/avdmanager create avd \
-n test_device \
-k "system-images;android-34;google_apis;x86_64"
# Start emulator
emulator -avd test_device -no-window -no-audio &
# Wait for boot
adb wait-for-device
adb shell getprop sys.boot_completed
# Run integration tests
python run_tests.py --integration-only
Troubleshooting
Common Issues
"adb: command not found"
# Install ADB (Ubuntu/Debian)
sudo apt install adb
# Or add to PATH
export PATH=$PATH:~/Android/Sdk/platform-tools
"No devices/emulators found"
# Check USB debugging is enabled
adb devices
# Restart ADB server
adb kill-server && adb start-server
# Check device permissions
adb shell pm list permissions
"Permission denied" errors
# Accept computer authorization on device
# Re-enable USB debugging
# Try different USB cable/port
Connection timeouts
# Increase timeout in function calls
click("Button", timeout=30.0)
# Check device is responsive
adb shell input keyevent KEYCODE_HOME
Element not found
# Dump UI hierarchy to inspect elements
python -c "from server import dump_hierarchy; print(dump_hierarchy())"
# Try different selector types
click("Button", selector_type="text")
click("com.app:id/button", selector_type="resourceId")
click("Button description", selector_type="description")
Debug Mode
Enable detailed logging:
import logging
logging.basicConfig(level=logging.DEBUG)
# In server.py, add debug prints
def click(selector, selector_type="text", timeout=10.0, device_id=None):
print(f"DEBUG: Clicking {selector} with type {selector_type}")
# ... rest of function
Performance Issues
# Use faster element location
wait_for_element("Button", timeout=5.0) # Shorter timeout
# Reduce screenshot quality for speed
# (Edit server.py screenshot function)
# Use emulator instead of real device for testing
Examples
Basic Device Control
from server import *
# Connect and get device info
device = connect_device()
print(f"Device: {device['manufacturer']} {device['model']}")
# Control screen
screen_on()
unlock_screen()
press_key("home")
App Automation Example
# Launch Settings app
start_app("com.android.settings", wait=True)
# Navigate to Wi-Fi settings
click("Network & internet", selector_type="text")
click("Wi-Fi", selector_type="text")
# Take screenshot
screenshot("wifi_settings.png")
# Go back to home
press_key("home")
UI Testing Workflow
# Start test app
start_app("com.example.testapp")
# Wait for login screen
wait_for_element("Username", selector_type="text", timeout=10)
# Fill login form
click("Username", selector_type="resourceId")
send_text("test_user")
click("Password", selector_type="resourceId")
send_text("test_password")
click("Login", selector_type="text")
# Verify success
wait_for_element("Welcome", selector_type="text")
assert get_current_app()["package_name"] == "com.example.testapp"
Gesture Automation
# Get device screen size
device_info = get_device_info()
width, height = map(int, device_info["resolution"].split("x"))
# Swipe gestures
swipe(width//2, height*3//4, width//2, height//4, 0.5) # Swipe up
swipe(width*3//4, height//2, width//4, height//2, 0.5) # Swipe left
# Scroll to find element
scroll_to("Settings", selector_type="text")
# Drag and drop
drag("com.app:id/item", "resourceId", width//2, height//2)
Error Handling
try:
# Attempt UI interaction
click("Button", timeout=5.0)
except Exception as e:
print(f"Click failed: {e}")
# Fallback: Try different approach
elements = dump_hierarchy()
if "Button" in elements:
# Element exists but not clickable
press_key("enter") # Alternative action
else:
# Element doesn't exist
screenshot("error_state.png")
raise Exception("UI state not as expected")
Contributing
Development Setup
# Clone repository
git clone https://github.com/your-repo/mcp-android-server.git
cd mcp-android-server
# Setup development environment
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install -r requirements-dev.txt
# Install pre-commit hooks
pre-commit install
Running Tests
# Run all tests
python run_tests.py
# Run specific test
pytest tests/test_unit_basic.py::test_mcp_health -v
# Check coverage
python run_tests.py --unit-only --coverage
Code Style
# Format code
black server.py tests/
# Lint code
ruff check server.py
# Type checking
mypy server.py
Adding New Features
- Add function to
server.py - Add
@mcp.tool()decorator - Write unit tests in
tests/test_unit_*.py - Write integration tests in
tests/test_integration_*.py - Update documentation in README.md
Submitting Changes
- Fork the repository
- Create feature branch:
git checkout -b feature-name - Make changes and add tests
- Run test suite:
python run_tests.py - Commit changes:
git commit -m "Add feature" - Push branch:
git push origin feature-name - Create pull request
License
This project is licensed under the MIT License. See file for details.
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: This README and inline code documentation
Made with love for the Android automation community