关于 simulator-use
simulator-use 是面向编码 Agent 的 iOS Simulator MCP 服务和 CLI,可构建、运行及测试 Xcode 项目,并通过屏幕元素文本执行交互。它还提供日志、崩溃信息、视频录制和云端 iPhone 操作。
主要功能
- 01构建、安装并启动 Xcode 项目
- 02以精简文本读取界面元素
- 03按标签执行点击、输入和滚动
- 04运行 XCTest 与 XCUITest
- 05读取应用日志并查看崩溃
- 06录制屏幕视频并操作云端 iPhone
适用场景
- 01在 iOS Simulator 中验证应用界面流程
- 02按单个测试用例运行并定位失败
- 03检查应用运行日志和崩溃位置
- 04从没有 Xcode 的机器连接云端 iPhone
MCP 相关
该项目提供 MCP 服务和 CLI,二者共享工具定义。MCP 客户端可通过工具构建和控制 Simulator 应用、读取界面与日志,并运行测试;也可使用云端 iPhone。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
12收录的工具列表 · 更新于 3 天前
此工具无需参数。
详细介绍
simulator-use
让 AI Agent 使用 iOS Simulator 的最快、最省 token 的方式。 simulator-use 让 Claude Code、Codex、Cursor 和任何其他 MCP 客户端都能使用一部手机:它会构建并运行你的 Xcode 项目,以几行文本读取屏幕,按标签点击和输入,并逐个运行测试用例。它自带的原生引擎直接与 Simulator 通信,因此读取整个屏幕约需 250 ms,点击不到 1 毫秒即可发出;而每次调用都要启动辅助程序的工具需要 1.5 到 3 秒。免费开源(MIT),可在任何安装了 Xcode 的 Mac 上使用;没有 Xcode 的 Linux、Windows 或 Mac 也可通过云端 iPhone 使用。
- **快速:**读取整个屏幕约需 250 ms,点击不到 1 ms 即可发出,截图约需 60 ms(在 M6 Mac mini 上于 2026 年 10 月测得)。
- **省 token:**每个 Agent 可使用的元素占一行,不含其他内容;提供十几个简短描述的工具。
- **功能完整:**支持逐个用例构建、安装、启动、运行 XCTest 和 XCUITest,查看日志和崩溃信息、录制视频、处理权限提示,以及使用 iPhone 和 iPad。
- **持续改进:**每周发布更新,改进依据是每天数千次会话。
- **随处可用:**运行
npx simulator-use cloud start,即可让任何设备使用配备 Xcode 的云端 iPhone。
它可以构建、运行和测试 Xcode 项目,读取并操作任何应用(SwiftUI、UIKit、React Native)的屏幕,响应 iOS 权限提示,读取应用日志和崩溃信息,并录制视频。
Agent 看到的内容
Demo · Sign In · iPhone 17 Pro (iOS 27.0)
textfield "Email" #email @201,194
securefield "Password" #password @201,246
switch "Remember me" #remember off @341,298
button "Sign In" #signIn @201,350
text "Not signed in" #status @201,402
tabs: Login (selected) @158,822, Items @244,822
- 每个元素占一行,包含类型、标签、
#id(应用的辅助功能标识符)、状态和@x,y(以点为单位的中心坐标)。 - 组、按钮内的图标、滚动条、状态栏和键盘按键都会折叠隐藏。标签栏、滚动视图和键盘各占一行。
- 只列出可点击的内容。警告框、工作表、菜单或全屏视图若覆盖在前景,会隐藏其后的屏幕;iOS 自带的权限提示会作为应用上方的警告框读取。导航栏、标签栏或键盘下方的行会计为隐藏(位于上方、下方、左侧或右侧),不会列出。
- UIKit 中的网页视图(Capacitor、React Native 的 WebView、大多数应用内的登录页面)会逐点读取,其标题、文本、字段、复选框、按钮和链接都会像其他内容一样列出。由 SwiftUI 承载的网页视图、Safari 自带的页面、应用内浏览器、地图、游戏,以及 iOS 进程外选取器都没有可供辅助功能读取的内容。它们会以一行
unreadable显示其位置,让 Agent 知道需要截图并按坐标点击。 - 如果请求截图,图片会按点缩放,因此图片中的一个点就是可点击的一个点。
screenshot_file会将全分辨率屏幕保存为 PNG,供用户、报告或 App Store 使用;在云端模式下,它也会保存到你的设备上。 - 上方的登录屏幕约占 70 个 token。它对应的完整辅助功能树约占 40,000 个 token。
使用屏幕
ui_act 使用 ui_look 输出的相同词语执行步骤,按顺序运行,并回答发生了哪些变化:
ui_act steps: ["fill #email [email protected]", "fill #password secret1", "tap #signIn", "wait \"Welcome\""]
4 steps done in 4.5 s
changed: #email "[email protected]" · #password "•••••••" · #status "Welcome, [email protected]"
步骤:
| 步骤 | 执行内容 |
|---|---|
tap #id, tap "label", tap button "label", tap @x,y | 点击;开关会受到真实触摸 |
fill #id text | 聚焦字段、清空内容、输入文本,然后读取文本 |
type text | 在当前获得焦点的字段中输入文本 |
scroll down, scroll right @201,402 | 滚动屏幕或一个轮播 |
swipe left, swipe left "Row 3" | 滑动屏幕或一行(以显示 Delete) |
hold "Row 5" [seconds] | 长按,以显示上下文菜单 |
set #volume 75 | 将滑块设为某个百分比 |
back, home, key return | 返回按钮(或边缘滑动)、主屏幕按钮、按键 |
wait "Welcome" [seconds], gone "Loading" | 等待某内容出现或消失 |
每个步骤都会经过检查,因此不会静默成功:
- 输入的文本会从字段中读回。如果 iOS 的自动更正或智能标点更改了文本(
--变成—,'变成’),则会改为粘贴文本,iOS 会原样处理。如果字段中仍显示其他内容,则会停止调用并说明显示的内容。 - 可以输入任何语言的文本(Café、日语、emoji):美式键盘无法输入的内容会通过 Simulator 的剪贴板输入。
fill会拒绝任何非文本字段,因此按键不会落入仍处于焦点状态的字段。- 如果点击没有任何变化,等待 2.5 秒以接收权限提示等延迟响应后,会报告这一情况。点击无法读取的区域时,会说明无法检查。
- 如果目标尚未出现在屏幕上,会等待两秒让其出现,然后失败并提示下一步:“下方有 2 个元素:向下滚动”,或者在有警告弹窗出现时提示:“请先处理:点击 "Cancel" 或 "Open"”。
- 第一个失败的步骤会停止后续步骤,并返回当前屏幕。
- 新屏幕会完整返回;否则只返回发生变化的内容。
工具
| 工具 | CLI | 执行内容 |
|---|---|---|
app_run | simulator-use run | 在此处构建 Xcode 项目,安装并启动,然后返回首个屏幕;错误格式为 file:line;--xcode 26.6 使用另一个已安装的 Xcode 构建 |
devices | simulator-use devices | 列出这台 Mac 上的 Simulators,包括其运行时、UDID、状态和 Xcode |
device_use | simulator-use use "iPhone 17 Pro" | 选择其他工具使用的 Simulator 并启动它(一次只启动一个);深色模式、干净的状态栏 |
app_control | simulator-use app launch dev.example.app | install、launch(返回首个屏幕)、terminate、uninstall、open_url;grant、revoke 和 reset_permissions;location;手机的 appearance、locale、timezone、text_size 和干净的 status_bar |
ui_look | simulator-use look | 读取屏幕;find 保留匹配的行,screenshot 添加图片,screenshot_file 保存全分辨率 PNG,full 保存完整树 |
ui_act | simulator-use act "tap #signIn" ... | 按顺序执行步骤,并返回发生变化的内容 |
app_logs | simulator-use logs | 应用的打印输出及其自身的系统日志行;grep、wait_for、crashes |
tests_run | simulator-use test | 运行单元测试和 UI 测试;每个用例完成时逐一返回,统计数量,列出每个失败的 file:line 和耗时最长的测试;“0 tests ran”表示错误 |
screen_record | simulator-use record start | 开始或停止录制屏幕视频;停止时返回 MP4 |
job_status | simulator-use job | 等待长时间构建,最多 40 s,并返回结果或进度 |
job_cancel | simulator-use cancel | 停止任务 |
cloud | simulator-use cloud start | 在 NoMac 云端手机上执行 start、status、stop,之后所有工具都会在该手机上运行;run 会在一次调用中完成构建、测试和停止(参见 Cloud) |
MCP 服务和 CLI 使用同一份列表构建,因此二者始终一致。工具列表和说明会控制在 4,000 tokens 以内;测试会对此进行验证。
构建和运行
app_run 一次调用即可完成整个流程:查找项目(依次查找工作区、项目、XcodeGen 规范或 ios/),选择方案,为 Simulator 构建、安装、启动,并返回首个屏幕。
安装应用并回答首次启动时的提示(包括通知权限提示)后,应用权限即已授予,因此不会有提示阻碍 Agent;permissions: "ask" 会保留 iOS 的提示,以便测试。对于会打开其他应用的链接,open_url 会处理 iOS 的“要在……中打开吗?”提示。
Built Demo in 4.2 s, installed dev.simtap.demo.
Launched Demo in 3.9 s.
Demo · Sign In · iPhone 17 Pro (iOS 27.0)
textfield "Email" #email @201,194
...
- 构建失败时,只返回错误,例如
Sources/App.swift:49:37: error: ...,以及完整日志的路径。 - 每个文件夹(每个 git worktree)都会使用自己的 DerivedData 进行构建,因此重新构建是增量式的,worktree 之间也不会共享构建产物。
SIMULATOR_USE_CACHE_DIR会将其放在你保留的磁盘上,因此下一台机器上的构建也会是增量式的。 - 每次构建前,都会根据
project.yml重新生成 XcodeGen 项目(未发生更改时会跳过),因此新文件总会包含在项目中。 - 在同一文件夹中进行下一次调用时,无需传入参数。
env: "API_URL=http://127.0.0.1:8080 MODE=test"会像 Xcode 方案一样向应用提供这些变量(应用通过ProcessInfo读取);这些变量会在后续启动时继续保留,而env: ""会清除它们。- MCP 调用会在 40 秒内返回;耗时更长的构建会返回一个 job,
job_status会等待其完成。使用命令行时,simulator-use run会直接等待。 - 同一项目的两个构建不会同时运行,即使它们来自两个进程也是如此:第二个会指出正在构建它的进程。
- Expo、React Native、Flutter 和 Capacitor 项目尚不能构建;请先使用各自的工具构建,然后调用
app_control install。
测试
tests_run 会运行方案中的测试,并从 Xcode 的结果包中读取结果,而不是从滚动输出中读取:
Tests failed: 1 passed, 2 failed (3 in 35.3 s). Result bundle: .../tests-1792370825323.xcresult
DemoTests/SignInTests/testRejectsAShortPassword(): Tests/SignInTests.swift:12: XCTAssertEqual failed: ("Welcome, [email protected]") is not equal to ("Invalid email or password")
DemoTests/rejectsAnEmailWithoutAt(): Tests/SignInTests.swift:18: Expectation failed: ...
- 同时支持 XCTest 和 Swift Testing。
- 每个失败的测试都会以
only接受的格式命名,便于只重新运行该测试。 - “0 tests ran”(没有测试目标,或筛选条件未匹配到任何测试)属于错误,绝不算通过。
日志和崩溃
app_logs 显示应用本身输出的内容,而不是 Apple 框架在应用内部记录的数千行日志:
- 从
app_control启动应用时开始保留的print()输出。 - 从启动时开始流式传输的应用自身系统日志行(应用的子系统日志,或由其自身代码记录的日志)。macOS 只会将信息级别的日志行保留在内存中;Simulator 忙碌时,这些日志会在几秒内被丢弃,因此事后读取日志存储会漏掉它们。
grep也会搜索 Apple 的日志行,例如查找缺失的图像或布局警告。wait_for最多等待 25 秒,直到出现某一行,例如在点击按钮发起网络调用后等待。crashes会列出崩溃报告,显示崩溃线程直至你的代码(ItemsView.body.getter (App.swift:64)),并附上应用的最后输出,其中包含 Swift 自身的消息(App.swift:64: Fatal error: ...)。macOS 写入报告最长可能需要一分钟。
多个 Agent,共用一台 Mac
- 每个 Agent 都运行自己的 MCP 服务,并通过
device_use使用自己的 Simulator,以及自己的云端手机:一个 Agent 的cloud start不会切换另一个 Agent 的工具,一个 Agent 的cloud stop不会结束另一个 Agent 的手机会话;Agent 的服务结束时,其手机会话也会停止。在终端中输入的cloud start属于命令行自身。 - 在 Mac 上的所有 simulator-use 进程之间,Simulator 启动都不会重叠:在 8 GB Mac 上同时启动两个 Simulator 会导致系统使用交换空间数分钟。
SIMULATOR_USE_MAX_BOOTED会限制同时运行的数量;若请求启动另一个 Simulator,会先关闭其他 Simulator。- 在同一 Simulator 上执行的操作,在 Mac 上的所有 simulator-use 进程之间都会依次进行,因此两个 Agent 或两条命令的点击操作不会交错执行。
一次执行一条命令
通过 Shell 每次执行一条命令来运行 simulator-use 的 Agent,可使用相同的工具:
simulator-use use会记住设置:下一条命令会使用该 Simulator,即使有多个已启动的 Simulator 也一样。SIMULATOR_USE_STATE_DIR可更改 simulator-use 存放文件的位置(默认:临时文件夹中的 simulator-use)。- 每条命令都会等待自己的任务完成,因此无需跟踪任务。
simulator-use call <tool> '<json>'会按 MCP 名称调用工具,并输出一行 MCP 内容;失败时输出{"content":[...],"isError":true},图像则以 base64 形式输出:
$ simulator-use call ui_look '{"find":"Sign In"}'
{"content":[{"type":"text","text":"Demo · Sign In · iPhone 17 Pro (iOS 27.0)\nbutton \"Sign In\" #signIn @201,350"}]}
目前尚不支持的功能
- 读取由 SwiftUI 托管的网页视图、Safari 页面、应用内浏览器、Flutter 或游戏画布:它会说明这一点;使用截图并按点点击即可操作。
- 真机、Android、旋转至横向,以及捏合和多点触控。
- 读取应用通过辅助功能隐藏的文本:某些 React Native 应用会将测试 ID 设为标签,读取结果会指出标签看起来像这种情况。
安装
需要安装 Xcode 和 Simulator 运行时的 macOS,以及 Node 20 或更高版本。
没有 Mac? 如果你的 Agent 运行在 Linux、Windows 或云沙箱中,NoMac 可在云端提供一台真实的 Mac,配备 Xcode 和 iOS Simulator,并按分钟计费。
# Claude Code
claude mcp add simulator-use -- npx -y simulator-use mcp
# Codex
codex mcp add simulator-use -- npx -y simulator-use mcp
Claude Code 也可将其作为插件使用:/plugin install simulator-use --marketplace NoMac-app/simulator-use。
Cursor、Windsurf、VS Code 和其他支持 JSON 配置的客户端:
{
"mcpServers": {
"simulator-use": { "command": "npx", "args": ["-y", "simulator-use", "mcp"] }
}
}
其他客户端:运行 npx -y simulator-use mcp,将其作为 stdio 服务。它支持 MCP 2024-11-05 至 2026-07-28。
通过 Shell 操作的 Agent 也可以改用 CLI;软件包中的 skill/SKILL.md 不到 2 KB,便会教会它如何使用。
在 Shell 中运行:npx simulator-use look。
云端
如果这台机器无法运行 Simulator(Linux、Windows、云端 Agent),或者用于 CI,同一套工具会在 NoMac 上的云端 iPhone Simulator 中运行。NoMac 提供一台装有 Xcode 的 Mac,按分钟计费,每小时 $0.80:
simulator-use cloud start # signs in through a link the first time (or NOMAC_API_KEY), starts a phone (--device ipad for an iPad, --device iphone-pro-max for 6.9-inch App Store screenshots)
simulator-use run # every tool now runs there; run and test send the project first
simulator-use cloud extend 30 # 30 minutes more (an hour by default), up to 8 hours in all
simulator-use cloud stop # ends it; the tools run on this machine again
simulator-use cloud run . --tests # CI in one line: start, build, run, test, a screenshot and a recording, stop
只会发送手机上缺少的文件(更改一个文件就只发送一个文件),并将其放入账户自己的加密工作区中;文件会在不同会话之间保留,因此构建可以增量进行。构建输出和依赖项会留在本地。只会重新读取自上次发送后发生更改的文件(索引位于 simulator-use 的状态文件夹中;SIMULATOR_USE_SYNC_INDEX=0 会读取所有文件)。CocoaPods 项目也可以在那里构建:如果 Pod 不是 Podfile 和 Podfile.lock 指定的版本,构建前会在手机所在的主机上运行 pod install,保留锁定文件中的版本;下次构建时则会跳过这一步。cloud 工具通过 MCP 执行相同操作。
cloud start 会返回一个链接,供他人在浏览器中观看手机,以及一个供你使用的链接。cloud stop 会返回该会话的回放:屏幕录像旁边列出每次调用(不包含输入的文本),保留 7 天。
如果应用需要连接你机器上的后端服务,可通过隧道访问(需要 Node 22 或更高版本):
simulator-use cloud tunnel 8080 # until Ctrl-C: the phone reaches localhost:8080 here, each request printed
响应中会给出手机上的应用应使用的地址,例如 http://127.0.0.1:20199;将应用指向该地址即可,例如使用 run --env "API_URL=http://127.0.0.1:20199"。每个成功通过的请求都会列出其状态和时间(不指定端口运行 cloud tunnel 时,会通过 MCP 显示这些信息)。隧道会在手机运行期间保持连接;如果连接断开,会自动恢复。使用端口 0 运行 cloud tunnel 会关闭隧道。隧道开启期间,手机上的任何程序都能访问该端口:包括应用、Safari 中的网页以及项目的构建过程;手机之外的任何内容都无法访问。
在 GitHub 上,可从任意运行器运行,并在每个拉取请求上发布结果,同时将屏幕截图和录屏保存为构建产物:
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v5
- uses: NoMac-app/[email protected]
with:
api-key: ${{ secrets.NOMAC_API_KEY }}
它会运行自身标签对应的 simulator-use 版本(@v0.12 运行该标签对应的版本;version 用于选择其他版本)。path 是项目文件夹;如果项目有多个方案,scheme 用于指定方案;tests: false 会跳过测试(没有测试目标的项目会失败:零个测试不算通过)。取消运行会停止手机;来自 fork 的拉取请求无法获得密钥,因此会因该原因失败。任务日志和拉取请求评论可能是公开的,因此在 CI 中(设置了 CI 或 GITHUB_ACTIONS 时),cloud run 不会输出无需登录即可打开的链接:链接指向的文件会保存在该次运行的构建产物中,回放链接则使用账户密钥读取(GET https://nomac.app/api/v1/simulator/sessions/{id},links.replay)。
隐私
除非启用云端模式,否则 simulator-use 不会发送任何内容。它没有遥测,也不会在运行时访问网络:所有操作都在你的 Mac 上通过 xcrun simctl、捆绑的 AXe 二进制文件和 sips 执行。启用云端模式后,它会将正在运行或测试的项目以及工具调用发送到 NoMac;NoMac 会将会话回放保留 7 天。项目范围为其所在的 git 仓库,即 git 跟踪或会跟踪的文件(.gitignore 排除的内容会留在你的机器上);如果项目不在仓库中,则范围为其文件夹。无论哪种情况,都不会发送构建输出、依赖项、编辑器状态或密钥和凭据文件(.env 文件,但不包括其示例文件、.p8、.p12、.pfx、.pem、.key、配置描述文件、密钥库、SSH 密钥、.netrc),即使这些文件由 git 跟踪也不会发送。
工作原理
simulator-use 通过一个小型原生引擎(native/engine)读取 Simulator,每个 Simulator 对应一个进程。该引擎基于 AXe(MIT)的框架构建,打包时会固定其版本并校验校验和;同时也会通过 xcrun simctl 读取。引擎会保持 Simulator 的输入、辅助功能会话和屏幕缓冲区处于打开状态,因此点击只需几毫秒,读取整个屏幕只需几百毫秒,而一个步骤会等待像素停止变化,而不是等待固定时长。它会逐点读取 Web 视图。如果引擎无法运行,AXe 会为每次调用启动一个进程来完成相同工作。无需构建测试运行器,因此第一次调用和之后的调用一样快。
开发
npm install
npm run axe # fetch the pinned AXe into vendor/axe
npm run native # build the engine and the clipboard helper into vendor/axe (IDB_HEADERS: idb's PrivateHeaders)
npm test # node --test, no build needed
npm run build # dist/ for the npm package
node bin/simulator-use.js look
引擎只能使用构建 AXe 框架时所用的 Swift 版本来构建:AXe 1.8.0 使用 Swift 6.3.2,这是构建 Xcode 26.5(版本 17F42)所用的 Swift。npm run native 会先检查编译器;如果选中了其他 Xcode,请将 DEVELOPER_DIR 设置为 Xcode 26.5 的 Contents/Developer。该构建具有可复现性:从发布标签的全新克隆开始,在任意文件夹中使用 Xcode 26.5 构建,两个二进制文件都与已发布软件包逐字节一致,包括签名。sha256,校验日期:2026 年 10 月 26 日:
| 版本 | simulator-use-engine | simulator-use-pbset |
|---|---|---|
| 0.12.0 至 0.12.2 | 2bc4891ec8a2a92b26bd970066df46d55553ff1fdd682f3637a7645a1d9184ea | 903d589b5d9b1a7763447472bc60a0f2dc971384a0ded6cd77782896d2da3f22 |
| 0.11.0 | f65ccd92d5eadcfa9dc9065c66c0f71e9acd3f22282f94be5f977a7c919c7cc0 | 903d589b5d9b1a7763447472bc60a0f2dc971384a0ded6cd77782896d2da3f22 |
examples/swiftui-demo 是测试所用屏幕对应的示例应用。scripts/golden.sh 会构建该应用,在 Simulator 上运行,并检查 19 项基准任务:一次调用完成构建和启动、登录、切换、打开项目、返回和滚动、应用日志、崩溃、以 file:line 格式显示的构建错误和失败测试、视频,以及必须明确失败的错误密码。
examples/edge-lab 是一款涵盖各种棘手屏幕的应用:分段控件、步进器、滑块、菜单、警告框、工作表、全屏覆盖层、权限提示、任何语言的文本、自动更正、延迟加载的内容、提示消息、滑动删除、长按、Web 视图、UIKit 和深层链接。scripts/lab.sh 会构建该应用并运行 26 项检查。
SIMULATOR_USE_DEBUG=1 会打印每个步骤和每次程序运行及其耗时。
在 NoMac 构建
simulator-use 在 NoMac 构建。在这里,AI Agent 可租用云端的真实 Mac 来构建、运行和测试 Apple 应用。它源自这些 Mac 上数千次 Agent 运行的经验:Agent 会在哪里卡住、会误读屏幕上的什么内容,以及需要告知它们什么才能继续。
如果 simulator-use 无法在当前环境中运行(没有 Mac、没有 Xcode 或没有 Simulator 运行时),它会在错误中将 NoMac 列为获取这些资源的途径。simulator-use 正常运行时绝不会显示此信息;设置 SIMULATOR_USE_NO_CLOUD_HINT=1 可将其隐藏。
许可证
MIT。AXe 及其包含的 IDB 框架也采用 MIT 许可证;请参阅 THIRD_PARTY_LICENSES。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。