基于MCP与ADB实现AI智能体远程控制安卓手机的实践指南

发布时间:2026/5/16 8:17:06

基于MCP与ADB实现AI智能体远程控制安卓手机的实践指南 1. 项目概述当你的手机成为AI的“眼睛”与“双手”最近在折腾AI智能体Agent的时候我一直在思考一个问题如何让这些运行在云端或本地电脑上的“大脑”能真正感知和操作我们物理世界里的设备比如让它帮我查一下手机上的未读消息、控制智能家居或者直接操作手机App完成一些重复性任务。直到我遇到了priyankark/phonepi-mcp这个项目眼前豁然开朗。这本质上是一个MCPModel Context Protocol服务器它巧妙地在你的AI应用比如使用Claude Desktop、Cline或任何支持MCP的框架和一台安卓手机之间架起了一座双向通信的桥梁。简单来说它把你的安卓手机变成了一个AI智能体可以远程调用的“工具”。AI不再只是一个聊天窗口它获得了“视觉”通过屏幕截图和“触觉”通过模拟点击、滑动、输入等操作。这个想法的精妙之处在于它没有尝试去重新发明轮子去破解复杂的安卓系统而是利用了安卓开发者工具中现成的、最稳定的ADBAndroid Debug Bridge协议。通过MCP标准化的工具定义AI可以像调用一个普通函数一样让手机执行“截屏”、“点击坐标(500, 1000)”、“输入文本”等操作并将结果如图片、文字返回给AI进行下一步分析决策。这解决了什么痛点对于自动化测试工程师你可以用它快速构建基于自然语言描述的测试用例对于效率狂人你可以让AI帮你自动处理手机上的日常任务对于开发者这为构建跨设备的AI助手提供了极其灵活的硬件交互层。接下来我就带你从零开始深入这个项目的核心完成部署并分享如何让它真正“活”起来。2. 核心原理与架构拆解MCP与ADB的化学反应要玩转phonepi-mcp必须理解其核心依赖的两大技术支柱MCP和ADB。它们一个负责“对话协议”一个负责“物理操控”两者的结合奠定了项目的基石。2.1 MCPAI智能体的“工具包”协议MCPModel Context Protocol是由Anthropic提出的一种开放协议旨在标准化AI模型与外部工具、数据源之间的交互方式。你可以把它想象成给AI智能体定义了一套可插拔的“工具API”规范。核心思想传统的AI应用集成外部功能需要针对每个模型、每个框架做大量定制化开发。MCP通过定义一套通用的服务器-客户端协议让任何支持MCP的AI客户端如Claude Desktop都能无缝使用任何按照MCP规范实现的服务端Server提供的工具Tools和资源Resources。在phonepi-mcp中的角色本项目就是一个MCP服务器。它启动后会向连接的AI客户端“宣告”自己拥有哪些工具比如get_screen获取屏幕、tap_screen点击屏幕等。当你在AI客户端中说“帮我看看手机屏幕”客户端会将其转化为对get_screen工具的调用请求发送给本服务器服务器执行操作后将截图结果返回给客户端客户端再呈现给你或交给AI模型分析。2.2 ADB通往安卓设备的万能钥匙ADB是安卓SDK的一部分是连接电脑与安卓设备进行调试的瑞士军刀。phonepi-mcp的所有底层操作最终都通过ADB命令实现。工作原理在电脑上运行ADB服务端server在手机上运行ADB守护进程adbd。通过USB或网络连接后电脑可以向手机发送特定的命令。本项目使用的关键ADB命令adb shell screencap -p捕获当前屏幕截图并以PNG格式输出到标准输出。adb shell input tap x y在屏幕坐标 (x, y) 处模拟一次点击事件。adb shell input swipe x1 y1 x2 y2模拟从 (x1, y1) 滑动到 (x2, y2)。adb shell input text string模拟输入文本注意不支持中文等复杂输入。adb shell am start -a android.intent.action.VIEW -d url通过Intent打开特定URL或应用。项目的封装phonepi-mcp服务器内部封装了这些ADB命令的调用逻辑并处理了结果解析如将二进制截图流转换为base64编码的图片数据向上提供干净的MCP工具接口。2.3 架构全景图整个系统的数据流如下用户在AI客户端如Claude Desktop中提出自然语言请求例如“打开手机上的微信”。AI客户端/AI模型理解请求识别出需要调用phonepi-mcp服务器提供的start_activity工具并可能通过其他工具如get_screen先确认当前屏幕状态。MCP客户端库将工具调用请求按照MCP协议格式发送到phonepi-mcp服务器通常通过SSE或HTTP。phonepi-mcp服务器收到请求解析参数调用对应的内部函数。ADB桥接层内部函数构造出具体的ADB命令如adb shell am start -n com.tencent.mm/.ui.LauncherUI。系统进程通过subprocess模块执行ADB命令并与手机上的ADB守护进程通信。安卓手机执行命令执行截图、点击等操作并将结果图片数据、命令执行状态通过ADB返回。结果返回结果沿原路返回最终由AI客户端将截图展示给用户或由AI模型根据返回结果决定下一步操作。这个架构的优势是解耦和标准化。AI部分只需要理解MCP无需关心ADB细节设备控制部分只需实现MCP服务器可以被任何兼容的AI系统使用。3. 环境准备与部署实战理论清晰后动手搭建环境是第一步。这里会详细走过每一个环节并指出可能遇到的坑。3.1 基础环境配置你需要准备一台电脑Windows/macOS/Linux和一部安卓手机。1. 电脑端准备安装Python项目需要Python 3.8。建议使用pyenv或直接安装最新稳定版Python 3.11。安装ADBmacOS:brew install android-platform-toolsUbuntu/Debian:sudo apt install adbWindows: 下载 Android SDK Platform-Tools 解压后将目录路径包含adb.exe添加到系统环境变量PATH中。验证打开终端/CMD输入adb version应显示版本号。2. 手机端准备开启开发者模式进入手机“设置” - “关于手机”连续点击“版本号”7次直到提示“您已处于开发者模式”。开启USB调试返回设置进入“系统与更新”或“更多设置” - “开发者选项”找到并开启“USB调试”。连接电脑使用USB数据线连接手机和电脑。此时手机会弹出“是否允许USB调试”的授权对话框勾选“始终允许”并确认。验证连接在电脑终端执行adb devices。如果看到设备列表中出现你的设备序列号且状态为device而非unauthorized则表示连接成功。List of devices attached xxxxxxxx device注意部分厂商手机如小米、华为需要在开发者选项中额外开启“USB调试安全设置”或关闭“MIUI优化”才能正常使用ADB点击等功能请根据自己手机型号搜索具体设置。3.2 部署phonepi-mcp服务器项目提供了多种运行方式这里介绍最直接的源码运行和Docker方式。方式一源码运行适合开发与调试# 1. 克隆仓库 git clone https://github.com/priyankark/phonepi-mcp.git cd phonepi-mcp # 2. 创建虚拟环境推荐 python -m venv venv # Windows: venv\Scripts\activate # macOS/Linux: source venv/bin/activate # 3. 安装依赖 pip install -r requirements.txt # 4. 运行服务器 python -m phonepi_mcp.server服务器默认会在http://localhost:8000启动。你可以通过--host和--port参数修改。方式二Docker运行适合快速部署与隔离# 1. 拉取镜像如果作者提供了 # docker pull priyankark/phonepi-mcp:latest # 2. 运行容器关键是将宿主机的ADB套接字挂载到容器内 # 首先在宿主机上找到ADB套接字路径通常是 /tmp/.adb-socket 或与 adb devices 相关。 # 更通用的方法是使用 adb kill-server adb start-server 后使用 adb -L tcp:localhost:5037 fork-server server --reply-fd 查看。 # 一种简单粗暴但有效的方法是直接挂载宿主机的ADB程序目录和Unix套接字目录。 docker run -it --rm \ --nethost \ # 使用主机网络方便容器内访问localhost上的ADB服务 -v /tmp/.android:/tmp/.android \ # 挂载ADB配置和密钥目录 -v $(which adb):/usr/bin/adb:ro \ # 挂载宿主机ADB二进制文件只读 priyankark/phonepi-mcp:latestDocker方式复杂度较高因为需要处理容器内外的ADB通信。更稳定的做法是在宿主机运行ADB服务让容器通过TCP连接访问宿主机的ADB服务端口默认5037。这需要先确保宿主机ADB服务监听在所有接口adb -a -P 5037 fork-server server然后在容器运行时通过--add-host或自定义网络连接。3.3 配置AI客户端以Claude Desktop为例这是让AI“认识”你手机的关键一步。打开Claude Desktop配置找到Claude Desktop的配置文件夹。macOS:~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:%APPDATA%\Claude\claude_desktop_config.json编辑配置文件在mcpServers字段下添加phonepi-mcp服务器的配置。{ mcpServers: { phonepi: { command: python, args: [ -m, phonepi_mcp.server ], env: { PHONEPI_ADB_SERIAL: 你的设备序列号从adb devices获取 } } } }command和args指向你启动服务器的方式。如果是全局安装或Docker运行可能需要调整。PHONEPI_ADB_SERIAL环境变量非常重要用于指定控制哪台手机如果你连接了多台。如果不设置默认操作adb devices列表中的第一台设备。重启Claude Desktop保存配置文件完全退出并重启Claude Desktop。验证连接重启后在Claude聊天界面你应该能看到一个手机或工具图标或者直接询问Claude“你能使用哪些工具”它应该会列出phonepi-mcp提供的工具集如get_screen,tap_screen等。4. 核心工具详解与使用范例服务器启动并连接成功后AI客户端就能调用一系列工具了。我们来深入看看每个工具能做什么以及如何在实际场景中运用。4.1 信息获取类工具get_screen获取当前屏幕截图功能捕获手机当前屏幕返回一张PNG格式的图片通常以base64编码或文件路径形式在客户端内呈现。AI调用场景“我的手机屏幕现在显示什么”、“截个图看看”、“检查一下通知栏有没有新消息”。底层实现执行adb exec-out screencap -p直接获取二进制流效率高于adb shell screencap -p file.png再拉取文件。注意事项截图速度受手机性能和分辨率影响。高分辨率屏幕的图片数据量大传输可能需要一秒左右。get_screen_info获取屏幕基础信息功能返回屏幕的物理尺寸如1080x2340和密度dpi。AI调用场景通常在执行点击、滑动等坐标操作前AI需要先获取此信息来计算相对坐标。例如AI模型可能会说“先获取屏幕尺寸然后点击屏幕中央”。底层实现通过adb shell wm size和adb shell wm density命令获取。4.2 交互操作类工具这是实现自动化的核心。所有坐标通常基于物理像素。tap_screen(x: int, y: int)点击屏幕指定坐标参数x,y为整数坐标。AI调用场景结合截图和视觉识别AI模型本身或结合OCR实现“点击返回键”、“点击登录按钮”。示例tap_screen(540, 2200)可能点击了屏幕底部中央的导航栏位置。避坑技巧坐标稳定性不同应用、不同状态栏下的元素坐标可能会变。更健壮的方式是让AI通过截图“看到”按钮位置然后计算相对坐标点击而不是使用固定坐标。点击反馈ADB点击是“盲点”没有视觉确认。复杂的操作流中最好在一次点击后调用get_screen确认点击效果如页面是否跳转。swipe_screen(x1, y1, x2, y2, duration_ms)滑动屏幕参数起始点(x1, y1)结束点(x2, y2)滑动持续时间毫秒。AI调用场景“向下滑动屏幕”、“在相册里滑动到下一张图片”、“滑动解锁”。示例swipe_screen(500, 1500, 500, 500, 300)实现从屏幕中下方向上滑动。实操心得duration_ms参数很关键。模拟快速翻页可以设置较短时间如100ms模拟慢速浏览可以设置较长时间如1000ms。这会影响滑动的流畅度和实际效果。input_text(text: str)输入文本参数需要输入的字符串。限制ADB的input text命令不支持直接输入中文、空格和大多数特殊字符。它只能输入ASCII字符集中的字母、数字和部分符号。替代方案对于复杂输入通常的策略是点击输入框调出系统键盘。使用get_screen截图通过AI的视觉能力“观察”键盘布局。通过一系列tap_screen模拟点击虚拟键盘按键。这需要更复杂的坐标管理和状态判断是目前的一个挑战。start_activity(intent_uri: str)通过Intent启动Activity功能一个更高级的操作可以直接启动应用或特定页面。示例打开浏览器访问百度start_activity(https://www.baidu.com)打开微信start_activity(package:com.tencent.mm)(需要知道包名和Activity名更常用的是adb shell monkey -p com.tencent.mm -c android.intent.category.LAUNCHER 1)注意Intent的构造需要一定的安卓知识对于普通自动化直接通过点击应用图标tap_screen启动可能更简单。4.3 使用模式与AI协作流程单独的工具是零件组合起来才能形成工作流。一个典型的AI协作流程如下用户请求“帮我给张三发一条微信消息说‘晚上老地方见’。”AI规划AI模型如Claude内部规划步骤a. 打开微信b. 找到联系人“张三”c. 进入聊天窗口d. 输入文本e. 点击发送。工具调用链AI调用get_screen确认当前是否在桌面。AI分析截图识别微信图标位置计算坐标调用tap_screen点击。等待后调用get_screen获取微信主界面。AI分析截图找到搜索框或通讯录位置点击。AI调用input_text输入“张三”假设为英文/拼音。AI分析搜索结果截图点击联系人头像。AI分析聊天窗口截图点击输入框。难点输入中文“晚上老地方见”。AI可能需要调用更复杂的输入法模拟点击或者本项目未来集成剪贴板操作adb shell am broadcast设置剪贴板再粘贴。找到发送按钮坐标调用tap_screen发送。状态校验在每个关键步骤后AI都应通过get_screen校验操作是否成功形成闭环反馈。这个过程高度依赖AI模型的视觉理解VLM能力和规划能力。phonepi-mcp完美地提供了“执行层”将AI的“思考”转化为真实的设备操作。5. 进阶技巧与性能优化当基础功能跑通后你会希望它更稳定、更快、更强。以下是一些进阶实践。5.1 坐标管理与屏幕适配不同手机分辨率不同写死坐标的脚本毫无移植性。方案一相对坐标始终基于get_screen_info返回的width和height计算比例坐标。# 假设要点击屏幕右下角“我的”标签假设在横向90%纵向95%的位置 screen_info client.call_tool(get_screen_info) tap_x int(screen_info[width] * 0.9) tap_y int(screen_info[height] * 0.95) client.call_tool(tap_screen, {x: tap_x, y: tap_y})方案二视觉定位这是更终极的方案。让AI分析截图直接指出“登录按钮”在哪里并返回其边界框bounding box。然后计算框的中心点坐标进行点击。这需要AI客户端或模型具备视觉定位并返回坐标的能力。目前一些先进的MCP客户端或结合了视觉能力的Agent框架如Cline结合GPT-4V可以做到这一点。5.2 操作延迟与异步处理ADB命令执行、截图传输都需要时间。在自动化脚本中盲目连续发送命令会导致失败。强制等待在关键操作如启动应用、页面跳转后添加固定的等待时间如time.sleep(2)。简单但低效。智能等待轮询操作后循环调用get_screen直到屏幕内容变化为预期状态例如出现特定的UI元素。这需要定义“预期状态”的判断逻辑可以结合OCR或图像特征匹配。MCP的异步支持确保你的MCP客户端和服务器的交互模式支持异步调用避免阻塞主线程提升多步骤任务的流畅度。5.3 扩展工具超越基础ADBphonepi-mcp项目本身提供的工具是基础。你可以基于其框架轻松扩展更多ADB能力文件传输增加push_file和pull_file工具用于与手机交换文件。获取设备信息增加get_device_info工具返回手机型号、安卓版本、电量等通过adb shell getprop等命令。模拟按键增加key_event工具模拟音量键、电源键、返回键、Home键等adb shell input keyevent KEYCODE_BACK。操作通知栏增加expand_notification和clear_notifications工具。更复杂的输入集成adb shell ime命令集尝试切换输入法或进行更复杂的文本输入但兼容性挑战大。扩展方法通常是模仿项目已有的工具实现在server.py中定义新的工具函数并在tools列表中注册。5.4 稳定性与错误处理连接保持USB连接可能意外断开Wi-Fi ADB也可能不稳定。在服务器端实现重连机制定期检查adb devices中设备状态。命令超时为每个ADB命令执行设置超时使用subprocess.run的timeout参数防止某个命令卡死导致整个服务无响应。异常捕获与日志在工具函数内部详尽捕获subprocess.CalledProcessError、FileNotFoundErrorADB未找到等异常并返回结构化的错误信息给MCP客户端而不是让服务器崩溃。同时记录详细的操作日志便于排查问题。6. 常见问题与排查实录在实际部署和使用中我遇到了不少问题这里汇总一下希望能帮你快速排雷。Q1: 运行adb devices提示unauthorized。A这是手机未授权电脑的ADB连接。确保手机已开启USB调试。用USB连接后手机屏幕一定要弹出授权对话框并勾选“始终允许”后确认。如果没弹出尝试重启ADB服务adb kill-server adb start-server并重新插拔数据线。检查开发者选项里是否有“撤销USB调试授权”有的话撤销后重试。Q2:phonepi-mcp服务器启动报错提示ADB命令找不到或执行失败。A路径问题确保ADB已正确安装并加入系统PATH。在运行服务器的终端里直接输入adb看是否能识别。权限问题Linux/macOS有时需要sudo权限才能访问USB设备。可以尝试为ADB设备设置udev规则Linux或使用sudo运行服务器不推荐建议配置用户组权限。端口占用ADB服务默认端口5037被占用。运行adb kill-server后再启动服务器。Q3: AI客户端如Claude Desktop连接不上phonepi-mcp服务器。A配置错误仔细检查claude_desktop_config.json中的command和args路径是否正确。如果使用虚拟环境python命令需要指向虚拟环境内的解释器绝对路径。服务器未运行在终端手动运行python -m phonepi_mcp.server看是否有错误输出并确认它在监听指定端口默认8000。网络/权限确保Claude Desktop有权限访问localhost:8000。在macOS上可能需要授予Claude Desktop网络权限。Q4: 工具调用成功但手机上没有反应点击无效、滑动无效。A坐标错误这是最常见的原因。确认你使用的坐标是物理像素坐标且在当前屏幕取景范围内。先用get_screen截图手动计算一个明显位置的坐标如状态栏中央测试。屏幕状态确保手机屏幕是点亮且解锁的。ADB命令在锁屏状态下可能无效。厂商限制部分手机厂商尤其是国内定制UI对ADB辅助功能有额外限制。在开发者选项里检查“禁止权限监控”、“USB调试安全设置”等选项尝试关闭或开启。有时需要关闭“MIUI优化”小米。输入法冲突某些输入法可能会拦截ADB输入事件。尝试切换到系统默认输入法。Q5:input_text无法输入中文或空格。A这是ADBinput text命令的固有局限。目前没有完美的纯ADB解决方案。变通方法使用剪贴板先通过其他方式如电脑上复制将文本复制到手机剪贴板然后使用ADB模拟粘贴操作adb shell input keyevent 279或adb shell am broadcast意图设置剪贴板再模拟KEYCODE_PASTE。但这需要更复杂的脚本和权限。模拟键盘点击如前所述通过OCR识别屏幕键盘然后用tap_screen模拟点击。这非常复杂且容易出错。接受现实对于自动化任务尽量设计为不需要复杂文本输入的流程或提前在手机端设置好。Q6: 操作速度慢感觉卡顿。A截图优化screencap命令本身有开销。可以尝试降低截图分辨率如果AI模型支持小图分析但需要修改ADB命令参数可能不是所有设备支持。网络延迟Wi-Fi ADB如果使用Wi-Fi连接延迟会显著高于USB。对于快速连续操作建议使用USB。AI处理耗时整个链路是截图 - 传输 - AI分析 - 决策 - 发送操作命令。其中AI模型分析图片可能是最耗时的环节。考虑使用更轻量的视觉模型或者只在必要时才进行全屏分析。这个项目打开了一扇新的大门它以一种优雅且标准化的方式将强大的AI模型与最普及的移动设备连接起来。虽然目前在处理复杂UI交互和中文输入上还有局限但其展现出的潜力和简洁的设计哲学令人兴奋。我个人的使用体会是从“能用”到“好用”中间需要大量的调试和针对特定场景的优化比如为常用应用编写特定的坐标映射或状态机。但一旦跑通一个流程那种让AI替你操作物理设备的成就感是完全不同的。下一步我打算尝试将它和本地视觉语言模型如LLaVA结合打造一个完全离线的、能理解我手机屏幕并执行任务的私人助手这或许才是真正意义上的“智能体”雏形。

相关新闻