Skip to main content
Glama
Amm-ar

Emulator MCP Server

by Amm-ar
README.md
# Emulator MCP Server

**Model Context Protocol (MCP)** server for controlling Android emulators from any MCP-capable client. Uses ADB and the Android emulator CLI. Control AVDs, install APKs, tap, swipe, type, take screenshots, read logs, and more—all through your AI assistant.

---

## Table of contents

- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [How to start the server](#how-to-start-the-server)
- [Adding to clients](#adding-to-clients)
  - [Cursor](#cursor)
  - [VS Code & Copilot](#vs-code--copilot)
  - [Google Antigravity](#google-antigravity)
  - [Claude Desktop](#claude-desktop)
  - [Other MCP clients](#other-mcp-clients)
- [Available tools](#available-tools)
- [Troubleshooting](#troubleshooting)
- [References](#references)

---

## Prerequisites

- **Python 3.9+**
- **Android SDK** with:
  - `adb` on your PATH
  - `emulator` on your PATH (for launching AVDs)
- (Optional) An Android Virtual Device (AVD) for emulator tools

To check:

```bash
adb version
emulator -list-avds
```

---

## Installation

1. **Clone or copy** this project to a folder, e.g. `android_emulator_mcp`.

2. **Install dependencies:**

   ```bash
   cd android_emulator_mcp
   pip install -r requirements.txt
   ```

3. **Verify the server loads:**

   ```bash
   python main.py
   ```

   The server runs over **stdio**: it will start and wait for JSON-RPC messages. Normal exit is when stdin closes (e.g. the client disconnects). Use **Ctrl+C** to stop. You don’t need to “run” it yourself when using Cursor, VS Code, etc.—they start it automatically using the config below.

---

## How to start the server

- **When used by a client (Cursor, VS Code, Claude, Antigravity, etc.):**  
  You do **not** start the server yourself. The client runs the `command` (e.g. `python`) with the `args` (e.g. path to `main.py`) you configure. The server process is started and stopped by the client.

- **For local testing / debugging:**  
  Run it in the terminal so it uses stdio and waits for input:

  ```bash
  cd /path/to/android_emulator_mcp
  python main.py
  ```

  Then either close stdin (client disconnect) or press **Ctrl+C** to stop.  
  To test the protocol, use the official MCP inspector or another MCP client that can launch a stdio server.

- **Path to Python:**  
  Use the same executable your client will use. Examples:
  - `python` or `python3` if it’s on PATH
  - Full path, e.g. `C:\Users\User\AppData\Local\Programs\Python\Python310\python.exe` (Windows) or `/usr/bin/python3` (Linux/macOS)

Replace any path below with **your** project path and Python path as needed.

---

## Adding to clients

### Cursor

The emulator server is already added to your Cursor config:

- **Global (all workspaces):** `~/.cursor/mcp.json` — contains the emulator server with path to this project.
- **This project only:** `.cursor/mcp.json` in this repo — uses `${workspaceFolder}/main.py` when you open this folder in Cursor.

**If you add it manually:**

1. Open **Cursor Settings** → **Features** → **MCP**.
2. Click **+ Add New MCP Server**.
3. Set:
   - **Name:** `emulator` (or any name).
   - **Type:** `stdio`.
   - **Command:** `python` (or full path to `python.exe`).
   - **Args:** path to `main.py`, e.g.  
     `C:\Users\User\Documents\android_emulator_mcp\main.py`
4. Save. Restart Cursor if the new server doesn’t appear.

**Using the server to launch the emulator:**

1. Restart Cursor (or reload the window) so it picks up `mcp.json` and starts the emulator MCP server.
2. Open **Chat** (Composer / Agent).
3. Ensure **emulator** (or its tools) appear under **Available Tools**. If not, check **Settings → Features → MCP** and that the server is enabled.
4. Ask the agent to use the emulator, for example:
   - *“List my Android AVDs”* → it can use `list_avds`.
   - *“Launch the Android emulator for AVD \<name\>”* → it can use `launch_emulator` with the AVD name.
   - *“List connected devices”* → it can use `list_devices`.

You can approve tool calls when prompted or enable **Auto-run** for MCP tools in agent settings.

---

### VS Code & Copilot

MCP is supported in VS Code 1.102+ with Copilot. Config can be **workspace** (`.vscode/mcp.json`) or **user** (via **MCP: Open User Configuration**).

**Option A – Workspace (project-only)**

1. Create `.vscode/mcp.json` in your project.
2. Add the emulator server:

```json
{
  "servers": {
    "emulator": {
      "type": "stdio",
      "command": "python",
      "args": ["C:\\Users\\User\\Documents\\android_emulator_mcp\\main.py"]
    }
  }
}
```

Use `${workspaceFolder}/main.py` if `main.py` is inside the workspace, e.g.:

```json
"args": ["${workspaceFolder}/android_emulator_mcp/main.py"]
```

**Option B – User config (all projects)**

1. **Command Palette** → **MCP: Open User Configuration**.
2. In the opened `mcp.json`, add the same `servers.emulator` block as above (adjust paths for your machine).

**Option C – Command Palette**

1. **MCP: Add Server** → choose **stdio**.
2. Command: `python` (or full path).
3. Args: path to `main.py`.
4. Choose **Workspace** or **Global**.

After adding, use **Chat** and ensure the emulator server (and its tools) are enabled in the tool picker. You may need to trust the server when prompted.

---

### Google Antigravity

Antigravity uses a custom MCP config (e.g. **Manage MCP Servers** → **View raw config** → `mcp_config.json`). Add a stdio entry for this server.

1. In Antigravity, open the **MCP Store** (e.g. "..." at the top of the agent/side panel).
2. Click **Manage MCP Servers** → **View raw config**.
3. Edit `mcp_config.json` and add an entry for the emulator server. Structure is usually a map of server names to configs; use the same pattern as other stdio servers in the file. Example:

```json
{
  "emulator": {
    "command": "python",
    "args": ["C:\\Users\\User\\Documents\\android_emulator_mcp\\main.py"]
  }
}
```

(or `"type": "stdio"` plus `command` / `args` if your Antigravity template uses that). Save and restart/reload MCP in Antigravity so it picks up the new server.

---

### Claude Desktop

1. Open the Claude Desktop config file:
   - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
   - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
   - **Linux:** `~/.config/Claude/claude_desktop_config.json`  
   Or: **Settings → Developer → Edit Config** in Claude Desktop.
2. Add the emulator under `mcpServers`:

```json
{
  "mcpServers": {
    "emulator": {
      "command": "python",
      "args": ["C:\\Users\\User\\Documents\\android_emulator_mcp\\main.py"]
    }
  }
}
```

Use forward slashes or escaped backslashes in paths; no trailing commas. Restart Claude Desktop fully so the new server is loaded. Tools should appear (e.g. hammer icon) when the server is connected.

---

### Other MCP clients

Most clients that support **stdio** MCP servers expect a config like:

- **Command:** executable to run (e.g. `python`, `python3`, or full path to Python).
- **Args:** list with the path to `main.py`.

Generic pattern:

```json
{
  "mcpServers": {
    "emulator": {
      "command": "python",
      "args": ["/absolute/path/to/android_emulator_mcp/main.py"]
    }
  }
}
```

Or with `type` (if the client requires it):

```json
{
  "emulator": {
    "type": "stdio",
    "command": "python",
    "args": ["C:\\Users\\User\\Documents\\android_emulator_mcp\\main.py"]
  }
}
```

Replace the path with your actual `android_emulator_mcp` path. Then point your client at this config (or merge this block into its MCP config).

---

## Available tools

| Tool | Description |
|------|-------------|
| `launch_emulator` | Launch an AVD in the background |
| `kill_emulator` | Kill the Android emulator |
| `restart_emulator_cold_boot` | **Use when emulator is hanging:** kill, wait 25s, then cold boot (avoids PC freeze) |
| `list_avds` | List available Android Virtual Devices |
| `list_devices` | List connected devices/emulators |
| `install_apk` | Install an APK on the device |
| `uninstall_app` | Uninstall an app by package name |
| `launch_app` | Launch an app by package (optional activity) |
| `tap_screen` | Tap at (x, y) coordinates |
| `swipe` | Swipe from one point to another |
| `type_text` | Type text on the device |
| `press_key` | Send key event (BACK, HOME, ENTER, etc.) |
| `batched_input` | Execute multiple input actions in one call |
| `get_ui_hierarchy` | Get UI XML tree (bounds, text, IDs) |
| `click_element_by_text` | Find and tap element by visible text |
| `start_activity_with_data` | Launch via Deep Link (URI) |
| `set_gps_location` | Set emulator GPS (lat, lng) |
| `get_screen_info` | Get device screen resolution |
| `take_screenshot` | Capture screenshot (optional scale 0.1–1.0) |
| `read_logs` | Read logcat (optional filter) |
| `get_logcat_stream` | Last N lines, filter by tag |
| `clear_logs` | Clear logcat buffer |
| `check_network_condition` | Test emulator internet access |
| `get_emulator_stats` | Memory/CPU usage |
| `record_screen` | Record screen as MP4 |
| `pull_file` | Pull file from device to host |
| `push_file` | Push file from host to device |
| `shell_command` | Run arbitrary adb shell command |

---

## Troubleshooting

- **“adb: command not found” / “emulator: command not found”**  
  Add the Android SDK `platform-tools` and `emulator` directories to your PATH.

- **PC or Cursor hangs when killing / launching emulator**  
  **What we fix:** The server uses a **timeout** (8 s) for `adb emu kill`. If the emulator is hung, the command stops after 8 s and on Windows the server **force-kills** `emulator.exe` / `qemu-system-*.exe` so your machine doesn’t stay stuck. **What we don't fix:** The whole PC can still freeze from load. Killing then immediately cold-booting is very heavy; on 16 GB / i5 that often causes a hang. **What to do:** Use **`restart_emulator_cold_boot(avd_name)`** only—it kills, waits 25 s, then cold boots in one call. Do not call kill_emulator and launch_emulator separately or the PC may freeze. Close other apps first on 16 GB / i5.

- **Server not showing in Cursor**  
  Confirm the path to `main.py` in Args is correct and that **python** (or the full path) runs `main.py` without errors. Restart Cursor and check **Features → MCP** for the server and any error state.

- **VS Code: server not starting / not trusted**  
  Run **MCP: List Servers**, select the emulator server, and use **Show Output** to see logs. Use **MCP: Reset Trust** if you need to be prompted to trust again.

- **Claude Desktop: tools never appear**  
  Restart Claude Desktop completely (quit and reopen). Ensure the config JSON is valid (no trailing commas). Check that `python` and the path in `args` are correct.

- **Paths with spaces**  
  Use quoted paths in configs where required. For `args`, a single string like `"C:\\Users\\User\\Documents\\android_emulator_mcp\\main.py"` is typical; avoid splitting the path across multiple args.

---

## References

- [Model Context Protocol](https://modelcontextprotocol.io/)
- [Cursor – MCP](https://cursor.com/docs/context/mcp)
- [VS Code – Use MCP servers](https://code.visualstudio.com/docs/copilot/customization/mcp-servers)
- [Antigravity – MCP](https://antigravity.google/docs/mcp)
- [MCP servers (GitHub)](https://github.com/modelcontextprotocol/servers)