Android UIAutomator2 MCP
一个面向 Agent、脚本和未来测试编排器的 Android 自动化工具。项目以 UIAutomator2 和 ADB 为设备后端,同时提供独立 JSON CLI 与本地 stdio MCP;两者共享相同的核心服务、数据模型、安全策略和错误码。
架构
Agent / Codex --------> MCP adapter ----+
+--> OperationDispatcher --> AndroidService --> UIAutomator2 / ADB
脚本 / 用例编排器 ----> JSON CLI -------+
AndroidService是协议无关的 Python API,负责设备选择、串行化、重试、安全检查和具体操作。- 同一进程使用线程锁,多个 CLI/MCP 进程通过 artifacts 下的按设备文件锁串行访问 UIAutomator。
OperationDispatcher提供统一操作目录、Pydantic 校验和 JSON Schema,供 CLI、MCP 以及未来用例编排器复用。android-cli接受 JSON 参数并输出稳定 JSON/退出码,不依赖 MCP 客户端。android-mcp是薄适配层,只处理 stdio、异步线程调度、MCP annotations 和图片内容。
环境要求
- Python 3.11-3.14
- Android Platform Tools,
adb可从PATH找到或通过环境变量指定 - 已启用 USB 调试或无线调试的 Android 设备
Windows PowerShell 安装:
python -m venv .venv
.venv\Scripts\python -m pip install -e ".[dev]"
adb devices -l
.venv\Scripts\python -m uiautomator2 init
若当前 Python 发行版创建的虚拟环境不带 pip,可从外层 Python 安装:
python -m pip --python .venv install -e ".[dev]"
requirements.lock 是本项目在 Python 3.14/Windows 上的完整验证锁。跨平台发布应以 pyproject.toml 的版本范围解析依赖。
独立 CLI
CLI 形式为 android-cli <operation> --json '<JSON object>'。未提供参数时使用空对象;也可通过 --json-file <path> 或 --json-file - 从标准输入读取。
以下示例假定已执行 .venv\Scripts\Activate.ps1;未激活时使用 .venv\Scripts\android-cli.exe。
android-cli list_devices --pretty
android-cli get_device_info --json '{"serial":"EYEE4LDM79GMTKJ7"}' --pretty
android-cli wake_and_unlock --pretty
android-cli inspect_screen --json '{"max_nodes":100}'
android-cli click_element --json '{"selector":{"text":"Settings"}}' --pretty
android-cli tap --json-file .\tap.json
android-cli describe --describe-operation wait_for_element --pretty
成功输出到 stdout:
{"ok":true,"operation":"tap","data":{"serial":"SERIAL","x":500,"y":800}}
失败输出到 stderr,不包含 Python 堆栈:
{"ok":false,"error":{"code":"NO_DEVICE","message":"No ready Android device is connected","operation":"tap","retryable":true}}
稳定退出码:0 成功、2 参数错误、3 设备不可用、4 超时、5 权限/安全策略拒绝、6 执行失败。截图在 CLI JSON 中表示为带 mime_type 和 encoding=base64 的对象。
MCP 接入
安装后直接启动本地 stdio 服务:
android-mcp
Codex CLI 配置示例:
codex mcp add android --env ANDROID_MCP_ADB_PATH="D:\Android\Sdk\platform-tools\adb.exe" -- "D:\path\to\auto-debug-mcp\.venv\Scripts\android-mcp.exe"
codex mcp list
也可以在可信项目的 .codex/config.toml 中配置:
[mcp_servers.android]
command = 'D:\path\to\auto-debug-mcp\.venv\Scripts\android-mcp.exe'
cwd = 'D:\path\to\auto-debug-mcp'
startup_timeout_sec = 30
tool_timeout_sec = 120
default_tools_approval_mode = "writes"
[mcp_servers.android.env]
ANDROID_MCP_ADB_PATH = 'D:\Android\Sdk\platform-tools\adb.exe'
Codex 配置语法参考 OpenAI 官方 MCP 文档。其他 MCP 客户端使用相同的 stdio command/env 配置。
工具能力
- 设备:
list_devices、get_device_info、get_current_app、wake_device、wake_and_unlock - 观察:
inspect_screen、get_ui_hierarchy、take_screenshot - 交互:
tap、click_element、long_press、input_text、swipe、drag、scroll、press_key、set_orientation - 同步:
wait_for_element、wait_for_app - 应用:
list_packages、get_app_info、launch_app、stop_app、open_deep_link、get_logcat - 文件:
pull_file - 默认关闭:
install_apk、uninstall_app、clear_app_data、push_file、run_shell
inspect_screen 返回当前应用和精简 UI 节点,仅保留有文字、有内容描述或可交互的节点;保留节点有资源 ID 时会输出 resource_id。该工具不截图,需要图像时单独调用 take_screenshot。节点坐标使用 [left, top, right, bottom],与设备原生屏幕坐标一致。为减少高频调用的返回长度,clickable、checked、selected、focusable、scrollable 仅在值为 true 时输出,enabled 仅在值为 false 时输出;与 current_app.package 相同的节点省略 package_name,跨应用节点仍会输出包名。
wake_and_unlock 在同一次设备调用内点亮屏幕并向上滑动,只用于无 PIN、图案或密码的滑动锁屏。设备已经亮屏且不在系统锁屏界面时不会滑动,避免误滚动当前应用;该工具不会输入凭据或绕过 Android 安全策略。
选择器字段支持 text、text_contains、text_regex、resource_id、resource_id_regex、class_name、description、description_contains、description_regex、package_name、clickable、enabled、checked、selected、instance。多个字段按 AND 匹配,至少需要一个字段。
input_text 传入空字符串可清空指定元素或当前焦点元素;clear=true 用于在输入非空文本前先清空当前内容。
配置
| 环境变量 | 默认值 | 作用 |
|---|---|---|
ANDROID_MCP_ADB_PATH |
adb |
ADB 可执行文件 |
ANDROID_MCP_DEFAULT_SERIAL |
空 | 默认设备 serial |
ANDROID_MCP_ARTIFACTS_DIR |
./artifacts |
截图和 pull 文件目录 |
ANDROID_MCP_ALLOWED_HOST_ROOTS |
当前目录和 artifacts | install/push 可读取的根目录,用系统路径分隔符分隔 |
ANDROID_MCP_TIMEOUT_SECONDS |
15 |
默认操作和等待超时 |
ANDROID_MCP_LOGCAT_MAX_LINES |
2000 |
服务端日志行数硬上限 |
ANDROID_MCP_MAX_PULL_BYTES |
52428800 |
单次 pull 最大字节数 |
ANDROID_MCP_ENABLE_DANGEROUS |
false |
启用高影响结构化工具 |
ANDROID_MCP_SHELL_ALLOWLIST |
空 | 允许的 shell 命令前缀,; 分隔 |
危险配置示例:
$env:ANDROID_MCP_ENABLE_DANGEROUS = "true"
$env:ANDROID_MCP_SHELL_ALLOWLIST = "getprop;dumpsys activity;pm list packages"
android-mcp
run_shell 只接受 argv 数组,并拒绝管道、重定向、命令连接符、引号和命令替换。即使已启用危险操作,命令仍必须匹配允许前缀。install/push 会解析真实路径并拒绝允许根目录之外的文件。
开发与验证
.venv\Scripts\ruff check src tests
.venv\Scripts\pytest -q
$env:ANDROID_MCP_TEST_SERIAL = "your-device-serial"
.venv\Scripts\pytest tests\test_device_integration.py -q
android-cli list_devices --pretty
android-cli take_screenshot --json '{"save":true}' --pretty
只读真机诊断:
adb devices -l
.venv\Scripts\python -m uiautomator2 doctor
android-cli inspect_screen --json '{"max_nodes":50}'
android-cli get_logcat --json '{"max_lines":50,"level":"W"}'
常见问题:
ADB_NOT_FOUND:设置ANDROID_MCP_ADB_PATH为 platform-tools 中的完整路径。DEVICE_AMBIGUOUS:在参数中传serial,或设置ANDROID_MCP_DEFAULT_SERIAL。DEVICE_NOT_READY:检查设备授权弹窗以及adb devices -l中的状态。UIAUTOMATOR_CONNECT_FAILED:执行python -m uiautomator2 doctor,必要时重新执行python -m uiautomator2 init。- MCP 启动超时:使用虚拟环境内
android-mcp的绝对路径,并将startup_timeout_sec调高到 30。
安全边界
本项目不会绕过锁屏密码、Android 授权弹窗或系统安全策略。pull_file 只能写入 artifacts 目录且受大小限制;高影响工具默认关闭。Agent 仍可能通过普通 UI 操作触发应用内副作用,接入端应使用 MCP tool approval 策略控制写操作。
Metadata
Release files for android-uiautomator2-mcp 0.1.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 | Provenance | Actions |
|---|---|---|---|---|
| android_uiautomator2_mcp-0.1.0.tar.gz | 33.2 kB | Without provenance | Details for android_uiautomator2_mcp-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| android_uiautomator2_mcp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for android_uiautomator2_mcp-0.1.0-py3-none-any.whl |
Total release size: 60.6 kB
Release files / android_uiautomator2_mcp-0.1.0.tar.gz
| Download URL | android_uiautomator2_mcp-0.1.0.tar.gz |
|---|---|
| Size | 33.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8b01fb9e2ef999cf217e8ac5fb7aa49fc9529fad09fc7746f625f011a834ae35
|
|
BLAKE2b-256 checksum How to use checksums |
f2c093e590287ebffa52eb82e9f6aea6b4109a135bf6c1d8bf3bbdfea3bae99b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / android_uiautomator2_mcp-0.1.0-py3-none-any.whl
| Download URL | android_uiautomator2_mcp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 27.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bc34aba63ef34d92fefc04e3916a70e67cf287bca8ac48c97e823df70c280462
|
|
BLAKE2b-256 checksum How to use checksums |
63632115f4deeaa2922a68a119f54a6673696dd338740b5a49fdfb03125f0cf5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for android-uiautomator2-mcp 0.1.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.