# Android MCP Server
An MCP (Model Context Protocol) server that provides programmatic control over
Android devices through ADB (Android Debug Bridge). This server exposes
various Android device management capabilities that can be accessed by MCP
clients like [Claude desktop](https://modelcontextprotocol.io/quickstart/user)
and Code editors
(e.g. [Cursor](https://docs.cursor.com/context/model-context-protocol))
## Features
- 🔧 ADB Command Execution
- 📸 Device Screenshot Capture
- 🎯 UI Layout Analysis
- 📱 Device Package Management
- 🚀 **NEW:** Automatic Emulator Startup
- 🎮 **NEW:** Emulator Management Tools
## Prerequisites
- Python 3.11+
- ADB (Android Debug Bridge) installed and configured
- Android device (physical or emulator)
## Installation
### Quick Install (Recommended)
```bash
# Using uvx (no installation needed)
uvx mcp-server-android
# Or using pip
pip install mcp-server-android
# Or using uv tool
uv tool install mcp-server-android
```
### Development Installation
1. Clone the repository:
```bash
git clone https://github.com/minhalvp/android-mcp-server.git
cd android-mcp-server
```
2. Install dependencies:
This project uses [uv](https://github.com/astral-sh/uv) for project
management via various methods of
[installation](https://docs.astral.sh/uv/getting-started/installation/).
```bash
uv python install 3.11
uv sync
```
## Configuration
The server supports flexible device configuration with multiple usage scenarios.
### Environment Variables
You can configure the server using environment variables:
- `ANDROID_DEVICE_SERIAL` - Specify the device serial (overrides config file)
- `ANDROID_MCP_CONFIG` - Path to custom config file (default: `config.yaml`)
- `ANDROID_AUTO_START_EMULATOR` - Enable/disable auto-start emulator (default: `true`)
Example:
```bash
export ANDROID_DEVICE_SERIAL="emulator-5554"
uvx mcp-server-android
```
### Device Selection Modes
**1. Automatic Selection (Recommended for single device)**
- No configuration file needed
- Automatically connects to the only connected device
- Perfect for development with a single test device
**2. Manual Device Selection**
- Use when you have multiple devices connected
- Specify exact device in configuration file
### Configuration File (Optional)
The configuration file (`config.yaml`) is **optional**. If not present, the server will automatically select the device if only one is connected.
#### For Automatic Selection
Simply ensure only one device is connected and run the server - no configuration needed!
#### For Manual Selection
1. Create a configuration file:
```bash
cp config.yaml.example config.yaml
```
2. Edit `config.yaml` and specify your device:
```yaml
device:
name: "your-device-serial-here" # Device identifier from 'adb devices'
```
**For auto-selection**, you can use any of these methods:
```yaml
device:
name: null # Explicit null (recommended)
# name: "" # Empty string
# name: # Or leave empty/comment out
```
### Finding Your Device Serial
To find your device identifier, run:
```bash
adb devices
```
Example output:
```
List of devices attached
13b22d7f device
emulator-5554 device
```
Use the first column value (e.g., `13b22d7f` or `emulator-5554`) as the device name.
### Usage Scenarios
| Scenario | Configuration Required | Behavior |
|----------|----------------------|----------|
| Single device connected | None | ✅ Auto-connects to the device |
| Multiple devices, want specific one | `config.yaml` with `device.name` | ✅ Connects to specified device |
| Multiple devices, no config | None | ❌ Shows error with available devices |
| No devices connected | N/A | ❌ Shows "no devices" error with emulator start instructions |
**Note**: If you have multiple devices connected and don't specify which one to use, the server will show an error message listing all available devices.
### Emulator Support
The server provides comprehensive emulator support with automatic startup capabilities:
#### Automatic Emulator Startup (New!)
By default, if no devices are connected, the server will:
1. Detect available Android Virtual Devices (AVDs)
2. Automatically start the first available emulator
3. Wait for it to boot (up to 60 seconds)
4. Connect to it automatically
This behavior can be disabled by:
- Setting `ANDROID_AUTO_START_EMULATOR=false` environment variable
- Or in config.yaml: `device.auto_start_emulator: false`
#### Manual Emulator Management
When auto-start is disabled or fails, the server:
**Example error message with emulator suggestions:**
```
No devices connected. Please:
- Connect a physical device with USB debugging enabled, OR
- Start an emulator: ~/Library/Android/sdk/emulator/emulator -avd <name>
Available AVDs: Pixel_8_API_35, Nexus_5X_API_28
```
### Automatic ADB Detection
The server now automatically searches for ADB in common installation locations if it's not in your PATH:
- macOS: `~/Library/Android/sdk/platform-tools`, `/opt/homebrew/bin`, `/usr/local/bin`
- Linux: `~/Android/sdk/platform-tools`, `/usr/bin`
- Android Studio installations
This means the server will work even when launched from environments with limited PATH access (like Claude Desktop or MCP routers).
## Usage
An MCP client is needed to use this server. The Claude Desktop app is an example
of an MCP client.
### MetaMCP Integration
To use with [MetaMCP](https://github.com/metatool-ai/metamcp), add this to your MetaMCP configuration:
```json
{
"mcpServers": {
"android": {
"command": "/path/to/android-mcp-server/run-mcp-server.sh"
}
}
}
```
For paths with spaces, use the wrapper script included in the package. See [METAMCP.md](METAMCP.md) for detailed setup instructions.
### Claude Desktop Configuration
To use this server with Claude Desktop:
1. Locate your Claude Desktop configuration file:
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
2. Add the Android MCP server configuration to the `mcpServers` section:
```json
{
"mcpServers": {
"android": {
"command": "uvx",
"args": ["mcp-server-android"],
"env": {
"ANDROID_DEVICE_SERIAL": "your-device-serial", // Optional
"ANDROID_AUTO_START_EMULATOR": "true" // Optional, default is true
}
}
}
}
```
Or if installed with pip:
```json
{
"mcpServers": {
"android": {
"command": "mcp-server-android",
"args": []
}
}
}
```
<https://github.com/user-attachments/assets/c45bbc17-f698-43e7-85b4-f1b39b8326a8>
### Available Tools
The server exposes the following tools:
```python
def get_packages() -> str:
"""
Get all installed packages on the device.
Returns:
str: A list of all installed packages on the device as a string
"""
```
```python
def execute_adb_shell_command(command: str) -> str:
"""
Executes an ADB shell command and returns the output.
Args:
command (str): The ADB shell command to execute
Returns:
str: The output of the ADB command
"""
```
```python
def get_uilayout() -> str:
"""
Retrieves information about clickable elements in the current UI.
Returns a formatted string containing details about each clickable element,
including their text, content description, bounds, and center coordinates.
Returns:
str: A formatted list of clickable elements with their properties
"""
```
```python
def get_screenshot() -> Image:
"""
Takes a screenshot of the device and returns it.
Returns:
Image: the screenshot
"""
```
```python
def get_package_action_intents(package_name: str) -> list[str]:
"""
Get all non-data actions from Activity Resolver Table for a package
Args:
package_name (str): The name of the package to get actions for
Returns:
list[str]: A list of all non-data actions from the Activity Resolver
Table for the package
"""
```
#### Emulator Management Tools (New!)
```python
def list_devices() -> dict:
"""
List all connected Android devices (physical and emulators).
Returns device serials and their types.
"""
```
```python
def list_emulators() -> dict:
"""
List available Android Virtual Devices (AVDs) that can be started.
Returns available AVD names and emulator command path.
"""
```
```python
def start_emulator_avd(avd_name: str | None = None, headless: bool = False) -> dict:
"""
Start an Android emulator with the specified AVD.
Args:
avd_name: Name of the AVD to start. If None, uses first available.
headless: If True, starts emulator without GUI (faster, uses less resources)
Returns:
Status information including success, device_serial, and message
"""
```
```python
def stop_emulator(device_serial: str | None = None) -> dict:
"""
Stop a running Android emulator.
Args:
device_serial: Serial of the emulator to stop (e.g., 'emulator-5554').
If None, stops all emulators.
Returns:
Status information
"""
```
## Contributing
Contributions are welcome!
## Acknowledgments
- Built with
[Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction)
Raw data
{
"_id": null,
"home_page": null,
"name": "mcp-server-android",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "adb, android, automation, debugging, mcp, testing",
"author": "minhalvp",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/5e/58/891db3faad30c57d74dcc8961d3310c34587cc1259830b1d0b2b22f40653/mcp_server_android-0.3.1.tar.gz",
"platform": null,
"description": "# Android MCP Server\n\nAn MCP (Model Context Protocol) server that provides programmatic control over\nAndroid devices through ADB (Android Debug Bridge). This server exposes\nvarious Android device management capabilities that can be accessed by MCP\nclients like [Claude desktop](https://modelcontextprotocol.io/quickstart/user)\nand Code editors\n(e.g. [Cursor](https://docs.cursor.com/context/model-context-protocol))\n\n## Features\n\n- \ud83d\udd27 ADB Command Execution\n- \ud83d\udcf8 Device Screenshot Capture\n- \ud83c\udfaf UI Layout Analysis\n- \ud83d\udcf1 Device Package Management\n- \ud83d\ude80 **NEW:** Automatic Emulator Startup\n- \ud83c\udfae **NEW:** Emulator Management Tools\n\n## Prerequisites\n\n- Python 3.11+\n- ADB (Android Debug Bridge) installed and configured\n- Android device (physical or emulator)\n\n## Installation\n\n### Quick Install (Recommended)\n\n```bash\n# Using uvx (no installation needed)\nuvx mcp-server-android\n\n# Or using pip\npip install mcp-server-android\n\n# Or using uv tool\nuv tool install mcp-server-android\n```\n\n### Development Installation\n\n1. Clone the repository:\n\n```bash\ngit clone https://github.com/minhalvp/android-mcp-server.git\ncd android-mcp-server\n```\n\n2. Install dependencies:\nThis project uses [uv](https://github.com/astral-sh/uv) for project\nmanagement via various methods of\n[installation](https://docs.astral.sh/uv/getting-started/installation/).\n\n```bash\nuv python install 3.11\nuv sync\n```\n\n## Configuration\n\nThe server supports flexible device configuration with multiple usage scenarios.\n\n### Environment Variables\n\nYou can configure the server using environment variables:\n\n- `ANDROID_DEVICE_SERIAL` - Specify the device serial (overrides config file)\n- `ANDROID_MCP_CONFIG` - Path to custom config file (default: `config.yaml`)\n- `ANDROID_AUTO_START_EMULATOR` - Enable/disable auto-start emulator (default: `true`)\n\nExample:\n```bash\nexport ANDROID_DEVICE_SERIAL=\"emulator-5554\"\nuvx mcp-server-android\n```\n\n### Device Selection Modes\n\n**1. Automatic Selection (Recommended for single device)**\n\n- No configuration file needed\n- Automatically connects to the only connected device\n- Perfect for development with a single test device\n\n**2. Manual Device Selection**\n\n- Use when you have multiple devices connected\n- Specify exact device in configuration file\n\n### Configuration File (Optional)\n\nThe configuration file (`config.yaml`) is **optional**. If not present, the server will automatically select the device if only one is connected.\n\n#### For Automatic Selection\n\nSimply ensure only one device is connected and run the server - no configuration needed!\n\n#### For Manual Selection\n\n1. Create a configuration file:\n\n```bash\ncp config.yaml.example config.yaml\n```\n\n2. Edit `config.yaml` and specify your device:\n\n```yaml\ndevice:\n name: \"your-device-serial-here\" # Device identifier from 'adb devices'\n```\n\n**For auto-selection**, you can use any of these methods:\n\n```yaml\ndevice:\n name: null # Explicit null (recommended)\n # name: \"\" # Empty string \n # name: # Or leave empty/comment out\n```\n\n### Finding Your Device Serial\n\nTo find your device identifier, run:\n\n```bash\nadb devices\n```\n\nExample output:\n\n```\nList of devices attached\n13b22d7f device\nemulator-5554 device\n```\n\nUse the first column value (e.g., `13b22d7f` or `emulator-5554`) as the device name.\n\n### Usage Scenarios\n\n| Scenario | Configuration Required | Behavior |\n|----------|----------------------|----------|\n| Single device connected | None | \u2705 Auto-connects to the device |\n| Multiple devices, want specific one | `config.yaml` with `device.name` | \u2705 Connects to specified device |\n| Multiple devices, no config | None | \u274c Shows error with available devices |\n| No devices connected | N/A | \u274c Shows \"no devices\" error with emulator start instructions |\n\n**Note**: If you have multiple devices connected and don't specify which one to use, the server will show an error message listing all available devices.\n\n### Emulator Support\n\nThe server provides comprehensive emulator support with automatic startup capabilities:\n\n#### Automatic Emulator Startup (New!)\nBy default, if no devices are connected, the server will:\n1. Detect available Android Virtual Devices (AVDs)\n2. Automatically start the first available emulator\n3. Wait for it to boot (up to 60 seconds)\n4. Connect to it automatically\n\nThis behavior can be disabled by:\n- Setting `ANDROID_AUTO_START_EMULATOR=false` environment variable\n- Or in config.yaml: `device.auto_start_emulator: false`\n\n#### Manual Emulator Management\nWhen auto-start is disabled or fails, the server:\n\n**Example error message with emulator suggestions:**\n```\nNo devices connected. Please:\n- Connect a physical device with USB debugging enabled, OR\n- Start an emulator: ~/Library/Android/sdk/emulator/emulator -avd <name>\n Available AVDs: Pixel_8_API_35, Nexus_5X_API_28\n```\n\n### Automatic ADB Detection\n\nThe server now automatically searches for ADB in common installation locations if it's not in your PATH:\n\n- macOS: `~/Library/Android/sdk/platform-tools`, `/opt/homebrew/bin`, `/usr/local/bin`\n- Linux: `~/Android/sdk/platform-tools`, `/usr/bin`\n- Android Studio installations\n\nThis means the server will work even when launched from environments with limited PATH access (like Claude Desktop or MCP routers).\n\n## Usage\n\nAn MCP client is needed to use this server. The Claude Desktop app is an example\nof an MCP client.\n\n### MetaMCP Integration\n\nTo use with [MetaMCP](https://github.com/metatool-ai/metamcp), add this to your MetaMCP configuration:\n\n```json\n{\n \"mcpServers\": {\n \"android\": {\n \"command\": \"/path/to/android-mcp-server/run-mcp-server.sh\"\n }\n }\n}\n```\n\nFor paths with spaces, use the wrapper script included in the package. See [METAMCP.md](METAMCP.md) for detailed setup instructions.\n\n### Claude Desktop Configuration\n\nTo use this server with Claude Desktop:\n\n1. Locate your Claude Desktop configuration file:\n\n - Windows: `%APPDATA%\\Claude\\claude_desktop_config.json`\n - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`\n\n2. Add the Android MCP server configuration to the `mcpServers` section:\n\n```json\n{\n \"mcpServers\": {\n \"android\": {\n \"command\": \"uvx\",\n \"args\": [\"mcp-server-android\"],\n \"env\": {\n \"ANDROID_DEVICE_SERIAL\": \"your-device-serial\", // Optional\n \"ANDROID_AUTO_START_EMULATOR\": \"true\" // Optional, default is true\n }\n }\n }\n}\n```\n\nOr if installed with pip:\n\n```json\n{\n \"mcpServers\": {\n \"android\": {\n \"command\": \"mcp-server-android\",\n \"args\": []\n }\n }\n}\n```\n\n<https://github.com/user-attachments/assets/c45bbc17-f698-43e7-85b4-f1b39b8326a8>\n\n### Available Tools\n\nThe server exposes the following tools:\n\n```python\ndef get_packages() -> str:\n \"\"\"\n Get all installed packages on the device.\n Returns:\n str: A list of all installed packages on the device as a string\n \"\"\"\n```\n\n```python\ndef execute_adb_shell_command(command: str) -> str:\n \"\"\"\n Executes an ADB shell command and returns the output.\n Args:\n command (str): The ADB shell command to execute\n Returns:\n str: The output of the ADB command\n \"\"\"\n```\n\n```python\ndef get_uilayout() -> str:\n \"\"\"\n Retrieves information about clickable elements in the current UI.\n Returns a formatted string containing details about each clickable element,\n including their text, content description, bounds, and center coordinates.\n\n Returns:\n str: A formatted list of clickable elements with their properties\n \"\"\"\n```\n\n```python\ndef get_screenshot() -> Image:\n \"\"\"\n Takes a screenshot of the device and returns it.\n Returns:\n Image: the screenshot\n \"\"\"\n```\n\n```python\ndef get_package_action_intents(package_name: str) -> list[str]:\n \"\"\"\n Get all non-data actions from Activity Resolver Table for a package\n Args:\n package_name (str): The name of the package to get actions for\n Returns:\n list[str]: A list of all non-data actions from the Activity Resolver\n Table for the package\n \"\"\"\n```\n\n#### Emulator Management Tools (New!)\n\n```python\ndef list_devices() -> dict:\n \"\"\"\n List all connected Android devices (physical and emulators).\n Returns device serials and their types.\n \"\"\"\n```\n\n```python\ndef list_emulators() -> dict:\n \"\"\"\n List available Android Virtual Devices (AVDs) that can be started.\n Returns available AVD names and emulator command path.\n \"\"\"\n```\n\n```python\ndef start_emulator_avd(avd_name: str | None = None, headless: bool = False) -> dict:\n \"\"\"\n Start an Android emulator with the specified AVD.\n Args:\n avd_name: Name of the AVD to start. If None, uses first available.\n headless: If True, starts emulator without GUI (faster, uses less resources)\n Returns:\n Status information including success, device_serial, and message\n \"\"\"\n```\n\n```python\ndef stop_emulator(device_serial: str | None = None) -> dict:\n \"\"\"\n Stop a running Android emulator.\n Args:\n device_serial: Serial of the emulator to stop (e.g., 'emulator-5554').\n If None, stops all emulators.\n Returns:\n Status information\n \"\"\"\n```\n\n## Contributing\n\nContributions are welcome!\n\n## Acknowledgments\n\n- Built with\n[Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "MCP server for Android device automation via ADB",
"version": "0.3.1",
"project_urls": {
"Documentation": "https://github.com/minhalvp/android-mcp-server#readme",
"Homepage": "https://github.com/minhalvp/android-mcp-server",
"Issues": "https://github.com/minhalvp/android-mcp-server/issues",
"Repository": "https://github.com/minhalvp/android-mcp-server"
},
"split_keywords": [
"adb",
" android",
" automation",
" debugging",
" mcp",
" testing"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "5785a595f2b91cacabf677480555f9f26d427645122df9b895da6edc70440444",
"md5": "b78881e6f6621045e9f38d763b87bcdb",
"sha256": "aabce096e441e42a07160bba4c2675e9f24970904ace2cdaf48e320505dfe8f1"
},
"downloads": -1,
"filename": "mcp_server_android-0.3.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b78881e6f6621045e9f38d763b87bcdb",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 22384,
"upload_time": "2025-09-10T04:42:36",
"upload_time_iso_8601": "2025-09-10T04:42:36.118503Z",
"url": "https://files.pythonhosted.org/packages/57/85/a595f2b91cacabf677480555f9f26d427645122df9b895da6edc70440444/mcp_server_android-0.3.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "5e58891db3faad30c57d74dcc8961d3310c34587cc1259830b1d0b2b22f40653",
"md5": "046cddf7dec72a98243b5c83d0dc5459",
"sha256": "82a8ab8a1e5e104e7a2cc5662e2fb816101f61365a601a0bcf39d76fd18f3f0a"
},
"downloads": -1,
"filename": "mcp_server_android-0.3.1.tar.gz",
"has_sig": false,
"md5_digest": "046cddf7dec72a98243b5c83d0dc5459",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 15571,
"upload_time": "2025-09-10T04:42:37",
"upload_time_iso_8601": "2025-09-10T04:42:37.409335Z",
"url": "https://files.pythonhosted.org/packages/5e/58/891db3faad30c57d74dcc8961d3310c34587cc1259830b1d0b2b22f40653/mcp_server_android-0.3.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-10 04:42:37",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "minhalvp",
"github_project": "android-mcp-server#readme",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "mcp-server-android"
}