mcpField
I
iphone-mirroir-mcp

iphone-mirroir-mcp

本地服务
github.com/jfarcand开发工具2691 天前更新

关于 iphone-mirroir-mcp

iphone-mirroir-mcp 是通过 macOS iPhone Mirroring 控制真实 iPhone 的 MCP 服务,面向需要自动化应用流程或测试的 Agent 与开发者。它结合屏幕识别和触控操作,无需编写固定坐标脚本。

主要功能

  1. 01读取屏幕文字与点击目标
  2. 02点击、滑动和输入文字
  3. 03导航系统界面与应用
  4. 04OCR 与可选图标检测
  5. 05探索应用并生成技能

适用场景

  1. 01测试 iOS 应用登录流程
  2. 02浏览设置并截取屏幕
  3. 03生成可重复使用的应用流程技能
  4. 04执行冒烟测试或教程演示

MCP 相关

该 MCP 服务向兼容的 MCP 客户端提供 38 个工具,用于通过 macOS iPhone Mirroring 查看和操作 iPhone,并支持 stdio 传输。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"jfarcand-iphone-mirroir": {
"command": "npx",
"args": [
"-y",
"iphone-mirroir-mcp"
]
}
}
}
启动命令npx -y iphone-mirroir-mcp

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

安装包
npmiphone-mirroir-mcp0.4.1

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

mirroir-mcp

mirroir-mcp

npm version Build Install Installers MCP Compliance License macOS 15+ Discord

为你的 AI 配备眼睛、双手和一部真正的 iPhone。这款 MCP 服务让任何 AI Agent 都能通过 macOS iPhone Mirroring 查看屏幕、点击需要的内容,并自行摸索其余操作。实验性支持 macOS 窗口。38 种工具,兼容任何 MCP 客户端。

愿景:既能测试,也能游玩的 Agent

mirroir 正在为游戏构建基于游戏类型的覆盖能力。游戏分为两个界面。外壳——菜单、商店、装备配置、设置、胜负画面——是普通的带文本标签 UI,现有技能已经能够操作。场景——游戏区域——则是由视觉驱动的循环,Agent 每次通过一次触控推进一步。务实的目标是游戏 QA 冒烟测试、教程演练和脚本化演示,而非实时游玩:iPhone Mirroring 只提供单个指针,因此双摇杆和快节奏游戏仍无法触及(参见游戏)。

减少 Token 消耗让场景循环变得经济可行。屏幕截图约占 Agent 成本的 90%,因此可通过 describe_screen 读取包含丰富文本的外壳界面,无需图像;而在无法避免截图时,区域/缩放捕获选项可减少每帧图像的成本。在游戏区域,视觉模式下的 describe_screen 会通过 embacle 将画面发送给大模型;在一场正在进行的 Brawl Stars 对局中测得,每帧消耗约 24k 提示词 Token,耗时 3–14 s;GitHub Copilot 会将其计为一次 Claude Sonnet 5.5 高级请求。

该路线图按 Gaming Surface A–E 跟踪——先交付外壳覆盖能力;在真实设备上测量场景循环后,再扩大范围。

要求

安装

/bin/bash -c "$(curl -fsSL https://mirroir.dev/get-mirroir.sh)"

或通过 npx 安装:

npx -y mirroir-mcp install

或通过 Homebrew 安装:

brew tap jfarcand/tap && brew install mirroir-mcp

首次截屏时,macOS 会提示授予屏幕录制和辅助功能权限。请同时授予这两项权限。

各客户端的配置
Claude Code
claude mcp add --transport stdio mirroir -- npx -y mirroir-mcp
GitHub Copilot(VS Code)

从 MCP 服务库安装:在 Extensions 视图中搜索 @mcp mirroir,或将其添加到 .vscode/mcp.json:

{
  "servers": {
    "mirroir": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "mirroir-mcp"]
    }
  }
}
Cursor

将其添加到项目根目录下的 .cursor/mcp.json:

{
  "mcpServers": {
    "mirroir": {
      "command": "npx",
      "args": ["-y", "mirroir-mcp"]
    }
  }
}
OpenAI Codex
codex mcp add mirroir -- npx -y mirroir-mcp

或添加到 ~/.codex/config.toml:

[mcp_servers.mirroir]
command = "npx"
args = ["-y", "mirroir-mcp"]
从源代码安装
git clone https://github.com/jfarcand/mirroir-mcp.git
cd mirroir-mcp
./mirroir.sh

在 .mcp.json 中使用二进制文件的完整路径:<repo>/.build/release/mirroir-mcp。

## 工作原理

每次交互都遵循同一个循环:观察、推理、行动。describe_screen 会向 AI 提供屏幕上的所有文本元素及其点击坐标(眼睛)。LLM 决定下一步该做什么(大脑)。tap、type_text、swipe 执行操作(双手)——然后循环回到观察。无需脚本,无需坐标,只需表达意图。

除基础功能外,服务还提供更高级的导航和生命周期工具:press_back 通过 OCR 点击“<”形箭头返回(并在必要时回退到标准位置),press_home/press_app_switcher/spotlight 执行系统手势,scroll_to 滚动屏幕,直到目标文本变为可见,reset_app 通过 App Switcher 强制退出应用,set_network 通过“设置”切换网络连接,measure 则测量某个操作让目标元素显示出来所需的时间。多目标设置可使用 list_targets/switch_target 在多个窗口自动化端点之间切换。可通过 record_step、save_compiled(编译后重放)和 calibrate_component(针对实时屏幕测试组件定义)编写技能。完整的 38 个工具请参阅工具参考。

描述你的应用

mirroir 可以盲目探索任何 iOS 应用,但如果你告诉它要期待什么,效果会更好。编写 APP.md 文件,mirroir 就会在开始探索前读取该文件:

---
app: Santé
archetype: dashboard
obstacle_mode: auto
---

## Structure
Dashboard with 4 tabs: Résumé, Partage, Parcourir, Profil.

## Résumé Tab
- Summary cards for health metrics that drill down to charts
- Cards often show "Aucune donnée" on test devices

## Obstacles
- Health Access permission → tap "Autoriser"
- Notification permission → tap "Ne pas autoriser"

## Skip
- Supprimer les données de Santé
- Réinitialiser

目前代码实际使用的内容:archetype 会覆盖配方自动检测;当 obstacle_mode: auto 时,obstacles 会自动关闭;skip 会与 permissions.json.skipElements 合并;tabs(内联定义或作为一个章节)会作为高优先级目标注入;生成技能时,Structure、标签页正文和 Tips 会成为 AI 上下文。

完整的字段列表、加载器解析规则和权限系统桥接方式,请参阅 APP.md 规范。三层模式协同工作——元素(行的外观)、屏幕(页面布局的含义)和应用(开发者了解的信息)。模式与技能介绍了完整的系统。

示例

将以下任意内容粘贴到 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
[email protected] / password123. Screenshot after each step.
Start recording, open Settings, scroll to General > About, stop recording.

游戏

通过 iPhone Mirroring,游戏可以使用三种控制方式:touch 可在多次调用之间持续按住手指,以操作虚拟摇杆和长按(begin、move、end);hold_keys 可在拖动鼠标右键时持续按住 w 等按键,适用于会切换到键盘和鼠标控制的游戏,例如 Roblox;pinch 和 rotate 可在使用手势识别器的 UI 中执行双指缩放和旋转。Mirroring 向应用提供的是单指针触控,因此仅支持触控的游戏无法接收两个彼此独立的手指输入——实测结果请参阅游戏与多点触控。

屏幕智能

describe_screen 是 AI 的眼睛。三个后端协同工作,为 Agent 完整呈现屏幕内容,包括文本、图标和语义 UI 结构。

Apple Vision OCR(默认)

默认后端使用 Apple 的 Vision 框架检测屏幕上的所有文本元素,并返回精确的点击坐标。速度快、在本地运行,无需 API 密钥或外部服务。

图标检测(YOLO CoreML)

纯文本 OCR 会漏掉按钮、开关、标签栏图标和活动圆环等非文本 UI 元素。将 YOLO CoreML 模型(.mlmodelc)放入 ~/.mirroir-mcp/models/,服务会在启动时自动检测并将图标检测结果与 OCR 文本合并。AI 因此可以获得纯文本 OCR 无法识别的元素的点击目标。

模式ocrBackend 设置行为
自动检测(默认)"auto"如果已安装模型,则使用 Vision + YOLO;否则仅使用 Vision
仅 Vision"vision"仅使用 Apple Vision OCR 文本
仅 YOLO"yolo"仅使用 CoreML 元素检测
两者"both"始终合并两个后端(无模型时回退到 Vision)
AI 视觉模式(embacle)

除了本地 OCR 外,describe_screen 还可以将屏幕截图发送给 AI 视觉模型,由模型从语义层面识别 UI 元素,例如卡片、标签页、按钮、图标和导航结构,而不只是识别原始文本。这能为 Agent 提供更丰富的上下文,尤其适用于布局复杂的屏幕。

embacle 运行时通过 Rust FFI 直接嵌入 mirroir-mcp 二进制文件中。describe_screen 会在进程内调用嵌入式运行时,无需单独的服务、网络往返或额外配置。FFI 层(EmbacleFFI.swift → libembacle.a)负责初始化、聊天补全请求,以及跨越 Swift/Rust 边界的内存管理。

embacle 通过已完成身份验证的 CLI 工具(GitHub Copilot、Claude Code)路由视觉请求,因此无需单独管理 API 密钥。如果你订阅了 Copilot 或 Claude Code,即可直接使用。

安装
brew tap dravr-ai/tap
brew trust --tap dravr-ai/tap # recent Homebrew refuses to load untrusted taps
brew install embacle          # CLI tools (embacle-server, embacle-mcp)
brew install embacle-ffi      # Rust FFI static library (libembacle.a)

两者均为可选项。如果没有 embacle-ffi,构建会链接到 Apple Vision,且 describe_screen 会使用本地 OCR。

然后从源代码重新构建 mirroir-mcp(或通过 Homebrew 重新安装),使二进制文件链接到 libembacle.a:

# From source
swift build -c release

# Or via Homebrew (rebuilds automatically)
brew reinstall mirroir-mcp
零配置启用

当 embacle FFI 链接到二进制文件中时,screenDescriberMode 默认值为 "auto",会自动解析为视觉模式。无需更改设置:安装 embacle-ffi 并重新构建后,describe_screen 就会开始使用 AI 视觉。

即使 embacle 可用,也可以显式设置为 "ocr",以强制使用本地 OCR:

// .mirroir-mcp/settings.json
{
  "screenDescriberMode": "ocr"
}

所有可用设置请参阅配置。

技能

当你发现自己反复执行相同的 Agent 工作流时,可以将其整理为技能。技能是 SKILL.md 文件,其中包含 AI 要遵循的编号步骤,并能适应布局变化和意外对话框。像 Tap "Email" 这样的步骤会使用 OCR,不依赖硬编码坐标。

将文件放在 ~/.mirroir-mcp/skills/(全局)或 <cwd>/.mirroir-mcp/skills/(项目本地)。

APP.md

描述应用的结构,以指导探索过程;请参阅上文的描述你的应用和完整的 APP.md 规范。将 APP.md 文件放在 ~/.mirroir-mcp/skills/ 中,或放在 mirroir-skills 仓库的 patterns/apps/ 目录中。

---
version: 1
name: Commute ETA Notification
app: Waze, Messages
tags: ["workflow", "cross-app"]
---

## Steps

1. Launch **Waze**
2. Wait for "Où va-t-on ?" to appear
3. Tap "Où va-t-on ?"
4. Wait for "${DESTINATION:-Travail}" to appear
5. Tap "${DESTINATION:-Travail}"
6. Wait for "Y aller" to appear
7. Tap "Y aller"
8. Wait for "min" to appear
9. Remember: Read the commute time and ETA.
10. Press Home
11. Launch **Messages**
12. Tap "New Message"
13. Type "${RECIPIENT}" and select the contact
14. Type "On my way! ETA {eta}"
15. Press **Return**
16. Screenshot: "message_sent"

${VAR} 占位符会从环境变量中解析。${VAR:-default} 用于提供回退值。

技能市场

从 jfarcand/mirroir-skills 安装可直接使用的技能:

git clone https://github.com/jfarcand/mirroir-skills ~/.mirroir-mcp/skills

从探索到 CI

generate_skill 工具可让 AI Agent 探索应用并生成 SKILL.md 文件。它使用广度优先搜索(BFS)将应用作为导航图进行遍历:屏幕是节点,可点击元素是边。探索器会描述每个屏幕,将元素与组件定义进行匹配,以决定点击哪些元素;随后访问子屏幕,并通过返回箭头返回。重复屏幕会通过结构指纹识别并跳过。有关探索器如何将原始元素解读为结构化 UI 组件,请参阅下文的组件检测。

探索器按视口逐步工作:校准页面长度后,它会根据当前视口制定计划,按从上到下的顺序点击元素,然后向下滚动以显示更多内容,并为每个新视口重新制定计划。此方法兼容 OCR 和 AI 视觉描述器。传入 seed 可确保不同运行之间的排序具有确定性。

探索范围有限,在大型应用中不会发现所有可到达的屏幕。深度、屏幕数量和时间限制可让运行保持在实用范围内。对于特定流程,可提供 goal 来聚焦遍历范围。

graph TD
    A["Launch App"] --> B["Describe Screen"]
    B --> C{"Calibrated?"}
    C -- No --> D["Scroll Full Page"]
    D --> E{"skip_calibration?"}
    E -- No --> F["Component Detect +\nClassify + Validate"]
    E -- Yes --> G["Classify Elements\nDirectly"]
    F --> H["Build Plan"]
    G --> H
    C -- Yes --> H

    H --> I{"Untried\nElements?"}
    I -- Yes --> J["Tap Element"]
    I -- No --> K["Return to Root"]

    J --> M["Describe +\nClassify Edge"]
    M --> N{"Transition"}
    N -- new screen --> O["Add to Frontier"]
    O --> P["Backtrack"]
    N -- revisited/dead --> P

    P -- push: tap back --> H
    P -- modal: tap close --> H
    P -- tab: tap prev --> H

    K --> Q{"Frontier\nEmpty?"}
    Q -- No --> R["Next Frontier\nScreen"]
    R --> B
    Q -- Yes --> S["Generate SKILL.md"]
生成

两种模式:自主探索(BFS)和引导式会话(手动逐步操作)。

自主 BFS 探索——Agent 自行探索:

Explore the Settings app and generate a skill that checks the iOS version.

这会在底层调用 generate_skill(action: "explore", app_name: "Settings", goal: "check iOS version")。探索器会启动应用,从根屏幕开始运行 BFS,并为发现的路径输出一个 SKILL.md。

参数默认值描述
app_name必填要探索的应用
goal无将探索重点放在特定流程上(例如“查看软件版本”)
goals无目标数组——每个目标对应一个 SKILL.md
max_depth6BFS 最大深度
max_screens30要访问的最大屏幕数
max_time300停止前的最长秒数
strategyauto"mobile"(默认)、"social"(Reddit、Instagram、TikTok)或 "desktop"(macOS 窗口)
explorerbfs探索算法:"bfs"(广度优先,默认)或 "dfs"(深度优先)
skip_calibrationfalse校准时跳过组件检测。仍会执行滚动。适用于使用能生成清晰语义元素的 AI 视觉描述器
seedrandom用于确定性探索排序的整数种子。相同的种子会生成相同的点击序列
freshtrue丢弃持久化的导航图并从头开始探索。设为 false 可进行增量探索

引导式会话——AI 手动导航并捕获每个屏幕:

  1. generate_skill(action: "start", app_name: "MyApp") — 启动应用并对首个屏幕执行 OCR
  2. 使用 tap/swipe/type_text 进行导航,然后调用 generate_skill(action: "capture") 记录每个屏幕
  3. generate_skill(action: "finish") — 将捕获的屏幕整理为 SKILL.md
测试

从 CLI 确定性地运行技能——整个过程不涉及 AI。YAML 技能会运行自身步骤。SKILL.md 的正文是供 AI 阅读的说明,因此会运行 .compiled.json 中记录的步骤;MCP 客户端首次运行该技能时会生成此文件(调用 get_skill,然后在每个步骤后调用 record_step,最后调用 save_compiled)。未编译的 SKILL.md 会因缺少该文件而被拒绝;自编译后编辑过的文件会因过期而被拒绝;不带技能参数运行时,任何没有编译文件的 SKILL.md 都会被跳过:

mirroir test apps/settings/check-about
mirroir test --junit results.xml --verbose        # JUnit output
mirroir test --dry-run apps/settings/check-about    # validate without executing
选项描述
--junit <path>写入 JUnit XML 报告
--report-json <path>写入 Playwright JSON 报告文档——mirroir-run 会读取此格式
--capture <key>将每个技能最终屏幕的 OCR 文本附加到 --report-json 文档中的 cross_surface.<key> 下
--screenshot-dir <dir>保存失败截图(默认:./mirroir-test-results/)
--timeout <seconds>wait_for 超时时间(默认:15)
--verbose显示逐步详细信息
--dry-run解析并验证,但不执行
--no-compiled跳过已编译的技能,强制执行完整 OCR
--no-auto-recompile跳过对已发生偏移的已编译技能进行自动重新编译
--agent <name>对失败步骤进行 AI 诊断(参见 AI 辅助诊断)

退出代码 0 = 全部通过,1 = 任一失败。所有步骤都被跳过的技能会视为失败;解析器无法读取某个步骤(例如未知动词或格式错误的 target:)时,该技能会在任何操作运行前被拒绝,即使使用 --dry-run 也不例外。

默认情况下,如果已编译技能的屏幕指纹发生偏移,CLI 会自动重新编译;--no-auto-recompile 会禁用此功能并继续使用过期坐标。

已编译技能

编译一次技能,即可记录坐标和时序。回放时无需 OCR——一个包含 10 个步骤的技能,耗时可从 5 秒以上降至不到 1 秒。

mirroir compile apps/settings/check-about        # compile
mirroir test apps/settings/check-about            # auto-detects .compiled.json
mirroir test --no-compiled check-about            # force full OCR

mirroir compile 会在设备上运行技能的步骤,重新记录坐标。对于 SKILL.md,这些步骤来自其现有的 .compiled.json,因此首次编译 SKILL.md 始终通过 MCP 客户端完成。

AI Agent 会在首次 MCP 运行时自动编译技能。详情请参阅已编译技能。

AI 辅助诊断

测试步骤失败时,传入 --agent,即可获取 AI 对问题原因的诊断和修复建议:

mirroir test --agent gpt-5.3 apps/settings/check-about
mirroir test --agent claude-sonnet-5-5 apps/settings/check-about
mirroir test --agent ollama:llama3 apps/settings/check-about
mirroir test --agent embacle apps/settings/check-about

内置 Agent:

Agent提供方API 密钥
gpt-5.3OpenAIOPENAI_API_KEY
claude-opus-5-5、claude-sonnet-5-5、claude-haiku-5-5AnthropicANTHROPIC_API_KEY
ollama:<model>Ollama(本地)无
embacle、embacle:claudeembacle-serverCLI Agent 密钥

请求到达 Agent 的方式:Anthropic、OpenAI 和 Ollama Agent 始终调用各自的 HTTP API。对于模型为纯 Copilot 模型 ID(embacle 会发送 claude-sonnet-5.5)的 embacle Agent,如果已链接 libembacle 且 agentTransport 不为 "http",则在嵌入式 embacle 运行时中运行;否则通过 HTTP 发送到 base_url。采用 embacle-server 的 runner:model 格式的 embacle 模型始终通过 HTTP 发送,因为嵌入式运行时仅支持 Copilot runner:embacle:claude 会发送 claude:sonnet,选择 embacle-server 的 Claude Code runner,因此需要 embacle-server 监听 http://localhost:3000。当模型为纯 runner 名称(claude、copilot 等)时,表示该 runner 的默认模型,且同样通过 HTTP 发送。

自定义 Agent 以 YAML 配置文件的形式定义,存放在 <cwd>/.mirroir-mcp/agents/<name>.yaml(项目本地)或 ~/.mirroir-mcp/agents/<name>.yaml(全局;项目本地配置优先)。将文件的 <name> 传给 --agent。

配置文件有两种运行模式:

mode: api — 调用云端或本地 HTTP 端点:

# ~/.mirroir-mcp/agents/my-gpt.yaml
mode: api
provider: openai          # anthropic | openai | ollama | embacle
model: gpt-5.3
api_key_env: OPENAI_API_KEY
base_url: https://api.openai.com
system_prompt: "You are a terse iOS automation debugger."
max_tokens: 4096

mode: command — 运行本地 CLI 进程(例如已通过身份验证的 claude -p / copilot -p,或自定义脚本)。诊断负载通过两种方式传递:如果任何 args 条目包含 ${PAYLOAD},就会在该处替换为 JSON 负载;否则会通过管道传入命令的标准输入:

# ~/.mirroir-mcp/agents/claude-cli.yaml
mode: command
command: claude
args: ["-p", "${PAYLOAD}"]
system_prompt: "Diagnose the failed step and reply with JSON."
键模式描述
mode两者均适用api(默认)或 command
providerapianthropic、openai、ollama 或 embacle
modelapi模型标识符
api_key_envapi存放 API 密钥的环境变量
base_urlapi端点基础 URL
commandcommand要启动的可执行文件(通过 PATH 解析,或使用绝对路径)
argscommand参数数组;${PAYLOAD} 会替换为 JSON 负载
system_prompt两者均适用随请求发送的系统提示词
max_tokens两者均适用响应的 token 预算
没有 API 密钥?使用 embacle

embacle 会通过已通过身份验证的 CLI 工具(GitHub Copilot、Claude Code 等)路由请求——无需单独的 API 密钥:

brew tap dravr-ai/tap && brew trust --tap dravr-ai/tap && brew install embacle
mirroir test --agent embacle my-skill
### 模式系统

探索器使用三层模式系统来理解 iOS 应用——同一声明式概念在不同规模上的体现:

  • 元素模式(patterns/elements/)——34 个定义,用于匹配行级 UI 组件(表格行、标签栏、切换开关、摘要卡片)。每个定义都指定匹配规则、交互行为和分组逻辑。
  • 屏幕模式(patterns/screens/)——7 个原型配方,根据元素组合识别屏幕级导航模型。校准期间会自动检测,也可通过 APP.md 中的 archetype 声明。
  • 应用模式(patterns/apps/)——包含结构、障碍、跳过列表和原型声明的 APP.md 文件,是开发者的事实来源。

内置原型:settings-list、dashboard、social-feed、content-grid、conversation-list、utility-display、detail-form。

将自定义模式放在 ~/.mirroir-mcp/components/(元素)、~/.mirroir-mcp/recipes/(屏幕)或 mirroir-skills 仓库中。

视觉指示符

AI 视觉描述器会用语义方式描述 UI 元素(“Activité chevron”),而非逐字符描述(“Activité” + “>”)。vision-indicators.md 文件会将这些描述映射到兼容 OCR 的字符,以便组件流水线在两种后端上保持一致:

## Indicators
- chevron: >
- dismiss: ×
- back: <

当视觉元素以已映射的后缀结尾时(例如“Entraînements chevron”),规范化器会将其拆分为两个元素:“Entraînements” + “>”。将 vision-indicators.md 放在组件定义文件旁边。

完整的定义格式、匹配规则参考和检测流水线,请参阅组件检测。

随处回放:mirroir-run

mirroir-mcp 操控 iPhone——结合 AX、OCR 和 BFS 探索。mirroir-run 可在 Web、进程、HTTP 和 iOS 界面上回放 .mirroir/ SkillStep 场景:通过 Playwright 操作 Web,原生运行子进程和 HTTP 请求,并将每个 target: { kind: ios } 代码块交给连接了 iPhone Mirroring 的 Mac 上的 mirroir-mcp test。两者采用相同的 SkillStep 语法,因此一个场景就能同时操控浏览器和手机,并检查它们显示的内容是否一致。它是一个独立的 Rust 二进制程序(本仓库中的 runner/);Web、进程和 HTTP 场景可在 Linux CI 上运行,无需依赖 macOS。了解这两个二进制程序如何协作:在同一场景中使用 Web 和 iOS。

在任意仓库中放入 .mirroir/ 目录,mirroir-run 就会从工作目录中发现它:

your-app/
└── .mirroir/
    ├── mirroir.yaml          # the plan: must-pass / nice-to-pass entries
    └── apps/<sample>/
        ├── SAMPLE.md         # how to boot the app under test
        ├── APP.md            # structure, obstacles, skip lists
        └── scenarios/*.yaml  # SkillStep flows to replay
cd your-app
mirroir-run                          # discover .mirroir/, replay the must-pass plan
mirroir-run --scenarios all          # include nice-to-pass entries too

每个计划条目要么指向一个 local: 示例树,要么通过实例级的 vars: 和 boot: 扩展共享的原型(archetypes: ["<pack>/<name>@<ver>"])。原型只需定义一次可复用的应用形态——例如 AI 聊天控制台——然后为每个应用配置参数。

iOS 部分的来源。 generate_skill … emit=true(在 finish 或 explore 时)会将捕获的流程写入 .mirroir/apps/<app>/,生成一个可运行的 iOS 部分:一个 target: { kind: ios } 场景、一个声明该场景的 SAMPLE.md,以及一个 must_pass 计划条目。mirroir-run 会将每个 ios 代码块交给连接了 iPhone Mirroring 的 macOS 主机上的 mirroir-mcp test,并在其他任何主机上按名称拒绝运行。请从使用该工具的仓库中运行 MCP(或传入 output_dir),以便目录树写入正确的 .mirroir/;不允许写入 ~/.mirroir(运行器的包主目录)。一个场景可以包含两部分:一个 web 代码块、一个 ios 代码块,以及一个 cross_surface: 步骤;其 captures: 会实时记录页面抓取内容和手机的最终屏幕,然后进行比较——运行检查门槛的流程会生成两部分内容。请参阅 runner/docs/mirroir-dotfile.md。

Web 步骤会编译为 Playwright .spec.ts,并在 chromium、firefox 和 webkit 上运行。选择器支持三种解析方式:原始 CSS、Playwright 引擎前缀(role=button[name="Save"]、text=Welcome、xpath=…),或由 Playwright 按自身优先级解析的简单标签——角色、标签、占位符、data-test、可见文本。每个编译后的 spec 还会收集未捕获的页面错误和失败的响应,因此即使所有定位器都已解析成功,只要页面抛出错误,测试仍会失败。spec、配置以及失败时的跟踪记录、视频和截图都会保存在 target/playwright/<sample>/<scenario>/ 下。进程和 HTTP 步骤会原生执行;LLM 裁判步骤会根据预期信号为 Agent 响应评分,漂移检测则会捕获输出相对于基线的偏差。

模式命令
根据语法验证场景mirroir-run --validate scenario.yaml
将 Playwright spec 编译到磁盘mirroir-run --emit playwright scenario.yaml
端到端运行单个场景mirroir-run --run-scenario scenario.yaml
启动示例目录并运行其中的场景mirroir-run --sample .mirroir/apps/foo
将 iOS 代码块交给指定的 mirroir-mcpMIRROIR_MCP_BIN=/path/to/mirroir-mcp mirroir-run …
独立执行文本漂移检查mirroir-run --diff-text a.txt b.txt
安装 mirroir-run
# crates.io
cargo install mirroir-run

# Homebrew
brew install jfarcand/tap/mirroir-run

每个 runner-v* 版本均附带适用于 macOS(Intel + Apple Silicon)、Linux(gnu + musl)和 Windows 的预编译二进制文件。在 Windows 上,尚未实现子进程终止信号,因此不支持进程场景。场景语法、SAMPLE.md 架构、裁判配置文件和 CI 集成信息,请参阅 runner/docs/。

安全

让 AI 访问手机,需要采取纵深防御。mirroir-mcp 在每一层都采用默认拒绝策略。

  • 工具权限 — 如果没有配置文件,只会开放 12 个只读工具(screenshot、describe_screen、start_recording、stop_recording、get_orientation、status、check_health、list_targets、list_skills、get_skill、calibrate_component、classify_screen)。所有会修改状态的工具——包括 press_back——都会对 MCP 客户端完全隐藏,因此客户端根本看不到它们。
  • 应用拦截 — permissions.json 中的 blockedApps 可阻止 AI 与 Wallet 或 Banking 等敏感应用交互,即使允许使用会修改状态的工具也不例外。
  • 无需 root 权限 — 作为普通用户进程运行,使用 macOS CGEvent API。无需守护进程、内核扩展或 root 权限,只需启用辅助功能权限。
  • 紧急停止开关 — 关闭 iPhone Mirroring 即可立即停止所有输入。
// ~/.mirroir-mcp/permissions.json
{
  "allow": ["tap", "swipe", "type_text", "press_key", "launch_app"],
  "deny": [],
  "blockedApps": ["Wallet", "Banking"]
}

完整的威胁模型请参阅权限和安全。

命令行工具

录制器

将交互录制为技能文件:

mirroir record -o login-flow.yaml -n "Login Flow" --app "MyApp"
Doctor

验证设置:

mirroir doctor
mirroir doctor --json    # machine-readable output
配置

为非美国键盘设置键盘布局:

mirroir configure

更新

# curl installer
/bin/bash -c "$(curl -fsSL https://mirroir.dev/get-mirroir.sh)"

# npx
npx -y mirroir-mcp install

# Homebrew
brew upgrade mirroir-mcp

# From source
git pull && swift build -c release

卸载

# Homebrew
brew uninstall mirroir-mcp

# From source
./uninstall-mirroir.sh

配置

所有设置都保存在 settings.json 中,可位于项目本地(.mirroir-mcp/settings.json)或全局位置(~/.mirroir-mcp/settings.json)。项目本地设置优先于全局设置。每项设置都有对应的环境变量(例如 MIRROIR_SCREEN_DESCRIBER_MODE)。

{
  "screenDescriberMode": "auto",
  "agent": "embacle",
  "ocrBackend": "auto",
  "keystrokeDelayUs": 15000,
  "explorationMaxScreens": 30
}

AI 系统提示词内置于程序中;如需覆盖,可将 diagnosis.md 或 screen-describe.md 放入项目本地的 .mirroir-mcp/prompts/ 或全局的 ~/.mirroir-mcp/prompts/ 中——详见系统提示词。

所有 40 多项设置的详情请参阅配置参考,涵盖屏幕智能、输入时序、滚动行为、探索预算、AI 提供商和键盘布局。

文档

工具参考全部 38 个工具、参数和输入工作流
配置全部设置:屏幕智能、输入时序、探索、AI 提供商
常见问题安全、焦点窃取、键盘布局、embacle/视觉模式
安全威胁模型、紧急停止开关和建议
权限默认拒绝的权限模型和配置文件
已知限制焦点窃取、键盘布局缺口、自动更正
模式与技能元素模式、屏幕配方、APP.md 应用描述和检测流程
探索新应用引入新应用的分步指南——APP.md、权限、组件、探索目标
YOLO 图标检测推荐的 YOLO 模型、CoreML 设置和配置
已编译技能零 OCR 技能重放
测试FakeMirroring、集成测试和 CI 策略
同一场景中的 Web 和 iOSmirroir-run 如何将 iOS 区块交给 mirroir-mcp,以及 cross_surface 如何比较浏览器与手机
跨界面重放mirroir-run 场景语法、.mirroir/ 计划、SAMPLE.md、评判配置、CI
故障排除调试模式和常见问题
贡献如何添加工具、命令和测试
技能市场技能格式、插件发现和编写

社区

加入 Discord 服务器,提问、分享技能并交流想法。

贡献

欢迎贡献。提交补丁即表示你同意 贡献者许可协议——你的 Git 提交元数据将作为电子签名。

限制登记表

本仓库通过 llm-registre 强制确保内容诚实:生产代码中的延期表述(“尚未接通”“后续会处理”“暂时返回”)会被 CI 禁止,除非该行带有 LIMITATION(registre#n): 标记,注明受限事项并指向项目私有登记表中的一个问题。同一组检查还会在推送前和 CI 中强制执行 500 行文件上限和内联 clippy 允许列表。运行 rg "LIMITATION\(registre#" 即可完整列出代码库中明确尚未实现的内容。克隆后,运行 git submodule update --init 并安装 ripgrep;工作流请参阅 CONTRIBUTING.md。


为什么叫“mirroir”?——这是 miroir(镜子)的旧法语拼写。这是对作者根源的致意,并非拼写错误。

评论

支持 Markdown

第一次接触 MCP?

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

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