mobile-harness

skill
Security Audit
Warn
Health Pass
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 34 GitHub stars
Code Warn
  • Code scan incomplete — No supported source files were scanned during light audit
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

Skills for controlling Android, iOS and cloud phones

README.md

Mobile Harness

Portable operating instructions for AI agents controlling Android and iOS devices—locally or in the cloud.

Mobile Harness is a compact Markdown harness, not an agent runtime. Its primary
control path is Python's mobilerun_core, with optional client apps where
needed.

Agent Setup Prompt

Copy paste it into your agent:

Set up https://github.com/droidrun/mobile-harness for me.

Read `install.md` and follow the steps to install `mobile-harness`.

Scope

  • Android through mobilerun-core using local ADB with optional Portal, Portal HTTP-only, or cloud.
  • iOS through mobilerun-core using ios-portal HTTP or cloud.

Manual Install

Install the full public control API:

cd /path/to/mobile-harness
python -m venv .venv
.venv/bin/python -m pip install "mobilerun-core[local]"
.venv/bin/python -c "from mobilerun_core import Mobilerun"

Use Python 3.11, 3.12, or 3.13 to create the venv.

Tell agents which Python runtime to use:

Use /path/to/mobile-harness/.venv/bin/python for mobile-harness.

Base mobilerun-core includes cloud support through mobilerun-sdk. The
local extra installs mobilerun-core-local, which mobilerun-core uses
internally for local Android and iOS backends. Agents should still import only
mobilerun_core.

Primary API

from mobilerun_core import Mobilerun

m = Mobilerun()
device = m.connect("<cloud-device-id>", backend="cloud")
device = m.connect("R5CT123456", backend="local-android-adb")
device = m.connect(backend="local-ios-http", url="http://127.0.0.1:6643")
device = m.connect(
    backend="local-android-http",
    url="http://127.0.0.1:18080",
    token="...",
)

device.ui()
device.screenshot()
device.start_app("com.android.settings")

After connecting, agents should inspect device.capabilities and use
device.supports(...) before optional operations.

device.execute_script("<js>") runs JavaScript in the device's foreground
Chrome tab and returns its JSON result. Cloud devices only; local backends
raise UnsupportedOperation. Gate it with
device.supports("execute_script"); the platform guides describe this key's
network-probe behavior and its two server-side errors.

Common Device Helpers

Use these helpers through the device returned by Mobilerun.connect(...):

  • device.find_nodes(...) searches the accessibility tree. any_contains=
    matches case-insensitive substrings across text, content description,
    resource id, and accessibility identifier. Nodes may carry offscreen: True
    (outside the viewport; scroll to reach it) and hidden: True (reported not
    visible; scrolling alone may not reveal it). A missing flag is not proof of
    visibility.
  • device.tap_node(node) taps the center of an accessibility node and raises
    if the node has no usable bounds. Before any bounds check, it raises a
    distinct error for a node flagged hidden unless the node is also offscreen.
  • device.tap_text("label") taps the first on-screen, non-hidden match across
    text, description, resource id, and accessibility identifier. It raises a
    distinct error when matches exist but none are tappable on-screen.
  • device.scroll(direction, distance=0.5, ms=..., verify=False) scrolls
    content-relative; verify=True returns whether the viewport actually moved.
  • device.scroll_until(text_contains=..., direction="down", max_swipes=10)
    scrolls until a match is on-screen, returning the node or None. It stops
    early with None when the viewport stops moving; do not re-call it blindly.
  • device.type("text", clear=True) clears the focused field before typing
    when the backend supports text input. device.clear_input() is available on
    local Android ADB and local iOS Portal HTTP.
  • device.list_apps() excludes system apps by default. Pass
    include_system_apps=True when a full inventory is needed and supported.

Cloud Mode

Cloud devices use the same Mobilerun facade:

export MOBILERUN_CLOUD_API_KEY="..."
export MOBILERUN_API_BASE_URL="https://api.mobilerun.ai/v1"
from mobilerun_core import Mobilerun

m = Mobilerun()
device = m.connect("<cloud-device-id>", backend="cloud")
device.ui()
device.screenshot()
device.start_app("com.android.settings")

Loading Model

Skill-based runtimes can load SKILL.md; all runtimes should start with
AGENTS.md. It routes agents to the smallest needed file:

  • platforms/android/GUIDE.md for Android work.
  • platforms/ios/GUIDE.md for iOS work.
  • platforms/<platform>/recovery/GUIDE.md only when control fails.
  • the credentials guide under core/credentials only when a credential or human-gated screen appears.
  • core/memory/GUIDE.md only when reading or writing local agent-owned memory.
  • apps/android/<package>/CARD.md or apps/ios/<bundle-id>/CARD.md only for the foreground app.
  • UPDATE.md only when the session-start git pull --ff-only fails.

Local Android Modes

ADB Android Portal HTTP Mode
yes yes backend="local-android-adb": core uses ADB and automatically uses Portal features when available.
yes no backend="local-android-adb": core uses ADB-native control, UI, text input, screenshots, and app lifecycle.
no yes backend="local-android-http" with the user-provided Portal base URL and bearer token.
no no Blocked: ask the user to enable ADB or provide reachable Portal HTTP access.

Android Portal HTTP-only means the agent already has both:

  • a base URL such as http://127.0.0.1:18080
  • a bearer token for Authorization: Bearer <token>

Without ADB, the harness cannot install, enable, port-forward, or fetch a token
for Portal.
Android Mobilerun Portal: https://github.com/droidrun/mobilerun-portal

Local iOS Mode

Local iOS has one active capability mode:

  • iOS Portal HTTP: backend="local-ios-http" with MOBILERUN_IOS_PORTAL_URL or an explicit URL. GET /device/date, GET /state, and GET /vision/screenshot must work.
  • Blocked: no reachable iOS Portal. Start ios-portal check info: https://github.com/droidrun/ios-portal

The default local iOS Portal example is http://127.0.0.1:6643.

A second local iOS server exists: mobilerun-ios --local <udid>, default
http://127.0.0.1:8080, setup guide:
https://docs.mobilerun.ai/guides/connect-iphone. backend="local-ios-http"
speaks only the ios-portal contract and cannot connect to that server; do
not point it at port 8080. platforms/ios/GUIDE.md explains how to tell the
two apart.

Local State

memory/ and credentials/ are local, ignored folders. The repository tracks only their rules/templates. Agents may write operational memory after reading core/memory/GUIDE.md.

Reviews (0)

No results found