mobilerun-core-cli is the slim async local-driver core of mobilerun.
No CLI, no agent, no LLM providers — just local Android/iOS drivers for higher-level tools such as mobilerun-core.
- 📱 Drive local devices — Android over ADB+Portal, Android Portal HTTP-only, or iOS Portal HTTP.
- ⚡ TCP-with-content-provider fallback — fast Android HTTP path over
adb forward, transparent fallback to content-provider RPC. - 🔌 HTTP-only drivers — connect to already-running Android/iOS portals without taking over setup.
- 🛠 Portal lifecycle — download, install, accessibility enablement, auto-upgrade.
- 🪶 Slim — a small async driver package with four runtime deps (
async_adbutils,httpx,requests,rich). - 🔌 Embeddable — designed to be wrapped by sync facades (e.g.
mobilerun-core) or used directly. - 🤝 In sync with upstream — verbatim slice of
droidrun/mobilerun; behaviour and API track upstream.
📦 Installation
Note: Python
>=3.11,<3.14. The Android ADB driver requires ADB onPATHand a device with USB debugging enabled. HTTP-only drivers require an already-running portal URL.
uv pip install mobilerun-core-cli
🚀 Quick usage
import asyncio
from async_adbutils import adb
from mobilerun_core_cli import AndroidDriver, ensure_portal_ready
async def main():
# 1. Make sure Portal is installed + accessibility is on.
device = await adb.device()
await ensure_portal_ready(device)
# 2. Drive the device.
driver = AndroidDriver(serial=device.serial, use_tcp=True)
await driver.connect()
await driver.tap(540, 1200)
await driver.swipe(540, 1600, 540, 400, duration_ms=300)
await driver.input_text("hello", clear=True)
png_bytes = await driver.screenshot()
tree = await driver.get_ui_tree()
asyncio.run(main())
HTTP-only Android:
import asyncio
from mobilerun_core_cli import AndroidPortalHttpDriver
async def main():
driver = AndroidPortalHttpDriver(
url="http://127.0.0.1:18080",
token="...",
)
await driver.connect()
await driver.tap(540, 1200)
asyncio.run(main())
iOS Portal:
import asyncio
from mobilerun_core_cli import IOSPortalDriver
async def main():
driver = IOSPortalDriver("http://127.0.0.1:6643")
await driver.connect()
await driver.start_app("com.apple.Preferences")
asyncio.run(main())
🧱 Layout
mobilerun_core_cli/
├── __init__.py Re-exports the public surface
├── portal.py Portal APK lifecycle + content-provider helpers
├── driver/
│ ├── base.py DeviceDriver ABC, DeviceDisconnectedError
│ ├── android.py AndroidDriver — ADB-backed concrete driver
│ ├── android_http.py AndroidPortalHttpDriver — HTTP-only Android driver
│ └── ios.py IOSPortalDriver — ios-portal HTTP driver
└── transport/
└── portal_client.py PortalClient — TCP-with-content-provider fallback
📚 Public API
Re-exported from mobilerun_core_cli:
| Symbol | What it is |
|---|---|
AndroidDriver |
ADB+Portal device driver. Async methods: tap, swipe, input_text, press_button, start_app, install_app, screenshot, get_ui_tree, get_apps, list_packages, get_date. |
AndroidPortalHttpDriver |
HTTP-only Android Portal driver. Requires url and bearer token; does not use ADB at runtime. |
IOSPortalDriver / IOSDriver |
iOS Portal HTTP driver. Requires an already-running ios-portal URL. |
DeviceDriver |
Abstract base for drivers. supported: set[str] declares which verbs a subclass implements. |
DeviceDisconnectedError |
Raised when the device drops mid-call. |
PortalClient |
HTTP-or-content-provider client for the on-device Portal. Used internally by AndroidDriver; can be constructed directly for low-level access. |
setup_portal(device) |
Download + install + enable the Portal APK on a device. |
ensure_portal_ready(device) |
Idempotent: install/upgrade Portal and enable accessibility if needed. |
setup_keyboard(device) |
Switch the device to the Mobilerun IME. |
ping_portal(device) |
Verify Portal is installed and reachable. |
PORTAL_PACKAGE_NAME, A11Y_SERVICE_NAME |
Portal identifiers. |
portal_content_uri(pkg, path) |
Build content://<pkg>/<path> URIs. |
portal_a11y_service(pkg), portal_ime_id(pkg) |
Accessibility service / IME component names. |
AndroidDriver accepts:
serial: str | None— ADB serial;Nonepicks the only connected device.use_tcp: bool = False— whenTrue, the underlyingPortalClientport-forwards Portal's HTTP server (localhost:N → device:8080) and uses it instead of the content provider. Faster but requires a working forward; falls back transparently.
🪵 Logging
All output goes through the "mobilerun_core_cli" logger. Configure it yourself; the package attaches no handlers.
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger("mobilerun_core_cli").setLevel(logging.DEBUG)
🔗 Relationship to upstream mobilerun
This package owns local execution drivers. The full framework imports these drivers for CLI/agent flows; mobilerun-core wraps them behind a sync, backend-neutral API.
Use mobilerun-core-cli when you need async local drivers directly.
Use mobilerun when you want the full LLM-agent experience, CLI/TUI, and multi-platform support out of the box.
📄 License
MIT — see LICENSE.
Metadata
Release files for mobilerun-core-cli 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mobilerun_core_cli-0.2.0.tar.gz | 43.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mobilerun_core_cli-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 74.5 kB
Release files / mobilerun_core_cli-0.2.0.tar.gz
| Download URL | mobilerun_core_cli-0.2.0.tar.gz |
|---|---|
| Size | 43.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dc13016c7983476cca564dd013fc281047474dc502de54f8c0bd5647b48211e2
|
|
BLAKE2b-256 checksum How to use checksums |
d67818cd91fccb2fb348a5150707245d303b6052890a9aca2c35bd391d776208
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Jun 7, 2026.
Transparency logRelease files / mobilerun_core_cli-0.2.0-py3-none-any.whl
| Download URL | mobilerun_core_cli-0.2.0-py3-none-any.whl |
|---|---|
| Size | 30.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d94c5478d299fc10ec3f8f850dc469d65e2533db4805e0d932b15925c8e5e351
|
|
BLAKE2b-256 checksum How to use checksums |
40542fe03bf7a98fb50b70580acef5c5bf3ea1c51ccf6ef867b5df81201934ea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Jun 7, 2026.
Transparency log