mcpField
C
computer-mcp

computer-mcp

本地服务
computermcp.dev生产力16 天前更新

关于 computer-mcp

computer-mcp 是通过辅助功能树控制桌面应用的 macOS MCP 服务,适用于需要操作电脑的 Agent。它提供密码遮挡、敏感操作确认门槛和仅追加审计日志等防护措施。

主要功能

  1. 01通过辅助功能控件操作应用
  2. 02在截图中遮挡安全文本字段
  3. 03敏感操作需经确认
  4. 04以指纹链记录调用审计日志
  5. 05支持多个服务实例并发运行

适用场景

  1. 01在其他窗口工作时自动操作应用
  2. 02避免 Agent 收到截图中的密码字段
  3. 03核查操作获准或被拒的记录
  4. 04让多个 Agent 同时操作桌面应用

MCP 相关

向 MCP 客户端提供电脑控制工具,包括 Claude Code、Cursor、VS Code 和 Codex。各客户端可通过 npx 运行服务;使用需要 macOS 辅助功能和屏幕录制权限。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"agent360dk-computer": {
"command": "npx",
"args": [
"-y",
"@agent360/computer-mcp"
],
"env": {
"CMCP_MODE": "<CMCP_MODE>",
"CMCP_ASK_TIMEOUT": "<CMCP_ASK_TIMEOUT>"
}
}
}
}
启动命令npx -y @agent360/computer-mcp
需要配置的环境变量
CMCP_MODEreadonly | ask (default) | allow
CMCP_ASK_TIMEOUTSeconds a consent dialog waits before refusing. Default 60.

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

安装包
npm@agent360/computer-mcp0.1.0

工具

12

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

Computer MCP

门 1:截图写入前,先在内存中将安全字段涂黑。门 2:菜单栏图标变为橙色,并在文件移至废纸篓前征求确认;密码管理器会被拒绝。门 3:日志行中,键入的文本以长度和加盐指纹表示。

真正可以一直运行的电脑操控工具。

一款面向 macOS 的电脑操控 MCP 服务,专为所有人都会忽略的部分而打造:当你不在旁边看着时,几个小时里会发生什么。

  • 它可以在任何 MCP 客户端中运行,而不局限于某个应用。 Claude Code、Cursor、VS Code、Codex,或你自己的 Agent——只需一行 npx 命令,就能在任何地方运行同一个服务。它不受限于某个供应商的桌面应用或套餐。
  • 它不会接管你的 Mac。 它会在你当前窗口后面的窗口中按按钮、填写字段,并让指针停留在你放置的位置。应用打开时若将自己切到前台,前台窗口会立即切回原处,回复也会说明这一点——不会留下任何东西抢走你正在输入的焦点。
  • 它不会装作一切正常。 遇到拒绝或失败时,它会明确告知,并说明原因。Agent 操控电脑最常见的抱怨就是:操作没成功,却仍然继续执行。
  • 可以同时运行多个实例。 没有会话锁,也没有一次只能运行一个实例的限制。写入共享日志时会短暂锁定文件,因此两个服务不会破坏彼此之间的日志链。
  • 它不会靠近你的密码。 默认模式下,Keychain、1Password 和另外五款密码管理器都会被拒绝(在前台运行时——也就是 Agent 正在操控屏幕时,或设置 CMCP_BACKGROUND=0 时——每次都会征求确认),而截图仍在内存中时,密码字段会被涂黑。屏幕录制会避开密码管理器,但不会将密码字段涂黑。
  • 你可以查看它做过什么。 每次调用都会写入只能追加的日志,并以指纹形式记录,而非明文。
  • Electron 应用不会成为盲点。 Slack、VS Code、Discord 和 Notion 会延迟构建其无障碍树,因此大多数工具看到的都是空窗口。这个工具会在查看前自行启用无障碍树。在一个打开两个窗口的 VS Code 分支版本上测得:启用前有 0 个按钮,启用后有 728 个,窗口相同,时刻相同。如果你不希望应用为了维护原本不会构建的无障碍树而付出开销,可以设置 CMCP_INGEN_ELECTRON=1 将其关闭。

需要坦诚说明的限制:仅支持 macOS。它会读取无障碍树,因此,自己在画布上绘制控件且不提供任何无障碍信息的应用——例如一些游戏和绘图工具——仍然是盲点。**浏览器则是另一回事:**上面的开关使用的是 Electron API,而 Chrome 并未实现它。在 Chrome 上测得,启用前后都是 29 个按钮,没有变化。你可以获取浏览器自身的窗口——标签页、工具栏、地址栏——而其中的网页只有在 Chrome 自己构建了无障碍树时才能访问(两种情况均已测量,见下文限制)。要操作网页,请使用浏览器工具。

无需账号,无需 API 密钥,内部也不包含模型。MIT。

npx @agent360/computer-mcp

无需使用 Swift:此软件包随附适用于 Apple 芯片和 Intel 处理器的通用二进制文件。它带有 macOS 运行程序所需的临时签名——不是 Developer ID 签名,也未经过公证。因此,Gatekeeper 首次运行时可能会询问你是否允许。

computermcp.dev · 安全模型


为什么

将键盘、鼠标和屏幕交给 Agent,是你能赋予它最有用、也最难撤回的权限。工作中的开发者 Mac 截图可能包含正在解锁的密码管理器、在编辑器中打开的 .env 文件,或客户数据。终端里一次意外的按键并非拼写错误——而是一条命令。

大多数桌面自动化 MCP 服务会一次性交出所有这些权限,却没有办法表达可以做这件事,但不能做那件事。因此,谨慎的人不会在真正工作的设备上运行它们。

这是同样的能力,但危险之处都有了应对措施。

三道安全关

1. 密码永远不会到达模型。 安全文本字段和密码管理器窗口会在内存中的位图上被涂成不透明的黑色,然后才写入 PNG。桌面未经遮挡的图片不会有任何时刻以文件形式存在。本机字段会暴露角色 AXSecureTextField;网页中的字段会暴露角色 AXTextField,其 子角色 为 AXSecureTextField。只检查角色会捕获本机字段,却漏掉所有浏览器密码框——因此两者都会检查。在网页中,只有浏览器向辅助功能层展示页面时,才能找到该字段;同一台 Mac 上的 Chrome 有时会这样做,有时却不会(见下文的限制)。如果浏览器没有展示,字段就不会被涂黑;它显示的会是浏览器自己的圆点,除非网页本身以明文显示密码。

2. 危险操作会先征求许可。 默认情况下,Agent 会在不打断你的情况下工作——这样它才能在你忙于其他事情时运行——并且每次写入都会记录。默认模式下,密码管理器和 Keychain 的操作绝不会自动通过,因为菜单栏无法显示将要输入的内容(在前台运行时——即 Agent 正在使用屏幕时,或设置了 CMCP_BACKGROUND=0 时——每次都会征求许可,即使设置为 allow 也是如此),而且这项规则无法配置。终端和编辑器中,一个按键就可能是一条命令,因此每个应用、每个会话只会征求一次许可。退出应用、关闭窗口、切换 Space,以及看起来具有破坏性的菜单项,每次都会征求许可;默认模式下,如果无法识别某项操作的目标应用,就会拒绝该操作。权限门控会判断操作实际落在哪个应用中:通过其他方式打开的应用——例如 Spotlight 或快捷键打开的应用——会根据 Agent 随后尝试在其中执行的操作受到保护。想在第一次写入之前也收到询问?设置 CMCP_MODE=ask。如果没有人回答,就视为拒绝。

3. 所有操作都会记下来。 ~/.local/state/computer-mcp/audit.jsonl,权限模式 0600,仅追加:记录每次调用、目标应用,以及该操作获准还是被拒绝及其原因。每行都带有该次调用的 ID;此 ID 与服务端的会话 ID 结合后,可以将某次调用的决策与结果配对,即使有多个 Agent 同时运行也一样。每行还包含自身及上一行的指纹,因此删除或编辑任何一行都会破坏链条。这不是数字签名:任何能以你的身份写入该文件的人——包括使用终端的 Agent——都可以重写整个文件。如果你需要防篡改的证明,请将日志复制到这台机器之外。如果无法写入日志——例如磁盘已满或文件被锁定——写入操作会被拒绝,直到日志可以写入为止。还有两种情况无法覆盖:磁盘写满时已经开始的操作可能没有结果记录;因辅助程序的时间限制而中断的输入会被记录为错误,但不会说明实际输入了多少字符。输入的文本只会以长度和带 盐 的 SHA-256 前缀存储,绝不会以明文保存——满是密码的审计记录本身就是一次泄露。每次运行都会随机生成盐,且绝不写入记录,因为拿到日志的人可以离线猜测短密码的无盐哈希。需要坦诚说明的代价是:同一次运行中的两项操作可以相互比较,但无法跨运行比较。 以下是未经编辑的实际记录。在下面几行中,Agent 在用户正在使用的窗口后方的 TextEdit 中输入了一句话,在菜单栏中请求将一个文件移到废纸篓,但没有得到答复(此次运行设置了 CMCP_ASK_TIMEOUT=1,因此问题在一秒后结束,并被记录为拒绝;使用默认值时,该调用会被记录为等待,问题会保留约十分钟),随后它尝试在 1Password 中输入内容时遭到拒绝。这些记录来自一次隔离测试运行——使用独立的状态文件夹,以及模拟的辅助程序和菜单栏图标,因此没有触碰真实屏幕,也没有读取任何人的日志——node scripts/log-uddrag.mjs 会重复这次运行。presence 字段中的空闲时间来自模拟辅助程序,图标版本来自模拟图标;会话计数来自隔离状态,界面类型则是推导得出的。只有方框设置是从执行此次运行的 Mac 上读取的。测试会逐字节检查每一行是否都与此次运行的完整日志一致,并验证日志链是否完整。

{"ts":"2026-10-20T18:52:45.701Z","session":"fabb2663","call":"746fffee","tool":"computer_type","tier":"write","args":{"app":{"length":8,"sha256_12":"1b330dc3a979","salted":true},"text":{"length":37,"sha256_12":"51f664abcb74","salted":true}},"target":"com.apple.TextEdit","mode":"allow","asker":"custom","decision":"allowed","asked":false,"reason":"CMCP_MODE=allow","l":1,"kaede":"e02a3d1b3560ea17"}
{"ts":"2026-10-20T18:52:45.705Z","session":"fabb2663","call":"746fffee","tool":"computer_type","tier":"write","target":"com.apple.TextEdit","phase":"executing","l":1,"kaede":"c1e763106513c3e7"}
{"ts":"2026-10-20T18:52:46.112Z","session":"fabb2663","call":"746fffee","tool":"computer_type","outcome":"ok","effect":"sent","l":1,"kaede":"b053781eb3511c4d"}
{"ts":"2026-10-20T18:52:47.761Z","session":"fabb2663","call":"88f2d9ae","tool":"computer_menu","tier":"write","args":{"app":{"length":6,"sha256_12":"0771e2f86fa0","salted":true},"path":"File > Move to Trash"},"target":"com.apple.finder","mode":"allow","asker":"menubar","presence":{"idle_at_ask":600,"idle_at_end":600,"server":"0.4.0","icon":"0.4.0","box":"on","sessions":1,"surface_derived":"box+menu"},"decision":"denied","asked":true,"reason":"background mode: nobody answered in the menu bar in time","l":1,"kaede":"9b82d6ae5a36942d"}
{"ts":"2026-10-20T18:52:48.229Z","session":"fabb2663","call":"0ba79155","tool":"computer_type","tier":"write","args":{"app":{"length":9,"sha256_12":"84b5a01fae6a","salted":true},"text":{"length":7,"sha256_12":"b56e1d9fbfd2","salted":true}},"target":"com.1password.1password","mode":"allow","asker":"custom","decision":"denied","asked":false,"reason":"background mode: this would need a dialog, and a dialog takes the screen (a password app can never be approved from the menu bar)","l":1,"kaede":"1be981d7eeaf7445"}

每个关卡都有对应的测试,而且每项测试都经过变异测试:故意破坏代码,测试就会失败。请参阅测试。

安装

# Claude Code
claude mcp add computer -- npx -y @agent360/computer-mcp

或者,在 Claude Code 中,将其作为固定到 npm 上版本的插件使用:

/plugin marketplace add Agent360dk/computerMCP
/plugin install computer-mcp@agent360
// Cursor, VS Code, Codex CLI - mcp.json
{
  "mcpServers": {
    "computer": { "command": "npx", "args": ["-y", "@agent360/computer-mcp"] }
  }
}

然后授予两项 macOS 权限:系统设置 → 隐私与安全性 → 辅助功能,以及同一位置下的屏幕录制。让你的 Agent 调用 computer_permissions,它会告诉你还缺少哪些权限。

应该向哪个应用授予权限? macOS 会将这些权限归于负责进程,而具体是哪个进程取决于你如何启动服务。如果从终端运行,通常就是终端。如果 MCP 客户端通过 npx 运行,它也可能是该客户端。坦白说:将权限授予系统对话框中列出的应用;如果没有出现对话框,就先从启动客户端的应用开始,然后再次检查 computer_permissions。

**尚未测试,我们宁愿如实说明:**我们还没有在重置权限的干净设备上进行测量,因此无法确定在你的设置中会是哪种情况。我们测量过辅助功能权限的升级情况(问题 #4):权限授予的是宿主应用,而不是我们临时签名的辅助程序——即使将辅助程序复制到新路径并使用不同签名启动,它仍然拥有该权限——因此在这种设置下,升级后无需重新打开“系统设置”。升级后屏幕录制权限的情况尚未单独测量。如果你遇到了其他情况,告诉我们你看到的现象,也是一项实实在在的贡献。

模式

CMCP_MODE行为
readonly写入工具甚至不会显示在列表中。Agent 可以查看,但不能操作。
ask首次写入时会在菜单栏图标中询问;如果图标未运行,在后台模式下会拒绝请求,在前台则会打开对话框。确认一次即可授权整个会话。密码管理器会被拒绝(在前台——即 Agent 操作屏幕时,或设置 CMCP_BACKGROUND=0 时——则每次都会询问);终端和编辑器每个会话询问一次。
allow默认值。 写入操作无需询问即可执行,但仍会记录日志。密码管理器仍会被拒绝(在前台——即 Agent 操作屏幕时,或设置 CMCP_BACKGROUND=0 时——则每次都会询问);终端和编辑器每个会话询问一次;在后台模式下,任何需要打开对话框的操作都会改为在菜单栏中等待。

CMCP_ASK_TIMEOUT(秒,默认值为 60)控制对话框等待多久后拒绝请求。只有在前台、菜单栏图标可能永远无法批准的问题,或图标未运行时,才会显示同意对话框;其他所有同意请求都会在图标中等待(见下文的菜单栏图标),而在后台模式下,如果图标未运行,则会被拒绝。前台的 computer_ask_user 始终会显示对话框。同一个数值也会限制图标中的同意请求等待时间:设为 45 或更小则会在相应时间后结束,设为大于 600 则会等待那么久。

工具

共 32 个工具:14 个用于查看,18 个用于操作。 默认提供其中 25 个,Agent 无需询问即可使用——就像浏览器工具操作浏览器一样。有两道限制仍然存在,而且正是关键所在:

  • 密码管理器会被拒绝。 Keychain、1Password 和其他五款工具,在所有模式下,即使你已经同意也会被拒绝;在前台(即 Agent 操作屏幕时,或设置 CMCP_BACKGROUND=0 时),则会每次都询问。这就是你可以工作和你可以使用我的密码之间的全部区别。
  • **任何会删除或清除内容的操作,每次都会询问,**根据操作本身的描述文字识别。

其他操作都会直接执行并写入日志。

它会在后台运行,而且这是默认设置。 不会有任何操作移动指针、将应用切换到前台,或在你正在使用的窗口中输入内容。过去需要屏幕交互的四个工具——computer_type、computer_key、computer_scroll 和 computer_click——现在都接受 app 参数,事件会进入该应用自己的队列,而不是全局输入流。我们在有人正在使用的机器上进行了测试:文本输入到了应用中,指针留在原处,前台窗口也没有变化。每次按键、点击、滚动和输入的字符串都会返回 took_screen,因此你不必只听我们说。

我们会如实说明实际效果:输入文字和按键经过了这种方式的测试,点击和滚动则采用相同机制实现,但尚未经过测试。 鼠标事件不包含窗口编号,因此,应用是否会接受一个它没有看到指针移动过去的事件,目前仍未得到验证。在确认之前,返回结果会说明 took_screen: false,表示没有使用屏幕——并不表示点击已生效。window 和 quit 现在也会返回该字段,并以相同方式测量——即使调用在中途失败也不例外,因为执行了一半、使用了屏幕的写入操作绝不能成为唯一一条不报告此信息的操作。press 和 menu 也会返回该字段:应用可能会因此将自己切换到前台(经过测量:File > New Finder Window 确实如此);发生这种情况时,返回结果会说明这一点,并将前台直接交还给你原先所在的应用(gave_back)。set_value、drag、paste 和 move 目前还不会返回该字段。 computer_launch 通过 background: true 将它们结合起来:应用会在你正在做的事后方启动。许多应用启动时会自行切到前台——在一台干净的 Mac 上,八个应用中有六个如此——如果发生这种情况,前台会立即切回去,答复中会显示 took_screen 和 gave_back。这只是一个瞬间,但并非毫无影响。另有七项操作仍被拦住:move、activate、quit、space、window、drag 和 paste——除非你借出屏幕:computer_request_screen 会在屏幕角落的方框中(以及菜单栏中)向你发出请求,每次只允许一个 Agent 使用,并通过 Touch ID 批准,最长 15 分钟。屏幕借出期间,你操作键盘或鼠标时,每一步都会等待(已经开始的步骤会完成);按下 Take the screen back now 会立即结束借用,并停止仍在运行的步骤。只要屏幕仍处于借出状态,这个按钮就会一直留在方框中——即使 Agent 没有操作,或你已关闭方框也是如此——而且它绝不会要求 Touch ID。设置 CMCP_BACKGROUND 会彻底禁用它。CMCP_BACKGROUND=0 也会为你启用这些操作——拼错不会将其关闭,只有 0、false、no 或 off 才会。CMCP_MODE=ask 会在每个会话的首次写入前询问一次是否同意;CMCP_MODE=readonly 则只保留那十四项只观察的操作。

这两道仍然生效的限制都经过修改验证:在源代码中破坏它们,拒绝就会变成畅通无阻,这让我们确认测试确实可能失败。

如实说明目前可用的内容。 npx @agent360/computer-mcp 当前提供 0.1.0,包含 12 个工具。此处介绍的 32 个工具就是源代码中的版本:它们已构建并经过测试,但尚未发布。若现在就想使用,基于源代码构建大约需要 35 秒。

查看: computer_pending · computer_screenshot · computer_record · computer_inspect · computer_find · computer_wait_for · computer_focused · computer_apps · computer_windows · computer_permissions · computer_displays · computer_menus · computer_audit · computer_learning

操作: computer_request_screen · computer_launch · computer_open · computer_quit · computer_paste · computer_window · computer_space · computer_menu · computer_press · computer_set_value · computer_ask_user · computer_click · computer_drag · computer_type · computer_key · computer_scroll · computer_move · computer_activate

**computer_ask_user 是唯一不能传递秘密的工具。**它只返回 true 或 false,不会返回文本。Agent 会将光标放入字段;对话框会显示即将输入内容的应用和窗口——这些信息由服务端编写,而非模型提供——然后由你使用自己的键盘输入。我们刻意不在此服务中提供任何能让密码传给模型的途径。在后台模式下,不会弹出对话框:问题会连同完整请求、输入位置以及 Take me there 一起显示在屏幕角落的方框中和菜单栏图标下方;点击后,切到前台的是应用,而不是 Agent。你输入内容并选择 Done。Done 只是一个信号,并不代表同意:它绝不能批准任何其他操作。

computer_set_value 可以在不移动指针的情况下,向另一个窗口后方的字段写入内容;每次遇到安全字段都会拒绝。我们曾故意移除这项检查一次:修改后的构建版本确实向密码框中写入了内容。这是唯一一道防线。 computer_type 也会以同样方式拒绝,并在输入每个字符前进行检查:如果 Tab、点击或页面本身在输入过程中将焦点移到了密码字段,输入就会立即停止。它还会监听 macOS 自带的密码信号(安全输入);浏览器在密码字段中会启用此信号,即便辅助功能层只能看到周围的页面也是如此:信号启用期间,任何位置都不会输入内容。此信号只能增加拒绝条件,绝不会把未知字段变成可输入字段。computer_paste 也会在粘贴前用同样方式检查前台字段。 computer_wait_for 会等待某个元素出现,而不是循环截屏。在这里,轮询 20 次只需调用一次;另一种方式则要处理 20 张图片。

computer_inspect 会读取辅助功能树——角色、标题、值和框架——这样 Agent 就能根据按钮的位置点击它,而不必根据像素猜测。computer_find 会进一步筛选出匹配某个角色、标题或子字符串的元素。绝不会返回安全字段的值,连 Agent 也看不到。

**刻意不提供:**不执行 shell 命令、不任意访问文件、不获取 URL。这些功能都只需一行代码就能实现。内置 shell 的电脑控制服务,只不过是换了个好听名字的远程访问。如果你需要 shell,请安装 shell MCP 服务——这样就是你主动选择了它,而且这个选择会清楚地显示在配置中。

不接管你的屏幕

computer_click 和 computer_type 会通过系统自己的输入接口执行操作,因此会作用于键盘焦点所在的位置,也会移动你的实际指针。你在旁边观看时,这没问题;但如果你正在另一个窗口中工作,就不合适了。

computer_press 则采用另一种方式:它会触发元素自身的辅助功能操作。即使窗口被其他窗口挡住,这种方式也能生效,而且不会移动屏幕上的任何内容。Agent 可以通过 computer_find 定位要按下的元素。

computer_find  { "app": "com.apple.Safari", "role": "AXButton", "contains": "Log in" }
computer_press { "app": "com.apple.Safari", "contains": "Log in" }

如果匹配项有两个或更多,就会拒绝操作,而不是猜测——Agent 会收到候选项,必须进一步缩小范围,因为按下第一个看似合理的按钮,正是那种事后无人察觉的差点出错的操作。

同意请求仍会送达给你(默认显示在菜单栏中),而始终要求确认的应用也仍会每次都征求同意。computer_press 会指定目标应用,安全闸会依据这个名称进行判断——因此,即使 1Password 完全没有处于前台,在其中按下某个内容仍会被拒绝(如果它在前台,则会要求确认)。

**Claude Code 的自动模式与屏幕工具。**10 月 1 日的实测结果:用户通过 Touch ID 授权屏幕访问后,Claude Code 的自动模式仍以安全性降低为由拒绝了 computer_move。这是客户端自身的防护措施,不属于此服务;谨慎行事是对的。要使用屏幕工具,请在不启用自动模式的情况下运行会话,并在 Claude Code 询问时批准每次调用;此服务中的租约和安全闸仍会继续生效。

**同时运行多个 Agent。**每个 MCP 客户端都会启动自己的服务,因此第二个聊天只是第二个进程。它们共用一份审计日志,每一行都带有按服务区分的 session 标记——设置 CMCP_CLIENT=<name> 后,日志行也会带上该值,因此可以从日志中查明哪个对话执行了点击。两个服务交错写入 50 次,日志行仍完整无损:test/concurrent.mjs。

**同一应用中的两个 Agent 会轮流操作。**9 月 22 日的实测结果显示:两个实际运行的服务同时向同一个窗口输入内容时,两段文本会逐字符交错——160 个字符中发生了 153 次切换——而两个服务都报告成功。现在,每个目标应用都有一把锁,操作期间跨进程持有。加锁后的同一项测试:只切换了 1 次,两段文本都完整输入(test/samtidige-agenter.mjs)。在不同应用中的两个 Agent 仍会同时运行;没有必要串行化的操作不会被串行化。

菜单栏图标

Agent 运行时,菜单栏中会显示一个小图标;Agent 工作时,屏幕右上角会显示一个小框。这两者就是本产品会显示在屏幕上的全部内容,而且都不会夺取焦点。

  • 下拉菜单会列出所有正在运行的 Agent——使用的是哪个客户端,以及当前在做什么。点选一个即可打开实时窗口,跟随它的操作。文字会说明它做了什么(Type 42 characters、Press an element in Finder),但绝不会显示输入了什么:这些字符不在状态文件、日志或图标中。
  • **工作时,方框会显示正在发生的事情。**它位于屏幕右上角,跟随你正在使用的窗口,而不是指针碰巧停留的窗口;切换屏幕时它也会跟着你。它会列出哪些 Agent 正在工作、在哪个应用中工作,以及当前在做什么。它绝不会接管键盘,并会在工作停止半分钟后消失。你可以在图标菜单中将其关闭。
  • **需要你处理的问题会让图标变成橙色。**在后台模式下,以前只要需要人工处理,服务就会拒绝请求,因为对话框会占用屏幕。现在它会等待你处理。大约 45 秒后,调用会返回“尚未回答”(而不是拒绝),问题会在方框中保留约十分钟,Agent 也会在聊天中告诉你。它再次执行相同操作时,会收集你的回答:一次“是”只对该操作有效,并且仅在你给出回答后的约两分钟内有效。在你回答之前,不会发生任何事情。请求屏幕访问时,等待时间最长为五分钟。
  • **方框也会变成橙色,并显示完整问题。**它会显示请求者、请求内容、请求的目标,以及“是”有效的时长——与服务写入菜单的内容相同,并提供菜单中的按钮:Allow (Touch ID) 和 Deny(或者对于你亲自完成的操作,显示 Done)。新问题出现后,按钮会等待一秒才启用,避免原本要点击上一个问题的操作落到新问题上。问题超过 280 个字符时,Allow 仅会出现在菜单中,菜单会显示完整内容:你可以在确认前查看“是”所涵盖的全部内容。
  • **允许操作必须经过明确确认。**菜单中的 Allow… 位于子菜单中,不能在主菜单中单击一次就执行;方框中则以按钮形式显示。两者每次都需要使用 Touch ID(或 Mac 密码)确认。回答会通过问题发起时使用的同一套 socket 连接返回,并绑定一次性编号和截止时间。超时回答、编号不符的回答,或未经指纹验证的“是”,都会被视为“否”。
  • **允许操作前,你可以看到完整内容。**完整文本会换行显示在子菜单中,紧挨着 Allow… 上方,最多 4,000 个字符。更长的内容根本不会被询问:你必须能看到“是”所涵盖的全部内容。
  • **向真人发送消息时,每次都需要确认。**在列表中的聊天和邮件应用(WhatsApp、Messages、Slack、Teams、Telegram、Signal、Discord、Mail、Outlook 等),以及通过页面标题识别的网页聊天和网页邮箱(WhatsApp、Messenger、Slack、Teams、Telegram、Discord、LinkedIn、Instagram、Facebook、Google Chat、X、Gmail、Outlook 等;其他网站上的聊天无法识别)中,按下或点击 Send(支持多种语言,或完全没有名称的按钮),以及在聊天中按 Return(邮件中按 Cmd+Return),都会先就这条消息向你确认。服务会从屏幕读取并显示消息的接收对象和内容:文本框上方的名称,以及文本框中的内容。如果其中任一项无法读取,就不会发送——由你亲自发送。聊天中输入换行会被拒绝,因为换行会发送消息;邮件中换行只会插入新行。如果你确认后对话或文本发生变化,就不会发送。无法识别的情况包括:列表之外的应用,以及客户端允许的其他工具(例如浏览器自动化或 osascript)发送的消息。
  • **它会告诉你哪些地方可以绕过防护。**此防护只管控该服务自身的调用,不会管控你的整台 Mac。computer_permissions 会列出它在客户端中识别到的规则,这些规则允许 Agent 绕过此防护直接点击、输入或发送,例如 shell、sudo、osascript、脚本解释器、浏览器或电脑自动化;你可以据此决定是否保留这些规则。它会读取 Claude Code 的设置,不会读取其他客户端的设置。
  • 有些操作永远无法通过此处批准:始终需要确认的应用(密码管理器)、无法确定目标应用的操作,以及未遮盖的屏幕截图。这些操作仍会被拒绝,并显示在 computer_pending 中。
  • **默认显示通知横幅,但横幅中绝不提供按钮。**有新问题时会显示横幅,前提是 macOS 允许 Computer MCP 显示通知(系统会询问一次)。如果通知中有 Allow 按钮,就会提供第二种确认“是”的方式——而 Agent 也可以点击通知——因此点击横幅只会在方框中显示问题,“是”仍只能在那里确认。问题得到回答或过期后,横幅就会消失。你可以在图标菜单中将其关闭。
  • **每个新问题都会播放提示音。**每个新问题都会播放一次提示音;你可以在图标菜单中将其关闭。同一个问题重复发送时不会再次播放,问题过期时也不会播放。
  • **Agent 无法操作图标。**任何针对图标的写入工具调用,在所有模式下都会被拒绝,甚至不会进入防护确认流程。实测结果:没有这条规则时,三次按压中有三次触发了辅助程序。
  • **立即停止所有 Agent。**只要有 Agent 已连接或正在使用屏幕(除非你隐藏了图标),图标菜单中就会显示 Stop all agents now;只要有 Agent 正在工作,方框中也会显示此选项。图标运行时,在任何应用中按 ⌃⌥⌘.(Control-Option-Command-period)也会执行相同操作(最后一个 Agent 结束后十秒,以及图标被隐藏时,快捷键就会失效);Agent 正在使用屏幕时,按 Esc 也会停止操作并交还屏幕(如果 Esc 可能被其他程序拦截,方框会说明这一点)。只有快捷键可用时,菜单才会显示该快捷键——其他应用或 macOS 的“增加对比度”可能会占用相同按键;菜单项和方框中的选项始终可用。使用同一状态文件夹的所有 Agent 都会停止:不会执行任何待处理操作,方框中的问题会被撤回,所有“本次会话剩余时间内均予以允许”的确认都会被撤回,录制会停止,正在进行的拖动、点击或按键也会被释放。两分钟内,任何写入操作都会返回“已停止”,并告知 Agent 在聊天中向你询问;读取操作仍可正常进行。停止并非锁定:两分钟后 Agent 可以再次操作;使用自有 shell 的工具或使用不同状态文件夹的服务也不会受到影响。Agent 无法代替你按下此快捷键。 如果菜单栏被隐藏(例如全屏应用或自动隐藏),图标也会随之隐藏,屏幕上的其他所有状态图标也一样。这样一来,问题可能一直无人注意,直到过期。这是目前确实存在的限制,不是可调整的设置。

它不做什么

  • 仅支持 macOS(14+)。没有 Windows 或 Linux 版本,也没有开发计划。
  • **只有 macOS 标记为安全的内容才会被遮盖。**纯文本编辑器中的密码或终端缓冲区中的令牌都不会被标记,也不会被隐藏。readonly 在这里无济于事:它仍然会截图。请先关闭此类窗口,或使用 app 将截图范围限定为一个应用;用另一个窗口遮住它还不够,因为截图时遮挡窗口可能不会被纳入。
  • **密码管理器不会出现在截图画面中。**截图会让 macOS 将拒绝列表中的所有应用排除在图像之外,因此这些应用的像素根本不会存在——截图过程中隐藏、移动或关闭密码管理器都不会泄露内容,而且它也不可能单独出现在截图中。之后仍会继续进行遮盖。仍未解决的问题是:普通应用中的安全字段若在扫描期间移动,遮盖会绘制在它现在的位置,而不是原来的位置。字段显示的是圆点,所以泄露的是长度,而不是密码。密码管理器运行的辅助进程使用不同的应用 ID,目前还未列入列表。此处未进行验证:macOS 是否真的会排除这些像素——这需要实际截图,而我们不会为此截取任何人的屏幕。
  • **征求同意不等于隔离。**你批准后,Agent 会操作你的真实 Mac——这正是你批准的内容。如果你需要的是隔离边界,而不是一次授权,请在虚拟机中运行。这是坦诚的答复,不是缺失的功能。
  • **无法指望它看见网页内部的内容。**9 月 23 日在两个 Chrome 上进行了测试——正在使用的 Chrome 和干净的 Chrome for Testing:辅助功能树中有 零个网页区域,没有页面文本,只有浏览器自身的按钮和地址栏。Chrome 为真正的屏幕阅读器构建这棵树,而不是为 Electron 应用支持的开关构建。基于 Electron 构建的应用——VS Code、Slack、Notion,以及进行此次测试的 IDE——会暴露其内容:一个窗口中有 4.000 个节点、1.434 段文本和 267 个按钮。10 月 9 日,同一台 Mac 上的 Chrome 确实显示了页面内容(一个页面上有 861 个节点)。原因未经测量——Chrome 会自行决定何时构建这棵树。在完成测量并据此构建之前,请将网页交给浏览器工具处理,将应用交给这个工具处理。
  • **Chromium 窗口未获得焦点时,按键不会输入其中。**同一天进行的测试中,辅助进程报告了 typed: 21 和 took_screen: false,但文本没有出现在任何地方。通过辅助功能层使用 computer_set_value 确实生效了——内容输入到了地址栏,它属于浏览器自身的界面。因此,静默操作应使用 computer_find + computer_press / computer_set_value,而不是输入文本。
  • **坐标点击会根据该位置下方的内容进行判断。**判断对象是 macOS 指定的所属应用,以及其上方一直到第一个不透明窗口的所有叠放窗口;点击前会再次检查。如果 macOS 报告某个窗口是不透明的,但它允许点击穿透到下方内容,那么此检查无法发现这一点。此处未经测试:这需要在非他人工作用的 Mac 上使用真实窗口进行验证。
  • **提示词注入仍有可能发生。**对话框和日志会让它显而易见,而不是悄无声息地发生,但无法让它变得不可能。
  • **后台模式下无法操作菜单和文件对话框,弹出式按钮除外。**测试结果:菜单打开时会占用 macOS 的整个输入流——菜单打开期间,系统甚至不会说明哪个应用拥有焦点;在后台应用的保存面板中,“保存”按钮也一直处于禁用状态。因此,任何可能在后台打开菜单的点击、按压或按键都会被拒绝,而灰显的“保存”按钮会返回 disabled。可以通过 computer_set_value 选择弹出式按钮中的选项:菜单会短暂显示在屏幕上(我们对两个选项进行的测试中约为 0.15 s),只有在你 2 s 内没有输入时才会继续;如果你在按下选项前开始操作,就不会选择任何内容;返回结果会说明菜单是如何关闭的。普通按钮弹出的菜单无法预先识别——如果菜单仍在你的工作界面上方打开,Agent 会尝试按 Escape 将其关闭,返回结果会说明发生了什么:已关闭、仍打开,或无法检查。

从源代码构建

git clone https://github.com/Agent360dk/computerMCP
cd computerMCP/helper && swift build -c release     # the privileged binary
cd ../mcp-server && npm install
CMCP_MODE=readonly node index.js

这个辅助程序是一个独立的 Swift 二进制文件,没有任何第三方依赖。 它负责使用辅助功能和屏幕录制功能,规模小到可以一口气读完, 并且可以替换,而不会影响服务。(macOS 会将这些权限授予哪个进程, 是另一个问题,而且尚无定论——请参阅“安装”下的说明。)每个被打包进 这种特权二进制文件的组件,都是你在未作选择的情况下信任的供应商。

测试

./test/run-all.sh                # everything, full output kept in a log

python3 test/redaction-unit.py   # the four redaction checks
node test/server-e2e.mjs         # the MCP protocol, read paths, readonly refusal
node test/failclosed.mjs         # an unanswered dialog must refuse
node test/claims.mjs             # every claim this README makes
node test/concurrent.mjs         # two servers at once: no torn lines, both identifiable
./test/redaction-proof.sh        # live secure-field detection (needs a normal desktop)

claims.mjs 会对照代码检查首页上的陈述:终端在 allow 模式下仍会 询问,无害应用不会询问(否则“拒绝所有内容”也能通过),输入的文本 只会以长度和哈希值的形式进入日志,并且没有新增 shell、文件或 URL 工具。

如果某项检查无法有意义地执行——例如屏幕上恰好没有安全字段——它会报告 SKIPPED,而不是报告通过。测试存在的目的,就是避免出现这种情况:测试套件 显示全绿,却什么也没测到。

redaction-unit.py 会自行构建图像,而不是测量实时屏幕。 第一个版本测量的是真实桌面——在编辑器全屏运行的机器上,测试窗口根本 无法显示,因此测试测量了一张空白截图,却把结果判定为通过。看不到任何 内容却能通过的安全测试,比没有测试更糟糕。

redaction-proof.sh 仍会测试实时流程,并且需要桌面不处于全屏模式。 它会明确报错,而不是悄悄跳过。

帮助构建

脱敏列表收录了我们想到的密码管理器,但没有你的银行应用、公司的机密 管理器,也没有你所在地区流行的任何应用。一支团队无法编写这份列表; 许多人各添加一行就能做到——每有人贡献一个应用,就能让之后安装此工具 的所有人都更安全。

你只需要填写问题表单, 不需要编写代码。记录某个 Mac 应用的实际行为也是如此。这些知识目前只存在于 那些已经亲自应对过该应用的人的脑海中。

愿望清单列出了其余事项:待处理事项、如实评估的工作量, 没有分配给任何人。贡献指南。

谁在打造它

由 Agent360 打造。这是一家丹麦公司,致力于构建 能完成实际工作的 Agent:

  • Browser MCP——为真实的、已登录的 Chrome 提供相同理念。它与本项目同期编写,二者会共享经验。
  • JesperAI——能在电话中进行真实对话的语音 Agent。
  • ForbrugerAgenten——能够读取家庭账单, 并为你更换供应商的 Agent。

这里的所有内容均采用 MIT 许可,并在你的机器上运行。以上任何产品都不是 必需组件,也不会被打包进来或向外发送数据。

本项目的目标

开发者可信度,而非增长引擎。 与其姊妹项目 browser-mcp 的宗旨相同: 诚实、纠正不实陈述,并设置真正能够变红的防护措施。除非有人提出要求, 否则增长、SEO 和渠道运营都不是本项目的工作。

完整宗旨,以及本项目得以存在的唯一理由,见 MANDAT.md。

隐私

此服务不会让任何内容离开你的设备。无需账户,不会收集遥测数据,处理流程中没有我们的服务,而且服务不会自行发起任何网络请求。

  • 屏幕截图会发送到你配置的 MCP 客户端——也就是对话内容发送到的同一处——不会发送到其他地方。安全文本字段会在 PNG 写入前从图像缓冲区中涂黑,因此发送的文件中不会包含密码。
  • 审计日志只保存在你的磁盘上,路径为 ~/.local/state/computer-mcp/audit.jsonl。日志会保存输入文本加盐后的指纹,绝不保存文本本身。同一文件夹还存放 Agent 用于协调的小文件(锁、会话、停止信号),以及 Agent 使用 computer_learning 保存的笔记。删除该文件夹即可全部清除。
  • 我们不收集任何信息。 不收集标识符、使用次数或崩溃报告。

完整政策:https://computermcp.dev/privacy.html

许可证

MIT © Agent360 Group ApS.

评论

支持 Markdown

第一次接触 MCP?

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

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