Skip to main content

pymobile-mcp

Pure Python MCP server for mobile automation.

  • Android: uiautomator2 + adbutils
  • iOS: pure pymobiledevice3 userspace tunnel + WebDriverAgent (no go-ios, no root)

Public contract: fixed upstream mobile-mcp@c5d7d27 — 23 tools by default, 26 with MOBILEFLEET_ENABLE=1. mobile_get_page_source is not public; fleet runtime uses the documented approved exception when no Python fleet provider is installed.

CI Release PyPI Python License: GPL-3.0

Current release: 0.3.1 · Changelog · Live regression checklist

Features

  • One stdio MCP server for Android + iOS
  • Upstream-compatible natural-language/image results and exact Actionable vs isError=true failures
  • Live smoke scripts that exit blocked (code 2) when devices are missing — never fake pass
  • Destructive actions (install/uninstall) gated by explicit env flags

Requirements

Platform Need
Host Python ≥ 3.10, pip
Android adb in PATH, authorized device or emulator
iOS macOS recommended, paired iPhone/iPad, Developer Mode, mounted DDI, installed WDA runner (default com.byte.WebDriverAgentRunner.xctrunner)

Install

From a git checkout (development)

git clone https://github.com/ByteTrue/pymobile-mcp.git
cd pymobile-mcp
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e .
pymobile-mcp --help

Dev install (tests)

pip install -e ".[dev]"
python -m pytest -q

From PyPI

pip install pymobile-mcp==0.3.1

From GitHub (no local clone of tooling)

pip install "git+https://github.com/ByteTrue/pymobile-mcp.git@v0.3.1"

Quick start

  1. Connect an Android emulator/device (adb devices) and/or a paired iPhone.
  2. For iOS, ensure your WDA runner is installed (Xcode once); pymobile-mcp launches it over userspace tunnel.
  3. Run the server:
pymobile-mcp run
# equivalent:
python -m pymobile_mcp.cli run
  1. Point an MCP client at the process (stdio).

MCP client config

Installed entrypoint (pymobile-mcp on PATH):

{
  "mcpServers": {
    "pymobile-mcp": {
      "command": "pymobile-mcp",
      "args": ["run"]
    }
  }
}

Checkout / venv (absolute paths are more reliable for GUI clients):

{
  "mcpServers": {
    "pymobile-mcp": {
      "command": "/ABS/PATH/pymobile-mcp/.venv/bin/python",
      "args": ["-m", "pymobile_mcp.cli", "run"],
      "cwd": "/ABS/PATH/pymobile-mcp",
      "env": {
        "NO_PROXY": "*",
        "PYTHONPATH": "src"
      }
    }
  }
}

First tools to try

After the client connects:

  1. mobile_list_available_devices — confirm Android/iOS ids
  2. mobile_get_screen_size / mobile_take_screenshot
  3. mobile_list_elements_on_screen — UI tree (no raw page source tool)
  4. mobile_list_apps → mobile_launch_app with a known package/bundle id

Capability matrix (23 default tools; 26 with fleet env)

Status Meaning
supported Implemented and covered by automated contract tests; this label is not a claim of current-device live attestation
approved exception Explicit, reviewed black-box difference with stable upstream-compatible text

Current live evidence passes on Android physical, Android emulator, iOS Simulator, and iOS real device. Android recording and iOS Simulator recording both passed live; iOS real-device recording remains the approved exception.

Tool Android iOS
mobile_list_available_devices supported supported
mobile_list_apps supported supported
mobile_launch_app supported supported
mobile_terminate_app supported supported
mobile_install_app supported (destructive) supported (destructive, gated)
mobile_uninstall_app supported (destructive) supported (destructive, gated)
mobile_get_screen_size supported supported
mobile_click_on_screen_at_coordinates supported supported
mobile_double_tap_on_screen supported supported
mobile_long_press_on_screen_at_coordinates supported supported
mobile_list_elements_on_screen supported supported (WDA source internal)
mobile_press_button supported supported (HOME/VOLUME_*; BACK unsupported)
mobile_open_url supported (http/https default) supported (device must be unlocked)
mobile_swipe_on_screen supported supported
mobile_type_keys supported supported
mobile_save_screenshot supported supported
mobile_take_screenshot supported supported
mobile_set_orientation supported supported
mobile_get_orientation supported supported
mobile_start_screen_recording supported; live passed simulator supported/live passed; real device approved exception
mobile_stop_screen_recording supported; live passed simulator supported/live passed; real device approved exception
mobile_list_crashes supported (dropbox) supported (crash reports)
mobile_get_crash supported (dropbox) supported (crash reports)

Environment variables

Env Purpose
MOBILEMCP_ALLOW_UNSAFE_URLS=1 allow non-http(s) schemes for mobile_open_url
MOBILEFLEET_ENABLE=1 expose the upstream fleet tool set (26 tools); runtime returns approved exception without a Python fleet provider
PYMOBILE_MCP_ANDROID_DROPBOX_ALL=1 include non-crash dropbox tags (strictmode/boot/…)
PYMOBILE_MCP_ANDROID_DEVICE pin Android serial for smokes
PYMOBILE_MCP_ANDROID_ACTIONS=1 enable tap/type interactions in Android UI smoke
PYMOBILE_MCP_ANDROID_TAP=x,y override Android tap point
PYMOBILE_MCP_ANDROID_APK + PYMOBILE_MCP_ANDROID_PACKAGE + PYMOBILE_MCP_ANDROID_DESTRUCTIVE=1 allow install/uninstall smoke
PYMOBILE_MCP_IOS_DEVICE pin iOS UDID
PYMOBILE_MCP_IOS_ACTIONS=1 enable interaction steps in iOS core smoke
PYMOBILE_MCP_WDA_XCTRUNNER WDA runner bundle id (default com.byte.WebDriverAgentRunner.xctrunner)
PYMOBILE_MCP_WDA_PORT WDA port used by the in-process userspace RSD service client (default 8100; not a remote WDA URL)
PYMOBILE_MCP_IOS_IPA + PYMOBILE_MCP_IOS_DESTRUCTIVE=1 allow iOS install/uninstall smoke
NO_PROXY=* recommended for iOS USB / usbmux

Live smoke

Scripts print JSON with status: passed|failed|blocked.
Exit 2 + blocked = missing device/env, not a product pass.

export NO_PROXY='*'
PATH=.venv/bin:$PATH

# Android
python tests/android_live_smoke.py
PYMOBILE_MCP_ANDROID_ACTIONS=1 python tests/android_live_smoke.py
python tests/android_app_system_live_smoke.py
python tests/android_recording_crash_live_smoke.py

# iOS (unlock phone for open_url)
python tests/ios_pmd3_wda_live_smoke.py
PYMOBILE_MCP_IOS_ACTIONS=1 python tests/ios_pmd3_wda_live_smoke.py
python tests/ios_system_helpers_live_smoke.py
python tests/ios_app_lifecycle_live_smoke.py
python tests/crash_tools_live_smoke.py
python tests/ios_app_recording_crash_live_smoke.py   # real recording uses approved exception

Full dual-device gate: docs/regression-checklist.md.

Architecture (short)

MCP client  --stdio-->  pymobile-mcp server
                           │
                           ├─ tools/registry + specs   (23 default / 26 fleet contract)
                           ├─ tools/* handlers
                           └─ drivers/
                                ├─ android.py       (adbutils / uiautomator2)
                                ├─ ios.py           (UserspaceRsdTunnel + WDA)
                                └─ ios_simulator.py (simctl + WDA)

Development

pip install -e ".[dev]"
python -m pytest -q

CI runs unit tests on Python 3.11 and 3.12 (workflow). Device live smokes stay local.

Known limits

  • Android crashes come from dumpsys dropbox --print, filtered to crash/ANR/tombstone-like tags by default
  • iOS real-device recording remains an approved exception; Simulator recording requires a booted CoreSimulator + WDA
  • Recording state is process-local (ActiveRecording); no cross-process resume
  • Custom URL schemes need MOBILEMCP_ALLOW_UNSAFE_URLS=1
  • Screenshot/recording host paths must resolve under cwd or system temp
  • No go-ios/mobilecli runtime fallback by design

Troubleshooting

Symptom What to check
iOS device list empty Cable/trust, pymobiledevice3 usbmux list, proxies (NO_PROXY=*)
iOS driver tunnel errors Developer Mode, pymobiledevice3 mounter auto-mount, only one userspace tunnel process
open_url fails on iPhone Unlock the device (passcode lock blocks Safari/WDA URL open)
Android no devices adb devices authorized; kill stale adb if offline
Install/uninstall smoke skipped Set package/apk/ipa and *_DESTRUCTIVE=1
CI green but live red Expected — CI is unit-only; use regression checklist

Metadata

Release files for pymobile-mcp 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pymobile-mcp 0.3.1
File Size Uploaded Provenance
pymobile_mcp-0.3.1.tar.gz 68.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pymobile-mcp 0.3.1
File Interpreter ABI Platform
pymobile_mcp-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 121.1 kB

Release files / pymobile_mcp-0.3.1.tar.gz

Download URL pymobile_mcp-0.3.1.tar.gz
Size 68.2 kB
Tags Source
SHA-256 checksum
How to use checksums
2b5ff7603854262bd7a6925311f9cb92f4b48346b820fb5ee9db849c78359b88
BLAKE2b-256 checksum
How to use checksums
880d61e5d99bbcb2324f943fdbbca06505a2d9bf57ce85c69094c5e474c3c8a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.

Transparency log

Release files / pymobile_mcp-0.3.1-py3-none-any.whl

Download URL pymobile_mcp-0.3.1-py3-none-any.whl
Size 52.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ec798dbcb89e3db1100935b4b7fd8d8270c23c3da84fd8cc21ad41394ee4fbc0
BLAKE2b-256 checksum
How to use checksums
c8faca02e8b8870109a2b4ad189848ea2a4ab9d2e1b491647bef3087b266127a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.

Transparency log

Security for pymobile-mcp 0.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pymobile_mcp-0.3.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page