Skip to main content
Glama
mcp-android-emulator

mcp-android-emulator

by Anjos2

MCP Android Emulator

npm version License: MIT

A Model Context Protocol (MCP) server that enables AI assistants like Claude to interact with Android devices and emulators via ADB (Android Debug Bridge).

Features

  • Screenshots: Capture device screen as base64 images

  • UI Inspection: Get UI hierarchy (like DOM but for Android)

  • Touch Input: Tap, swipe, scroll, pinch zoom, multi-tap gestures

  • Text Input: Type, clear, select all, set text in input fields

  • System Keys: Press BACK, HOME, ENTER, VOLUME, etc.

  • App Management: Launch, install, force stop, clear data

  • Clipboard: Get and set clipboard content

  • Device Control: Rotate screen, get device info

  • Logs: Access logcat with filters and log levels

  • Wait & Assert: Wait for elements, UI stability, assertions for testing

  • Safe Interactions: Tap avoiding system bars, element bounds detection

Related MCP server: autoglm-mcp-server

Requirements

  • Node.js 18+

  • ADB (Android Debug Bridge) installed

  • One of the following:

    • Android Studio Emulator (AVD)

    • Redroid (Docker-based Android)

    • Genymotion

    • Physical Android device via USB/WiFi

Installation

npm install -g mcp-android-emulator

From source

git clone https://github.com/Anjos2/mcp-android-emulator.git
cd mcp-android-emulator
npm install
npm run build

Quick Start

1. Ensure ADB is working

adb devices
# Should show your device/emulator

2. Add to Claude Code

claude mcp add android-emulator -- npx mcp-android-emulator

3. Start using

Ask Claude: "Take a screenshot of the Android device"


Configuration

Environment Variables

Variable

Default

Description

ADB_PATH

adb

Path to ADB executable

SCREENSHOT_DIR

/tmp/android-screenshots

Directory for temporary screenshots

Claude Code Integration

Option 1: CLI command

claude mcp add android-emulator -- npx mcp-android-emulator

Option 2: Manual configuration

Edit ~/.claude.json:

{
  "mcpServers": {
    "android-emulator": {
      "command": "npx",
      "args": ["mcp-android-emulator"],
      "env": {
        "ADB_PATH": "/path/to/adb"
      }
    }
  }
}

Claude Desktop Integration

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "android-emulator": {
      "command": "npx",
      "args": ["mcp-android-emulator"],
      "env": {
        "ADB_PATH": "/path/to/adb"
      }
    }
  }
}

Available Tools (40 tools)

Screen Capture & UI

Tool

Description

screenshot

Capture screen as base64 PNG image

get_ui_tree

Get UI element hierarchy with coordinates

get_all_text

Get all visible text elements on screen (for debugging)

get_clickable_elements

NEW Get all clickable elements with text/id/coordinates (useful when tap_text fails)

get_screen_size

Get screen dimensions and density

get_focused_element

Get info about currently focused element

is_element_visible

Check if element is visible on screen

get_element_bounds

Get exact coordinates of an element

assert_screen_contains

Assert text is visible (for testing)

Touch Interactions

Tool

Description

tap

Tap at specific coordinates

tap_text

Find element by text and tap it

tap_element

Tap element by text or resource-id (more reliable)

tap_safe

Tap avoiding system navigation bars

double_tap

Double tap at coordinates

long_press

Long press for context menus

multi_tap

Multiple rapid taps at same position

swipe

Swipe between two points

scroll

Scroll in a direction (up/down/left/right)

scroll_to_text

Scroll until text is visible

drag

Drag gesture for drag & drop

pinch_zoom

Pinch zoom gesture (zoom in/out)

Text Input

Tool

Description

type_text

Type text into focused input

clear_input

Clear focused text field

select_all

Select all text in focused field

set_text

Clear and type new text (combines both)

get_focused_input_value

NEW Get current text value of focused input

is_keyboard_visible

NEW Check if soft keyboard is currently visible

System & Keys

Tool

Description

press_key

Press system key (BACK, HOME, ENTER, etc.)

rotate_device

Rotate to portrait or landscape

set_clipboard

Set text to device clipboard

get_clipboard

Get clipboard content

App Management

Tool

Description

launch_app

Launch app by package name

install_apk

Install APK file

list_packages

List installed packages

clear_app_data

Clear app data

force_stop

Force stop an app

get_current_activity

Get currently focused activity

Device Info & Logs

Tool

Description

device_info

Get device model, Android version, screen size

get_logs

Get logcat logs with filters and log levels

Wait & Sync

Tool

Description

wait_for_element

Wait for element with text to appear

wait_for_element_gone

Wait for element to disappear

wait_for_ui_stable

Wait for UI to stop changing (after animations)


Emulator Setup Guides

Option 1: Android Studio Emulator (AVD)

Best for: Local development on machines with display

# List available AVDs
emulator -list-avds

# Start emulator
emulator -avd YOUR_AVD_NAME

# Verify connection
adb devices

Best for: Headless servers, CI/CD, cloud VPS

Redroid runs Android in a Docker container without requiring KVM on x86.

# Run Redroid container
docker run -d --name redroid \
  --privileged \
  -p 5555:5555 \
  redroid/redroid:13.0.0-latest \
  androidboot.redroid_width=720 \
  androidboot.redroid_height=1280 \
  androidboot.redroid_dpi=320

# Connect ADB
adb connect localhost:5555

# Verify
adb devices

For apps using network (React Native, Expo, etc.):

# Forward ports from device to host
adb reverse tcp:8081 tcp:8081  # Metro bundler
adb reverse tcp:3000 tcp:3000  # API server

Option 3: Genymotion

Best for: Local development, faster than AVD

  1. Download from genymotion.com

  2. Create and start a virtual device

  3. Enable ADB bridge in settings

  4. Connect: adb connect localhost:5555

Option 4: Physical Device

Best for: Real-world testing

USB Connection:

  1. Enable Developer Options on device

  2. Enable USB Debugging

  3. Connect via USB

  4. Run adb devices

WiFi Connection:

# First connect via USB, then:
adb tcpip 5555
adb connect DEVICE_IP:5555
# Disconnect USB

Running on Cloud/VPS Servers

Prerequisites

  • Linux server (Ubuntu 20.04+ recommended)

  • Docker installed

  • At least 4GB RAM, 2 CPU cores

Step-by-Step Setup

1. Install ADB

# Ubuntu/Debian
sudo apt update
sudo apt install android-tools-adb

# Verify
adb version

2. Run Redroid

docker run -d --name redroid \
  --privileged \
  -p 5555:5555 \
  redroid/redroid:13.0.0-latest \
  androidboot.redroid_width=720 \
  androidboot.redroid_height=1280 \
  androidboot.redroid_dpi=320

3. Connect ADB

adb connect localhost:5555
adb devices  # Should show "localhost:5555 device"

4. Install Node.js and MCP

# Install Node.js 18+
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs

# Install MCP
npm install -g mcp-android-emulator

5. Configure Claude Code

claude mcp add android-emulator -- npx mcp-android-emulator

Running AVD Headless (Alternative)

If you have KVM support:

# Install Android SDK
sudo apt install openjdk-11-jdk
wget https://dl.google.com/android/repository/commandlinetools-linux-latest.zip
# ... setup SDK ...

# Run emulator headless
emulator -avd YOUR_AVD \
  -no-window \
  -no-audio \
  -no-boot-anim \
  -gpu swiftshader_indirect \
  -memory 2048 \
  -cores 2

Usage Examples

Once configured, ask Claude to:

"Take a screenshot of the Android device"

"Tap on the Login button"

"Type 'hello@example.com' in the email field and press Enter"

"Scroll down until you see 'Submit' and tap it"

"Launch the Chrome app and navigate to google.com"

"Get error logs from the last 100 lines"

"Wait for the loading spinner to disappear, then take a screenshot"

"Check if 'Welcome' text is visible on screen"

"Rotate the device to landscape mode"

Automated Testing Example

"Test the login flow:
1. Take a screenshot of the initial state
2. Type 'testuser' in the username field
3. Type 'password123' in the password field
4. Tap the Login button
5. Wait for the UI to stabilize
6. Assert that 'Dashboard' is visible
7. Take a final screenshot"

Troubleshooting

ADB not found

# Check if ADB is installed
which adb

# If not found, install it
sudo apt install android-tools-adb  # Ubuntu/Debian
brew install android-platform-tools  # macOS

# Or set custom path
export ADB_PATH=/path/to/android-sdk/platform-tools/adb

No devices connected

# List devices
adb devices

# If using Redroid, connect explicitly
adb connect localhost:5555

# Check if emulator is fully booted
adb shell getprop sys.boot_completed  # Should return "1"

Permission denied on screenshots

mkdir -p /tmp/android-screenshots
chmod 755 /tmp/android-screenshots

Redroid container won't start

# Check logs
docker logs redroid

# Ensure privileged mode
docker run --privileged ...

# Try different Android version
docker run ... redroid/redroid:11.0.0-latest

Apps can't reach localhost services

# Forward ports from device to host
adb reverse tcp:8081 tcp:8081
adb reverse tcp:3000 tcp:3000

# Verify
adb reverse --list

Changelog

See CHANGELOG.md for the full history.

v2.0.0 (Latest) — Security release

  • Eliminated command injection across the MCP tool surface (issue #1). The ADB execution layer was rebuilt on child_process.execFile, and every LLM-controlled input now passes through strict zod allowlists before reaching the device shell.

  • Dependencies pinned to exact versions (npm audit clean).

  • New SECURITY.md with responsible disclosure policy.

  • Breaking: stricter allowlists reject some inputs previously accepted. See CHANGELOG.md for migration notes.

v1.4.0

  • New tools:

    • get_clickable_elements - Get all clickable elements with text, resource-id, class, and coordinates. Useful when tap_text fails to find an element.

v1.3.0

  • New tools:

    • get_all_text - Get all visible text elements on screen (useful for debugging)

    • is_keyboard_visible - Check if soft keyboard is currently visible

    • get_focused_input_value - Get current text value of focused input field

  • Improvements:

    • wait_for_ui_stable - Now uses UI fingerprint instead of raw XML comparison (more reliable)

    • get_current_activity - Multi-method approach for compatibility with different emulators (AVD, Redroid, Genymotion, etc.)

    • is_keyboard_visible - Multiple detection methods with fallbacks

v1.2.3

  • Updated documentation with comprehensive setup guides

  • Added emulator comparison (AVD, Redroid, Genymotion, Physical)

  • Added cloud/VPS deployment instructions

  • Added troubleshooting section

v1.2.2

  • Fixed set_clipboard and get_clipboard for Redroid/Docker compatibility

  • Uses /data/local/tmp as fallback path

v1.2.0

  • Added 14 new tools:

    • get_screen_size, is_element_visible, get_element_bounds

    • scroll_to_text, wait_for_ui_stable, wait_for_element_gone

    • multi_tap, pinch_zoom, tap_safe, tap_element

    • set_clipboard, get_clipboard, rotate_device

    • get_focused_element, assert_screen_contains

v1.1.0

  • Added double_tap, drag, set_text, select_all, clear_input

v1.0.0

  • Initial release with core functionality


Development

# Clone repo
git clone https://github.com/Anjos2/mcp-android-emulator.git
cd mcp-android-emulator

# Install dependencies
npm install

# Build
npm run build

# Watch mode for development
npm run dev

License

MIT License - see LICENSE for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Ideas for contributions:

  • Support for multiple connected devices

  • Screen recording

  • File transfer (push/pull)

  • Network simulation

  • Battery/GPS simulation

Available Tools

42 tools
assert_screen_containsC

Assert that specific text is visible on screen (useful for testing)

Inputs: text (required), exact.

clear_app_dataC

Clear all data for an application

Inputs: package (required).

clear_inputA

Clear the currently focused text input field

Inputs: maxChars.

device_infoC

Get information about the connected device

Inputs: no named parameters.

double_tapC

Perform a double tap at the specified coordinates

Inputs: x (required), y (required).

dragA

Perform a drag gesture from one point to another (slower than swipe, for drag & drop)

Inputs: x1 (required), x2 (required), y1 (required), y2 (required), +1 more.

force_stopB

Force stop an application

Inputs: package (required).

get_all_textA

Get all visible text elements on screen (useful for debugging and verification)

Inputs: includeEmpty.

get_clickable_elementsA

Get all clickable elements on screen with their text, resource-id, and coordinates (useful when tap_text fails)

Inputs: includeDisabled.

get_clipboardA

Get the current device clipboard content

Inputs: no named parameters.

get_current_activityB

Get the currently focused activity/screen

Inputs: no named parameters.

get_element_boundsA

Get the exact bounds and center coordinates of an element

Inputs: text, index, resourceId.

get_focused_elementB

Get information about the currently focused UI element

Inputs: no named parameters.

get_focused_input_valueA

Get the current text value of the focused input field

Inputs: no named parameters.

get_logsB

Get device logs (logcat). Filtering is applied in-process, never on the device shell.

Inputs: level, lines, filter.

get_screen_sizeA

Get the screen dimensions and density of the device

Inputs: no named parameters.

get_ui_treeA

Get the UI element tree of the device (like DOM but for Android). Returns clickable elements with their coordinates.

Inputs: no named parameters.

install_apkA

Install an APK file on the device. Path must end in .apk and contain no shell metacharacters.

Inputs: path (required).

is_element_visibleB

Check if an element with specific text or resource-id is visible on screen

Inputs: text, resourceId.

is_keyboard_visibleA

Check if the soft keyboard is currently visible on screen

Inputs: no named parameters.

launch_appA

Launch an application by its package name (e.g., com.android.chrome). Package name is validated against the Android package naming convention.

Inputs: package (required).

list_packagesA

List installed packages on the device. Optional filter is applied in-process (JavaScript), never on the device shell.

Inputs: filter.

long_pressA

Perform a long press at the specified coordinates (useful for context menus)

Inputs: x (required), y (required), duration.

multi_tapB

Perform multiple rapid taps at the same position

Inputs: x (required), y (required), taps, interval.

pinch_zoomA

Perform a pinch zoom gesture (requires Android 8+)

Inputs: x (required), y (required), scale (required), duration.

press_keyA

Press a system key (BACK, HOME, ENTER, etc)

Inputs: key (required).

rotate_deviceA

Rotate the device to portrait or landscape orientation

Inputs: orientation (required).

screenshotA

Take a screenshot of the Android device/emulator and return it as a base64 image

Inputs: no named parameters.

scrollB

Scroll the screen in a direction

Inputs: direction (required), amount.

scroll_to_textA

Scroll the screen until an element with specific text is visible

Inputs: text (required), direction, maxScrolls.

select_allA

Select all text in the currently focused input field

Inputs: no named parameters.

set_clipboardA

Set text to the device clipboard. Text is transferred via adb push (binary transfer, no shell involvement, full Unicode support).

Inputs: text (required).

set_textA

Clear the current input field and type new text. Unicode is supported via URL-encoding. Shell metacharacters are rejected.

Inputs: text (required), maxClearChars.

swipeC

Perform a swipe gesture on the screen

Inputs: x1 (required), x2 (required), y1 (required), y2 (required), +1 more.

tapB

Tap at the specified coordinates on the screen

Inputs: x (required), y (required).

tap_elementA

Find and tap an element by text or resource-id (more reliable than tap_text)

Inputs: text, exact, index, resourceId.

tap_safeA

Tap at coordinates while avoiding system navigation bars

Inputs: x (required), y (required), avoidNavBar, avoidStatusBar.

tap_textA

Find an element by its text content and tap on it

Inputs: text (required), exact.

type_textA

Type text into the currently focused input field. Unicode is supported via URL-encoding. Shell metacharacters (; & | ` $ ( ) < > \ quotes) are rejected.

Inputs: text (required).

wait_for_elementB

Wait for a UI element with specific text to appear

Inputs: text (required), timeout.

wait_for_element_goneB

Wait for an element to disappear from the screen

Inputs: text (required), timeout.

wait_for_ui_stableA

Wait for the UI to stop changing (useful after animations)

Inputs: timeout, checkInterval.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.1/5.0

    Scored across 42 tools

    Disambiguation2/5

    There is heavy overlap among tap-related tools (tap, tap_text, tap_safe, tap_element, double_tap, multi_tap, long_press) and gesture tools (swipe, scroll, drag, scroll_to_text), making it easy for an agent to select the wrong one. UI inspection tools like get_ui_tree, get_clickable_elements, and get_all_text also have unclear boundaries despite their descriptions.

    Naming Consistency4/5

    The vast majority of tools follow a clear snake_case verb_noun pattern such as get_ui_tree, launch_app, and force_stop. A few exceptions like screenshot and device_info break the pattern, but the overall convention is still predictable and readable.

    Tool Count2/5

    42 tools is well above the threshold for a cohesive tool set. Many tools are minor variations of core actions—especially taps, gestures, and UI querying—so the count feels bloated rather than carefully scoped.

    Completeness4/5

    The tool set covers the core Android emulator workflow well: app lifecycle management, UI interaction, waiting/assertions, clipboard, logs, orientation, and keyboard handling. It is missing a few obvious operations like uninstalling an app, but agents can generally complete common automation tasks without dead ends.

    Maintenance

    ActivityInactive
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables interaction with Android devices and emulators through ADB, allowing control actions like tapping, text input, screenshots, UI inspection, and app launching through natural language.
      14 npm
      8
      ISC
    • A
      license
      A
      quality
      C
      maintenance
      Enables AI agents to control, inspect, and automate Android devices, Waydroid containers, and AVD emulators over ADB. Provides tools for screenshots, UI-hierarchy text-based tapping, gestures, key presses, text input, app management, and raw shell commands.
      12
      MIT