flutter-skill 是一个 MCP 服务器,用于将 AI 智能体连接到正在运行的应用,实现跨平台的端到端(E2E)测试。它允许智能体通过自然语言执行截图、点击元素、输入文本、滚动、导航、检查 UI 树和验证状态等操作,无需编写测试代码。
支持的平台
- Flutter(iOS/Android/Web):flutter pub add flutter_skill
- React Native:npm install flutter-skill-react-native
- Electron:npm install flutter-skill-electron
- iOS(Swift/UIKit):SPM: FlutterSkillSDK
- Android(Kotlin):Gradle: flutter-skill-android
- Tauri(Rust):cargo add flutter-skill-tauri
- KMP Desktop:Gradle dependency
- .NET MAUI:NuGet package
安装
推荐使用 npm 全局安装:
npm install -g flutter-skill
或使用 Homebrew:
brew install ai-dashboad/flutter-skill/flutter-skill
也可以从 GitHub Releases 下载二进制文件。
MCP 配置
将以下内容添加到 AI 智能体的 MCP 配置中(如 Claude Desktop、Cursor、Windsurf、OpenClaw 等):
{ "mcpServers": { "flutter-skill": { "command": "flutter-skill", "args": ["server"] } } }
快速开始
- 初始化应用(一次性操作):
flutter-skill init
该命令会自动检测项目类型,并为应用打上测试桥接补丁。验证:输出应确认已检测到项目类型并修补了主入口点。如果失败,请检查是否位于项目根目录且框架受支持。
- 启动并连接:
flutter-skill launch .
验证:输出中应出现 VM Service URI(例如 ws://127.0.0.1:50000/ws)。如果没有出现 URI,请检查是否安装了 Flutter/目标框架且应用可编译。
- 使用自然语言测试:
智能体遵循以下核心循环:
- screenshot() — 查看当前屏幕
- inspect_interactive() — 发现所有可点击/可输入元素及其语义引用
- tap(ref: "button:Login") — 使用稳定的语义引用点击
- enter_text(ref: "input:Email", text: "admin@test.com") — 在字段中输入文本
- wait_for_element(key: "Dashboard") — 验证导航成功
- screenshot() — 确认最终状态
如果 inspect_interactive() 未返回任何元素:先截图确认屏幕已加载,然后检查 get_logs() 中的错误。应用可能仍在加载,稍等后重试。
可用的 MCP 工具
核心操作
- screenshot:将当前屏幕捕获为图像
- tap:通过 key、text、ref 或坐标点击元素
- enter_text:在字段中输入文本
- scroll:向上/下/左/右滚动
- swipe:在两点之间滑动
- long_press:长按元素
- drag:从点 A 拖动到点 B
- go_back:返回上一页
- press_key:发送键盘按键事件
检查
- inspect_interactive:获取所有交互元素及其语义引用 ID
- get_elements:列出屏幕上所有元素
- find_element:通过 key 或 text 查找元素
- wait_for_element:等待元素出现(带超时)
- get_element_properties:获取元素的详细属性
文本操作
- set_text:替换字段中的文本
- clear_text:清空文本字段
- get_text:读取文本内容
应用控制
- get_logs:读取应用日志
- clear_logs:清空日志缓冲区
语义引用
inspect_interactive 返回带有稳定语义引用 ID 的元素:
- button:Login → 登录按钮
- input:Email → 邮箱文本字段
- toggle:Dark Mode → 深色模式开关
- button:Submit[1] → 第二个提交按钮(消歧)
格式:{role}:{content}[{index}]
共 7 种角色:button、input、toggle、slider、select、link、item
使用引用进行可靠的元素定位,可适应 UI 变化:
tap(ref: "button:Login") enter_text(ref: "input:Email", text: "test@example.com")
测试工作流
核心循环
screenshot() → inspect_interactive() → tap/enter_text → screenshot() → verify
始终在操作前后调用 screenshot()。导航后使用 wait_for_element() — 应用需要时间过渡。
验证检查点
- 在 screenshot() 之后:确认预期屏幕可见后再操作。
- 在 tap() 或 enter_text() 之后:调用 screenshot() 验证 UI 已响应。
- 导航后:使用 wait_for_element(key: "target_screen") 并设置超时。如果超时,调用 screenshot() 和 get_logs() 进行诊断。
- 遇到意外状态时:调用 get_logs() 和 inspect_interactive() 了解当前存在的元素。
元素定位优先级
- ref:(最可靠)来自 inspect_interactive() 的语义引用
- key:开发者设置的 widget key
- text:可见文本内容(文本变化时脆弱)
- 坐标:最后手段,在不同屏幕尺寸下会失效
链接
- GitHub
- npm
- Documentation
- pub.dev
- VSCode Extension