mcpField
N
NexusAndroid

NexusAndroid

本地服务
julienpiron.fr开发工具2今天更新

关于 NexusAndroid

NexusAndroid 是通过 ADB 控制真实 Android 手机的 MCP 服务,供 AI Agent 查看屏幕并执行操作。它无需 root、手机端应用或云中继,可通过 USB 或本地 Wi-Fi 连接。

主要功能

  1. 01读取屏幕内容和 UI 树
  2. 02执行手势、输入文字和表情符号
  3. 03读取短信、RCS 和通知
  4. 04访问手机文件与设置
  5. 05通过 USB 或本地 Wi-Fi 使用 ADB

适用场景

  1. 01查看手机屏幕并操作应用
  2. 02读取短信并拟写回复,发送前需确认
  3. 03调整勿扰模式和屏幕亮度
  4. 04将手机照片复制到电脑

MCP 相关

该 MCP 服务通过 ADB 将 AI 客户端连接到 Android 手机,并提供屏幕读取、手势操作、消息、通知、文件和设置相关能力。连接使用 USB 或本地 Wi-Fi,无需在手机安装应用。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"pironjulien-nexus-android": {
"command": "uvx",
"args": [
"nexus-android"
],
"env": {
"NEXUS_ANDROID_ADB": "<NEXUS_ANDROID_ADB>",
"NEXUS_ANDROID_SERIAL": "<NEXUS_ANDROID_SERIAL>",
"NEXUS_ANDROID_KEEP_AWAKE": "<NEXUS_ANDROID_KEEP_AWAKE>",
"NEXUS_ANDROID_AWAKE_IDLE": "<NEXUS_ANDROID_AWAKE_IDLE>",
"NEXUS_ANDROID_ADB_DOWNLOAD": "<NEXUS_ANDROID_ADB_DOWNLOAD>",
"NEXUS_ANDROID_UPDATE": "<NEXUS_ANDROID_UPDATE>",
"NEXUS_ANDROID_MANAGED": "<NEXUS_ANDROID_MANAGED>"
}
}
}
}
启动命令uvx nexus-android
需要配置的环境变量
NEXUS_ANDROID_ADBFull path to adb when it is not on the PATH
NEXUS_ANDROID_SERIALForce a device by serial number or ip:port
NEXUS_ANDROID_KEEP_AWAKE0 turns off the keep-screen-on session while the agent works
NEXUS_ANDROID_AWAKE_IDLESeconds without any gesture before the original screen timeout is restored and the screen turned off
NEXUS_ANDROID_ADB_DOWNLOAD0 never downloads Google's Platform Tools when adb is missing or the server's own copy is outdated
NEXUS_ANDROID_UPDATE0 turns off the daily update check (PyPI, Platform Tools manifest)
NEXUS_ANDROID_MANAGEDSet by a plugin that pins the server version (who updates it); the server then prepares no update

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypinexus-android0.20.3

工具

14

收录的工具列表 · 更新于 今天

参数类型必填说明
showenum否both | image | elements | none
marksenum否auto | all | none
queryany否
regionany否
confirmboolean否

详细介绍

NexusAndroid 徽章

NexusAndroid

Release PyPI Tests OpenSSF Scorecard License: MIT Python 3.12+ MCP

在 VS Code 中安装 在 Cursor 中安装 Claude Desktop 扩展

NexusAndroid:通过纯 ADB 为 AI Agent 提供 Android 设备控制能力。适用于 Claude、Codex 和 Antigravity。

NexusAndroid:AI Agent 通过 ADB 在真实 Android 手机上启动计算器,输入 1618 × 20 并读回 32 360

通过纯 ADB 为 AI Agent 提供 Android 设备控制能力。 一个 MCP 服务 nexus-android,让 Claude Code、Codex 和 Antigravity 能查看并操控真实 Android 手机:屏幕和 UI 树、手势、输入带重音符号和表情符号的文字、 读取 SMS/RCS、准备回复、通知、文件、设置。无需 root,无需在手机上安装应用,无需云端中转:只需 USB 线缆或本地 Wi-Fi。

在 Windows PC 上使用 Samsung Galaxy Fold(SM-F971B,One UI)构建并测试。其他开启 USB 调试的 Android 手机应该也能使用,但尚未测试(参见兼容性)。发送给客户端的所有内容均为英文:服务指令、 工具说明和工具报告(结果、拒绝、错误)。 属于 Nexus 系列:NexusWindows (Claude · Codex · Antigravity), NexusBrowser(仓库), NexusAndroid(仓库)。 项目页面:julienpiron.fr/nexusandroid。

快速入门

Windows 上大约需要 10 分钟,无需任何事先准备。服务会在 PC 上查找 adb,或者自行下载 Google 官方的 Platform Tools。

  1. 安装 uv(它负责运行服务并获取 Python):打开 PowerShell 并运行

    winget install --id astral-sh.uv -e
    

    (Windows 自带的包管理器;其他安装方式请参阅 uv 安装指南)。关闭 PowerShell,然后重新打开。

  2. 运行设置程序,每台电脑只需运行一次:

    uvx nexus-android setup
    

    它会下载缺少的内容,向检测到的 AI 应用注册服务(Claude Code、Claude Desktop、Codex、 Antigravity;会保留你自己的条目,并在编辑每个文件前先备份),然后引导你连接手机并等待手机响应:

    • 在手机上打开“设置”>“关于手机”(Samsung:>“软件信息”)> 连点版本号 7 次;
    • 打开“设置”> 开发者选项 > 开启 USB 调试 (Android 指南);
    • 使用 USB 数据线连接手机,并接受 允许 USB 调试?(勾选始终允许)。

    手机已连接且所有 AI 应用均已配置时,程序会以 Ready. 结束;否则会说明哪一项未就绪。 手机已插入但始终无法检测到:请安装制造商的 USB 驱动程序 (Samsung)。

  3. **重启 AI 应用。**也可以手动注册:

    • VS Code 或 Cursor:使用本页面顶部的 Install 按钮;
    • Claude Desktop:下载 nexus-android.mcpb 并打开(Settings > Extensions);
    • Claude Code:claude mcp add nexus-android --scope user -- uvx nexus-android (或注册整个 Nexus 插件包:先运行 /plugin marketplace add pironjulien/nexus-plugins,再运行 /plugin install nexus-android@nexus-plugins);
    • Codex:codex mcp add nexus-android -- uvx nexus-android;
    • Antigravity:在 Agent 面板中选择 ⋯ > MCP Servers > Manage MCP Servers > View raw config,在 "mcpServers" 中添加下方的 nexus-android 条目,然后保存。

然后询问你的 AI:“看看我的手机,告诉我屏幕上显示了什么。”

手动配置(Codex ~/.codex/config.toml,JSON 客户端:Antigravity、Claude Desktop、Cursor)
[mcp_servers.nexus-android]
command = "uvx"
args = ["nexus-android"]
{
  "mcpServers": {
    "nexus-android": {
      "command": "uvx",
      "args": ["nexus-android"]
    }
  }
}

setup 选项:--no-wait(注册服务并获取 adb,不等待手机)、--no-register(不修改 AI 应用配置)、--apps claude-code,codex(仅配置这些 AI 应用:claude-code、claude-desktop、codex、antigravity; 插件包会将其 -Only/-Skip 选项作为 NEXUS_PACK_TARGETS 传入,名称相同;若设置为空,则不配置任何 AI 应用)。退出代码:0 表示全部就绪,1 表示 adb 或手机未就绪,2 表示某个 AI 应用未配置,3 表示两者都未就绪。Nexus 插件包会使用 NEXUS_PACK=1 运行该程序:不提问、不等待,成功时退出代码为 0,并以 NEXUS_PACK_RESULT Claude Desktop=declared; Codex=declared; Antigravity=plugin 作为最后一行输出。在 Antigravity 中,该服务以插件形式提供(~/.gemini/config/plugins/nexus-android:服务和 Agent 指南),不会作为全局条目注册。 更新。 AI 应用运行不带版本号的 uvx nexus-android:离线时,uv 会保留缓存中的版本。启动时,服务会在后台每天最多向 PyPI 查询一次最新版本;如果有更新,且服务由 uvx 启动,就会在 uv 的缓存中准备新版本(uvx nexus-android@latest),供下次启动 AI 应用时使用。服务自带的 Platform Tools 也会以同样方式更新(绝不会改动你安装的 adb)。如果通过 setup 安装的版本是 0.11 到 0.12.1,声明中仍会指定版本:运行一次 uvx nexus-android setup 即可切换。状态会写入 ~/.nexus/status/android.json(product、version、latest、state、checked_at、message),供 Nexus 应用使用。Claude Desktop 扩展和 install.ps1 会保持原有版本,直到再次安装;固定版本并设置 NEXUS_ANDROID_MANAGED 的插件也一样(其状态会说明由谁负责更新)。设置 NEXUS_ANDROID_UPDATE=0 可关闭检查。

在 PC 上查看手机画面。 uvx nexus-android mirror 会打开 scrcpy(安装一次即可:winget install Genymobile.scrcpy),并使用与服务相同的 adb,避免另一个版本的 adb 中断 Agent 的连接。选项会传递给 scrcpy(例如 mirror --turn-screen-off、连接多部手机时使用 mirror -s SERIAL);NEXUS_ANDROID_SCRCPY 用于指定其完整路径。手机上不会安装任何应用:scrcpy 只会将其小型服务端复制到 /data/local/tmp,与手势操作的方式相同。

查找 adb 的顺序如下:NEXUS_ANDROID_ADB(完整路径)、PATH、winget 的 Platform Tools、Android SDK(ANDROID_HOME、Android Studio 的默认文件夹),然后是 ~/.nexus/nexus-android/tools/platform-tools。如果找不到,服务会从 Google 的 SDK 仓库(dl.google.com,即 sdkmanager 读取的清单)下载适用于此系统的当前稳定版 Platform Tools,检查归档的大小和 Google 发布的 SHA-1 值,然后解压到该目录;使用即表示你接受 Android SDK 条款。设置 NEXUS_ANDROID_ADB_DOWNLOAD=0 可关闭此功能。输入带重音符号的文字和 emoji 需要 scrcpy 服务端(Genymobile,Apache 2.0,固定为版本 5.0.1):Agent 首次输入此类文字时,服务会从 GitHub 上的 scrcpy 官方版本发布页下载该服务端,将其 SHA-256 与代码中记录的值进行校验,并将其保存在 ~/.nexus/nexus-android/tools 中(install.ps1 会提前下载)。如果无法下载(离线或使用代理),系统会拒绝输入带重音符号的文字,并说明应将文件放在哪里;绝不会用其他文字替代。输入 ASCII 字符则不需要该文件。

提示词示例
  • “打开 Google Maps,开始导航到最近的药店。”
  • “读取 Alice 发给我的最近一条 SMS,并起草一条回复,说我会晚 10 分钟到。”(只起草;未经你回复“是”绝不会发送)
  • “开启勿扰模式并调低亮度。”
  • “把手机里最近的三张照片传到我的 PC 上。”
  • “运行一次检查:电池、存储空间、安全补丁,以及从应用商店之外安装的应用。”

工作原理

flowchart LR
    A["Claude Code"] --> S
    B["Codex"] --> S
    C["Antigravity"] --> S
    S["nexus-android<br/>MCP server (Python)"] -->|"ADB over USB or local Wi-Fi"| P["Android phone<br/>(no app, no root)"]
    S -.->|"shared lock, screen-awake state"| L[("~/.nexus")]

look 会返回带编号的 UI 树,优先显示文本(只有在没有可读内容或用户提出要求时才显示截图);act 会批量执行手势,每次执行前重新读取屏幕,并报告实际发生的情况。消息、通知、联系人和设置均通过 Android 自带的 provider 和 dumpsys 读取,绝不通过抓取屏幕内容获取。

为什么使用共享服务

每个 Agent 都有自己的桌面电脑操作能力,但这三个客户端都没有内置的手机工具。使用一个服务可以避免重复维护三套相同的 ADB 访问方式,并让这三个 Agent 共用一把锁、一个保持屏幕唤醒的会话以及相同的安全保护措施。

工具

工具作用
phone已连接的手机(USB 或 Wi-Fi)、型号、屏幕、前台应用、折叠状态、重启检测(结构化输出)
look带编号的 [N] 元素,包含文本、状态和中心坐标 @x,y,优先显示文本:没有可读内容时会附上屏幕图像(act 和 launch 在步骤失败(✗)、失去连接(?)或未能读取回操作结果(~),且屏幕没有变化时也会附上;否则使用 look(show="both"));也可按需显示(show=both 或 image、region);marks 会在图像上标出 [N] 编号(auto:元素较少时标出全部,否则标出未命名元素;all;none)
act批量手势:点击、长按、输入(包括重音符号和表情符号)、清除、按键、滚动、滑动、等待、链接(geo:、google.navigation:、tel: 打开拨号器但不拨号、mailto:、https://);then="changes" 仅返回自上次列表以来新增、更改和移除的元素(未更改的元素也计入,[N] 保持有效);如果应用或屏幕大部分发生变化,则返回完整列表
launch按包名或部分应用名称打开应用,或打开精确指定的屏幕:action(android.settings.WIFI_SETTINGS)、data(深层链接)、extras;先解析并报告目标;直接拨打电话、发送内容或付款需要 confirm=true,并且必须获得针对该确切操作的同意;绝不会以这种方式打开银行和身份验证应用
clipboard读取手机剪贴板(代码会被屏蔽,单独的代码、密码或令牌绝不显示),或将文本写入剪贴板,但不会粘贴
messagesSMS 和 RCS 对话,可按联系人姓名或号码读取,并读取附带的照片;安全码会被屏蔽;回复最多约 60,000 个字符,并在消息之间截断;使用 before 游标读取更早的消息
draft打开 SMS/RCS 或 WhatsApp,并预先写好回复;收件人可按姓名或号码指定(WhatsApp:使用 SIM 卡的国家代码);只有用户明确说“发送”后才会发送
notifications屏幕上的通知:应用、时间、标题、文本;安全码会被屏蔽;all 会添加持续显示的通知
files仅限共享存储(/sdcard):按最新优先列出,将文件 pull 到 PC(~\Downloads\Telephone),将文件 push 到手机;绝不覆盖或删除。在 PC 上:Downloads、Documents、Desktop、Pictures 和 Videos 可自由访问;其他位置需要 confirm=true;密钥和机密(.ssh、.env 等)以及 Windows Startup 文件夹始终不可访问
capture将屏幕保存为 PC 上的文件,使用与 files pull 相同的文件夹和规则(~\Downloads\Telephone,绝不覆盖):screenshot 以全分辨率保存(PNG,或按名称指定 JPEG),安全码和密码字段会涂黑(无法屏蔽时,除非设置 unmasked=true,否则拒绝);record(固定时长)或 start/stop(期间可继续操作)录制 MP4 视频,分辨率为 720p、码率为 4 Mbit/s、最长 180 s,传到 PC 后从手机删除。视频中的代码不会被屏蔽,因此不会在银行或身份验证应用中开始录制;录制期间,大约每秒检查一次前台应用;如果此类应用打开,或检查中断超过 5 秒,视频会从手机中擦除,绝不保存;受保护而无法截取的屏幕会显示为黑屏;先唤醒休眠屏幕,再解除 Android 保持解锁状态的锁屏(受信任地点);如果手机确实处于锁定状态,则拒绝操作(由用户解锁)
logs查看 Android 日志,以了解崩溃或异常应用行为:crash(每次崩溃一个区块:时间、包名、异常及 Caused by、应用首批堆栈帧;原生崩溃包含信号和回溯)、anr(应用无响应,来自 Android 的 drop box 和事件日志,并附原因)、recent(最后几行;使用 app 时显示一个应用的进程,无论是否正在运行,以及提及该应用的日志行);since(15m、13:05……)、query 过滤器;按时间从旧到新排列,约 30,000 个字符。代码、令牌、电子邮件地址和电话号码会被屏蔽;对于银行和身份验证应用,不提供 recent,崩溃日志仅保留异常类型和应用堆栈帧
info只读:最近已知的位置(精度、时间、Maps 链接)、最近通话、联系人的号码、即将发生的事件(结构化输出)
settings读取或更改设置,然后读回:Wi-Fi、Bluetooth、移动数据、位置、NFC、勿扰模式、亮度、媒体音量;如果 Wi-Fi 是当前连接方式,则拒绝关闭 Wi-Fi(结构化输出)
functions应用向助手公开的结构化操作(Android AppFunctions:Samsung Clock、Reminder、Notes、Calendar、Contacts、Gallery、Files、Phone……),可在不操作屏幕的情况下列出和运行;读取免费;删除和通话处理需要 confirm=true,拨打电话还需获得同意
web通过 Chrome DevTools(或可调试的 WebView)读取手机上的网页:全文、标题、地址、链接,无需操作屏幕;query 过滤行;tabs 列出页面;只读,代码、令牌、电子邮件和号码会被屏蔽;绝不读取银行应用,也绝不读取银行、支付、税务和身份验证网站(会再次检查实际读取的地址)
apps管理应用:info、stop(强制停止)、clear(清除数据)、uninstall(系统应用仅会被隐藏,restore 可将其恢复)、install(从 PC 安装 .apk);clear、uninstall 和 install 需要 confirm=true;绝不操作系统自身组件,也绝不清除或卸载银行和身份验证应用
map手机全局地图,可在不操作屏幕的情况下读取。find:根据用户描述查找某项设置的位置 → Settings 中的路径(“Settings > Notifications > …”)、当前值,以及如何直接打开并高亮显示该项的屏幕。根据手机自带的 Settings 应用(每个屏幕和选项均使用手机语言)构建,并在更新后自动重建;对于 Settings 应用未描述的应用屏幕(Galaxy Buds……),可在 Agent 正在显示的屏幕上使用 note 添加。snapshot / diff:设置值、应用及版本、敏感权限、默认应用、设备管理员和 Bluetooth 设备,并与上次快照比较;标识符、令牌和号码会被屏蔽
checkup健康报告:系统、安全补丁、电池、存储、内存、从应用商店之外安装的应用、无线调试;clean 清除缓存
look 和 act 还会读取 UI 树未提供的屏幕文字(游戏、Flutter 应用、视频或地图界面),使用 PC 上 Windows 内置的 OCR 引擎识别图像:列出带有 @x,y 的文字行,可通过文字定位,应用相同的安全保护措施,文字中的验证码会被遮蔽,图像中的验证码会被涂黑。例程:act(remember="name") 会保存已执行的一批操作,并使用稳定的目标(id:、文字、desc:;绝不使用 [N] 或坐标;仅由 {{x}} 构成的输入文字会成为参数);act(routine="name", params={...}) 会为三个 Agent 中的任意一个重放该例程,但仅限录制该例程的应用,且会再次应用所有安全保护措施(不会保存 confirm 和 accords);look 会列出前台应用的例程。

Google Messages 会像存储 MMS 一样,将 RCS 消息存储在 Android 的消息提供程序中,因此服务无需通过屏幕即可读取消息。RCS 群组在其中只有一个编码后的地址:服务会找出群组成员,并标明每条收到的消息的发送者。在 Google Messages 中归档或移入垃圾箱的对话仍可读取,并会在应用中标记为隐藏。

读取速度很快:每次 adb shell content query 都会在手机上启动一个 Java 进程(约 1 秒),因此首次读取时,服务会将一个 20 KB 的辅助程序(phone/NexusQuery.java,构建为 nexus-query.dex)推送到 /data/local/tmp,并像 scrcpy 一样以 shell 身份通过 app_process 启动一次:无需安装应用,也不需要 ADB 以外的权限。它会像 Android 自带的 content 命令一样,以只读方式(仅执行 query)查询提供程序,并自行序列化各行,使用长度前缀标记值,因此消息文本绝不会被误认为额外的一行。每次启动都会生成一个随机令牌,该令牌会写入套接字名称,并随每条回复返回;任何其他服务都会被拒绝。它只接受来自 shell 或 root 用户的连接(由内核检查的 adbd),并会在 10 分钟没有请求后停止。如果辅助程序无法运行,读取会回退到 adb shell,结果相同;在这种情况下,如果读取结果的行号或行数(与同一次读取中缩减为 _id 的结果进行核对)不匹配,则会拒绝显示该结果。

同一个辅助程序还会读取屏幕:它会打开一个无障碍连接(UiAutomation,即 uiautomator dump 每次调用都会打开并关闭的连接)并保持该连接,因此 look 可以在一次交互中获取 UI 树、屏幕截图(在手机上生成的 JPEG)和屏幕状态。它只读(不执行手势、全局操作或输入文字),也不会停止用户自己的无障碍服务。Android 一次只允许一个此类连接:所有 Agent 共用该辅助程序;在任何 uiautomator dump 回退前,它会先释放连接;屏幕读取闲置 45 s 后,它会自行释放连接;读取受保护的应用(银行或身份验证类应用)后,它也会立即释放连接,以便其他工具(Appium、uiautomator2)使用。元素列表、编号、验证码遮蔽和拒绝规则都与 uiautomator dump 相同。

性能

在 Samsung Galaxy Fold 上测量:通过共享守护进程经 USB 读取消息,其他行则通过 Wi-Fi 读取:

读取内容耗时
对话列表(messages())0.07 s(0.5.0 之前为 35 s)
单个对话0.03 到 0.05 s
phone(Wi-Fi,链接已知)0.19 s,一次 adb 往返
位置(Wi-Fi)0.11 到 0.15 s
look(列表和图像,Wi-Fi)0.17 到 0.19 s(之前为 2.9 s);45 s 未执行 look 后的首次调用:约 1.2 s

安全保护措施

对外操作的威胁模型(发送、拨打、付款、发布、转账):Agent 绝不能执行与用户批准的操作不一致的对外操作。已批准的操作有唯一的规范身份:前台应用、UI 树元素按文档顺序呈现的内容(元素文本;若文本被遮蔽,则为原始文本的带密钥封印;不包含元素的精确位置,因此偏移 4 像素或键盘弹出不会使其失效),以及手势的完整目标(接收点击的元素,包括其资源 ID、边界框和绘制顺序、点击位置、滑动的起点和终点、滚动方向,以及按键操作时获得焦点的字段)。此约定在每次物理注入的边界处生效:每次点击(包括双击的每一次点击;快速读取时不等待屏幕稳定,或不执行第二次点击)、每次滚动滑动(根据手指落点及其在该处触发的操作进行判定)、每次提交按键(单独作为一个步骤),都必须紧接在各自对屏幕进行的全新读取后发送,依据该次读取进行判定,并与已批准的身份进行比对;任何不一致都会导致拒绝执行。令牌仅与该身份绑定;可读摘要(收件人、内容、附件)会一并显示。滑动或拖动的起点和终点根据同一次读取进行判定。type 只会在获得焦点的可编辑字段中输入内容,并会将任何控制字符(换行、制表符)作为文本粘贴,绝不会将其作为按键输入。UI 树未描述的内容(仅通过 OCR 找到的目标、覆盖目标或收件人的绘制表面、标题栏中没有树文本的绘制表面)绝不会被绑定到授权操作:此类对外操作会被拒绝,由用户自行执行;如果发送按钮旁有视频或照片预览,且树中描述了收件人,则不会因此阻止操作。明确说明其局限:从最后一次读取到 ADB 注入之间的几毫秒内屏幕发生的变化,超出了 ADB 工具的感知范围。

  • 付款、汇款、拨打电话、发布、永久删除、格式化、卸载、重置、取消订阅、将仓库设为公开:没有 confirm=true,这类按钮会对每个指向它的操作一律拒绝(包括轻触、输入、清除、滑动和 x,y 坐标)。Agent 仅会在用户明确要求执行该操作,或用户说“是”后为其设置此项。标签来自与桌面工具共用的一个策略文件(garde-fous.json),匹配时不区分重音符号或大小写,也会匹配文件中列出的所有形式(“Envoyez”“Payez”“Paiement”“Commandez”“Checkout”“Appeler”…)。其他操作不受限制:移至垃圾桶、接受、分享。在提及付款或格式化的屏幕上,通用的“OK”或“Validate”也需要此项。在消息、邮件、社交或电话应用中,没有名称的可点击图标(通常是发送或拨打电话按钮)也需要此项。Enter、通话键以及安全列表之外的任何按键也需要此项。
  • 同意必须绑定到确切操作(发送、拨打电话、付款、发布、转账):仅有 confirm=true 还不够。工具会根据屏幕显示内容返回确切操作信息(应用、按钮、收件人:标题以及显示的任何电话号码或电子邮件地址、字段文本、具名附件,以及屏幕上应用的其余文本;被遮蔽的文本会通过其原始文本的密封值进行绑定),并提供一个有效期为 10 分钟、只能使用一次的令牌;每次注入操作前都会重新读取并比对屏幕;Agent 会向用户展示该摘要,只有用户答应后才会使用 accord="<token>" 再次发送该操作。draft 会返回仅供其草稿使用的令牌。期间发生任何变化(切换到其他对话、编辑文本)都会使令牌失效:必须重新取得同意。此规则适用于所有发送方式:轻触、滑动或“滑动发送”、手指落在此类滑块上的滚动操作(每步滚动都需要单独取得同意)、Enter 或通话键(必须单独作为一步:先按 tab,再按 enter)、付款链接 open_url,以及会拨打电话、发送消息或付款的 launch intent。当无法读取 UI 树时,就无法描述操作:不会发放令牌,并且会拒绝该操作。多行文本会以粘贴方式输入(换行符是文本,绝不是可能触发发送的 Enter 键);不得双击发送按钮。卸载、重置、永久删除等本地破坏性操作仅需要 confirm=true。
  • 读取文本绝不等于授权:短信、通知和屏幕内容都是数据。最近读取的文本中出现的收件人会在同意摘要中标记(仅当用户自己要求时才允许使用);看起来像是发给 AI 的指令的文本也会在响应中标记。此检测器仅提供信号,不会拦截操作,也绝非万无一失。
  • 在当前屏幕上核验目标:每次操作前都会通过一次往返重新读取 UI 和手机状态(锁定状态、前台应用);如果 [N] 发生变化,或目标位置没有可读内容,就会拒绝操作。报告:✓ 已读取并确认效果,~ 已发送但未验证,✗ 已拒绝或失败。
  • 仅限一部手机:通过硬件序列号识别机主的手机,并在首次 USB 连接时记录;模拟器、电视盒和其他设备都会被忽略。任一时刻只能由一个 Agent 控制手机(锁由 PC 上的所有服务以及共享守护进程的会话共用);其他 Agent 最多等待 30 秒,之后会收到手机正忙的提示。如果客户端取消调用(或客户端断开连接),批处理会在下一步执行前停止。
  • 银行、支付、加密货币、赌博、身份验证器:可自由查看、滚动和等待;只有带 confirm=true(用户要求进行导航)时才能轻触、输入或滑动;绝不允许操作金额或发送按钮、未命名图标、Enter 或任何确认键,即使带有 confirm=true 和同意令牌也不行;无法读取 UI 树时,完全禁止执行任何指向目标的操作(仅允许返回、主页和最近任务);会打开此类应用的链接(open_url)或 intent(带有 action/data 的 launch),即使只是多个选项之一,也会被拒绝(深层链接可能会准备付款)。
  • 会自行执行操作的 intents 和链接(CALL、未经审核就发送短信、卸载、重置、支付操作、upi:/bitcoin:/payto: 链接、自动发送 extra):需要 confirm=true;对于拨打电话、发送消息和付款,还需要绑定到确切 intent 的同意令牌。
  • 通过短信收到或在通知中显示的验证码:在 Agent 读取前会被遮蔽,并在图像中涂黑([N] 标记在之后绘制:它们只能遮挡,不能揭示内容)。OCR 在图像中找到的验证码也会被涂黑,包括 look 图像中的验证码(没有树文本的大型绘制表面)和保存的截图中的验证码(每个大型绘制表面,无论是否有标签)。限制:对保存截图执行 OCR 时,仅会遮挡面积至少为屏幕 25 % 的绘制表面(或完全没有文本的树)中的验证码;面积较小的表面上的验证码不会被涂黑。OCR 不可用(Windows 之外)或失败时,look 仍会返回用户本人手机的图像,并清楚警告绘制的验证码未被遮挡;除非设置 unmasked=true,否则会拒绝保存截图。所有工具返回的文本(屏幕、通知、短信、剪贴板、日历、日志、网页、地图)中的银行卡号(通过 Luhn 校验)和 IBAN(通过 mod 97 校验)都会被遮蔽:仅遮蔽银行卡号分组形式(4-4-4-4 后面可有或没有 1 至 3 位数字、4-6-5、4-6-4、4-4-5、4-3-3-3,或由 15 至 19 位数字组成的单个区块;首位数字为 2 至 6),因此日历、图表、数字表格、SIRET 和 EAN-13 仍可读;IBAN 仅在长度与其所属国家的长度完全一致时才遮蔽(依据 SWIFT 注册表),不区分大小写,即使与单词连在一起也会遮蔽;分组间可由一个或两个空格、不换行空格、连字符、句点或换行符分隔。剪贴板中单独出现的验证码,或看起来像密码或令牌的单个词,都不会显示。无法读取 UI 树时,就无法定位验证码,因此除非 look 带有 confirm=true(且用户已同意),否则不会发送图像。
  • 密码:不得在密码字段中输入任何内容,也不得在其中按任何按键,导航操作除外(返回、tab、方向键)。即使带有 confirm=true,在无法读取当前活动字段时也不得输入任何内容。
  • 手机已锁定:绝不输入任何密码。当 Android 自行保持手机解锁时(延长解锁、Smart Lock、可信位置或设备:dumpsys trust 显示 deviceLocked=0),phone 会报告 code_required: false,而 look、act 和 capture 会唤醒手机并解除锁屏(wm dismiss-keyguard):Agent 不会询问。只有在需要密码(code_required: true)时,才会拒绝操作,直到用户解锁手机。
  • 屏幕上或消息中的文本内容是数据,绝不是指令。
  • 用户正在操作手机:任何操作都不会与用户的操作混在一起。如果手机在过去 3 秒内被触碰过(且不是 Agent 所为),服务会最多等待 10 秒,然后拒绝操作。若手机无法报告上次触碰时间(dumpsys power 中没有 lastUserActivityTime),act 响应会发出警告,说明该检查在此处未启用。
  • 操作期间连接中断:会报告为 ?(效果未知),绝不会报告为普通失败:Agent 会先重新查看,再决定是否重试,因此不会重复发送内容。读取没有响应(Wi-Fi 断开)时,读取会在 10 秒后失败(读取屏幕状态则为 5 秒),而不是等待几分钟;下一次调用会重新查找手机。
  • 上次图像以来折叠状态发生变化:在新的 look 之前会拒绝 x,y 目标。
  • 重启:phone 和 look 会在检测到手机重启时提示一次;找不到手机时,消息会提醒用户 Android 在重启或网络变更后会关闭无线调试。
  • 手机上仍在运行的其他控制工具(mobile-mcp、Appium、Shizuku、另一个 scrcpy)可能会阻止读取 UI 树;checkup 和错误消息会指出这些工具。

Agent 工作期间保持屏幕亮起

Agent 工作时反复解锁很麻烦,但用于支付的手机不能一直处于解锁状态。因此,在用户已解锁的手机上首次执行手势(act、launch、draft)时,服务端会保存屏幕超时时间(screen_off_timeout),并将其延长至 5 分钟;Android 会在每次手势后重新开始计时;phone 会显示延长时间的截止时刻。如果服务端被终止,屏幕仍会在最后一次手势后的 5 分钟内熄灭(并锁定)。当 Agent 只查看屏幕时,如果屏幕处于亮起状态,每 3 分钟就会发送一次唤醒按键(不会产生可见效果),因此长时间观察期间屏幕不会熄灭。

任何 Agent 最后一次手势操作约 2 分钟后,系统会恢复原来的超时时间并关闭屏幕,使手机重新锁定。如果此时用户正拿着手机,或者自行更改了超时时间,系统就不会干预。原始值只会保存一次(~\.nexus\nexus-android\awake.json),并由所有服务端通过共享锁共用:只保存一次,只恢复一次,绝不会把延长后的值当作原始值。崩溃后,下一个启动的服务端会恢复原始值。服务端绝不会解锁 Android 保持锁定状态的手机。NEXUS_ANDROID_AWAKE_IDLE(秒,默认值为 120)可更改延迟时间;设置 NEXUS_ANDROID_KEEP_AWAKE=0 可关闭此功能。

兼容性

手机只需启用 USB 调试即可运行此服务端;任何支持 ADB 的 Android 设备都应该可用,但此处仅运行过下表所列的已测试设备。请在 issue 中报告你的设备,帮助我们提升其状态。

设备或系统状态
Samsung Galaxy Fold SM-F971B、One UI、Android 17、USB 和无线调试已测试(真实手机场景,tests/scenarios.py)
Windows 11 PC已测试
Linux PC 上的 Android 14 模拟器(Google APIs,x86_64)已测试;CI 会在每次推送时运行测试(tests/test_emulator.py:真实服务端和真实 adb)
其他 Samsung 手机(One UI)预计可用:系统和应用与已测试手机相同
Pixel、Motorola、Nothing、OnePlus、Sony、Fairphone 及其他接近原生 Android 的设备预计可用,尚未测试
Xiaomi、Redmi、POCO(MIUI、HyperOS)启用开发者选项中的“USB 调试(安全设置)”后预计可用(启用前会拒绝手势,并给出相应错误提示)
Android 10 及更早版本预计仅支持 USB(无线调试从 Android 11 开始提供);应用功能需要 Android 16
平板电脑和其他折叠屏设备预计可用;折叠和展开状态会像 Fold 一样进行跟踪
由雇主管理的手机(受策略限制,无法启用 USB 调试)无法使用
iPhone、iPad不支持(无 ADB)
Android 模拟器除非通过 NEXUS_ANDROID_SERIAL 指定(用于测试),否则会忽略
Linux PC服务端仅针对模拟器进行过测试(尚未测试真实手机);无安装程序,请使用 uvx nexus-android 运行;OCR 仅支持 Windows
macOS PC尚未测试;无安装程序;OCR 仅支持 Windows

已知限制

  • 手势会直接作用于真实屏幕,这是有意为之:用户可以看到 Agent 正在操作。不使用不可见的虚拟显示屏。
  • 带重音符号的文本和表情符号通过剪贴板输入(Android 的 input text 只接受 ASCII):scrcpy 服务端(Genymobile,Apache 2.0,版本和 SHA-256 均已固定,由 install.ps1 下载,或在首次输入带重音符号的文本时下载)仅在粘贴期间运行,随后恢复之前的剪贴板内容。Samsung 的剪贴板历史记录可能会保留粘贴的文本。
  • 通知:Android 只会保留已关闭通知的应用名称,不会保留通知文本。
  • 受 FLAG_SECURE 保护的应用会生成黑色截图;服务端会说明原因,[N] 元素仍然可读。
  • Android 同一时间只允许一个无障碍自动化客户端:如果另一个工具的服务端(mobile-mcp、Appium、uiautomator2 等)占用了它,UI 树将无法读取;look 会显示该工具及其 pid。关闭或停止该工具后重试。
  • 连接方式为 USB 或通过无线调试连接的本地 Wi-Fi,并且需要与每台 PC 配对。ADB 不能通过 Bluetooth 使用。
  • Xiaomi、Redmi 和 POCO(MIUI、HyperOS)在开发者选项中开启“USB 调试(安全设置)”之前,会拒绝注入手势;错误信息会说明这一点。
  • 安装脚本(install.ps1)、test.ps1 和 OCR 仅支持 Windows。在 Linux 上,服务端本身可以运行,并且已在 CI 中通过模拟器测试;macOS 未经测试。

已排除的方案

  • 手机上的配套应用:通知、输入带重音符号的文本、文件和设置都由 ADB 本身提供;应用只会增加脱离 USB 和家庭 Wi-Fi 的控制能力,而这很少用到。
  • 不可见屏幕:能看到 Agent 在真实屏幕上操作是一项功能。
  • 互联网中继(隧道、VPN):仅支持 USB 或本地 Wi-Fi。

完整安装(Windows)

这是 uvx 的替代方案:使用单一本地环境,在 PC 上找到的客户端中注册,并提前获取 scrcpy 服务端。

前置条件:Windows、PowerShell 7 和 uv;Android Platform Tools 为可选项(winget install Google.PlatformTools,否则会在首次使用时下载)。手机端:开发者选项 → USB 调试(nexus-android setup 会引导你完成设置)。

git clone https://github.com/pironjulien/NexusAndroid
cd NexusAndroid
pwsh -NoProfile -File install.ps1          # environment, scrcpy server, Codex/Antigravity registration, tests
pwsh -NoProfile -File install.ps1 -Live    # plus a run on the connected phone (types then clears a draft SMS, never sends)

脚本的操作(可安全重复运行,例如在 git pull 后运行):

  • 环境:~\.nexus\nexus-android\venv,其中包含软件包副本(而非指向克隆仓库的链接)。
  • scrcpy 服务端:从官方发布版本下载,只有 SHA-256 匹配时才会保留。
  • Codex:如果存在 ~\.codex,则在 ~\.codex\config.toml 中添加 [mcp_servers.nexus-android] 表格(stdio,使用该环境的 Python),替换旧的 nexus-android 表格,并保留文件其余内容不变。修改前会先将原文件复制到 ~\.nexus\nexus-android\backups。
  • Antigravity:如果存在 ~\.gemini\antigravity 或其配置,则在 ~\.gemini\config\mcp_config.json 中添加 nexus-android 条目,并创建相同的备份。
  • Claude Code:脚本会打印用于同一环境的 claude mcp add 命令,供你运行;脚本本身不会调用 Claude CLI。
  • 测试:test.ps1(离线运行,无需手机)。-SkipTests 会跳过测试,-NoRegister 会保留客户端配置不变。

之后,每个客户端都会通过 stdio 启动自己的服务端。它们通过 ~\.nexus 共享手机锁定状态和屏幕常亮状态;如需所有客户端共用单个进程,请参阅 共享守护进程。

无线 Wi-Fi 连接,每台 PC 设置一次
  1. 手机:设置 → 开发者选项 → 无线调试 → 使用配对码配对设备。
  2. PC:运行 adb pair <ip>:<port>,然后输入手机上显示的配对码。

此后,nexus-android 就能在本地 Wi-Fi 上找到手机。由于 One UI 不会通过 mDNS 广播手机,服务器会在每次通过 USB 插入手机时,记录其 Wi-Fi 地址和无线调试端口。重启或网络变更后,此端口会改变:这时只需通过 USB 插入一次即可。服务器会先尝试上次记录的地址,然后再尝试 mDNS;只有在 PC 与手机处于同一网络时,服务器才会查找新端口,并在连接前通过 ADB 握手进行确认。如果找不到手机,服务器会在 2 分钟内不再搜索 Wi-Fi(插入数据线后仍会立即检测到)。插入数据线时,数据线连接优先。NEXUS_ANDROID_SERIAL 可按序列号或 ip:port 地址指定设备。

没有共用的 Wi-Fi 网络(仅通过以太网连接的办公 PC 配有 Wi-Fi 网卡):开启手机热点并让 PC 连接,然后在插入数据线的情况下运行 adb tcpip 5555。服务器会记录手机的热点地址,并在拔掉数据线后找到手机。TCP 模式会持续到手机重启(或运行 adb usb)为止。如果希望 PC 的互联网流量继续通过以太网而不是手机移动数据传输,请提高 PC 的 Wi-Fi 接口跃点数。

未加密。 与无线调试(已配对,使用 TLS)不同,adb tcpip 5555 使用的是传统的明文 TCP ADB:网络中的其他人可以读取所有流量,包括屏幕截图和消息,而且该端口会一直保持开放。仅在手机自身的热点或其他由你控制的网络上使用此模式,并在使用后运行 adb usb 将其关闭。

共享守护进程(可选)

默认情况下,每个客户端都会启动自己的 nexus-android 进程。若要让所有客户端共用一个进程,请以 HTTP 模式启动服务器:

$env:NEXUS_MCP_TOKEN = "<random string, 32 characters or more>"   # or NEXUS_MCP_TOKEN_FILE = path of a file holding it
nexus-android --http 16180

服务器仅在 127.0.0.1 上提供 MCP Streamable HTTP 服务(默认端口为 16180),地址为 http://127.0.0.1:16180/mcp,并会拒绝所有未包含 Authorization: Bearer <token> 标头的请求(HTTP 401);未提供令牌时,服务器不会启动。将每个客户端指向此 URL,并设置该标头。每个 MCP 会话都有独立的 [N] 编号和对话列表;ADB 连接和手机锁则由所有会话共用。是否启动守护进程(例如在登录时启动)由你决定:install.ps1 不会进行相关设置。令牌可防止配置错误的客户端或意外会话操控手机;但它无法防范同一 PC 上运行的恶意软件,因为后者可以通过 ADB 直接访问手机(参见 SECURITY.md)。

隐私

NexusAndroid 完全在你的 PC 上运行,并通过 ADB(USB 数据线或本地 Wi-Fi)与手机通信。它没有账户、遥测、分析功能或云中继。它发出的互联网请求均不包含与你或手机有关的数据:最多每天一次,从 PyPI 获取最新版本号;在使用自带的 adb 副本时,获取 Google 的 SDK 仓库清单(可通过 NEXUS_ANDROID_UPDATE=0 关闭);当 PC 上找不到 adb 或自带副本已过时,从 dl.google.com 获取 Google 的 Platform Tools(可通过 NEXUS_ANDROID_ADB_DOWNLOAD=0 关闭);首次输入带重音符号的文本时,从 GitHub 获取固定版本的 scrcpy 服务端(如果 install.ps1 已经获取,则会跳过)。

  • 读取的内容:屏幕和 UI 树、SMS/RCS 消息、通知、共享存储中的文件、位置、最近通话、联系人和日历,仅在 Agent 调用相应工具时读取。安全码会在 Agent 看到之前进行遮蔽。
  • 数据去向:工具结果会返回给你连接的 AI 客户端(Claude、Codex、Antigravity……)。该客户端可能会根据其自身的隐私政策,将数据发送给其模型提供商;NexusAndroid 不会将数据发送到其他任何地方。
  • PC 上存储的内容,位于 ~/.nexus/ 下:手机地图(map/:Settings 树、使用 map note 记录的屏幕,以及最多 30 份设置值、应用、权限和 Bluetooth 设备名称的快照,其中标识符、令牌、地址和号码均已遮蔽)、手机的序列号、Wi-Fi 地址和无线调试端口、保存的屏幕超时时长、锁文件、上次检查更新的日期(update.json)、固定版本的 scrcpy 服务端、下载的 Platform Tools(当 PC 上找不到 adb 时)、setup 或 install.ps1 修改的 AI 客户端配置备份(backups/),以及使用 install.ps1 时的环境信息。你 pull 的文件会保存到 ~/Downloads/Telephone。服务不会将消息或屏幕截图写入磁盘。
  • 日志,位于 %LOCALAPPDATA%\NexusJournal\android\<agent>\<YYYY-MM>.jsonl(或 NEXUS_JOURNAL_HOME),采用 Nexus 工具的共享格式:每次手势或工具调用占一行,记录发起调用的 AI(Claude、Codex、Antigravity)、操作、结果、耗时、执行方式、应用包名,以及预设列表中的错误类别。绝不记录屏幕文本、SMS、联系人、输入的文本或代码。不会将任何内容发送到其他地方;日志按月保留,直到你删除:可随时删除 android 文件夹(或单个月份文件)。在服务的环境中设置 NEXUS_JOURNAL=0 即可关闭日志(不会写入任何内容,也不会创建文件夹)。
  • 手机上,/data/local/tmp 中的两个辅助程序(nexus-scrcpy.jar、nexus-query-*.dex)会保留在此;UI 转储文件(nexus-android-ui-*.xml)和临时读取文件夹(nexus-q-*、nexus-p-*)会在每次读取后立即删除。读取辅助程序在 10 分钟内没有收到请求时会自行停止。
  • 移除方法:删除 ~/.nexus/nexus-android/、~/.nexus/android.lock 和 %LOCALAPPDATA%\NexusJournal\android\,从每个客户端的配置中删除 nexus-android 条目,运行 adb shell "rm -rf /data/local/tmp/nexus-*"(删除辅助程序、UI 转储文件,以及读取中断后残留的任何读取文件夹),并在手机上撤销 PC 的密钥(开发者选项 → 撤销 USB 调试授权)。

如有疑问或顾虑,请提交 issue,或参阅 SECURITY.md 进行私下报告。

开发

请先安装 Node.js。在本地已备好 Python 和锁定的依赖包后,运行:

pwsh -NoProfile -File test.ps1   # ruff, pyright and the unit tests, offline, no phone needed

检查不会下载 Python、依赖包或 Pyright:uv 被强制设为离线模式,自动下载 Python 的功能已禁用,Pyright 则使用已安装的 Node.js 运行其捆绑的 JavaScript。缺少 Python 或依赖缓存不完整时,会明确报错。每个检出版本都会将测试环境保存在源代码树之外。

在新机器上或锁文件变更后,请在联网时单独准备缓存(CI 会在离线检查前执行此操作):

$env:UV_PROJECT_ENVIRONMENT = Join-Path $env:TEMP 'nexus-android-prepare'
uv sync --frozen --python 3.14  # explicitly online preparation, including development and build dependencies
pwsh -NoProfile -File test.ps1 -Python 3.14

-Python 3.12、3.13、3.14 或 3.15 会选择已安装的解释器,并创建单独的测试环境。-Full 还会运行现有的真实手机场景;手机必须可连接且已解锁。

许可证

MIT。与 Google、Samsung、Anthropic、OpenAI 或 Genymobile 均无关联。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。