mcp-android-server

davidgin/mcp-android-server

3.1

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.

Tools
5
Resources
0
Prompts
0

MCP Android Server

Python 3.13 License: MIT

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

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

  1. 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
    
  2. Connect Android Device

    # Enable USB debugging on your Android device
    # Connect via USB cable
    adb devices  # Should show your device
    
  3. Start the Server

    python server.py  # MCP stdio mode
    # OR
    uvicorn server:app --host 0.0.0.0 --port 8000  # HTTP mode
    
  4. 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
  1. Download Android Studio
  2. Install and run Android Studio
  3. Open SDK Manager and install "Android SDK Platform-Tools"
  4. Add ADB to PATH:
    • Linux/macOS: Add ~/Android/Sdk/platform-tools to PATH
    • Windows: Add %LOCALAPPDATA%\Android\Sdk\platform-tools to PATH
Option 2: Standalone ADB Installation

Ubuntu/Debian:

sudo apt update
sudo apt install adb

macOS:

brew install android-platform-tools

Windows:

  1. Download Platform Tools
  2. Extract to a folder (e.g., C:\platform-tools)
  3. Add the folder to system PATH

Device Setup

  1. Enable Developer Options

    • Go to Settings > About phone
    • Tap "Build number" 7 times
    • Developer options will appear in Settings
  2. Enable USB Debugging

    • Go to Settings > Developer options
    • Enable "USB debugging"
    • Enable "Stay awake" (recommended)
  3. 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

ToolDescriptionParameters
mcp_healthCheck server healthNone
connect_deviceConnect to device and get infodevice_id (optional)
get_device_infoGet detailed device informationdevice_id (optional)
check_adb_and_list_devicesCheck ADB status and list devicesNone
screen_onTurn screen ondevice_id (optional)
screen_offTurn screen offdevice_id (optional)
unlock_screenUnlock device screendevice_id (optional)
press_keyPress hardware keykey, device_id (optional)

App Management

ToolDescriptionParameters
get_installed_appsList all installed appsdevice_id (optional)
get_current_appGet current foreground appdevice_id (optional)
start_appStart app by package namepackage_name, device_id (optional), wait
stop_appStop app by package namepackage_name, device_id (optional)
stop_all_appsStop all running appsdevice_id (optional)
clear_app_dataClear app data/cachepackage_name, device_id (optional)
wait_activityWait for specific activityactivity, timeout, device_id (optional)

UI Automation

ToolDescriptionParameters
clickClick on UI elementselector, selector_type, timeout, device_id
long_clickLong click on elementselector, selector_type, duration, device_id
send_textSend text to focused fieldtext, clear, device_id
get_element_infoGet element informationselector, selector_type, timeout, device_id
wait_for_elementWait for element to appearselector, selector_type, timeout, device_id
swipePerform swipe gesturestart_x, start_y, end_x, end_y, duration, device_id
scroll_toScroll to elementselector, selector_type, device_id
dragDrag element to positionselector, selector_type, to_x, to_y, device_id
screenshotTake screenshotfilename, device_id
dump_hierarchyGet UI hierarchy as XMLcompressed, pretty, max_depth, device_id
get_toastGet last toast messagedevice_id

Selector Types

  • text: Match by visible text
  • resourceId: Match by Android resource ID
  • description: Match by content description

Key Names for press_key

  • home, back, menu, search, volume_up, volume_down
  • power, camera, focus, enter, delete, recent
  • volume_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

  1. Add function to server.py
  2. Add @mcp.tool() decorator
  3. Write unit tests in tests/test_unit_*.py
  4. Write integration tests in tests/test_integration_*.py
  5. Update documentation in README.md

Submitting Changes

  1. Fork the repository
  2. Create feature branch: git checkout -b feature-name
  3. Make changes and add tests
  4. Run test suite: python run_tests.py
  5. Commit changes: git commit -m "Add feature"
  6. Push branch: git push origin feature-name
  7. Create pull request

License

This project is licensed under the MIT License. See file for details.

Support


Made with love for the Android automation community