# Android Remote Control Mcp

> An MCP Server for Android running on the phone, optmized for token usage, supports also files downloads and cloudflare (free) and ngrok automated tunnelling.

- **Type:** MCP server
- **Install:** `agentstack add mcp-danielealbano-android-remote-control-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [danielealbano](https://agentstack.voostack.com/s/danielealbano)
- **Installs:** 0
- **Category:** [Cloud & Infrastructure](https://agentstack.voostack.com/c/cloud-infrastructure)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [danielealbano](https://github.com/danielealbano)
- **Source:** https://github.com/danielealbano/android-remote-control-mcp

## Install

```sh
agentstack add mcp-danielealbano-android-remote-control-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Android Remote Control MCP

[](https://github.com/danielealbano/android-remote-control-mcp/actions/workflows/ci.yml)
[](https://opensource.org/licenses/MIT)

An Android application that runs as an **MCP (Model Context Protocol) server**, enabling AI models to **fully control an Android device** remotely using accessibility services and screenshot capture.

The app runs directly on your Android device (or emulator) and exposes an HTTP server (with optional HTTPS) implementing the MCP protocol. AI models like Claude can connect to it and interact with any app on the device — reading UI elements, tapping buttons, typing text, swiping, capturing screenshots, managing files, launching apps, and more.

> **Warning:** This software is provided "as-is" without warranty of any kind, for **research and educational purposes only**. The authors do not condone the use of this tool for any illegal, unauthorized, or unethical activities. Users are solely responsible for ensuring their use complies with all applicable laws and regulations. By using this software, you agree to use it responsibly and at your own risk.

---

## Features

### MCP Server
- HTTP server running directly on Android (Ktor + Netty), with optional HTTPS
- Streamable HTTP transport at `/mcp` (MCP specification compliant, JSON-only, no SSE)
- Combined authentication: static bearer token and/or a self-contained OAuth 2.1 server (Claude.ai / Claude Desktop custom connectors, with on-device approval)
- Auto-generated self-signed TLS certificates (or custom certificate upload)
- Configurable binding: localhost (127.0.0.1) or network (0.0.0.0)
- Auto-start on boot
- Remote access tunnels via Cloudflare Quick Tunnels or ngrok (public HTTPS URL)

### 56 MCP Tools across 13 Categories

Screen introspection, system actions, touch actions, gestures, node actions, text input, utilities, file operations, app management, camera, intents, notifications, and location.

All tool names use the `android_` prefix by default (e.g., `android_tap`). When a device slug is configured (e.g., `pixel7`), the prefix becomes `android_pixel7_` (e.g., `android_pixel7_tap`).

See [docs/MCP_TOOLS.md](docs/MCP_TOOLS.md) for the full tool reference with input/output schemas and examples.

### Android App
- Material Design 3 UI with tabbed layout (Server / Settings / About) and dark mode
- Server status monitoring (running/stopped) with permission warning banner
- Connection info display (IP, port, token, tunnel URL)
- Per-tool and per-parameter permissions (enable/disable individual MCP tools)
- Permission management (Accessibility, Notifications, Camera, Microphone)
- Remote access tunnel configuration (Cloudflare / ngrok)
- Storage location management (automatic locations + SAF authorization for file tools)
- Server log viewer (MCP tool calls, tunnel events)
- Headless setup via ADB (configure, grant permissions, start/stop server without UI)

### Comparison with Alternatives

| Feature | This project | [mobile-mcp] | [Android-MCP] | [android-mcp-server] | [adb-mcp] | [droidrun-mcp] |
|---------|:-:|:-:|:-:|:-:|:-:|:-:|
| MCP tools | 56 | 21 | 11 | 5 | 10 | 11 |
| Runs on the phone (no ADB) | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
| Action latency | 10-100 ms | 1-4 s | 1-4 s | 1-4 s | 1-4 s | 1-4 s |
| Works over the internet | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
| Token-efficient screen state | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :white_check_mark: |
| Annotated screenshots | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :x: |
| Configurable screenshot resolution/quality | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
| Per-tool enable/disable | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
| Multi-device support | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: |
| Camera, clipboard, files, downloads | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
| iOS support | :x: | :white_check_mark: | :x: | :x: | :x: | :x: |

[mobile-mcp]: https://github.com/mobile-next/mobile-mcp
[Android-MCP]: https://github.com/CursorTouch/Android-MCP
[android-mcp-server]: https://github.com/minhalvp/android-mcp-server
[adb-mcp]: https://github.com/srmorete/adb-mcp
[droidrun-mcp]: https://github.com/chukfinley/droidrun-mcp-server

Most alternatives rely on ADB running on a host machine, which means a USB cable or local network connection and a computer sitting next to the phone. This project runs entirely on the device itself, so you can expose the MCP endpoint through a tunnel and control your phone from anywhere.

On the token efficiency side, ADB-based tools typically return raw `uiautomator` XML dumps which can easily be 10-50x more verbose than the compact representation used here. Combined with numbered screenshot annotations, configurable image quality, and the ability to disable tools you don't need (every tool definition costs tokens on every turn), this significantly reduces the per-interaction cost in agentic loops.

---

## Install

### Option A: Download on your phone (easiest)

1. Open the [Releases](https://github.com/danielealbano/android-remote-control-mcp/releases) page on your phone's browser
2. Download the APK from the latest release
3. Open the downloaded APK and follow the prompts to install it (you may need to allow installation from unknown sources)

### Option B: Download on your PC and install via ADB

1. Download the APK from the [Releases](https://github.com/danielealbano/android-remote-control-mcp/releases) page
2. Connect your phone via USB (with USB Debugging enabled)
3. Install the APK:
```bash
adb install app-release.apk
```

### Option C: Build from sources

```bash
git clone https://github.com/danielealbano/android-remote-control-mcp.git
cd android-remote-control-mcp
make build
make install  # installs on connected device/emulator
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for full build requirements and instructions.

---

## Setup

1. **Open the app** and go to Settings > Permissions
2. **Enable Accessibility Service** (required for UI introspection, actions, and screenshots)
3. **Grant additional permissions** as needed (Camera, Microphone, Location, Notifications)
4. **Configure storage locations** in Settings > Storage if you plan to use file tools (includes automatic locations like Downloads, plus custom locations via SAF)
5. Go back to the **Server tab** and tap **Start** to start the MCP server

The server starts on `http://127.0.0.1:8080` by default. The connection info (IP, port, token, URL) is displayed on the Server tab.

> **Note**: `127.0.0.1` refers to the phone's localhost, not your computer. To connect from your computer, use [adb port forwarding](#using-with-adb-port-forwarding), bind to `0.0.0.0` (network mode), or enable a [remote access tunnel](#using-remote-access-tunnels).

---

## Connect

### Claude Desktop / Claude Code

Add the server to your `.mcp.json` configuration file:

```json
{
  "mcpServers": {
    "android-phone": {
      "type": "http",
      "url": "http://DEVICE_IP:PORT/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      }
    }
  }
}
```

Replace `DEVICE_IP`, `PORT`, and `YOUR_TOKEN` with the values shown in the app's Server tab. If the server is bound to localhost (default), you'll need [adb port forwarding](#using-with-adb-port-forwarding) or a [remote access tunnel](#using-remote-access-tunnels) to connect.

> **Note for clients without custom-header support:** if your MCP client cannot send an `Authorization` header and does not support OAuth, you can turn off both auth methods in the app (**Settings → Access** — disable Bearer token and OAuth). The app warns and asks you to confirm, because the server is then **open**: anyone who can reach it has full control. Only do this on a network you trust.

### Connect from Claude.ai & Claude Desktop (Custom Connector, OAuth)

Claude.ai (web) and Claude Desktop connect as a **custom connector** (remote MCP) using OAuth 2.1 — the app is its own OAuth Authorization Server, so no external account or pre-registration is needed. This requires the server to be reachable over a **public HTTPS URL**, so you must first enable a [remote access tunnel](#using-remote-access-tunnels) — a `localhost`/LAN address or `adb` port-forward will **not** work.

1. **OAuth is enabled by default** — no action needed (if you previously disabled it, re-enable it under **Settings → Access**). The bearer token stays enabled too; both are accepted.
2. Open **Settings → Tunnel**, enable **Remote Access** (Cloudflare Quick Tunnels needs no account), and start the server. Copy the public `https://…` URL from the Server tab and append `/mcp` (e.g. `https://your-tunnel.trycloudflare.com/mcp`).
3. In Claude, open **[Customize → Connectors → Add custom connector](https://claude.ai/customize/connectors?modal=add-custom-connector)**, paste the `https://…/mcp` URL, and **leave the OAuth Client ID and Client Secret blank** (the app uses Dynamic Client Registration). Click **Add**.
4. Claude opens a browser approval page showing a **2-digit code**. On the device, a heads-up notification appears — tap it to open the in-app approval screen, confirm the code matches, and **Approve**.
5. Manage or revoke connected clients any time under **Settings → Access → Connected clients**. Revoking immediately invalidates that client's tokens.

> **Public URL override (optional):** if your tunnel/host topology needs a fixed public host (or you bind to `0.0.0.0` without a trusted proxy), set a **Public URL override** in Settings → Access so OAuth metadata and links use a stable host.

Custom connectors are available on the Free (1 connector), Pro, Max, Team, and Enterprise plans (currently in beta).

> ⚠️ **Security:** treat the public tunnel URL as sensitive, approve only connections you initiated (verify the 2-digit code), revoke clients you no longer use, and stop the tunnel and server when you are done. Never point it at a device holding sensitive data.

### Other MCP Clients

The MCP server exposes a standard Streamable HTTP endpoint at `/mcp` with combined authentication (static bearer token and/or OAuth 2.1). Any MCP-compatible client can connect to it — refer to your client's documentation for the specific configuration format.

### Testing with MCP Inspector

[MCP Inspector](https://github.com/modelcontextprotocol/inspector) is the official visual testing tool for MCP servers. It provides a browser-based UI to connect, list tools, fill parameters, and see responses:

```bash
npx @modelcontextprotocol/inspector
```

This opens a UI at `http://localhost:6274` where you can connect to your server and test tools interactively.

### Testing with curl

All requests are sent as JSON-RPC 2.0 via `POST /mcp` (Streamable HTTP transport). The server requires a session initialization handshake before tool calls:

```bash
# Initialize a session (required before any tool call)
# Capture the mcp-session-id from the response headers
curl -s -D- -X POST http://localhost:8080/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl-client","version":"1.0.0"}}}'

# Use the mcp-session-id from the response headers in all subsequent requests

# List available tools
curl -X POST http://localhost:8080/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-session-id: SESSION_ID" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

# Get the current screen state (UI nodes + optional screenshot)
curl -X POST http://localhost:8080/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-session-id: SESSION_ID" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"android_get_screen_state","arguments":{}}}'

# Tap at coordinates
curl -X POST http://localhost:8080/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-session-id: SESSION_ID" \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"android_tap","arguments":{"x":540,"y":1200}}}'
```

Replace `SESSION_ID` with the `mcp-session-id` value from the initialize response headers.

The bearer token is shown in the app's connection info and can be copied directly. Bearer authentication is controlled by the **Bearer token** toggle in **Settings → Access** (not by clearing the value): with it enabled, every `/mcp` request must present the token (or a valid OAuth access token). The server accepts unauthenticated requests only when **both** the Bearer token and OAuth are disabled.

---

## Configuration

### Server Settings (via App UI)

| Setting | Default | Description |
|---------|---------|-------------|
| Port | `8080` | HTTP/HTTPS server port |
| Binding Address | `127.0.0.1` | `127.0.0.1` (localhost, use with adb port forwarding) or `0.0.0.0` (network, all interfaces) |
| Bearer Token | Enabled, auto-generated UUID | Static token for MCP requests (Settings → Access). Enforcement is set by the Bearer toggle, not by clearing the value. |
| OAuth | Enabled | Self-contained OAuth 2.1 server for Claude.ai / Claude Desktop custom connectors (Settings → Access). |
| Public URL override | Empty (auto-detect) | Pin the public host used for OAuth metadata and share links. |
| HTTPS | Disabled | Enable HTTPS with auto-generated self-signed certificate (configurable hostname) or upload custom .p12/.pfx |
| Auto-start on Boot | Disabled | Start MCP server automatically when device boots |
| Device Slug | Empty | Optional device identifier for tool name prefix (e.g., `pixel7` makes tools `android_pixel7_tap`) |
| Remote Access Tunnel | Disabled | Expose server via public HTTPS URL (Cloudflare Quick Tunnels or ngrok) |
| Tool Permissions | All enabled | Per-tool and per-parameter enable/disable (Settings > MCP Tools) |
| File Size Limit | 50 MB | Maximum file size for file operations (range 1-500 MB) |
| Allow HTTP Downloads | Disabled | Allow non-HTTPS downloads via `android_download_from_url` |
| Download Timeout | 60 seconds | Timeout for file downloads (range 10-300 seconds) |

### Using with adb Port Forwarding

When the server is bound to `127.0.0.1` (default, most secure):

```bash
# Forward device port to host
adb forward tcp:8080 tcp:8080

# Test connection from host
curl -X POST http://localhost:8080/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"ping"}'
```

### Using over Network

When the server is bound to `0.0.0.0`:

1. Find the device's IP address (shown in the app's connection info)
2. Connect directly via `POST http://DEVICE_IP:8080/mcp` with bearer token

**Warning**: Binding to `0.0.0.0` exposes the server to all devices on the same network. Only use on trusted private networks.

### Using Remote Access Tunnels

For connecting from outside the local network without port forwarding:

1. **Cloudflare Quick Tunnels** (default, no account required): Creates a temporary tunnel with a random `*.trycloudflare.com` HTTPS URL.
2. **ngrok** (account required): Supports optional custom domains. Requires an ngrok authtoken (free tier available). Only available on ARM64 devices.

Enable the tunnel in the app's "Remote Access" section. The public URL is displayed in the connection info and server logs.

### Headless Setup via ADB

The app can be fully configured and controlled from the command line without opening the UI. This is useful for automated setups, CI pipelines, or headless devices.

Replace `` with t

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [danielealbano](https://github.com/danielealbano)
- **Source:** [danielealbano/android-remote-control-mcp](https://github.com/danielealbano/android-remote-control-mcp)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-danielealbano-android-remote-control-mcp
- Seller: https://agentstack.voostack.com/s/danielealbano
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
