Skip to content

LIghtJUNction/AndroidUse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AndroidUse logo

AndroidUse

Research and Education Use Only

This project is intended for research and educational purposes only. Any use for illegal data access, system interference, or unlawful activities is strictly prohibited.

AndroidUse is a rooted Android automation module. It exposes a secret-protected MCP Streamable HTTP server on the phone, provides compact UI/XML analysis for daily navigation, and hosts an Android Use Zygisk Module runtime for dynamic app-process adaptation.

The project is built around three parts:

  • Root module: starts the MCP server and stores runtime config under the module directory.
  • Rust CLI: implements MCP tools, shell sessions, UI automation, file transfer, app install helpers, and AUZM control.
  • Companion Android app: settings entry, AUZM status page, and AndroidUse Outer IME.

Capabilities

  • MCP Streamable HTTP endpoint with bearer-secret authentication.
  • Default local bind: 127.0.0.1:8765.
  • User-editable host/port config.
  • Persistent Android shell sessions through portable-pty.
  • XML-first UI analysis with screenshot fallback.
  • Coordinate, keyevent, swipe, UI-element tap, wake, and unlock tools.
  • AndroidUse Outer IME for text injection without permanently replacing the user's preferred keyboard.
  • File station for upload/download without asking agents to invent Android paths.
  • APK and root-module install helpers.
  • Runtime App group registration for progressive MCP tool disclosure.
  • AUZM target control through runtime config, not hardcoded packages.
  • Kam/kamfw lifecycle support across KernelSU, APatch, and Magisk.

Module Paths

After installation, the active module root is:

/data/adb/modules/AndroidUse/

Important installed paths:

/data/adb/modules/AndroidUse/cli
/data/adb/modules/AndroidUse/bin/androiduse-cli
/data/adb/modules/AndroidUse/.secret/mcp_secret
/data/adb/modules/AndroidUse/.config/androiduse/mcp.env
/data/adb/modules/AndroidUse/.config/androiduse/app-groups.json
/data/adb/modules/AndroidUse/.config/androiduse/zygisk-target
/data/adb/modules/AndroidUse/.config/androiduse/auzm.d/androiduse-runtime/payload.so
/data/adb/modules/AndroidUse/zygisk/arm64-v8a.so

During a pending KernelSU/APatch update before reboot, files may temporarily exist under:

/data/adb/modules_update/AndroidUse/

Runtime scripts should derive MODDIR from their own location and must not persist modules_update paths.

Root Manager Lifecycle

AndroidUse uses kamfw to keep runtime behavior unified while adapting install and lifecycle details per root manager:

  • KernelSU/APatch: use boot-completed.sh.
  • Magisk: package/install compatibility falls back to service.sh.
  • Runtime home is normalized to the active module directory.
  • Module bin/ is placed before common Magisk/KSU/system paths in PATH.

Business logic should use $MODDIR, not direct Magisk/KSU/APatch home assumptions.

Secret

The MCP server refuses unauthenticated requests. The secret is generated on first boot if missing:

/data/adb/modules/AndroidUse/.secret/mcp_secret

The secret directory and file use mode 700.

Refresh the secret manually:

adb shell 'su -M -c "/data/adb/modules/AndroidUse/action.sh"'

action.sh prints the new secret, restarts MCP, and opens the AndroidUse app if the companion app is installed.

Do not store the secret directly in project config.

Connect From Host

Forward the phone-local MCP port:

adb forward tcp:8765 tcp:8765

Export the secret in your host shell:

export ANDROIDUSE_MCP_SECRET="$(adb shell 'su -M -c "cat /data/adb/modules/AndroidUse/.secret/mcp_secret"' | tr -d '\r\n')"

Register the MCP server:

codex mcp add androiduse --url http://127.0.0.1:8765/mcp --bearer-token-env-var ANDROIDUSE_MCP_SECRET

Host And Port

The listener is configured by:

/data/adb/modules/AndroidUse/.config/androiduse/mcp.env

Default:

ANDROIDUSE_MCP_HOST=127.0.0.1
ANDROIDUSE_MCP_PORT=8765

Use 127.0.0.1 for adb-forward-only access. Use 0.0.0.0 or a LAN address only on trusted networks. The bearer secret is still required, but exposing the port beyond adb forwarding increases risk.

The AndroidUse companion app also exposes Host and Port fields in the MCP access section. Saving them writes mcp.env and restarts MCP.

After editing mcp.env, restart MCP:

adb shell 'su -M -c "sh /data/adb/modules/AndroidUse/boot-completed.sh"'

Core MCP Tools

mksh

Runs commands in an Android shell. By default, the server keeps a persistent PTY session per MCP HTTP session, so state such as cd and shell variables can survive across tool calls.

Useful arguments:

  • command: command line to run.
  • timeout_secs: command timeout, default 30.
  • reset: restart the persistent shell session before running.
  • stateless: run a fresh /system/bin/sh -c process instead of the PTY session.

UI Control

  • foreground_app: current focus, focused package, and secure-window flag.
  • ui_dump: compact XML-derived UI analysis.
  • tap_ui: tap a UI element by text, resource-id, or content-desc.
  • tap: tap raw coordinates.
  • swipe: swipe raw coordinates.
  • keyevent: send an Android keyevent.
  • wake: wake the display.
  • unlock_device: wake, swipe, enter a numeric PIN, and press enter.
  • take_over: request user review for login, captcha, payment confirmation, or other cases where automation should pause for human approval.
  • human_takeover: hand control to the user for captcha, login, or complex pages, then continue after the user marks the takeover complete.

AndroidUse also exposes AutoGLM-compatible generic action names for clients that expect that tool surface: Launch, Tap, Type, Swipe, Back, Home, Long Press, Double Tap, Wait, and Take_over. These are MCP aliases over the same device-control layer, not app-specific AUZM logic.

ui_dump is the default navigation tool. It filters redundant XML containers and emits one core element per line:

meta count=... vision_fallback=false
text=... id=... desc=... class=... pkg=... bounds=[x1,y1][x2,y2] clickable=true

Use screenshot only when visual context is needed or ui_dump reports a vision fallback, such as SurfaceView, TextureView, WebView, game/video content, or captcha-like screens.

Text Input

  • text_input: inject text into the current focused editor.
  • ime_action: trigger editor actions such as send, done, or search.

AndroidUse uses an outer IME design. The MCP server temporarily switches to AndroidUse Outer IME, commits text or an editor action, then restores the user's previous input method by default. This keeps automation input-method independent without permanently replacing Sogou, Gboard, or another preferred keyboard.

Screenshot

screenshot captures the screen into the module state directory and returns a protected HTTP URL such as:

http://127.0.0.1:8765/screenshots/shot-...png

Fetch that URL with the same MCP secret, using Authorization: Bearer <secret> or X-AndroidUse-Secret. For clients that cannot attach headers, include_secret_in_url=true returns an additional url_with_secret, but the default avoids putting the secret into model-visible text. include_base64=true is still available for compatibility, but URL transfer is preferred.

AndroidUse tries direct framebuffer access first where available, then falls back to Android screencap -p.

Normal Android screenshots cannot reliably capture FLAG_SECURE windows. See the CaptureSposed section below.

File Station

The phone side exposes a module-local file station:

/data/adb/modules/AndroidUse/.state/file-station/

Tools:

  • file_upload: upload data_base64 as name.
  • file_download: download name and return data_base64.
  • file_list: list station files and sizes.
  • file_delete: delete a station file.

File names must be plain basenames. Path separators and .. are rejected.

Install Helpers

  • install_app: install an APK from the file station or an absolute phone path.
  • install_root_module: install a root module ZIP through auto-detected KernelSU, Magisk, or APatch command paths.

AUZM Runtime

AUZM means Android Use Zygisk Module. Do not use the generic term "Zygisk module" for AndroidUse's dynamic runtime modules.

The active loader lives at:

/data/adb/modules/AndroidUse/zygisk/arm64-v8a.so

This loader is a meta module: it is the Zygisk module whose job is to load other AUZM modules. App-specific behavior belongs in separate AUZM payload.so files, not in the loader itself.

AUZM modules are registered under:

/data/adb/modules/AndroidUse/.config/androiduse/auzm.d/<module-id>/

Each registry directory uses small text files:

enabled
name
scope
path
payload.so

The default runtime payload lives at:

/data/adb/modules/AndroidUse/.config/androiduse/auzm.d/androiduse-runtime/payload.so

The loader reads the registry and loads every enabled AUZM whose scope matches the current package/process. scope may contain one match string per line.

AUZM Template

New AUZM modules should start from the Kam-compatible template under:

tmpl/auzm_template/

Build all workspace members to regenerate the distributable template archive:

kam build -a

This produces:

templates/auzm_template.tar.gz
dist/templates.zip

templates/auzm_template.tar.gz is the single-template archive. dist/templates.zip is the release bundle consumed by Kam/setup-kam template import workflows.

The compatibility target file is:

/data/adb/modules/AndroidUse/.config/androiduse/zygisk-target

set_auzm_target writes both zygisk-target and the default runtime module's auzm.d/androiduse-runtime/scope. Empty scope means the default AUZM is not loaded. Use MCP to set it:

{
  "name": "set_auzm_target",
  "arguments": {
    "use_foreground": true
  }
}

Or set an explicit package:

{
  "name": "set_auzm_target",
  "arguments": {
    "package": "com.example.app"
  }
}

Clear it:

{
  "name": "set_auzm_target",
  "arguments": {
    "clear": true
  }
}

Restart the target app after changing the target. A device reboot may be needed when root-manager Zygisk scope changed.

Inspect registered AUZM modules:

{
  "name": "auzm_status",
  "arguments": {}
}

Dynamic MCP Tool Registry

AndroidUse supports runtime MCP tool blueprints for owner-controlled app adaptation.

Register a new dynamic tool with generate_new_hook_tool. It writes:

/data/adb/modules/AndroidUse/.config/androiduse/dynamic-tools/blueprints/<tool>.json
/data/adb/modules/AndroidUse/.config/androiduse/dynamic-tools/sources/<tool>.java

Calling the tool writes a request:

/data/adb/modules/AndroidUse/.state/dynamic-tools/requests/<request_id>.json

The injected AUZM payload consumes the request through the app cache bridge and writes a response:

/data/adb/modules/AndroidUse/.state/dynamic-tools/responses/<request_id>.json

Use dynamic_tool_status to inspect blueprints, pending requests, responses, and bridge paths.

Dynamic App Groups

App-specific tools are not hardcoded into the Rust binary. Tool visibility is controlled by:

/data/adb/modules/AndroidUse/.config/androiduse/app-groups.json

Register a group for the current foreground app:

{
  "name": "register_app_group",
  "arguments": {
    "group_name": "example_app",
    "use_foreground": true
  }
}

Register an explicit package and set AUZM target at the same time:

{
  "name": "register_app_group",
  "arguments": {
    "group_name": "example_app",
    "package": "com.example.app",
    "make_auzm_target": true
  }
}

When the foreground package matches a configured group, MCP progressively discloses tools whose blueprint uses that group_name. The built-in global group is always visible.

Use app_group_status to inspect the current config.

Remove a runtime group:

{
  "name": "unregister_app_group",
  "arguments": {
    "group_name": "example_app"
  }
}

Human Review

take_over opens the AndroidUse companion app and asks the user to review an automation request. The dialog exposes four choices:

  • Allow
  • Always allow
  • Deny
  • Always deny

Allow and Always allow require biometric authentication before the decision is written, so automation cannot approve itself by clicking the dialog. Deny and Always deny do not require biometric authentication.

Example:

{
  "name": "take_over",
  "arguments": {
    "reason": "Login or captcha needs user confirmation.",
    "scope": "com.example.app",
    "timeout_secs": 300
  }
}

Decisions are written under:

/data/adb/modules/AndroidUse/.state/take-over/

Remembered policies are stored at:

/data/adb/modules/AndroidUse/.config/androiduse/take-over-policy.json

Human Takeover

human_takeover is a separate flow for complex screens where the user needs to operate the phone directly, such as captcha, login, or a page that automation cannot interpret reliably.

Example:

{
  "name": "human_takeover",
  "arguments": {
    "reason": "Please complete the captcha and return to AndroidUse.",
    "scope": "com.example.app",
    "timeout_secs": 600
  }
}

The AndroidUse app shows a human takeover dialog. After the user completes the task on the phone, they tap Done / 完成接管, and MCP receives completed.

Companion App

The companion app source is under:

app/androiduse-app/

It provides:

  • AndroidUse settings entry.
  • Secret display/copy flow.
  • MCP Host/Port editor.
  • Human review dialog.
  • Human takeover dialog.
  • AUZM module cards with metadata and paths.
  • Light/dark and language toggles.
  • AndroidUse Outer IME service.

Build:

bash tools/build_androiduse_app.sh

Install:

adb install -r target/androiduse-app/androiduse-app.apk

Companion Modules

CaptureSposed

CaptureSposed is only for secure-window screenshot support:

https://github.com/99keshav99/CaptureSposed

AndroidUse does not bundle it. Install and enable it separately if you need to inspect apps using FLAG_SECURE. CaptureSposed is not the AUZM target and should not be written into zygisk-target unless you are specifically testing CaptureSposed itself.

liboemcrypto-disabler

For rooted-device testing against DRM streaming apps, users may optionally install:

https://github.com/Anonym0usWork1221/liboemcrypto-disabler

This is not a hard dependency for AndroidUse. Install it only when the target test case needs rooted-device DRM compatibility.

Build

Build the Android CLI:

PATH=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH \
  cargo build --release --target aarch64-linux-android -p androiduse-cli

Build the Rust AUZM loader:

tools/build_zygisk_module.sh

Build the Rust payload:

tools/build_payload_module.sh

Package the root module:

kam build

Build the root module and AUZM templates together:

kam build -a

The pre-build hooks copy the release binary into:

src/AndroidUse/bin/androiduse-cli

and package:

src/AndroidUse/zygisk/arm64-v8a.so
src/AndroidUse/.config/androiduse/auzm.d/androiduse-runtime/payload.so

Skip AUZM builds when needed:

ANDROIDUSE_BUILD_ZYGISK=0 ANDROIDUSE_BUILD_PAYLOAD=0 kam build

Verification

Local checks:

cargo fmt -- --check
cargo check -p androiduse-cli
cargo check -p androiduse-payload
bash tools/build_androiduse_app.sh
tools/build_zygisk_module.sh
tools/build_payload_module.sh
kam build

Device checks:

adb shell 'su -M -c "sh /data/adb/modules/AndroidUse/boot-completed.sh"'
adb shell 'su -M -c "ss -lntp 2>/dev/null | grep 8765"'
adb forward tcp:8765 tcp:8765

Then call tools/list with the bearer secret and confirm core tools such as mksh, ui_dump, text_input, register_app_group, and set_auzm_target are present.

Safety Notes

  • This project is intended for research and educational purposes only. Any use for illegal data access, system interference, or unlawful activities is strictly prohibited.
  • Keep the MCP listener on loopback unless you trust the network.
  • Do not print or commit MCP secrets.
  • Do not edit KSU, Vector, or LSPosed databases from AndroidUse automation.
  • Prefer ui_dump and tap_ui over blind coordinate taps.
  • Use screenshots only when XML is insufficient.
  • Dynamic hooks should be scoped to owner-controlled automation, compatibility, observability, and UI tooling.

Acknowledgements

AndroidUse's generic mobile action surface is inspired by AutoGLM-compatible mobile GUI agent workflows. We thank the AutoGLM and MobileRL authors for their work on autonomous mobile GUI agents.

AndroidUse's AUZM loader and hot-swap workflow also reference HanSoBored/Zygisk-Loader, a Zygisk module project for dynamically loading native payload libraries into Android application processes without requiring a full device reboot.

@article{liu2024autoglm,
  title={Autoglm: Autonomous foundation agents for guis},
  author={Liu, Xiao and Qin, Bo and Liang, Dongzhu and Dong, Guang and Lai, Hanyu and Zhang, Hanchen and Zhao, Hanlin and Iong, Iat Long and Sun, Jiadai and Wang, Jiaqi and others},
  journal={arXiv preprint arXiv:2411.00820},
  year={2024}
}

@article{xu2025mobilerl,
  title={MobileRL: Online Agentic Reinforcement Learning for Mobile GUI Agents},
  author={Xu, Yifan and Liu, Xiao and Liu, Xinghan and Fu, Jiaqi and Zhang, Hanchen and Jing, Bohao and Zhang, Shudan and Wang, Yuting and Zhao, Wenyi and Dong, Yuxiao},
  journal={arXiv preprint arXiv:2509.18119},
  year={2025}
}

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors