MobileMCP
Enables AI agents to operate and automate a real Android phone through an accessibility service, including reading the screen UI tree, tapping, typing, scrolling, gestures, taking screenshots, opening apps, managing notifications, and controlling system settings.
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., "@MobileMCPopen WhatsApp and text Mom that I'm on my way home"
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.
Companion: LiveMCP does the same for Chrome; MobileMCP is its mobile sibling and shares the hub/bridge design.
MobileMCP is for people who want an agent (Claude Code, Cursor, any MCP client) to operate their own phone from anywhere: an Android accessibility service (the app) dials out to a hub (the server) over WebSocket; agents talk to the hub through MCP. No USB, no ADB, no rooting. The hub also serves a dashboard with connected devices, a live activity feed and a per-device live view.
Status: active, early (server 0.4.0, app 0.3.0). Verified on a Pixel 7 emulator (API 35) and a OnePlus phone (Android 15). No Play Store listing; the app is sideloaded. No automated test suite; verification is scripted against real devices.
agent (Claude Code, Codex, …) ──stdio──▶ mobilemcp ──IPC──▶ mobilemcp-hub ◀──WebSocket── MobileMCP app (phone)
──HTTP /mcp (hosted)──▶ ──HTTP / ──▶ dashboardWhy accessibility instead of ADB
Accessibility service (this) | ADB / UiAutomator | |
Needs a tethered computer / wireless-debug pairing | No | Yes, re-pair after reboot |
Works over the internet / VPN | Yes (outbound WebSocket) | Only with port forwarding |
Sees the UI tree | Yes, with view ids and states | Yes |
Taps, typing, scrolling, gestures, back/home | Yes | Yes |
Screenshots | Yes (Android 11+) | Yes |
Shell, logcat, app install, arbitrary key codes | No | Yes |
Secure (FLAG_SECURE) screens, e.g. banking | Hidden | Hidden |
The accessibility route is what "use my phone like a normal user" means. ADB-level control could be added later as a second driver for emulators and development.
Related MCP server: phone-mcp-server
Tools (35)
Group | Tools |
Devices |
|
Observe |
|
Act |
|
Apps |
|
Notifications |
|
System |
|
Batch |
|
Every action returns a compact observation after the UI settles (or observe:false). A snapshot line looks like @4 button ~"Network & internet · Mobile, Wi‑Fi, hotspot" (540,472): roles imply clickability, rows carry their children's text and hide the duplicates, coordinates are centers. Refs are keyed by content identity (class, view id, text, occurrence) per package, so they survive scrolling, re-layout and app switches. Most flows need no snapshot at all: tap text="Send", type_text field="Message", scroll_until text="…" tap=true, chained in run_mobile_actions. See OPTIMIZATIONS.md for the reasoning and measurements.
Quick start
Published release
Download mobilemcp-0.3.0.apk, mobilemcp-0.3.0.tgz and SHA256SUMS from v0.3.0 into one directory.
shasum -a 256 -c SHA256SUMS # Linux: sha256sum -c SHA256SUMS
npm install --prefix ./mobilemcp-local ./mobilemcp-0.3.0.tgz
./mobilemcp-local/node_modules/.bin/mobilemcp-hubInstall the APK on the phone (adb install mobilemcp-0.3.0.apk or copy it over), then follow the app steps below and point your MCP client at ./mobilemcp-local/node_modules/mobilemcp/dist/index.js.
From source
Requires Node.js 18+ and Android 11+ on the phone.
npm ci
npm run build
npm run hub # keep this running: ws://127.0.0.1:17692Build the app with Android Studio (open app/) or from the command line:
cd app && ./gradlew :app:assembleDebug # app/app/build/outputs/apk/debug/app-debug.apkInstall the APK on the phone, then in the app:
Google Play Protect blocks accessibility apps installed from chat apps or browsers in some countries (India, Singapore, Thailand, Brazil, …) with no override. Install over adb (
adb install mobilemcp-0.3.0.apk) or pause Play Store → Play Protect → Scan apps while installing from the Files app, then re-enable it.Enable accessibility service — Android 13+ first requires App info → ⋮ → Allow restricted settings for sideloaded apps (the app has an App info button).
Enter the hub URL (
ws://<your-computer-ip>:17692on the same Wi‑Fi, or your hostedwss://origin) and a device name, then Connect.Optionally Allow background so Doze does not throttle the connection; grant Notification access for the notification tools and DND, and Modify system settings for brightness/rotation.
Register the MCP server with your agent:
{
"mcpServers": {
"mobilemcp": {
"command": "node",
"args": ["/absolute/path/to/mobilemcp/server/dist/index.js"]
}
}
}For Claude Code, plugin/ is a ready plugin: a self-contained server bundle (plugin/bin/mobilemcp.js, no npm needed) plus a skill describing the workflow. Add it with claude plugin add ./plugin or point your marketplace at the directory.
Emulator
adb install -r app/app/build/outputs/apk/debug/app-debug.apk
adb shell appops set labs.magi.mobilemcp ACCESS_RESTRICTED_SETTINGS allow
adb shell settings put secure enabled_accessibility_services labs.magi.mobilemcp/.MobileAccessibilityService
adb shell settings put secure accessibility_enabled 1
adb shell am start -n labs.magi.mobilemcp/.MainActivity --es hubUrl ws://10.0.2.2:17692 --es name Emulator --ez connect trueDebug builds accept settings through intent extras; release builds ignore them so no other app can repoint the hub.
How it works
The app's AccessibilityService owns the hub connection, reads the window tree, performs node actions and injected gestures and takes screenshots. The hub routes requests per account, serves MCP over HTTP, local sessions over IPC, and the dashboard. shared/src/protocol.ts is the single contract. Details, trust boundaries and failure modes: docs/ARCHITECTURE.md; decisions in docs/decisions.
Hosted hub
The hub also serves authenticated MCP over HTTP at /mcp and the phone endpoint at /device on one port, so the phone and remote agents can both reach it through a reverse proxy:
MOBILEMCP_HOST=0.0.0.0 MOBILEMCP_PUBLIC_URL=https://mobile.example.com MOBILEMCP_TOKEN=<32+ chars> npm run hubPhone: hub URL
wss://mobile.example.com, token =MOBILEMCP_TOKEN.Agent:
{"type":"http","url":"https://mobile.example.com/mcp","headers":{"Authorization":"Bearer <token>"}}, or stdio withMOBILEMCP_TOKENset.MOBILEMCP_ACCOUNTS='[{"id":"me","agentToken":"…","deviceToken":"…"}]'isolates several users; devices and selections never cross accounts.
The reverse proxy provides TLS; the hub never binds a public address without a token. The dashboard at / shows devices, a live activity feed (names and timings only) and a per-device live view with click-to-tap; see HOSTING.md.
Agent workflow
If you know the label, act on it directly:
tap text=,type_text field=,scroll_until text= tap=true; chain known steps in onerun_mobile_actions.Otherwise
get_screen_snapshot(scoped/filtered) and act on@refs. Read theobservationevery action returns instead of re-snapshotting.wait_for_text/timeoutparameters for loading;take_screenshot marks=truefor visual content.After
STALE_REFor an app change, snapshot again. Never repeat a submission after a timeout without inspecting state.
Screen content is untrusted data. The server instructions tell agents to enter credentials, OTPs or payments only when the task explicitly includes them.
Limitations and data handling
The hub forwards requests and responses without storing them; activity events hold device names, action names, durations and error codes. The app persists only its settings. Password fields are masked in snapshots. Screen content reaches whatever MCP client you connect, so connect clients you trust.
Android 11+ (API 30) for accessibility screenshots and
ACTION_IME_ENTER.Apps with
FLAG_SECURE(banking, DRM video) expose neither nodes nor pixels.Custom-drawn views without accessibility nodes need
take_screenshotplus coordinate taps. A few system pages expose no tree at all (snapshots then reportnoTree: truewith the window title).Launcher folder creation by
dragdepends on the launcher's drop rules; the defaults (900 ms hold, 300 ms move, 250 ms hover) merge icons on Launcher3/Pixel. Long hovers trigger reorder instead. Cross-page drags: add a waypoint at the screen edge withpauseMs≈ 800 per page flip (hold times above ~1.2 s flip twice on OxygenOS).Phones can self-update from their hub:
GET /app.apk?token=<device token>(see HOSTING.md); a running MobileMCP can drive the download and installer itself.No arbitrary key codes, shell or app installation; that is ADB territory.
Google Play would require a declaration for this accessibility usage; the app is distributed as a sideloaded APK.
Development
Contributor setup and change workflow: CONTRIBUTING.md. Agent/maintainer instructions: AGENTS.md.
npm run typecheck && npm run build
STEPS='[["get_device_info"],["get_screen_snapshot",{"maxNodes":20}]]' node server/test/e2e.mjs # against a connected phone/emulatorDocumentation
HOSTING.md — Docker, reverse proxy, tokens, dashboard, self-update
OPTIMIZATIONS.md — observation format, literature, measurements
License
MIT © Deepak Silaych. Third-party notices in docs/THIRD_PARTY.md.
This server cannot be deployed
Maintenance
Related MCP Connectors
Control real Android and iOS devices with LLM agents — tap, swipe, type, automate flows.
Cloud Android phones for AI agents: create a phone, read the screen, tap, type, install APKs, park.
Drive real devices from your AI Coding tool. Embed a client SDK (Unity, Godot, Flutter, iOS/macOS, Android, React Native, Web) in your app, then capture screenshots, traverse the UI tree, inject taps and key events, and run automated test tasks on the physical device over a secure relay.
Disposable cloud Android emulators for coding agents: run an APK or PR build, tap, type, screenshot.
Related MCP Servers
- AlicenseAqualityFmaintenanceProvides AI agents with real-time vision and control over Android devices through screen streaming, UI automation, and fast input control via scrcpy protocol.3318MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to control Android phones via MCP and HTTP. Supports screen capture, taps, swipes, text input, and app management.6AGPL 3.0
- AlicenseNot gradedqualityBmaintenanceEnables LLM agents to drive real Android devices or emulators by reading the live accessibility tree, acting on UI nodes instead of coordinates, verifying every action, and typing Unicode text.41 npm1Apache 2.0
- FlicenseNot gradedqualityBmaintenanceEnables an agent to control a real Android phone by reading structured UI elements and performing actions such as tapping, swiping, typing, and extracting fields from known app screens.1-