内容
<p align="center">
<img src="assets/androiduse-logo.png" alt="AndroidUse logo" width="160">
</p>
# AndroidUse
<div align="center">
<p>
<a href="Cargo.toml"><img alt="Rust" src="https://img.shields.io/badge/Rust-2021-f46623?logo=rust&logoColor=white" /></a>
<a href="Cargo.toml"><img alt="MIT License" src="https://img.shields.io/badge/License-MIT-green.svg" /></a>
<a href="docs/guide/what-is-androiduse.md"><img alt="Docs" src="https://img.shields.io/badge/Docs-available-blue" /></a>
<a href="CHANGELOG.md"><img alt="Changelog" src="https://img.shields.io/badge/Changelog-updated-8b5cf6" /></a>
</p>
</div>
<p align="center">
<a href="#概述">概述</a>
· <a href="#快速开始">快速开始</a>
· <a href="#模块路径">模块路径</a>
· <a href="#简体中文速览">简体中文</a>
</p>
> **仅限研究和教育用途**
>
> 本项目仅用于研究和教育目的。严禁用于非法数据访问、系统干扰或违法活动。
AndroidUse 是一个面向 Root Android 的自动化模块,它在手机上暴露一个受口令保护的 MCP Streamable HTTP 服务器,提供紧凑的 UI/XML 分析用于日常导航,并托管一个 Android Use Zygisk 模块运行时,用于动态应用进程适配。
## 概述
AndroidUse 将三个层次合并为一个设备端的自动化栈:
- 一个运行 MCP 服务器的 rooted 模块
- 一个处理自动化、传输和控制流程的 Rust CLI
- 一个用于设置、状态和用户界面控制的配套 Android 应用
结果是一个设备本地的工具链,可以检查 UI 状态、操纵应用,并向 MCP 客户端公开受控的自动化原语。
## 快速开始
```bash
adb forward tcp:8765 tcp:8765
export ANDROIDUSE_MCP_SECRET="$(adb shell 'su -M -c "cat /data/adb/modules/AndroidUse/.secret/mcp_secret"' | tr -d '\r\n')"
codex mcp add androiduse --url http://127.0.0.1:8765/mcp --bearer-token-env-var ANDROIDUSE_MCP_SECRET
```
## 简体中文速览
AndroidUse 是一个面向 Root Android 的自动化模块,把设备端 MCP 服务、UI 分析、文件传输、Shell 会话和 AUZM 运行时整合到一起。
- 适合本地设备自动化、移动端 agent 工具链、受控 UI 操作。
- 支持 KernelSU、APatch 和 Magisk。
- 强调“设备本地执行 + 口令保护 + 可审计控制”。
## 能力
- MCP Streamable HTTP 端点,带有 bearer-secret 认证。
- 默认本地绑定:`127.0.0.1:8765`。
- 用户可编辑的主机/端口配置。
- 通过 `portable-pty` 实现持久的 Android Shell 会话。
- 基于 XML 的 UI 分析,带有截图备用方案。
- 坐标、按键事件、滑动、UI 元素点击、唤醒和解锁工具。
- AndroidUse Outer IME,用于文本注入,而无需永久替换用户的首选键盘。
- 文件站,用于上传/下载,而无需询问代理构造 Android 路径。
- APK 和 root 模块安装助手。
- 运行时应用组注册,用于渐进式 MCP 工具披露。
- 通过运行时配置(而非硬编码包)控制 AUZM 目标。
- 跨 KernelSU、APatch 和 Magisk 的 Kam/kamfw 生命周期支持。
## 模块路径
安装后,活动模块根目录为:
```text
/data/adb/modules/AndroidUse/
```
重要安装路径:
```text
/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
```
在待处理 KernelSU/APatch 更新期间重启前,文件可能临时存在于:
```text
/data/adb/modules_update/AndroidUse/
```
运行时脚本应从其自身位置导出 `MODDIR`,并且不得持久化 `modules_update` 路径。
## Root 管理器生命周期
AndroidUse 使用 kamfw 在适应安装和生命周期细节的同时保持运行时行为统一:
- KernelSU/APatch:使用 `boot-completed.sh`。
- Magisk:包/安装兼容性降级为 `service.sh`。
- 运行时主目录规范化为活动模块目录。
- 模块 `bin/` 在 `PATH` 中置于公共 Magisk/KSU/系统路径之前。
业务逻辑应使用 `$MODDIR`,而非直接的 Magisk/KSU/APatch 主目录假设。
## 口令
MCP 服务器拒绝未经身份验证的请求。口令在缺失时会在首次启动时生成:
```text
/data/adb/modules/AndroidUse/.secret/mcp_secret
```
口令目录和文件使用模式 `700`。
手动刷新口令:
```sh
adb shell 'su -M -c "/data/adb/modules/AndroidUse/action.sh"'
```
`action.sh` 打印新的口令,重启 MCP,并打开 AndroidUse 应用(如果已安装)。
请勿直接在项目配置中存储口令。
## 从主机连接
转发手机本地的 MCP 端口:
```sh
adb forward tcp:8765 tcp:8765
```
在主机 Shell 中导出口令:
```sh
export ANDROIDUSE_MCP_SECRET="$(adb shell 'su -M -c "cat /data/adb/modules/AndroidUse/.secret/mcp_secret"' | tr -d '\r\n')"
```
注册 MCP 服务器:
```sh
codex mcp add androiduse --url http://127.0.0.1:8765/mcp --bearer-token-env-var ANDROIDUSE_MCP_SECRET
```
## 主机和端口
侦听器由以下配置:
```text
/data/adb/modules/AndroidUse/.config/androiduse/mcp.env
```
默认:
```sh
ANDROIDUSE_MCP_HOST=127.0.0.1
ANDROIDUSE_MCP_PORT=8765
```
仅在受信任的网络上使用 `0.0.0.0` 或 LAN 地址。尽管端口暴露于 adb 转发之外,但仍需要 bearer 口令。
AndroidUse 配套应用还提供 MCP 访问部分中的主机和端口字段。保存它们会写入 `mcp.env` 并重启 MCP。
编辑 `mcp.env` 后,重启 MCP:
```sh
adb shell 'su -M -c "sh /data/adb/modules/AndroidUse/boot-completed.sh"'
```
## 核心 MCP 工具
### `mksh`
在 Android Shell 中运行命令。默认情况下,服务器为每个 MCP HTTP 会话保留一个持久的 PTY 会话,因此诸如 `cd` 和 Shell 变量等状态可以跨工具调用存活。
有用的参数:
- `command`:要运行的命令行。
- `timeout_secs`:命令超时,默认为 `30`。
- `reset`:在运行前重启持久 Shell 会话。
- `stateless`:运行一个全新的 `/system/bin/sh -c` 进程,而不是 PTY 会话。
### UI 控制
- `foreground_app`:当前焦点、聚焦包和安全窗口标志。
- `ui_dump`:紧凑的 XML 派生 UI 分析。
- `tap_ui`:通过文本、资源 ID 或内容描述点击 UI 元素。
- `tap`:点击原始坐标。
- `swipe`:滑动原始坐标。
- `keyevent`:发送 Android 按键事件。
- `wake`:唤醒显示屏。
- `unlock_device`:唤醒、滑动、输入数字 PIN 并按 Enter。
- `take_over`:请求用户审查登录、验证码、支付确认或其他自动化应暂停以供人类批准的情况。
- `human_takeover`:将控制权交给用户以进行验证码、登录或复杂页面,然后在用户标记完成后再继续。
AndroidUse 还为期望该工具表面的客户端提供 AutoGLM 兼容的通用操作名称:`Launch`、`Tap`、`Type`、`Swipe`、`Back`、`Home`、`Long Press`、`Double Tap`、`Wait` 和 `Take_over`。这些是 MCP 别名,适用于同一设备控制层,而不是特定于应用的 AUZM 逻辑。
`ui_dump` 是默认导航工具。它过滤冗余的 XML 容器,并每行发出一个核心元素:
```text
meta count=... vision_fallback=false
text=... id=... desc=... class=... pkg=... bounds=[x1,y1][x2,y2] clickable=true
```
仅当需要视觉上下文时才使用 `screenshot`,或者当 `ui_dump` 报告视觉回退时,例如 SurfaceView、TextureView、WebView、游戏/视频内容或类似验证码的屏幕。
### 文本输入
- `text_input`:将文本注入当前聚焦的编辑器。
- `ime_action`:触发编辑器操作,例如 `send`、`done` 或 `search`。
AndroidUse 使用外部 IME 设计。MCP 服务器临时切换到 AndroidUse 外部 IME,提交文本或编辑器操作,然后默认恢复用户的输入法。
### 截图
`screenshot` 将屏幕捕获到模块状态目录并返回受保护的 HTTP URL,例如:
```text
http://127.0.0.1:8765/screenshots/shot-...png
```
使用相同的 MCP 口令获取该 URL,使用 `Authorization: Bearer <secret>` 或 `X-AndroidUse-Secret`。对于无法附加标头的客户端,`include_secret_in_url=true` 返回一个额外的 `url_with_secret`,但默认避免将口令放入模型可见的文本中。`include_base64=true` 仍然可用于兼容性,但首选 URL 传输。
AndroidUse 首先尝试直接帧缓冲区访问,然后回退到 Android `screencap -p`。
普通 Android 截图无法可靠地捕获 `FLAG_SECURE` 窗口。参见下面的 CaptureSposed 部分。
### 文件站
手机侧暴露一个模块本地文件站:
```text
/data/adb/modules/AndroidUse/.state/file-station/
```
工具:
- `file_upload`:上传 `data_base64` 为 `name`。
- `file_download`:下载 `name` 并返回 `data_base64`。
- `file_list`:列出站点文件和大小。
- `file_delete`:删除站点文件。
文件名必须是纯basename。路径分隔符和 `..` 被拒绝。
### 安装助手
- `install_app`:从文件站或绝对手机路径安装 APK。
- `install_root_module`:通过自动检测的 KernelSU、Magisk 或 APatch 命令路径安装 root 模块 ZIP。
## AUZM 运行时
AUZM 即 Android Use Zygisk 模块。不要为 AndroidUse 的动态运行时模块使用通用术语“Zygisk 模块”。
活动加载器位于:
```text
/data/adb/modules/AndroidUse/zygisk/arm64-v8a.so
```
此加载器是一个 **元模块**:它的任务是加载其他 AUZM 模块。应用特定的行为属于单独的 AUZM `payload.so` 文件,而不是加载器本身。
AUZM 模块在以下路径注册:
```text
/data/adb/modules/AndroidUse/.config/androiduse/auzm.d/<module-id>/
```
每个注册目录使用小文本文件:
```text
enabled
name
scope
path
payload.so
```
默认运行时 payload 位于:
```text
/data/adb/modules/AndroidUse/.config/androiduse/auzm.d/androiduse-runtime/payload.so
```
加载器读取注册表并加载每个启用的 AUZM,其 `scope` 与当前包/进程匹配。`scope` 可以包含每个换行符一个匹配字符串。
### AUZM 模板
新的 AUZM 模块应从 Kam 兼容的模板开始:
```text
tmpl/auzm_template/
```
构建所有工作区成员以重新生成可分布的模板存档:
```sh
kam build -a
```
生成:
```text
templates/auzm_template.tar.gz
dist/templates.zip
```
`templates/auzm_template.tar.gz` 是单个模板存档。`dist/templates.zip` 是 Kam/setup-kam 模板导入工作流消耗的发布包。
兼容性目标文件是:
```text
/data/adb/modules/AndroidUse/.config/androiduse/zygisk-target
```
`set_auzm_target` 写入 `zygisk-target` 和默认运行时模块的 `auzm.d/androiduse-runtime/scope`。空范围表示默认 AUZM 不被加载。使用 MCP 设置:
```json
{
"name": "set_auzm_target",
"arguments": {
"use_foreground": true
}
}
```
或设置显式包:
```json
{
"name": "set_auzm_target",
"arguments": {
"package": "com.example.app"
}
```
清除它:
```json
{
"name": "set_auzm_target",
"arguments": {
"clear": true
}
}
```
重启目标应用更改目标。设备重启可能需要在更改 root-manager Zygisk 范围后进行。
检查已注册的 AUZM 模块:
```json
{
"name": "auzm_status",
"arguments": {}
}
```
## 动态 MCP 工具注册表
AndroidUse 支持运行时 MCP 工具蓝图的所有者控制的应用适配。
使用 `generate_new_hook_tool` 注册新的动态工具。它写入:
```text
/data/adb/modules/AndroidUse/.config/androiduse/dynamic-tools/blueprints/<tool>.json
/data/adb/modules/AndroidUse/.config/androiduse/dynamic-tools/sources/<tool>.java
```
调用该工具会写入请求:
```text
/data/adb/modules/AndroidUse/.state/dynamic-tools/requests/<request_id>.json
```
注入的 AUZM payload 通过应用缓存桥接器消耗请求并写入响应:
```text
/data/adb/modules/AndroidUse/.state/dynamic-tools/responses/<request_id>.json
```
使用 `dynamic_tool_status` 检查蓝图、待请求、响应和桥接路径。
```json
{
"name": "dynamic_tool_status",
"arguments": {}
}
```
## 动态应用组
应用特定的工具不会硬编码到 Rust 二进制文件中。工具的可见性由以下控制:
```text
/data/adb/modules/AndroidUse/.config/androiduse/app-groups.json
```
为当前前景应用注册一个组:
```json
{
"name": "register_app_group",
"arguments": {
"group_name": "example_app",
"use_foreground": true
}
}
```
为显式包和 AUZM 目标注册一个组:
```json
{
"name": "register_app_group",
"arguments": {
"group_name": "example_app",
"package": "com.example.app",
"make_auzm_target": true
}
}
```
当前景包与配置的组匹配时,MCP 会渐进式公开使用该 `group_name` 的工具。内置的 `global` 组始终可见。
使用 `app_group_status` 检查当前配置。
删除运行时组:
```json
{
"name": "unregister_app_group",
"arguments": {
"group_name": "example_app"
}
}
```
## 人机交互
`take_over` 打开 AndroidUse 配套应用并要求用户审查自动化请求。对话框公开了四个选项:
- 允许
- 始终允许
- 拒绝
- 始终拒绝
`Allow` 和 `Always allow` 需要生物识别身份验证,然后写入决策,因此自动化无法自行批准决策。`Deny` 和 `Always deny` 不需要生物识别身份验证。
示例:
```json
{
"name": "take_over",
"arguments": {
"reason": "登录或验证码需要用户确认。",
"scope": "com.example.app",
"timeout_secs": 300
}
}
```
决定写入:
```text
/data/adb/modules/AndroidUse/.state/take-over/
```
记住的策略存储在:
```text
/data/adb/modules/AndroidUse/.config/androiduse/take-over-policy.json
```
## 人机接管
`human_takeover` 是用于复杂屏幕的单独流程,用户需要在那里直接操作手机,例如验证码、登录或自动化无法可靠解释的页面。
示例:
```json
{
"name": "human_takeover",
"arguments": {
"reason": "请完成验证码并返回 AndroidUse。",
"scope": "com.example.app",
"timeout_secs": 600
}
}
```
AndroidUse 应用显示一个人工接管对话框。用户完成任务后,点击 `Done` / `完成接管`,MCP 收到 `completed`。
## 配套应用
配套应用的源代码位于:
```text
app/androiduse-app/
```
它提供:
- AndroidUse 设置入口。
- 口令显示/复制流程。
- MCP 主机/端口编辑器。
- 人机审查对话框。
- 人机接管对话框。
- AUZM 模块卡,带有元数据和路径。
- 亮/暗主题和语言切换。
- AndroidUse 外部 IME 服务。
构建:
```sh
bash tools/build_androiduse_app.sh
```
安装:
```sh
adb install -r target/androiduse-app/androiduse-app.apk
```
## 配套模块
### CaptureSposed
CaptureSposed 仅用于安全窗口截图支持:
```text
https://github.com/99keshav99/CaptureSposed
```
AndroidUse 不会将其捆绑。如果需要检查使用 `FLAG_SECURE` 的应用,请单独安装并启用它。CaptureSposed 不是 AUZM 目标,不应将其写入 `zygisk-target`,除非您正在专门测试 CaptureSposed 本身。
### liboemcrypto-disabler
对于基于 DRM 流媒体应用的 root 设备测试,用户可以可选地安装:
```text
https://github.com/Anonym0usWork1221/liboemcrypto-disabler
```
这不是 AndroidUse 的硬依赖项。仅当目标测试用例需要基于 root 设备的 DRM 兼容性时才安装它。
## 构建
构建 Android CLI:
```sh
PATH=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH \
cargo build --release --target aarch64-linux-android -p androiduse-cli
```
构建 Rust AUZM 加载器:
```sh
tools/build_zygisk_module.sh
```
构建 Rust payload:
```sh
tools/build_payload_module.sh
```
打包 root 模块:
```sh
kam build
```
构建 root 模块和 AUZM 模板:
```sh
kam build -a
```
预构建钩子将发布二进制文件复制到:
```text
src/AndroidUse/bin/androiduse-cli
```
和包:
```text
src/AndroidUse/zygisk/arm64-v8a.so
src/AndroidUse/.config/androiduse/auzm.d/androiduse-runtime/payload.so
```
跳过 AUZM 构建时:
```sh
ANDROIDUSE_BUILD_ZYGISK=0 ANDROIDUSE_BUILD_PAYLOAD=0 kam build
```
## 验证
本地检查:
```sh
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
```
设备检查:
```sh
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:1765 tcp:1765
```
然后使用口令调用 `tools/list` 并确认核心工具,例如 `mksh`、`ui_dump`、`text_input`、`register_app_group` 和 `set_auzm_target` 存在。
## 安全注意事项
- 本项目仅限研究和教育用途。严禁用于非法数据访问、系统干扰或违法活动。
- 将 MCP 侦听器保持在环回地址,除非您信任该网络。
- 不要打印或提交 MCP 口令。
- 不要编辑 KSU、Vector 或 LSPosed 数据库中的 AndroidUse 自动化。
- 优先使用 `ui_dump` 和 `tap_ui` 而非盲目坐标点击。
- 仅在 XML 不足时才使用截图。
- 动态钩子应限制在所有者控制的自动化、兼容性、观察性和 UI 工具。
## 致谢
AndroidUse 的通用移动操作表面灵感来自 AutoGLM 兼容的移动 GUI 代理工作流。我们感谢 AutoGLM 和 MobileRL 作者的辛勤工作。
AndroidUse 的 AUZM 加载器和热交换工作流还引用了 [HanSoBored/Zygisk-Loader](https://github.com/HanSoBored/Zygisk-Loader),一个用于动态加载原生 payload 库到 Android 进程的 Zygisk 模块项目,无需完整的设备重启。
```bibtex
@article{liu2024autoglm,
title={Autoglm: 通用 GUI 智能体},
author={刘晓, 秦博, 梁东柱, 董广, 赖汉瑜, 张涵辰, 赵翰林, 叶一龙, 孙嘉代, 王家琪, others},
journal={arXiv preprint arXiv:2411.00820},
year={2024}
}
@article{xu2025mobilerl,
title={MobileRL:移动 GUI 智能体的在线强化学习},
author={徐一帆, 刘晓, 刘兴汉, 傅家琪, 张涵辰, 景博浩, 张淑丹, 王宇婷, 赵文毅, 董宇晓},
journal={arXiv preprint arXiv:2509.18119},
year={2025}
}
```
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器