Ultimate Android MCP
Provides tools to interact with Android devices, including application management, input simulation, device information retrieval, file management, UI interaction, and execution of ADB shell commands.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Ultimate Android MCP Launch the Settings app and turn on Wi-Fi."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Ultimate Android MCP 🤖
📝 Description
Ultimate Android MCP is a powerful and versatile MCP (Model Context Protocol) server designed to interact with connected Android devices. It provides a wide range of tools and functionalities to perform various tasks on Android devices, such as managing applications, interacting with the UI, retrieving device information, and more. This project aims to provide the widest set of capabilities to ensure optimal interaction via LLMs using the Model Context Protocol.
Related MCP server: mcp-android-emulator
✨ Features
The MCP server provides the following features:
📱 Application Management
Retrieve a list of all installed packages (system and user-installed).
Retrieve a list of user-installed application package names.
Retrieve a list of system application package names (pre-installed apps).
Launch applications by package name.
Install an APK on the connected Android device.
Uninstall a specified package from the device.
Check if a specified package is installed on the device.
🎮 Input Simulation
Simulate input events such as key presses, taps, swipes, and text input.
Simulate a key event with a specified keycode.
Simulate a tap gesture at specified (x, y) coordinates.
Simulate typing text into the currently focused field.
Simulate a key press event with a specified keycode.
Simulate a rolling gesture with specified dx and dy values.
Simulate a swipe gesture from one coordinate to another with an optional duration.
Check if the virtual keyboard is currently open.
Simulate a back button press.
Simulate a home button press.
📊 Device Information
Retrieve device-specific information, including serial number, properties, and battery level.
Retrieve the serial number of the connected Android device.
Retrieve build.prop properties of the device.
Retrieve device overlay configuration properties.
Retrieve the battery level of the device.
Retrieve the screen density of the device.
Retrieve the screen size of the device.
🖥️ System and Performance Monitoring
Retrieve CPU information, such as core count and load percentage.
Retrieve the number of CPU cores on the device.
Retrieve the current CPU load percentage on the device.
Retrieve top activities and processes.
Retrieve the process ID (PID) for a specified package name.
Retrieve the activities currently on top of the device.
Retrieve the singular activity currently on top of the device.
📂 File Management
Manage files on the device, including pushing and pulling files.
Pull a file from the connected Android device to the local machine.
Push a file from the local machine to the connected Android device.
🖱️ UI Interaction
Retrieve UI elements and focused nodes from the device screen.
Retrieve a list of UI nodes currently visible on the device screen, focusing on text labels and content descriptions.
Retrieve a list of UI nodes that are currently focused on the device screen.
⚙️ Advanced Operations
Execute raw ADB shell commands and retrieve the output.
🎥 Demo
Physical device (Pixel 7 Pro running Android 15) connected via USB, which is having its screen shared via scrcpy. Using Claude for Desktop (Version 0.9.2). The text provided to Claude was the following :
In the connected android device, play the song 'mask off' by future on spotify.
Claude then figured out how to launch the app, which button to click and what text to enter where. Everything in the demo is autonomous with no user interaction in between.
https://github.com/user-attachments/assets/5811fcc1-9047-48be-b057-1049754710c0
📋 Prerequisites
To run this project, ensure you have the following:
Python 3.
ADB (Android Debug Bridge) installed and configured on your system (ensure that
adbcommand works).A connected Android device with USB debugging enabled.
The
pure-python-adblibrary installed (included in the project dependencies).
⚙️ Installation and Setup
Follow these steps to set up the project:
Clone the repository:
git clone https://github.com/oddlyspaced/ultimate-android-mcp.git android-mcp cd android-mcpInstall the required libraries:
By default this project uses
uvfor dependency management, however you can install the required packages via pip if you like.uv syncor
pip install pure-python-adb pip install mcpConfigure the project by editing the
config.pyfile to match your ADB setup and device details. (More in next section)Run
doctor.pyto ensure that the setup is done correctly.Here is reference response from the
doctor.pyscript :Checking device connection using the following configuration: ADB Client Host: 127.0.0.1 ADB Client Port: 5037 ADB Device Serial: 32241FDH3002EH Device connected: 32241FDH3002EH Hello from Android! Ready to use with MCP.
🛠️ Configuration Overview
The config.py file contains the following configuration options:
adb_client_host: The host address of the ADB server (default:127.0.0.1).adb_client_port: The port of the ADB server (default:5037).adb_device_serial: The serial number or IP address of the connected device. If not specified, the first available device will be used.
🖥️ Usage via Claude MCP Config JSON
To use the MCP server, you can interact with it via Claude Desktop MCP configuration JSON.
The Claude Desktop configuration file is present at the following locations:
Windows: %APPDATA%\Claude\claude_desktop_config.json
macOS: ~/Library/Application Support/Claude/claude_desktop_config.jsonHere is an example configuration using uv:
{
"mcpServers": {
"Android MCP": {
"command": "uv",
"args": [
"--directory",
"/Users/hardik/Projects/Android-Agents/android-mcp", // Replace this with your folder path
"run",
"server.py"
]
}
}
}or with python
{
"mcpServers": {
"Android MCP": {
"command": "python",
"args": [
"/Users/hardik/Projects/Android-Agents/android-mcp/server.py", // Replace this with your folder path
]
}
}
}Alternatively, you can run the MCP server using the following command:
python server.py🐞 Known Issues
Often times after continously querying the user interface, results might become unavailable temporarily unless device is restarted. This is an issue with dumping the current UI tree. Logic will be updated to fix this shortly.
💻 Technologies Used
Contributors
Hardik Srivastava (oddlyspaced)
📜 License
This project is licensed under the GNU General Public License v3.0. You may obtain a copy of the license at:
https://www.gnu.org/licenses/gpl-3.0.en.html
This license allows you to use, modify, and distribute the software, provided that any modifications or derivative works are also licensed under the GPL. For more details, refer to the license documentation.
Available Tools
35 toolsall_packagesA
Returns a list of all packages (both system and user-installed) currently installed on the connected Android device. No parameters are required.
Inputs: no named parameters.
cpu_countA
Returns the number of CPU cores on the connected Android device. No parameters are required.
Inputs: no named parameters.
cpu_percentA
Returns the current CPU load percentage on the connected Android device. No parameters are required.
Inputs: no named parameters.
execute_adb_shellC
Executes a raw ADB shell command on the connected Android device and returns the output. Requires the command parameter, which is the shell command to execute.
Inputs: command (required).
get_all_packagesB
Returns a list of all packages on the connected Android device, with optional filters for user-installed or system-installed packages. Accepts user_installed_only and system_installed_only as optional boolean parameters to filter the results.
Inputs: user_installed_only, system_installed_only.
get_battery_levelA
Returns the battery level of the connected Android device. No parameters are required.
Inputs: no named parameters.
get_current_focused_nodesA
Returns a list of UI nodes that are currently focused on the connected Android device screen. No parameters are required.
Inputs: no named parameters.
get_current_ui_labelsA
Returns a list of UI nodes currently visible on the device screen, focusing on text labels and content descriptions. Each node contains properties like text, bounds, clickable, focusable, and others. No parameters are required.
Inputs: no named parameters.
get_pidB
Returns the process ID (PID) for the specified package name on the connected Android device. Requires the package_name parameter, which is the name of the package to query.
Inputs: package_name (required).
get_propertiesA
Returns the build.prop properties of the connected Android device. No parameters are required.
Inputs: no named parameters.
get_serial_noA
Returns the serial number of the connected Android device. No parameters are required.
Inputs: no named parameters.
get_system_packagesB
Returns a list of system-installed packages on the connected Android device. No parameters are required.
Inputs: no named parameters.
get_top_activitiesB
Returns the activities currently on top on the connected Android device. No parameters are required.
Inputs: no named parameters.
get_top_activityA
Returns the singular activity currently on top on the connected Android device. No parameters are required.
Inputs: no named parameters.
get_user_packagesA
Returns a list of user-installed packages on the connected Android device. No parameters are required.
Inputs: no named parameters.
input_backB
Simulates a back button event on the connected Android device. No parameters are required.
Inputs: no named parameters.
input_homeA
Simulates a home button event on the connected Android device. No parameters are required.
Inputs: no named parameters.
input_keyeventC
Simulates a key event with the specified keycode on the connected Android device. Requires the keycode parameter, which is the keycode of the key to simulate.
Inputs: keycode (required).
input_pressC
Simulates a key press event with the specified keycode on the connected Android device. Requires the keycode parameter, which is the keycode of the key to press.
Inputs: keycode (required).
input_rollB
Simulates a rolling gesture with the specified dx and dy values on the connected Android device. Requires dx and dy parameters, which are the rolling distances in the x and y directions respectively.
Inputs: dx (required), dy (required).
input_swipeB
Simulates a swipe gesture from (x1, y1) to (x2, y2) with an optional duration on the connected Android device. Requires x1, y1, x2, y2 parameters for the start and end coordinates, and an optional duration_ms parameter for the swipe duration in milliseconds.
Inputs: x1 (required), x2 (required), y1 (required), y2 (required), +1 more.
input_tapA
Simulates a tap gesture at the specified (x, y) coordinates on the connected Android device screen. Requires x and y parameters, which are the coordinates of the tap.
Inputs: x (required), y (required).
input_textA
Simulates typing the given text input into the currently focused field on the connected Android device. Requires the text parameter, which is the string to be typed.
Inputs: text (required).
install_apkB
Installs an APK on the connected Android device. Requires the apk_path parameter, which is the path to the APK file to be installed.
Inputs: apk_path (required).
is_installedA
Checks if the specified package is installed on the connected Android device. Requires the package_name parameter, which is the name of the package to check.
Inputs: package_name (required).
is_keyboard_openA
Checks if the virtual keyboard is currently open on the connected Android device. No parameters are required.
Inputs: no named parameters.
launch_appC
Launches the app with the specified package name on the connected Android device. Requires the package_name parameter, which is the package name of the app to be launched.
Inputs: package_name (required).
list_featuresA
Returns the device overlay configuration properties of the connected Android device. No parameters are required.
Inputs: no named parameters.
pull_fileA
Pulls a file from the connected Android device to the local machine. Requires remote and local parameters, which are the paths of the file on the device and the local machine respectively.
Inputs: local (required), remote (required).
push_fileA
Pushes a file from the local machine to the connected Android device. Requires local and remote parameters, which are the paths of the file on the local machine and the device respectively.
Inputs: local (required), remote (required).
system_packagesA
Returns a list of system application package names (pre-installed apps) on the connected Android device. No parameters are required.
Inputs: no named parameters.
uninstall_packageA
Uninstalls the specified package from the connected Android device. Requires the package_name parameter, which is the name of the package to uninstall.
Inputs: package_name (required).
user_packagesA
Returns a list of user-installed application package names on the connected Android device. No parameters are required.
Inputs: no named parameters.
wm_densityA
Returns the screen density of the connected Android device. No parameters are required.
Inputs: no named parameters.
wm_sizeA
Returns the screen size of the connected Android device. No parameters are required.
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 35 tools
Several tools are exact duplicates in purpose: all_packages/get_all_packages, user_packages/get_user_packages, system_packages/get_system_packages, and input_keyevent/input_press both accept a keycode. get_top_activity and get_top_activities also blur together, so an agent would frequently misselect.
Naming mixes bare nouns (all_packages, cpu_count, wm_size), get_-prefixed getters (get_properties, get_serial_no), and verb-first actions (launch_app, pull_file). The get_/no-prefix duplication for package listing makes the inconsistency worse, though the input_ prefix shows some grouping.
35 tools is well above the typical coherent range, mostly because of redundant package-list and input commands. A tighter set of 20-25 tools would cover the same functionality without the duplication.
The surface covers package management, UI inspection, input injection, device info, file transfer, and raw shell access, which is broad enough for many Android automation workflows. Gaps like screenshot capture or logcat are workarounds via execute_adb_shell.
Maintenance
Related MCP Connectors
Give your AI agent a real cloud Android phone: push APKs, drive it, get screenshots and logs.
Cloud Android phones for AI agents: create a phone, read the screen, tap, type, install APKs, park.
Let AI agents control Android and iOS devices on Mobilerun Cloud: screen, input, apps, workflows.
AI agents on real phones: run tasks, read the screen, tap, type and install apps.
Related MCP Servers
- AlicenseBqualityCmaintenanceEnables control of Android devices via ADB for automation and testing. Supports app management, screen capture, UI analysis, and input simulation through natural language commands.9167 npm38MIT
- AlicenseBqualityDmaintenanceEnables AI assistants to interact with Android devices and emulators via ADB, providing tools for screenshots, UI inspection, touch and text input, app management, and device control.42200 npm22MIT
- AlicenseAqualityDmaintenanceEnables AI models to control Android devices via ADB through natural language commands, supporting screen analysis and automated actions.346 npmMIT
- AlicenseBqualityDmaintenanceEnables AI agents to control Android devices via ADB, supporting gestures, input, screenshots, UI analysis, and app management.1914 npm1ISC