jduartedj/android-mcp-server
If you are the rightful owner of android-mcp-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 dayong@mcphub.com.
A Model Context Protocol (MCP) server that provides Android device control capabilities via ADB (Android Debug Bridge).
Android MCP Server
A Model Context Protocol (MCP) server providing comprehensive Android device control with 22 powerful tools for UI automation, screen capture, and ultra-fast H.264 streaming via Scrcpy.
Features
- 📸 Screenshots: Capture screenshots from Android devices
- 👆 Touch & Gestures: Simulate touch, long press, swipe, and multi-point interactions
- ⌨️ Text Input & Key Events: Direct text input and key event simulation (2 tools)
- Send key events (HOME, BACK, ENTER, etc.)
- Input text directly into focused fields
- 🔧 Generic ADB Commands: Execute any ADB command with custom parameters (1 tool)
- Full flexibility for agents to run custom ADB operations
- Access to all ADB functionality (logcat, shell commands, package manager, etc.)
- 🎯 UIAutomator: Full UI hierarchy inspection and element interaction (10 tools)
- Dump complete XML UI hierarchy
- Find elements by resource ID or text
- Click, double-click, long-click on elements
- Set/clear text in input fields
- Toggle checkboxes
- Wait for elements to appear
- Scroll within specific elements
- ⚡ Scrcpy Streaming: Ultra-fast H.264 video streaming (4 tools)
- Start/stop H.264 video streams (~2s setup, <50ms frame polling)
- Capture single frames (100-300ms) or latest stream frames (<50ms)
- Dramatically faster than screenshot capture
- 🚀 App Management: Launch apps and list installed packages
- 🔌 ADB Integration: Direct integration with Android Debug Bridge
- ⚡ Auto-Download: Automatically downloads ADB and Scrcpy from official sources
Prerequisites
- Node.js 18 or higher
- Android device connected via USB with USB debugging enabled, or emulator running
Note: ADB (Android Debug Bridge) and Scrcpy are optional - the server automatically downloads them from official sources on first use if needed.
Quick Start
-
Clone and Build
git clone https://github.com/jduartedj/android-mcp-server.git cd android-mcp-server npm install npm run build -
Test the Server
node dist/index.jsThe server will start and automatically download ADB/Scrcpy if needed.
-
Add to VS Code (see VS Code Integration below)
Installation
npm install
npm run build
Usage
Running the Server Standalone
node dist/index.js
Configuration
The server supports the following environment variables:
ADB_PATH: Custom path to ADB executable (default: uses system PATH or auto-downloads)DEVICE_SERIAL: Specific device serial number to target (default: first available device)
VS Code Integration
Adding to VS Code GitHub Copilot
To use this MCP server with GitHub Copilot in VS Code:
-
Open VS Code Settings (Ctrl+, or Cmd+,)
-
Search for MCP or navigate to:
GitHub Copilot > Chat > MCP Servers -
Edit the MCP configuration by clicking "Edit in settings.json"
-
Add the Android MCP Server to your configuration:
{
"github.copilot.chat.mcp.servers": {
"android-mcp-server": {
"command": "node",
"args": ["F:\\android-mcp-server\\dist\\index.js"],
"env": {
"ADB_PATH": "",
"DEVICE_SERIAL": ""
}
}
}
}
Note: Replace F:\\android-mcp-server\\dist\\index.js with the actual absolute path to your dist/index.js file. Use double backslashes on Windows.
- Alternative: Using npx (if published to npm):
{
"github.copilot.chat.mcp.servers": {
"android-mcp-server": {
"command": "npx",
"args": ["-y", "android-mcp-server"]
}
}
}
- Reload VS Code or restart the GitHub Copilot extension
Verifying the Integration
After adding the server:
- Open GitHub Copilot Chat in VS Code
- Type
@workspaceand you should see the Android MCP tools available - Try asking: "Take a screenshot of my Android device"
- Copilot will use the appropriate tool to capture the screen
Example Prompts for Copilot
Once integrated, you can ask GitHub Copilot:
- "Take a screenshot of my Android device"
- "Start streaming my device screen for real-time monitoring"
- "Get the latest frame from the stream"
- "Tap at coordinates 500, 1000 on my phone"
- "Swipe up on my Android screen"
- "Press the back button on my device"
- "Send the home key event"
- "Type 'hello world' into the current field"
- "Press enter to submit the form"
- "Get the device battery status using ADB"
- "Read the logcat output for debugging"
- "Clear the app data for com.example.app"
- "List all installed packages"
- "Launch the Chrome app"
- "Find the login button and click it"
- "Fill in the email field with user@example.com"
- "Dump the UI hierarchy of the current screen"
- "Long press on the menu button"
- "Scroll down in the settings list"
- "Toggle the enable notifications checkbox"
- "Wait for the loading indicator to disappear"
All 22 MCP Tools
Basic Tools (5)
1. android_screenshot
Capture a screenshot from the Android device.
Parameters:
outputPath(optional): Local path to save the screenshot. If not provided, returns base64 encoded image.deviceSerial(optional): Target specific device by serial number
Performance: ~1-2 seconds per capture
Example:
{
"name": "android_screenshot",
"arguments": {
"outputPath": "./screenshot.png"
}
}
2. android_touch
Simulate a touch event at specific screen coordinates. Supports both quick taps and long presses.
Parameters:
x(required): X coordinatey(required): Y coordinateduration(optional): Touch duration in milliseconds (default: 100ms for tap, >100ms for long press)deviceSerial(optional): Target specific device by serial number
Performance: Immediate
Example - Quick Tap:
{
"name": "android_touch",
"arguments": { "x": 500, "y": 1000, "duration": 100 }
}
Example - Long Press:
{
"name": "android_touch",
"arguments": { "x": 500, "y": 1000, "duration": 2000 }
}
3. android_swipe
Perform a swipe gesture between two coordinates.
Parameters:
startX(required): Starting X coordinatestartY(required): Starting Y coordinateendX(required): Ending X coordinateendY(required): Ending Y coordinateduration(optional): Swipe duration in milliseconds (default: 300)deviceSerial(optional): Target specific device by serial number
Performance: Immediate
Example:
{
"name": "android_swipe",
"arguments": {
"startX": 500, "startY": 1500, "endX": 500, "endY": 500, "duration": 300
}
}
4. android_launch_app
Launch an Android app by package name.
Parameters:
packageName(required): Package name of the app (e.g., com.example.app, com.google.android.apps.maps)deviceSerial(optional): Target specific device by serial number
Performance: ~1-2 seconds
Example:
{
"name": "android_launch_app",
"arguments": { "packageName": "com.example.app" }
}
5. android_list_packages
List installed packages on the Android device with optional filtering.
Parameters:
filter(optional): Search filter for package names (case-insensitive)deviceSerial(optional): Target specific device by serial number
Performance: Medium (retrieves full package list)
Example - List All Packages:
{
"name": "android_list_packages",
"arguments": {}
}
Example - Filter Packages:
{
"name": "android_list_packages",
"arguments": { "filter": "google" }
}
Text Input & Key Event Tools (2)
6. android_input_text
Input text into the currently focused field on the Android device via ADB.
Parameters:
text(required): Text to input. Spaces are automatically handled.deviceSerial(optional): Target specific device by serial number
Performance: Immediate
Use Cases:
- Quick text input without UIAutomator
- Inputting text when element resource ID is unknown
- Simple form filling
- Command-line style text entry
Example:
{
"name": "android_input_text",
"arguments": {
"text": "user@example.com"
}
}
7. android_send_key_event
Send a key event to the Android device (e.g., HOME, BACK, ENTER).
Parameters:
keyCode(required): Key event code. Can be key name (e.g., KEYEVENT_HOME, KEYEVENT_BACK) or numeric code (e.g., 3 for HOME, 4 for BACK)deviceSerial(optional): Target specific device by serial number
Performance: Immediate
Common Key Codes:
KEYEVENT_HOMEor3- Home buttonKEYEVENT_BACKor4- Back buttonKEYEVENT_ENTERor66- Enter/Return keyKEYEVENT_DELor67- Delete keyKEYEVENT_MENUor82- Menu buttonKEYEVENT_VOLUME_UPor24- Volume upKEYEVENT_VOLUME_DOWNor25- Volume downKEYEVENT_POWERor26- Power button
Use Cases:
- Navigation (HOME, BACK)
- Submitting forms (ENTER)
- Controlling device functions (VOLUME, POWER)
- Keyboard shortcuts
Example:
{
"name": "android_send_key_event",
"arguments": {
"keyCode": "KEYEVENT_BACK"
}
}
Generic ADB Command Tool (1)
8. android_execute_command
Execute a generic ADB command with custom arguments. This powerful tool gives agents full flexibility to run any ADB command with their own parameters.
Parameters:
args(required): Array of ADB command arguments (e.g., ["shell", "pm", "list", "packages"])deviceSerial(optional): Target specific device by serial number
Performance: Varies by command
Returns: Both stdout and stderr from the command execution
Use Cases:
- Execute custom shell commands
- Access logcat for debugging
- Manage packages (install, uninstall, clear data)
- Query device properties
- File operations (push, pull)
- Network operations (port forwarding)
- Any ADB functionality not covered by specific tools
Common Examples:
List all packages:
{
"name": "android_execute_command",
"arguments": {
"args": ["shell", "pm", "list", "packages"]
}
}
Get device properties:
{
"name": "android_execute_command",
"arguments": {
"args": ["shell", "getprop", "ro.build.version.release"]
}
}
Read logcat:
{
"name": "android_execute_command",
"arguments": {
"args": ["logcat", "-d", "-s", "MyTag:V"]
}
}
Clear app data:
{
"name": "android_execute_command",
"arguments": {
"args": ["shell", "pm", "clear", "com.example.app"]
}
}
Get battery info:
{
"name": "android_execute_command",
"arguments": {
"args": ["shell", "dumpsys", "battery"]
}
}
Push file to device:
{
"name": "android_execute_command",
"arguments": {
"args": ["push", "/local/path/file.txt", "/sdcard/file.txt"]
}
}
Install APK:
{
"name": "android_execute_command",
"arguments": {
"args": ["install", "-r", "/path/to/app.apk"]
}
}
Port forwarding:
{
"name": "android_execute_command",
"arguments": {
"args": ["forward", "tcp:8080", "tcp:8080"]
}
}
UIAutomator Tools (10)
9. android_uiautomator_dump
Dump the complete UI hierarchy of the current screen as XML for inspection and element identification.
Parameters:
deviceSerial(optional): Target specific device by serial number
Returns: Complete XML UI hierarchy that can be parsed to find element resource IDs and attributes.
Performance: ~500-800ms
Use Cases:
- Inspecting app UI structure
- Finding element resource IDs for automation
- Understanding view hierarchies
Example:
{
"name": "android_uiautomator_dump",
"arguments": {}
}
10. android_uiautomator_find
Find UI elements by resource ID or text content using UIAutomator.
Parameters:
resourceId(optional): Resource ID to search for (e.g., com.example.app:id/button_submit)text(optional): Text content to search fordeviceSerial(optional): Target specific device by serial number
Performance: Fast
Example - Find by Resource ID:
{
"name": "android_uiautomator_find",
"arguments": { "resourceId": "com.example.app:id/email_input" }
}
Example - Find by Text:
{
"name": "android_uiautomator_find",
"arguments": { "text": "Submit" }
}
11. android_uiautomator_click
Click on a UI element by resource ID.
Parameters:
resourceId(required): Resource ID of the element to clickdeviceSerial(optional): Target specific device by serial number
Performance: Immediate
Example:
{
"name": "android_uiautomator_click",
"arguments": { "resourceId": "com.example.app:id/button_submit" }
}
12. android_uiautomator_double_click
Perform a double-click on a UI element by resource ID.
Parameters:
resourceId(required): Resource ID of the elementdeviceSerial(optional): Target specific device by serial number
Performance: Immediate
Example:
{
"name": "android_uiautomator_double_click",
"arguments": { "resourceId": "com.example.app:id/text_field" }
}
13. android_uiautomator_long_click
Perform a long-click on a UI element by resource ID.
Parameters:
resourceId(required): Resource ID of the elementdeviceSerial(optional): Target specific device by serial number
Performance: Immediate
Example:
{
"name": "android_uiautomator_long_click",
"arguments": { "resourceId": "com.example.app:id/menu_item" }
}
14. android_uiautomator_set_text
Set text on a UI element by resource ID. Automatically clears existing text first.
Parameters:
resourceId(required): Resource ID of the elementtext(required): Text to setdeviceSerial(optional): Target specific device by serial number
Performance: Immediate
Example:
{
"name": "android_uiautomator_set_text",
"arguments": {
"resourceId": "com.example.app:id/email_input",
"text": "user@example.com"
}
}
15. android_uiautomator_clear_text
Clear text from a UI element by resource ID.
Parameters:
resourceId(required): Resource ID of the elementdeviceSerial(optional): Target specific device by serial number
Performance: Immediate
Example:
{
"name": "android_uiautomator_clear_text",
"arguments": { "resourceId": "com.example.app:id/search_input" }
}
16. android_uiautomator_toggle_checkbox
Toggle a checkbox element by resource ID.
Parameters:
resourceId(required): Resource ID of the checkboxdeviceSerial(optional): Target specific device by serial number
Performance: Immediate
Example:
{
"name": "android_uiautomator_toggle_checkbox",
"arguments": { "resourceId": "com.example.app:id/agree_checkbox" }
}
17. android_uiautomator_wait
Wait for a UI element to appear by resource ID with timeout support.
Parameters:
resourceId(required): Resource ID to wait fortimeoutMs(optional): Maximum wait time in milliseconds (default: 5000)deviceSerial(optional): Target specific device by serial number
Performance: Configurable (up to timeout)
Example:
{
"name": "android_uiautomator_wait",
"arguments": {
"resourceId": "com.example.app:id/loading_indicator",
"timeoutMs": 10000
}
}
18. android_uiautomator_scroll_in_element
Scroll within a specific scrollable UI element.
Parameters:
resourceId(required): Resource ID of the scrollable elementdirection(required): Direction to scroll (up, down, left, right)distance(optional): Distance to scroll in pixels (default: 500)deviceSerial(optional): Target specific device by serial number
Performance: Immediate
Example:
{
"name": "android_uiautomator_scroll_in_element",
"arguments": {
"resourceId": "com.example.app:id/list_view",
"direction": "down",
"distance": 500
}
}
Scrcpy Streaming Tools (4)
Scrcpy streaming provides ultra-fast frame capture using H.264 video encoding, perfect for real-time monitoring, rapid screenshot sequences, or continuous frame polling.
19. android_start_scrcpy_stream
Initialize an H.264 video stream from the Android device using Scrcpy.
Parameters:
deviceSerial(optional): Target specific device by serial numberbitrate(optional): Video bitrate in Mbps (default: 4)fps(optional): Frames per second (default: 60)
Performance: ~2 seconds setup, <50ms per frame polling afterward
Advantages:
- Ultra-fast frame capture (<50ms vs 1-2s for screenshot)
- Continuous streaming with pre-buffered frames
- Ideal for real-time monitoring
- H.264 compression reduces bandwidth
Example:
{
"name": "android_start_scrcpy_stream",
"arguments": {
"bitrate": 4,
"fps": 30
}
}
20. android_get_latest_frame
Poll the latest frame from an active Scrcpy stream.
Parameters:
deviceSerial(optional): Target specific device by serial numberoutputPath(optional): Save frame to file, otherwise returns base64
Performance: <50ms per frame (due to pre-buffered streaming)
Use Cases:
- Real-time monitoring
- Rapid screenshot sequences
- Continuous frame polling
- Streaming visualization
Example:
{
"name": "android_get_latest_frame",
"arguments": {
"outputPath": "./current_frame.png"
}
}
21. android_stop_scrcpy_stream
Stop an active Scrcpy H.264 stream.
Parameters:
deviceSerial(optional): Target specific device by serial number
Example:
{
"name": "android_stop_scrcpy_stream",
"arguments": {}
}
22. android_capture_frame_scrcpy
Capture a single frame using Scrcpy without starting a persistent stream.
Parameters:
deviceSerial(optional): Target specific device by serial numberoutputPath(optional): Save frame to file, otherwise returns base64bitrate(optional): Video bitrate in Mbps (default: 4)
Performance: 100-300ms (faster than screenshot, slower than streaming)
Use Cases:
- One-off frame captures
- When streaming overhead isn't justified
- Single frame comparison
- Lightweight capture operations
Example:
{
"name": "android_capture_frame_scrcpy",
"arguments": {
"outputPath": "./single_frame.png"
}
}
Performance Comparison
| Tool | Purpose | Speed | Best For |
|---|---|---|---|
android_screenshot | Basic capture | 1-2s | Simple screenshots, initial inspection |
android_capture_frame_scrcpy | Single Scrcpy frame | 100-300ms | Faster one-off captures than screenshot |
android_start_scrcpy_stream | Initialize stream | ~2s setup | Real-time monitoring workflows |
android_get_latest_frame | Poll stream | <50ms | Rapid frame sequences, real-time apps |
android_touch | Tap/long press | Immediate | UI interaction |
android_swipe | Swipe gesture | Immediate | Navigation, scrolling |
android_input_text | Direct text input | Immediate | Quick text entry via ADB |
android_send_key_event | Key events | Immediate | Navigation (HOME, BACK, ENTER) |
android_execute_command | Generic ADB | Varies | Custom ADB operations, full flexibility |
android_uiautomator_dump | UI inspection | 500-800ms | Element discovery |
android_uiautomator_find | Element search | Fast | Located specific elements |
android_uiautomator_* | Element interaction | Immediate | Form filling, UI automation |
Common Use Cases
1. Automated Testing
1. Dump UI hierarchy to find element IDs
2. Click buttons and input text using resource IDs
3. Use streaming to verify visual changes in real-time
4. Scroll and navigate through the app
2. Real-Time Monitoring
1. Start Scrcpy stream (one-time ~2s setup)
2. Poll latest frames continuously (<50ms each)
3. Process frames for visual analysis
4. Stop stream when done
3. Rapid Frame Capture Sequence
1. Start Scrcpy stream
2. Get latest frame multiple times (much faster than screenshot)
3. Process frame sequence for animation/comparison
4. Stop stream
4. Form Filling (WebView or Native)
1. Find form fields by resource ID or text
2. Clear existing text
3. Set new text values
4. Toggle checkboxes and radio buttons
5. Click submit button
5. Multi-Device Automation
Use deviceSerial parameter to target specific devices:
1. List connected devices via ADB
2. Specify device serial for each tool call
3. Automate workflows on multiple devices in parallel
4. Useful for device farms and testing labs
6. App Discovery
1. List all packages (potentially 100+)
2. Filter packages by name (e.g., "google", "com.example")
3. Launch apps by package name
4. Perfect for discovering available apps on the device
ADB & Scrcpy Setup
Automatic Installation
The server automatically downloads and installs from official sources:
- ADB: From Android Platform Tools
- Scrcpy: From official releases
Downloaded tools stored in ~/.android-mcp-server/platform-tools/
Manual Installation (Optional)
Windows:
choco install adb
choco install scrcpy
macOS:
brew install android-platform-tools
brew install scrcpy
Linux (Ubuntu/Debian):
sudo apt-get install android-tools-adb scrcpy
Enabling USB Debugging on Android
- Go to Settings → About Phone
- Tap Build Number 7 times to enable Developer Options
- Go to Settings → Developer Options
- Enable USB Debugging
- Connect device via USB and accept the debugging prompt
Verify Connection
adb devices
You should see your device listed.
Troubleshooting
| Issue | Solution |
|---|---|
| "No Android devices found" | Ensure device is connected via USB and USB debugging is enabled. Run adb devices to verify. |
| UIAutomator element not found | Use android_uiautomator_dump to inspect the XML and verify the resource ID exists. |
| Scrcpy stream won't start | Ensure Scrcpy is installed or allow auto-download to complete. Check device is connected. |
| "ADB not found" error | Run the server once to auto-download ADB, or manually install platform-tools. |
| Touch coordinates not working | Verify coordinates are within screen bounds. Use screenshots to determine correct coordinates. |
| App launch fails | Verify package name is correct using android_list_packages. Try filtering if unsure. |
| Streaming frames are slow | Reduce bitrate/fps or use single android_capture_frame_scrcpy for one-off captures. |
Advanced Patterns
Real-Time Visual Monitoring
1. android_start_scrcpy_stream (2s setup)
2. Loop: android_get_latest_frame (<50ms each)
3. Process frames for ML/analysis
4. android_stop_scrcpy_stream when done
Stress Testing with Rapid Frames
1. Start stream
2. Perform action on device
3. Capture 10+ frames in rapid succession (<50ms each)
4. Compare frame changes for regression detection
Multi-Step Form Automation
1. android_uiautomator_dump (find all fields)
2. For each field:
- android_uiautomator_find (locate)
- android_uiautomator_set_text (fill)
3. android_uiautomator_click (submit)
4. android_uiautomator_wait (result screen)
5. android_screenshot (verify)
Device Farm Parallel Testing
1. Get device list
2. For each device:
- Specify deviceSerial in all tool calls
- Run automation sequence
- Compare results across devices
Architecture
The server uses the Model Context Protocol to expose Android device control:
- ADB Wrapper (
src/adb-wrapper.ts): Device communication, auto-downloads ADB - Scrcpy Integration (
src/adb-wrapper.ts): H.264 streaming, frame polling - UIAutomator Methods (
src/adb-wrapper.ts): Full XML dumping, element interaction - Tool Handlers (
src/handlers.ts): All 19 tool operations - MCP Server (
src/index.ts): Exposes all tools via Model Context Protocol
Supported Android Versions
- Android 5.0+ (API Level 21+)
- Scrcpy streaming: Android 5.0+ via ADB, optimal on 7.0+
Development
# Install dependencies
npm install
# Build
npm run build
# Watch mode (if supported)
npm run watch
Adding New Tools
To add a new tool:
- Implement method in
src/adb-wrapper.ts - Implement handler in
src/handlers.ts - Register tool in
src/index.tswith name, description, and schema - Build and test with the server running
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.