mcpField
N
noracu

noracu

本地服务
github.com/sgInnora浏览器自动化21 天前更新

关于 noracu

noracu 是一个本地 MCP 服务,可操作 macOS 应用和 Playwright 浏览器,并实验性支持通过 iPhone Mirroring 控制真实 iPhone。它面向需要让 MCP 客户端观察界面并按索引元素执行操作的场景。

主要功能

  1. 01通过辅助功能树操作 Mac 应用
  2. 02按元素索引控制 Playwright 浏览器
  3. 03使用持久化浏览器配置文件
  4. 04通过 OCR 实验性控制 iPhone Mirroring
  5. 05提供只读模式和禁用求值选项

适用场景

  1. 01自动执行 Mac 原生应用中的任务
  2. 02浏览并操作网页
  3. 03使用已有的登录浏览器会话
  4. 04通过 Mac 镜像查看或操作 iPhone

MCP 相关

它以本地 stdio MCP 服务运行,提供 Mac 应用、Playwright 浏览器控制和实验性 iPhone Mirroring 工具。

配置

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

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

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

安装包
npmnoracu0.1.4

工具

35

收录的工具列表 · 更新于 1 天前

参数类型必填说明
regionobject否

详细介绍

noracu

一个本地 MCP 服务,可让 Claude、Cursor 或任何 MCP 客户端通过 element_index 操作 macOS 应用和 Playwright 浏览器;此外,还可通过 Apple 的 iPhone 镜像功能,以实验性方式操作真实 iPhone(在 Mac 上进行 OCR,使用归一化坐标点击)。无需 API 密钥;该服务不会收集遥测数据。

CI npm node license

中文说明见 README.zh-CN.md。

一个 stdio MCP 服务。Agent 会先捕获树状结构,获取带索引的元素列表,然后通过 element_index 点击或输入,而不是使用原始像素坐标——在 Mac 和浏览器中采用相同的观察/操作流程。实验性的 iPhone 层通过 OCR 文本和归一化坐标运行相同的观察 → 操作流程。

浏览器 element_index 演示

browser_snapshot 返回带索引的 ARIA 树;browser_click 通过 element_index 执行操作。Mac 层运行相同的流程(mac_ax_state → mac_click)。高亮框是 demo/record-browser.mjs 中的叠加层,并非产品功能。此演示不包含 iPhone 层。

功能

一个 MCP 服务,提供三种控制界面:

层工具驱动方式状态
Mac9 个(mac_*)cliclick、screencapture、JXA System Events稳定
浏览器12 个(browser_*)Playwright(持久化配置文件)稳定
iPhone14 个(phone_*)通过随附的 imctl 驱动(Python + pyobjc)使用 iPhone 镜像实验性

iPhone 层为实验性功能,随附其驱动(imctl,位于 imctl/ 中)。它需要 Apple 的 iPhone 镜像功能,并且 iPhone 必须锁定且靠近 Mac;还需要带有 pyobjc 的 python3。该层使用 OCR 进行观察,并基于归一化坐标而非 element_index 执行操作。如果没有 pyobjc,phone_* 工具会返回一行 imctl unavailable 错误,并附上安装命令;Mac 和浏览器层不受影响。观察/操作术语遵循 ChatGPT 计算机使用功能推广的操作/观察分离模式,并基于本地开源工具重新实现。

为什么选择 noracu

noracu 是本地执行操作的双手,而不是模型。你的 MCP 客户端(Claude Desktop、Claude Code、Cursor)决定要做什么;此服务只观察并操作这台机器。

  • 服务完全在你的机器上运行。 无云服务、无 API 密钥、无遥测、无 postinstall 脚本。唯一的运行时依赖是 Playwright。noracu 本身不会发起网络请求;唯一的自动请求是在首次运行 browser_launch 时一次性下载 Chromium(设置 NORACU_DISABLE_AUTO_INSTALL=1 可关闭此功能)。浏览器仍会获取你指定的网页,而你的 MCP 客户端仍会将工具结果——屏幕截图、OCR 文本——发送给它使用的模型。
  • 根据语义而非像素操作。 观察会以索引列表的形式返回辅助功能树(Mac)或 ARIA 树(浏览器)——也就是文本,而不是屏幕截图。操作通过 element_index 指定元素;索引会在 30 秒后失效,点击前会重新验证目标(浏览器中的标签、名称、href、位置;Mac 上的最前端应用)。如果引用已过期,会返回 element_no_longer_valid,而不是误点其他内容。树信息不够时,可以使用屏幕截图。
  • 一个循环,三种界面。 原生 Mac 应用和持久化配置文件浏览器共用 element_index 协议(观察树,再按索引操作)。实验性的 iPhone 层则通过 Apple 的 iPhone Mirroring 执行相同的观察 → 操作循环,并使用 OCR 文本和归一化坐标,因为手机不会向 Mac 提供辅助功能树。
  • 使用你的真实会话。 使用你已登录的浏览器配置文件和 Mac 应用,而不是托管虚拟机。与云端电脑操作相比,两者并非哪一种总是更可靠,而是各有不同的失效方式。noracu 会让屏幕留在你的机器上。
  • 真正有效的关闭开关。 NORACU_READ_ONLY=1(仅观察,默认拒绝操作)、NORACU_DISABLE_EVAL=1,以及默认阻止 file://。请参阅安全性。
  • 可验证。 包含 39 项端到端检查(npm test),在 macos-latest 上运行 CI,采用 MIT 许可证,整个服务只有一个文件:src/server.mjs。

不适合以下情况: 你需要多个浏览器标签页或会话(目前只支持单个会话);你不使用 macOS(Mac 和 iPhone 层仅支持 macOS;浏览器层支持跨平台);或者你今天就需要一套成熟的 iPhone 层(该功能已发布,但仍处于实验阶段,而且 Apple 不在欧盟提供 iPhone Mirroring)。如果你只需要浏览器自动化,playwright-mcp 提供 noracu v0.1 尚不具备的标签页管理和选择器 API;noracu 适合还需要让一个 Agent 离开浏览器并操作 Mac 应用的场景。

快速入门

首次成功调用的是 mac_ax_state(或获取浏览器快照),而不是点击操作,也不是 phone_* 工具。第一天最常见的失败原因,是把 macOS 权限授予了 node,而不是宿主应用;授予权限后,只有彻底退出并重新打开宿主应用才会生效。

1. 安装(Node ≥ 20;无 postinstall 脚本):

npm install noracu          # server at node_modules/noracu/src/server.mjs
brew install cliclick       # required for Mac input (mac_click/type/key/paste)

或者从源码安装:git clone https://github.com/sgInnora/noracu.git && cd noracu && npm install && npm test(添加 NORACU_CI=1 可跳过受硬件限制的检查)。

2. 添加到 MCP 客户端——使用 src/server.mjs 的绝对路径。 从 Finder/Dock 启动的 GUI 应用不会继承 shell 的 PATH,因此也要为 node 二进制文件提供绝对路径(which node)——单独使用 node、npx 或 noracu 时,GUI 的 PATH 中必须有 Node,否则会报 ENOENT。

Claude Desktop(~/Library/Application Support/Claude/claude_desktop_config.json)/ Cursor(~/.cursor/mcp.json):

{
  "mcpServers": {
    "noracu": {
      "command": "/opt/homebrew/bin/node",
      "args": ["/ABSOLUTE/PATH/TO/noracu/src/server.mjs"]
    }
  }
}

Claude Code:claude mcp add noracu -- /ABSOLUTE/PATH/TO/node /ABSOLUTE/PATH/TO/noracu/src/server.mjs

使用 which node 查找 Node 路径(Apple Silicon:/opt/homebrew/bin/node;Intel:/usr/local/bin/node;nvm:带版本号的路径)。仅当 Node 已在 GUI 的 PATH 中时,才可使用便捷方式:"command": "npx", "args": ["-y", "noracu"]。

然后彻底退出宿主应用(包括任何菜单栏图标)并重新打开。 加载出工具列表表示传输正常——此时还不需要任何权限。

3. 将 macOS 权限授予宿主应用,而不是 node。 前往“系统设置” →“隐私与安全性” → “辅助功能”和“屏幕录制”(macOS 15:“屏幕与系统音频录制”)→ 启用宿主应用(Claude Desktop / Cursor / 你的终端)。这里不会出现 noracu。授予权限后退出并重新打开宿主应用。

4. 验证。 将 Finder 置于前台,调用 mac_ax_state(不带参数)——它会返回带索引的辅助功能树;索引有效期为 30 秒。浏览器冒烟测试(无需辅助功能权限):browser_launch(首次运行时会下载 Chromium,除非设置了 NORACU_DISABLE_AUTO_INSTALL=1)→ browser_navigate → browser_snapshot → 按索引调用 browser_click。

故障排除
症状原因 / 解决方法
mac_* 失败,报错 -1719未向宿主应用授予辅助功能权限——授予权限后退出并重新打开宿主应用
截图全黑未向宿主应用授予屏幕录制权限——授予权限后退出并重新打开宿主应用
ENOENT 中提到 cliclick执行 brew install cliclick(或设置 NORACU_CLICLICK)
GUI 宿主调用 spawn node / npx 时出现 ENOENT在配置中使用 node 的绝对路径——nvm/volta/homebrew 的 shim 不在 GUI 的 PATH 中
首次使用时 browser_launch 一直卡住这是一次性的 Chromium 下载;也可能是自动安装已禁用(NORACU_DISABLE_AUTO_INSTALL=1)→ 执行 npx playwright install chromium
phone_* 提示 imctl unavailable: no python3 with pyobjc found为某个 python3 安装 pyobjc(python3 -m pip install pyobjc-framework-Quartz pyobjc-framework-Vision pyobjc-framework-AppKit;通常建议使用 Homebrew 的 python3),或设置 NORACU_PYTHON——参见 iPhone 层
phone_* 因 mirror_not_live: …(“Connection Paused”“iPhone in Use”)而拒绝操作镜像已暂停,或 iPhone 处于解锁状态——锁定 iPhone,并将它放在 Mac 附近,然后调用 phone_launch(该工具会点击“Resume”)
输入的文字间距异常(例如“no ra cu”)正在使用 CJK 输入法——请改用 mac_paste,而不是 mac_type
element_no_longer_valid快照已超过 30 秒,或 UI 已更改——重新运行 mac_ax_state / browser_snapshot 并使用新索引

启动时会拒绝 Node 18——请使用 Node ≥ 20。Claude Desktop 可能会为每个界面(例如聊天界面和另一个界面)启动一个 noracu 进程;这些进程共享浏览器配置文件,因此一次只从一个进程启动浏览器。

完整的操作示例:docs/usage.md。

iPhone 层(实验性)

noracu 可以通过 Apple 的 iPhone Mirroring 操作真实 iPhone。Agent 使用 Mac 上的 OCR 进行观察(phone_screenshot、phone_ocr、phone_find),在归一化的 0–1 坐标上执行操作(phone_tap、phone_swipe、phone_scroll),通过粘贴输入文字(phone_type),并按名称打开应用(phone_open)。这不是 element_index:手机不会向 Mac 提供辅助功能树,因此点击位置取决于 OCR 识别到的文本位置。驱动程序(imctl,Python,MIT,约 1,000 行)随项目附在 imctl/ 中。

Apple 的要求(support.apple.com/120421:配备 Apple 芯片或 T2 芯片、运行 macOS 15 或更高版本的 Mac;运行 iOS 18 或更高版本且设有密码的 iPhone;两台设备均登录同一个启用了双重认证的 Apple Account;蓝牙和 Wi-Fi 已开启;Mac 未共享互联网连接,也未使用 AirPlay 或 Sidecar。iPhone 必须处于锁定状态并靠近 Mac——解锁 iPhone 或退出 iPhone Mirroring 都会结束会话。iPhone Mirroring 目前在欧盟不可用。一次只能连接一台 Mac 和一台 iPhone;摄像头和麦克风不会镜像。

**无人值守会话:**在 iPhone Mirroring → 设置中,启用“自动认证”后,会话启动时不会提示输入密码。代价是:任何能使用已解锁 Mac 的人都可以打开你的手机。

**Python:**驱动程序需要一个能够导入 pyobjc(Quartz、Vision、AppKit)的 python3。设置 NORACU_PYTHON,或者 noracu 会在首次调用 phone_* 时依次探测 /opt/homebrew/bin/python3、/usr/local/bin/python3、python3、/usr/bin/python3,仅探测一次。Apple 的 /usr/bin/python3 通常未安装 pyobjc;常见的可用配置是安装 Homebrew 的 python3,并运行 python3 -m pip install pyobjc-framework-Quartz pyobjc-framework-Vision pyobjc-framework-AppKit。

镜像状态:phone_status 会报告 live(正在串流手机屏幕)、overlay(iPhone Mirroring 显示的替代文本,例如“连接已暂停”或“iPhone 正在使用中”)和 paused(该覆盖层显示“继续”按钮)。检测读取窗口的结构,而不是其文本。镜像未处于实时状态时,phone_tap、phone_longpress、phone_swipe、phone_scroll、phone_type、phone_key 和 phone_open 会返回 mirror_not_live,而不会点击覆盖层;phone_ocr / phone_find 则会在输出开头添加警告。镜像会在一段时间没有活动后暂停;phone_launch 会将其调到前台并点击“继续”。

**隐私:**手机上显示的任何内容——通知、消息、邮件、一次性验证码——都会成为工具输出,并由 MCP 客户端发送给模型。开启专注模式,在开始前打开一个无敏感信息的应用,并以 NORACU_READ_ONLY=1 开始(phone_status、phone_screenshot、phone_ocr 和 phone_find 仍可使用;所有手机输入操作都会被拒绝)。设置好 Mirroring 后,iPhone 通知也会显示在 Mac 上。

首次成功操作:phone_status → 如果 live 不是 true,则运行 phone_launch → phone_screenshot → phone_ocr → phone_find + phone_tap。

**已知限制:**点击位置取决于 OCR 识别到的文本位置,因此重复或识别错误的标签可能导致误点;phone_scroll 使用触控板式滚动事件滚动列表(垂直方向的 phone_swipe 拖动不会滚动列表——可用于主屏幕翻页等手势);在一套经过测试的配置中(iPhone 17 Pro Max,运行 iOS 27.0.1;Mac 运行 macOS 26.6.2),iPhone Mirroring 在所有视图尺寸下都会将手机画面放大约 17%,导致右侧栏和底部行被裁切且无法触及;在显示器之间移动窗口、更改主显示器并重新启动都没有效果,iOS 27 / macOS 26 版本不匹配最可能是原因——如果点击屏幕边缘附近没有反应,请检查 phone_screenshot;phone_open 会在 Spotlight 中输入应用名称并点击精确匹配项,否则返回主屏幕;phone_home / phone_app_switcher 使用 iPhone Mirroring 菜单(英文版 macOS),连接后无需 Python 即可使用。

环境变量

变量默认值用途
NORACU_READ_ONLY未设置=1 仅观察模式:默认拒绝,仅允许 12 个观察工具和浏览器生命周期工具;所有点击/输入/粘贴/按键/求值工具均会被拒绝
NORACU_DISABLE_EVAL未设置=1 调用 browser_evaluate(任意 JS)时会返回错误(但仍会列出该工具)
NORACU_ALLOW_FILE_URL未设置=1 允许 browser_navigate 打开 file:// URL(默认阻止)
NORACU_DISABLE_AUTO_INSTALL未设置=1 跳过首次调用 browser_launch 时自动安装 Chromium
NORACU_CLICLICK/opt/homebrew/bin/cliclickcliclick 二进制文件路径
NORACU_PYTHON自动探测用于捆绑的 iPhone 驱动程序的 python3;必须能够导入 pyobjc(Quartz、Vision、AppKit)。未设置时 → 按顺序使用第一个可用项:/opt/homebrew/bin/python3、/usr/local/bin/python3、python3、/usr/bin/python3
NORACU_IMCTL_DIR捆绑的 imctl/覆盖驱动程序位置(仅用于开发)

安全

noracu 使用 MCP 客户端的权限运行。它会在这台机器上点击、输入、粘贴并操控真实浏览器——没有沙箱,也没有远程审批提示。请在服务条目中设置这些变量,然后完全退出宿主应用并重新打开:

"env": { "NORACU_READ_ONLY": "1", "NORACU_DISABLE_EVAL": "1" }
  • NORACU_READ_ONLY=1 是安全的首次运行模式。它会拒绝任何不在 12 个名称的允许列表中的工具(观察工具以及 browser_launch/browser_navigate/browser_close);所有点击、输入、粘贴和求值工具都会被拒绝。browser_navigate 在允许列表中,因此仍可加载 URL。
  • NORACU_DISABLE_EVAL=1 会使调用 browser_evaluate 时返回错误(该工具仍会列在 tools/list 中)。快照、点击和输入仍可使用。
  • 除非设置 NORACU_ALLOW_FILE_URL=1,否则会拒绝 file://,因此浏览器 Agent 无法通过导航到 ~/Documents 来读取其中的内容。(初始导航 URL 会进行协议检查;重定向不会——参见 SECURITY.md。)
  • 焦点保护: 将 app 传给 mac_type/mac_paste/mac_key,除非该应用位于最前方,否则会拒绝输入。省略 app 即关闭此保护。
  • 过期元素保护: element_index 不是坐标。它会在 30 s 后过期(element_no_longer_valid);浏览器点击会重新检查标签/名称/href/位置,如果自快照创建后最前方的应用发生变化,则会拒绝 Mac 点击。
  • iPhone 屏幕内容会作为模型输入: phone_screenshot/phone_ocr/phone_find 会返回手机屏幕上显示的所有内容——包括通知、消息和一次性验证码。请使用专注模式和中性应用,并从 NORACU_READ_ONLY=1 开始(允许观察手机,拒绝操作手机)。镜像暂停时也会拒绝手机操作(mirror_not_live)。
  • 防注入 JXA: 字符串参数会作为 argv 数据传给 osascript,绝不会嵌入脚本;唯一的数值(AX 读取深度)会先限制在 1–10,再用于操作。已通过回归测试。

这些开关并不能让观察到的内容变得可信。屏幕截图文字、辅助功能名称和页面内容都是提供给模型的不可信输入——不要让它们覆盖任务要求。完整威胁模型及各项威胁的状态:SECURITY.md。

工具与文档

路线图

  • 浏览器:标签页管理(列出/选择/关闭)
  • 操作词汇(浏览器):hover、set_value、wait_for
  • 通过快照差异减少 token 用量——待测量
  • iPhone:对 OCR 区域使用 element_index,并在点击前重新检查文本

维护

由个人维护,不提供 SLA。Mac 层需要 macOS 15+;iPhone 层还需要 Apple 芯片或 T2 Mac、iOS 18+ 和 iPhone Mirroring(欧盟地区不可用);浏览器层可在 Playwright 支持的任何环境中运行。

许可证

MIT — 参见 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

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

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