mcpField
S
simulator-use

simulator-use

本地服务
simulator-use.dev开发工具44 天前更新

关于 simulator-use

simulator-use 是面向编码 Agent 的 iOS Simulator MCP 服务和 CLI,可构建、运行及测试 Xcode 项目,并通过屏幕元素文本执行交互。它还提供日志、崩溃信息、视频录制和云端 iPhone 操作。

主要功能

  1. 01构建、安装并启动 Xcode 项目
  2. 02以精简文本读取界面元素
  3. 03按标签执行点击、输入和滚动
  4. 04运行 XCTest 与 XCUITest
  5. 05读取应用日志并查看崩溃
  6. 06录制屏幕视频并操作云端 iPhone

适用场景

  1. 01在 iOS Simulator 中验证应用界面流程
  2. 02按单个测试用例运行并定位失败
  3. 03检查应用运行日志和崩溃位置
  4. 04从没有 Xcode 的机器连接云端 iPhone

MCP 相关

该项目提供 MCP 服务和 CLI,二者共享工具定义。MCP 客户端可通过工具构建和控制 Simulator 应用、读取界面与日志,并运行测试;也可使用云端 iPhone。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"app-nomac-simulator-use": {
"command": "npx",
"args": [
"-y",
"simulator-use"
]
}
}
}
启动命令npx -y simulator-use

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

安装包
npmsimulator-use0.12.2

工具

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_runsimulator-use run在此处构建 Xcode 项目,安装并启动,然后返回首个屏幕;错误格式为 file:line;--xcode 26.6 使用另一个已安装的 Xcode 构建
devicessimulator-use devices列出这台 Mac 上的 Simulators,包括其运行时、UDID、状态和 Xcode
device_usesimulator-use use "iPhone 17 Pro"选择其他工具使用的 Simulator 并启动它(一次只启动一个);深色模式、干净的状态栏
app_controlsimulator-use app launch dev.example.appinstall、launch(返回首个屏幕)、terminate、uninstall、open_url;grant、revoke 和 reset_permissions;location;手机的 appearance、locale、timezone、text_size 和干净的 status_bar
ui_looksimulator-use look读取屏幕;find 保留匹配的行,screenshot 添加图片,screenshot_file 保存全分辨率 PNG,full 保存完整树
ui_actsimulator-use act "tap #signIn" ...按顺序执行步骤,并返回发生变化的内容
app_logssimulator-use logs应用的打印输出及其自身的系统日志行;grep、wait_for、crashes
tests_runsimulator-use test运行单元测试和 UI 测试;每个用例完成时逐一返回,统计数量,列出每个失败的 file:line 和耗时最长的测试;“0 tests ran”表示错误
screen_recordsimulator-use record start开始或停止录制屏幕视频;停止时返回 MP4
job_statussimulator-use job等待长时间构建,最多 40 s,并返回结果或进度
job_cancelsimulator-use cancel停止任务
cloudsimulator-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-enginesimulator-use-pbset
0.12.0 至 0.12.22bc4891ec8a2a92b26bd970066df46d55553ff1fdd682f3637a7645a1d9184ea903d589b5d9b1a7763447472bc60a0f2dc971384a0ded6cd77782896d2da3f22
0.11.0f65ccd92d5eadcfa9dc9065c66c0f71e9acd3f22282f94be5f977a7c919c7cc0903d589b5d9b1a7763447472bc60a0f2dc971384a0ded6cd77782896d2da3f22

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。

评论

支持 Markdown

第一次接触 MCP?

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

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