README
version: 1 name: Commute ETA Notification app: Waze, Messages tags: ["workflow", "cross-app"]
步骤
- 启动 Waze
- 等待 "Où va-t-on ?" 出现
- 点击 "Où va-t-on ?"
- 等待 "${DESTINATION:-Travail}" 出现
- 点击 "${DESTINATION:-Travail}"
- 等待 "Y aller" 出现
- 点击 "Y aller"
- 等待 "min" 出现
- 记录:读取通勤时间和预计到达时间(ETA)。
- 按下主页按钮
- 启动 Messages
- 点击 "New Message"
- 输入 "${RECIPIENT}" 并选择联系人
- 输入 "On my way! ETA {eta}"
- 按下 Return
- 截图:"message_sent"
`${VAR}` 占位符会从环境变量中解析。`${VAR:-default}` 用于设置回退值。
### 技能市场
可从 [jfarcand/mirroir-skills](https://github.com/jfarcand/mirroir-skills) 安装现成的技能:
```bash
git clone https://github.com/jfarcand/mirroir-skills ~/.mirroir-mcp/skills
测试运行器
可从命令行确定性地运行技能,无需 AI 参与,专为持续集成(CI)和回归测试设计。
mirroir test apps/settings/check-about
mirroir test --junit results.xml --verbose # 输出 JUnit 报告
mirroir test --dry-run apps/settings/check-about # 验证但不执行
| 选项 | 描述 |
|---|---|
| --junit <path> | 写入 JUnit XML 报告 |
| --screenshot-dir <dir> | 保存失败截图(默认:./mirroir-test-results/) |
| --timeout <seconds> | wait_for 超时时间(默认:15 秒) |
| --verbose | 显示详细步骤 |
| --dry-run | 解析并验证但不执行 |
| --no-compiled | 跳过已编译的技能,强制进行完整 OCR |
退出代码 0 表示所有测试通过,1 表示有测试失败。
编译技能
可对技能进行一次编译,以捕获坐标和时间信息,后续回放时无需进行 OCR。
mirroir compile apps/settings/check-about # 编译
mirroir test apps/settings/check-about # 自动检测 .compiled.json 文件
mirroir test --no-compiled check-about # 强制进行完整 OCR
AI 智能体在首次运行 MCP 时会自动编译技能。具体细节请参考 编译技能。
AI 辅助诊断
当测试步骤失败时,可使用 --agent 选项获取 AI 对问题的诊断和建议修复方案:
mirroir test --agent gpt-5.3 apps/settings/check-about
mirroir test --agent claude-sonnet-4-6 apps/settings/check-about
mirroir test --agent ollama:llama3 apps/settings/check-about
mirroir test --agent embacle apps/settings/check-about
内置智能体:
| 智能体 | 提供商 | API 密钥 |
|-------|----------|---------|
| gpt-5.3 | OpenAI | OPENAI_API_KEY |
| claude-sonnet-4-6, claude-haiku-4-5 | Anthropic | ANTHROPIC_API_KEY |
| ollama:<model> | Ollama(本地) | 无 |
| embacle, embacle:claude | embacle-server | CLI 智能体密钥 |
可在 ~/.mirroir-mcp/agents/ 目录下以 YAML 配置文件的形式定义自定义智能体。
没有 API 密钥?使用 embacle-server
embacle-server 可将已认证的 CLI 工具(GitHub Copilot、Claude Code 等)封装在兼容 OpenAI 的 API 之后。如果你有 Copilot 或 Claude Code 订阅,无需单独的 API 密钥即可使用:
cargo install embacle-server
embacle-server --port 3000 --provider copilot # 或者:--provider claude_code
mirroir test --agent embacle my-skill
录制功能
可将交互过程录制为技能文件:
mirroir record -o login-flow.yaml -n "Login Flow" --app "MyApp"
技能生成
可让 AI 智能体探索应用并自动生成 SKILL.md 文件:
Explore the Settings app and generate a skill that checks the iOS version.
使用深度优先搜索(DFS)图遍历算法,点击未访问的元素,当分支耗尽时回溯。自动跳过重复的屏幕。
组件检测
原始 OCR 返回的是无结构的文本元素列表。组件定义可让探索器了解 UI 模式的样子,每个模式对应一个 .md 文件(如表格行、开关、标签栏、摘要卡片)。探索器根据这些定义匹配屏幕区域,以决定点击哪些元素、跳过哪些元素以及何时回溯。
项目包含 18 个 iOS 组件定义。可将自定义定义放在 ~/.mirroir-mcp/components/ 或 <cwd>/.mirroir-mcp/components/ 目录下。
可使用以下命令针对当前实时屏幕测试定义:
Use calibrate_component with my-component.md to check how it matches.
具体的定义格式、匹配规则和检测流程请参考 组件检测。
环境检查
可使用以下命令验证你的设置:
mirroir doctor
mirroir doctor --json # 输出机器可读的结果
配置键盘布局
可使用以下命令为非美国键盘设置键盘布局:
mirroir configure
更新方法
# curl 安装器
/bin/bash -c "$(curl -fsSL https://mirroir.dev/get-mirroir.sh)"
# npx
npx -y mirroir-mcp install
# Homebrew
brew upgrade mirroir-mcp
# 从源代码更新
git pull && swift build -c release
卸载方法
# Homebrew
brew uninstall mirroir-mcp
# 从源代码卸载
./uninstall-mirroir.sh
图标检测
默认情况下,describe_screen 使用 Apple Vision OCR 检测屏幕上的文本。如果 ~/.mirroir-mcp/models/ 目录下存在 YOLO CoreML 模型(.mlmodelc),服务器会自动检测并将图标检测结果与 OCR 文本合并,为 AI 提供非文本元素(如按钮、开关和标签栏图标)的点击目标,这些元素是仅使用文本 OCR 无法检测到的。
| 模式 | ocrBackend 设置 | 行为 |
|------|---------------------|----------|
| 自动检测(默认) | "auto" | 如果安装了模型,则使用 Vision + YOLO;否则仅使用 Vision |
| 仅使用 Vision | "vision" | 仅使用 Apple Vision OCR 文本 |
| 仅使用 YOLO | "yolo" | 仅使用 CoreML 元素检测 |
| 同时使用 | "both" | 始终合并两个后端(如果没有模型,则优雅地回退到 Vision) |
安装模型
将编译好的 CoreML 模型(.mlmodelc)放在 ~/.mirroir-mcp/models/ 目录下,服务器会自动找到并加载它。也可以通过 yoloModelPath 设置或 MIRROIR_YOLO_MODEL_PATH 环境变量指定特定路径。
yoloConfidenceThreshold 设置(默认值:0.3)控制最小检测置信度,较低的值会检测更多元素,但可能会引入噪声。
配置设置
可通过 settings.json 文件覆盖默认的时间设置:
// .mirroir-mcp/settings.json(项目本地)或 ~/.mirroir-mcp/settings.json(全局)
{
"keystrokeDelayUs": 20000,
"clickHoldUs": 100000
}
环境变量同样有效,如 MIRROIR_KEYSTROKE_DELAY_US。所有可用的键请参考 TimingConstants.swift。
📚 详细文档
| 文档名称 | 说明 | |---|---| | 工具参考 | 所有 32 种工具、参数和输入工作流程 | | 常见问题解答 | 安全、焦点窃取、键盘布局等问题 | | 安全说明 | 威胁模型、终止开关和建议 | | 权限设置 | 故障关闭权限模型和配置文件 | | 已知限制 | 焦点窃取、键盘布局差距、自动更正等问题 | | 组件检测 | 组件定义、校准和检测流程 | | 编译技能 | 零 OCR 技能回放 | | 测试说明 | 模拟镜像、集成测试和 CI 策略 | | 故障排除 | 调试模式和常见问题 | | 贡献指南 | 如何添加工具、命令和测试 | | 技能市场 | 技能格式、插件发现和创作 |
📄 许可证
本项目采用 Apache-2.0 许可证。
💻 使用示例
可将以下示例粘贴到 Claude Code、Claude Desktop、ChatGPT、Cursor 或任何 MCP 客户端中:
Open Messages, find my conversation with Alice, and send "running 10 min late".
Open Calendar, create a new event called "Dentist" next Tuesday at 2pm.
Open my Expo Go app, tap "LoginDemo", test the login screen with
test@example.com / password123. Screenshot after each step.
Start recording, open Settings, scroll to General > About, stop recording.
Scan to join WeChat group