关于 hypruse
hypruse 是面向 Hyprland 的 MCP 服务,让 AI Agent 通过 Wayland IPC、无障碍树和原生输入控制桌面。它结合语义化窗口状态与按需截图,支持在不同工作区操作应用而不干扰用户当前操作。
主要功能
- 01读取窗口、工作区和显示器状态
- 02通过无障碍名称操作控件
- 03截取屏幕、窗口和指定区域
- 04原生鼠标、键盘及窗口管理
- 05按桌面事件等待并执行操作序列
适用场景
- 01切换工作区并整理窗口
- 02在应用中定位并点击命名控件
- 03对缺少无障碍信息的界面使用截图操作
- 04在后台工作区启动并操作应用
MCP 相关
该 MCP 服务通过 STDIO 向客户端提供桌面状态、截图、输入和窗口管理工具。它还将每种工具作为 shell 命令提供给使用命令行的 Agent。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx hypruseHYPRUSE_SCREENSHOT_MODEHow captures are returned: 'file' writes to XDG_RUNTIME_DIR and returns the path, 'image' returns the image inline. Use 'image' for clients that render MCP images but cannot read files, such as Claude Desktop.HYPRUSE_READONLYSet to 1 to expose only the observation tools (desktop, screenshot, zoom, ui, marks, binds, wait_for). The agent can see and narrate but cannot click, type, or launch.HYPRUSE_CONFINERestrict input to a scope of windows and refuse everything outside it: 'launched' (only windows hypruse opened this session), 'class:firefox,kitty', or 'workspace:3,special:notes'. Unset means no confinement.HYPRUSE_AUTH_GUARD密钥Refuse to click or type into system authentication dialogs (polkit, keyring prompts). On by default; 'strict' also refuses password fields in ordinary windows; 0 disables it.HYPRUSE_STRICTSet to 1 to refuse to act when the cursor or focused window moved since hypruse's last action, so the agent must re-read the desktop before retrying.HYPRUSE_MARKSet to 1 to make the agent's presence legible: tag every window it opens 'hypruse-owned' and flash an on-screen notice when it opens a window or captures the screen.HYPRUSE_CLIPBOARDSet to 1 to register the opt-in clipboard tool (never in read-only mode). Off by default because clipboards hold passwords.HYPRUSE_JOURNALRecord every tool call, refusals included, as one NDJSON line: 1 writes to XDG_STATE_HOME/hypruse/journal.ndjson, or give a path. Read it back with 'hypruse journal'. Off by default.HYPRUSE_JOURNAL_MAX_BYTESRotate the journal once it reaches this size, keeping one previous generation alongside it. Set 0 to never rotate.HYPRUSE_JOURNAL_TEXTSet to 1 to record typed and copied text in the journal verbatim instead of as a length plus digest. Off by default because keystrokes are passwords; needed only to replay typing.HYPRUSE_DRYRUNSet to 1 for a rehearsal: every acting tool validates its arguments and runs every trust guard, then reports what it would have done and delivers no input.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
hypruse
适用于 Hyprland 的计算机操控。 一个 MCP 服务,为 AI Agent 提供对 Wayland 桌面的原生操控能力:工作区、窗口、鼠标、键盘和屏幕截图。
无需 ydotool 守护进程。无需 root。无需门户。无需 X11。

为什么要用
macOS 和 Windows 上已有计算机操控功能,但厂商的 Linux 应用仍不支持该功能:Claude Desktop 的 Linux 文档称 Linux 上无法使用计算机操控,而 ChatGPT 的计算机操控功能仅支持 macOS 和 Windows。Anthropic 的参考实现运行在 X11 容器中。其他 Wayland 工具则依赖 ydotool 和 uinput、仅适用于 GNOME 的门户,或是专为某个特定 Hyprland 版本构建的合成器插件。
与此同时,Hyprland 已经提供了 Agent 所需的一切,而且比任何辅助功能桥接都更完善:用于状态查询和窗口管理的完整 IPC 接口,以及用于输入的原生 Wayland 协议。hypruse 只需将它们接入 MCP:
- 语义优先。
desktop一次调用即可返回真实的窗口和工作区树(地址、类名、标题、几何信息)。Agent 通过切换工作区和聚焦窗口来操作,就像你一样(通过 IPC 即时完成),而不是眯着眼睛辨认像素。 - 必要时使用视觉。 可截取显示器、单个窗口(在 Hyprland 0.54+ 搭配 grim 1.5+ 时,即使窗口位于隐藏工作区或被其他窗口遮挡,也会直接截取该窗口本身;不过隐藏的应用可能会显示其上次的画面),或放大后的区域,并提供几何信息和缩放元数据,将任意像素映射到可点击的坐标:这种由粗到细的循环基于 GUI Agent 研究。
- 原生输入。 点击和滚动事件通过 Wayland 协议(
zwlr_virtual_pointer_v1)直接发送;输入文字则使用wtype的虚拟键盘和正确的 XKB 键位映射,可在任何键盘布局下安全输入 Unicode 字符。 - 与你并行工作。 Agent 可以在自己的工作区中操作应用,同时你继续使用自己的工作区。它通过辅助功能树按下控件,并通过辅助功能树或 Hyprland 的
sendshortcut输入文字,因此你的光标、键盘焦点和工作区都会保持原样。使用原生 Hyprland,无需合成器插件:请参阅后台模式。
工作原理
agent (Claude Code, or any MCP client)
│ stdio
▼
hypruse
├── hyprctl -j ········▶ desktop state: monitors, workspaces, windows, layers
├── hyprctl dispatch ··▶ focus / move / close / launch / movecursor,
│ and sendshortcut for keys to a hidden window
├── grim ··············▶ screenshots: monitor, window, region
├── D-Bus (AT-SPI) ····▶ accessibility tree: named controls, current
│ values, exact coords (ui / marks / click_ui),
│ and presses and text in the background
├── wtype ·············▶ keyboard (zwp_virtual_keyboard_v1, real XKB keymap)
└── raw Wayland wire ··▶ click & scroll (zwlr_virtual_pointer_v1)
可选二进制文件可启用另外两个工具:imagemagick 为 marks 绘制编号覆盖层,而 wl-clipboard 则为选择启用的 clipboard 工具提供支持。
设计决策:
- 不使用 ydotool / uinput。 这种方式需要守护进程、udev 规则或 root,而且输入的是在其他键盘布局下会出错的美国键盘扫描码。hypruse 只是合成器的另一个 Wayland 客户端,与
wlrctl一样。 - 不使用门户。
xdg-desktop-portal-hyprland未实现 RemoteDesktop 门户(InputCapture 用于捕获,而非注入),因此任何基于 libei/门户构建的工具在 Hyprland 上都会静默降级。hypruse 不会尝试使用它们。 - 通过合成器自身的光标分发器定位光标(使用全局逻辑坐标,可在任何显示器布局下精确定位),虚拟指针仅发送按钮和轴事件,从而避开绝对虚拟指针移动已知的多显示器问题(hyprwm/Hyprland#6749)。
工具
| 工具 | 功能 |
|---|---|
desktop | 一次调用获取语义快照:显示器、工作区、窗口(地址/类名/标题/几何信息)、活动窗口、光标和图层表面(启动器、栏、通知弹窗),并尽可能提供类型和几何信息。列出的图层是合成器跟踪的图层,并不代表你能看到它:透明和休眠表面也会报告,因此在需要确认可见性时请截图 |
screenshot | 可截取当前显示器、按地址指定的单个窗口(在 Hyprland 0.54+ 搭配 grim 1.5+ 时,即使窗口隐藏或被遮挡也可截取;元数据 visible 表示合成器是否正在绘制该窗口,source 表示像素来自窗口本身还是屏幕裁剪,隐藏窗口的截图可能已过时),或 x,y,WxH 区域;返回图像和坐标映射元数据;默认快速使用 JPEG(lossless=true 时使用 PNG);stable=true 会等待画面稳定 |
zoom | 围绕估算点以原生分辨率重新截图(可选择将范围限制在某个窗口内):这是点击小控件前的精确定位步骤,元数据约定相同 |
ui | 读取窗口的辅助功能树(适用于提供辅助功能树的 AT-SPI、GTK/Qt 应用),并返回带有准确全局坐标的可点击元素名称,无需截图;也会报告当前值(输入文本、滑块位置、复选框状态);如果应用未提供任何信息,则回退到视觉识别 |
marks | Set-of-Marks 截取:窗口截图中会为每个可访问控件绘制编号标记,并附上 JSON 图例(角色、名称、当前值,以及每个编号对应的准确点击位置);绘制标记需要 ImageMagick,没有它时则只返回图例 |
click_ui | 一次调用即可通过辅助功能名称或 marks 编号点击控件:坐标取自辅助功能树。在你当前所在窗口中,点击会通过真实指针执行(可见,并具备相同的安全保障);在其他窗口中,则会在后台触发控件的辅助功能操作。名称有歧义时会返回候选项,而不是猜测 |
pointer | 在全局坐标中移动/点击/拖动/滚动(离散滚轮格)。使用你的真实光标,因此默认情况下,如果输入目标位于其他窗口上,会拒绝执行 |
keyboard | 输入原样文本(安全支持 Unicode),或按下应用级组合键(ctrl+shift+t、esc、F5);可选的 window 地址用于指定按键发送目标:你当前所在的窗口会获得焦点并接收输入,其他窗口则在后台接收按键。合成器绑定(super+...)请使用 use_bind,而不是此工具 |
hypr | 切换工作区、聚焦/移动/关闭窗口、切换全屏或浮动(纯 IPC,耗时数毫秒;close_window 还会等待最多 1s,直到收到销毁事件,因此其结果和 then= 观察结果会反映关闭状态,而不会发生竞态) |
launch | 启动应用,默认在 Agent 自己的下一个工作区静默启动,除非指定工作区(或传入 background=false 以在你当前的工作区启动);等待应用实际触发 openwindow 事件后返回其地址;检测单实例应用(如浏览器)中忽略 exec 规则的窗口,并将其移至请求的工作区 |
binds | 用户自己的按键绑定,已解码(SUPER+Q、操作、描述);Agent 使用 use_bind 执行绑定 |
use_bind | 按组合键(SUPER+F)执行按键绑定及其对应操作,让 Agent 使用用户自己的启动器和快捷键。无法用于 hyprland.lua 中的绑定:这些是匿名闭包,Hyprland 没有提供调用方式,因此 binds 会将其显示为操作 lua,而 use_bind 也会明确说明,而不是含糊地失败 |
sequence | 一次调用中按顺序执行一组操作(pointer/keyboard/click_ui/hypr/wait_for);如果桌面发生当前步骤未预期的变化,则立即停止,因此点击/输入/回车组成的微型序列只需一次往返,而非多次 |
wait_for | 等待实际的合成器事件(窗口打开/关闭、工作区更改、标题更改、图层表面出现/关闭、紧急状态、屏幕共享开启/关闭),并支持匹配筛选和超时;如果经过筛选的等待条件已经满足(窗口已消失、工作区已激活、图层已映射),则会立即返回 already: true,不会错过订阅前已触发的事件。可替代多步自动化中的休眠等待 |
clipboard | 通过 wl-clipboard 读取或写入文本剪贴板;需主动启用,且仅当服务环境中设置了 HYPRUSE_CLIPBOARD=1 时才可用 |
操作工具(pointer、keyboard、click_ui、hypr、use_bind、sequence)接受可选的 then 参数,可将结果附加到同一次调用中,让 Agent 无需再进行一次往返即可看到效果:then='desktop' 会添加一份最新的语义快照(约 20 ms,开销低,最适合窗口或焦点变化);then='screenshot' 会添加一张稳定的截图(最适合视觉变化);then='ui' 会添加操作窗口的控件及其当前值(精确占用几百个 token,最适合输入文字或切换选项之后;click_ui 会读取被点击的窗口,即使点击操作将焦点交给了对话框,其他工具则会读取当前聚焦的窗口);then='none' 表示不添加任何内容(除 sequence 默认值为 'desktop' 外,其他工具的默认值都是 'none')。 |
每个工具也都是一个 shell 动词(适用于运行命令而非 MCP 的 Agent):hypruse desktop、hypruse click_ui Save --window 0x...,并配有教会 Agent 使用方法的技能:参见Shell 动词和 Agent 技能。
功能
这些工具分为五种能力,按可靠性从高到低、开销从低到高排列。按此顺序使用这些工具,Agent 的速度和准确度都会更高,而且许多任务根本不需要截图。
1. 语义化桌面控制(从这里开始)
desktop 一次调用即可返回完整的窗口和工作区树:每个窗口的地址、类名、标题和几何信息、当前活动窗口、光标,以及合成器正在跟踪的所有图层表面(启动器、栏、通知弹窗)。随后,hypr 和 launch 可通过 IPC 在毫秒内执行操作:切换工作区,按地址聚焦、移动、关闭、全屏显示或浮动窗口,或启动应用。
善用方法: 切勿为了查找或排列窗口而截图。读取 desktop 的结果,然后对目标地址执行操作。launch 会等待实际的 openwindow 事件,并返回新窗口的地址,因此无需轮询或猜测;它还会移动忽略工作区规则的单实例应用(如浏览器)。
2. 按名称点击控件,无需像素坐标
当应用提供无障碍树时(大多数 GTK 和 Qt 应用都提供),你可以按名称定位控件,而不用依赖像素坐标。ui 会列出每个控件及其精确的全局坐标,并报告带有值的控件的当前值:输入框中的文字、滑块的百分比、复选框的状态。click_ui 会在一次调用中解析名称并点击控件,使用真实光标(因此信标和所有安全保障仍然适用);如果目标窗口未处于当前桌面,则会通过控件自身的无障碍操作完成点击,不会触碰光标。marks 会在截图上绘制带编号的标记并附上图例,适用于想先查看选项,再使用 click_ui(mark=N) 的情况。
善用方法: 在估算任何像素坐标之前,先使用 click_ui name="Save",因为它精确且不消耗图像。使用 ui 读取表单状态(框是否真的已勾选?),而不是截图查看。如果名称存在歧义,工具会返回候选项,而不会猜测。当应用不提供无障碍树时(终端、画布应用,以及未启用 --force-renderer-accessibility 的 Electron/Chrome),工具会明确告知,你可以改用视觉识别。
3. 在需要时使用视觉识别:缩放循环
对于无障碍树无法命名的内容,screenshot(显示器、窗口或区域)和 zoom(围绕某个点以原生分辨率重新截图)遵循严格的坐标约定:global = geometry + pixel / scale,确保在所有显示器和小数缩放比例下坐标始终精确。
善用方法: 不要根据全屏图像猜测小型控件的位置。按由粗到细的顺序操作:截取窗口截图,估算目标位置,在该处使用 zoom,根据清晰的裁剪图重新估算,然后点击。研究已验证,采用这种两步循环最适合点击小型目标;详见研究。
4. 减少往返调用:降低延迟的关键
对于 Agent,模型调用是任务延迟的主要来源,而不是桌面,因此真正的提速要从结构入手。sequence 会在单次调用中按顺序执行微型计划(点击、输入、按回车、等待),一旦桌面发生了步骤未预期的结构性变化,就立即停止(窗口打开、关闭或移动,意外切换工作区,或占据操作席位的启动器或屏幕键盘;它会刻意忽略单纯的焦点变化和通知弹窗)。then='desktop' | 'screenshot' | 'ui' 会将结果的最新视图融合到执行操作的调用本身。wait_for 会等待实际的合成器事件(窗口或启动器打开、标题更改、工作区切换、紧急提示、开始屏幕共享),而不是单纯休眠并寄希望于事情发生。
**善用方式:**将已知的点击/输入/回车流程合并为一个 sequence。在表单中输入后,添加 then='ui',用几百个精确 token 读取操作结果,而不是查看屏幕截图。启动应用或使用会打开内容的快捷键后,通过 wait_for 等待事件,而不是休眠。
5. 安全委派:信任层级
hypruse 会让 Agent 使用你的实际操作席位,因此它提供了限制 Agent 操作范围的控制措施。除了始终启用的审批提示和 Waybar 活动指示器之外,还可以选择启用环境变量标志,进一步限制 Agent 可以操作的内容:HYPRUSE_READONLY 仅开放观察工具;HYPRUSE_CONFINE 将输入限制在 Agent 启动的窗口内,或限制在允许列表中的类/工作区内;HYPRUSE_AUTH_GUARD(默认开启)会拒绝操作身份验证对话框;HYPRUSE_STRICT 会在你重新接管操作席位时拒绝执行操作;HYPRUSE_MARK 会标记由 Agent 所有的窗口,并在 Agent 打开窗口或截取屏幕时发出提示。还有两个标志只记录而不限制操作:HYPRUSE_JOURNAL 会为每次工具调用(包括拒绝的调用)写入一条可审计的 NDJSON 记录;HYPRUSE_DRYRUN 会执行所有检查但不实际执行任何操作,让你可以先观察 Agent 如何规划工作,再让它操作桌面。
**善用方式:**第一周先以只读模式运行。当你信任某个工作流后,再允许列表中相应的工具;如果你想离开一会儿,可以将 Agent 限制在指定范围内,避免它在其他工作区点击或输入内容到你的密码管理器。准备好紧急停止命令(hypruse stop,或 pkill -f hypruse)。安全模型中有完整说明。
后台模式
Agent 可以在你看不到的工作区中操作应用,同时你继续处理自己的工作。在原生 Hyprland 上,没有合成器插件时,hypruse 不会移动你的光标、抢占键盘焦点,也不会切换你的工作区来执行操作。应用仍可能因 Agent 的操作而将自己的某个窗口置于前台;如果这导致当前聚焦窗口发生变化,结果会说明这一点。
此模式默认开启,并设为自动模式。对当前所在窗口执行的操作会像往常一样在你的屏幕上进行。对其他任何窗口执行的操作则会在后台进行:
click_ui通过应用的辅助功能操作来按下控件。文本字段会改用应用自身的焦点(GTK 4 除外,因为它不允许这样做)。如果没有按钮、框或字段与名称匹配,click_ui也会对具有操作的其他角色的同名元素执行操作,例如 Web 应用列表中的一行。其中一些操作只会聚焦元素(Qt WebEngine 的行没有其他操作)。结果会说明它聚焦了该元素,以及应用是否报告该元素已聚焦。这不会打开该行:测试中,向已聚焦的 Qt WebEngine 行发送 Enter 也无法将其打开。- 带有
window=的keyboard会通过辅助功能接口,将文本输入到窗口中已聚焦的文本字段(或唯一的文本字段)。否则,它会通过 Hyprland 的sendshortcut,按照你的键盘布局逐键将按键仅发送到该窗口。换行、制表符和退格始终作为按键发送。按键会发给应用自身聚焦的控件,而该控件不一定是文本输入到的字段,因此 Agent 会先用click_ui聚焦字段,再向其发送按键。 - 不指定工作区的
launch会在 Agent 自己的某个工作区中打开应用,不会出现在你的视野中。 - 指针就是你的真实光标,因此无法在后台操作。如果输入会落到不属于你的窗口上,操作就会被拒绝,并提示 Agent 改用
click_ui。
无法在后台执行的操作会被拒绝,并说明原因和替代做法。调用时设置 background=false(CLI 中使用 --foreground)即可在你的屏幕上执行。
设置
此保证优先于所有其他设置。没有此保证时,调用自身的 background 参数优先于自动规则。
| 设置 | 作用 |
|---|---|
HYPRUSE_BACKGROUND=1 | 此保证生效。Agent 只会在自己的工作区中的窗口上操作。指针操作、工作区切换、focus_window、fullscreen、未指定目标的 toggle_floating 和 use_bind 都会被拒绝;move_window 和 launch 只会使用 Agent 的工作区(且不会使用当前显示在屏幕上的工作区);background=false 也会被拒绝。 |
background=true 或 false | 在每次调用 click_ui、keyboard、pointer、launch 和 sequence 时指定(CLI:--background、--foreground)。true 会强制在后台执行,并拒绝无法在后台完成的操作;false 会请求在你的屏幕上执行。对于 sequence,此设置会应用于指针、键盘和 click_ui 步骤;此外,true 还会拒绝会切换你的工作区或焦点的 hypr 步骤。 |
| 未设置 | 自动处理,如上所述。 |
HYPRUSE_BACKGROUND=0 | 关闭:操作会像 0.12 中那样在你的屏幕上执行,除非调用传入 background=true。(ui 仍会列出可编辑文本字段并附上说明;请参阅更新日志。) |
此保证限制的是 hypruse 自身的输入。它无法限制 launch 启动程序后该程序的行为:命令会按原样通过 shell 运行,因此即使设置了 HYPRUSE_BACKGROUND=1,也请确保 launch 仍受客户端的审批提示约束。
Agent 的工作区由 HYPRUSE_AGENT_WORKSPACES 指定,默认从 99 到 90,位于编号的高端,以免与您使用的工作区重叠。A-B 支持两个方向的范围;逗号分隔列表(99,98,50)和命名工作区(name:research)也可使用。HYPRUSE_AGENT_FILL(默认值为 1)用于设置 Agent 的应用在切换到下一个工作区之前,共用一个工作区的数量。设为 1 时,每个应用都会独占一个工作区,从而让隐藏窗口保持完整尺寸。如果某个范围内的工作区包含您的窗口,则会跳过该工作区;您正在查看的工作区也会跳过,以确保您的窗口和 Agent 的窗口不会混在一起。整个范围都已占满时,下一个应用会放到 Agent 使用最少的工作区中。较早的会话打开的窗口,如果被 HYPRUSE_MARK 标记,也会计为 Agent 的窗口。设置 HYPRUSE_CONFINE=workspace:... 后,应用只会在此范围内的 Agent 工作区中打开;如果没有此类工作区,则仍会像以前一样在您的工作区中打开。
launch 会等待它自己的窗口:即在指定工作区打开的窗口,或属于已启动程序自身类别的窗口。您在此期间打开的其他应用窗口会保持不动;同一应用的窗口则可能会被视为已启动应用的窗口。已经运行的应用(通常是浏览器)会从正在运行的进程中打开新窗口,而该进程会忽略工作区规则,因此新窗口会出现在您的屏幕上并取得焦点,直到 hypruse 将其移走;结果会说明这一情况,并且在保证生效时会附带警告。为 Agent 启动单独的实例(浏览器则使用单独的配置文件)即可避免此问题。
返回内容
每个后台结果都会说明操作是如何执行的、操作前后您聚焦的窗口和工作区是否相同;对于带有值的控件,还会说明无障碍树读回的内容:
pressed check box 'Agree' through its accessibility action (no pointer, the human's focus untouched) in yad; now: checked=true
typed 12 characters into the text field in yad through the accessibility interface (the human's focus untouched); the field now holds the typed text (12 characters)
sent ctrl+a to 0x5648592451c0 (yad) with sendshortcut, to the control the app has focused (the human's focus untouched)
如果应用忽略了对复选框或滑块的操作,读回结果会显示 no change seen。按钮操作、聚焦字段或通过 sendshortcut 发送的按键都没有可读回的值,因此请通过 ui 检查效果。如果操作期间您聚焦的窗口发生变化(因为应用将某个窗口调到前台,或因为您切换了窗口),结果末尾会显示一条 WARNING,指出当前聚焦的窗口。键入操作的结果不会重复文本,因为日志会保留每一行结果,而键入文本始终只记录为长度和摘要。截图不会用于确认任何内容,因为许多应用在隐藏时会停止绘制,隐藏窗口的像素可能已过期;ui 会显示窗口的当前状态。
限制
- 只有无障碍树公开的控件才能在后台按下,而且只能执行其主要操作:右键或双击会被拒绝。在隐藏窗口中点击任意位置需要合成器插件或独立的输入座席,而本设计避免了这一点。没有无障碍树的应用(终端、画布应用,以及未使用
--force-renderer-accessibility的 Electron 和 Chrome)仍可接收按键。 - 无障碍树通过标题或大小区分应用的窗口。如果两者都无法将目标窗口与该应用的其他窗口区分开来(例如,单实例应用的第二个窗口与第一个窗口标题和大小相同),或者应用的无障碍连接属于与其窗口不同的进程,hypruse 就无法确定某个控件属于哪个窗口:此时
click_ui会拒绝操作,keyboard会发送按键,Hyprland 会将按键发给窗口本身,而ui会提示其控件可能属于另一个窗口。 - 隐藏窗口的
ui坐标是控件在窗口内部的位置,而不是它们在屏幕上的位置;这些坐标对应的屏幕区域显示的是你自己的窗口。ui最后会附上说明,因为在这些坐标上使用pointer点击会点到你当前看到的内容。 - GTK 3 应用中的字段通过无障碍接口获得焦点时,会将窗口置于前台。如果启用了 Hyprland 的
misc:focus_on_activate,焦点就会切换到该应用,因此此时会拒绝聚焦 GTK 3 字段。无法查看按窗口设置的focus_on_activate规则;操作后的检查会报告这一点。 - 如果键盘布局中没有对应按键的字符(例如大多数布局中的表情符号或中日韩文字),只能通过无障碍接口输入。隐藏的 GTK 窗口不会报告多个文本字段中哪个字段处于焦点,因此在多字段表单中,此类文本会在发送任何按键前被拒绝;如果表单的多个字段中包含密码字段,向其中输入内容也会被拒绝,除非设置了
allow_auth=true。 - 对于每个按键,
sendshortcut都会在一个合成器步骤内将键盘焦点移到目标窗口,然后再移回来,因此你自己的输入不会混入其中。应用确实会看到焦点离开后又返回,大多数应用会忽略这一情况,但少数应用会关闭已打开的菜单。 - 对于 XWayland 窗口,
sendshortcut会被拒绝,因为当两个窗口都使用 XWayland 时,Hyprland 会将按键发送给当前聚焦的窗口。 - 使用多个键盘布局时,
sendshortcut仅在你使用第一个布局时有效。Hyprland 会根据当前布局查找每个按键,但应用会按第一个布局读取按键;在其他布局下会输入不同的字符,因此 hypruse 会拒绝操作。通过无障碍接口输入文本不受布局影响。 - 后台网页需要浏览器桥接功能,该功能将在后续版本中提供。
- 会话锁定时,后台操作和所有其他输入一样会被拒绝。
每层信任保护都适用于后台操作路径:隔离检查会验证目标窗口,身份验证保护会拒绝在身份验证对话框中执行后台按键或键盘输入,而向无障碍树显示的密码字段输入内容则需要设置 allow_auth=true(与前台操作一样,没有无障碍树的应用无法进行此项检查)。你无法看到后台操作,因此对于任何无人值守的操作,请设置 HYPRUSE_BACKGROUND=1:输入会留在 Agent 的工作区中,hypruse 自身的输入不会占用你的屏幕(Agent 启动的应用可能会占用,结果中会给出警告),日志会记录每条结果及其操作方法,而 HYPRUSE_MARK 会在 Agent 打开窗口时通知你。
Shell 动词与 Agent 技能
并非每个 Agent 都支持 MCP;即使支持的 Agent,也越来越倾向于使用命令行:在首次调用前,工具列表每个会话就要耗费几千个 Token,而 Shell 动词在运行前无需任何开销。因此,同样的 15 个工具也可以作为动词使用,调用 MCP 服务注册的同一组函数,并遵循相同的信任防护、日志记录和活动信标:
hypruse desktop # one line per monitor, workspace, window, layer
hypruse launch --workspace 2 -- firefox --new-window https://example.org
hypruse ui --window 0x55a4479a1200 --name Save # [0] push button "Save" @1204,88
hypruse click_ui Save --window 0x55a4479a1200 --then ui
hypruse screenshot --window 0x55a4479a1200 # a file path, then {"geometry":[x,y,w,h],"scale":1.0,...}
hypruse zoom 1180 840 --window 0x55a4479a1200
hypruse keyboard type "hello" --window 0x55a4479a1200
hypruse wait_for title_change --match Inbox --timeout 10
hypruse sequence '[{"op":"click_ui","name":"Search","window":"0x55a4479a1200"},{"op":"keyboard","action":"type","text":"btop","window":"0x55a4479a1200"},{"op":"keyboard","action":"key","keys":"enter","window":"0x55a4479a1200"}]'
这份约定是为读取输出的程序设计的:动词就是工具名称,工具的 action 是位置子动词(pointer click 800 60、hypr workspace 3、clipboard read),输出是精简的纯文本(每条事实占一行,使用 --json 可将原始结果作为单行输出),捕获操作会打印文件路径和坐标元数据,而不是字节数据;错误会在 stderr 上输出一行有意义的信息,并返回相应的退出码:0 表示已交付,1 表示错误,2 表示用法错误,3 表示被信任层(或只读模式)拒绝,4 表示已运行但没有可操作的内容(wait_for 超时、没有辅助功能树、名称不明确)。hypruse --help 会列出所有动词,hypruse <verb> --help 会列出其标志;--dry-run 可预演会执行操作的动词。动词启动只需几百毫秒:这条路径不会导入 MCP 堆栈。
在一次性进程之间,hypruse 会将动词原本会丢失的一些少量状态保存在 $XDG_RUNTIME_DIR/hypruse/cli-state.json 中,并按合成器实例进行区分:marks 的编号(因此 click_ui --mark N 可以正常工作)、launched 隔离集,以及 HYPRUSE_STRICT 的座位基线;否则,该基线可能会以开放模式失败。
这项技能会教 Agent 使用这些动词、桌面优先的工作流和安全规则,并随软件包一同发布。你可以将它安装到机器上各个 Agent 的技能目录中(Claude Code、Codex、Pi、Hermes、OpenClaw、OpenCode、Gemini、Antigravity、Cursor、Copilot),也可以通过 skills CLI 安装:
hypruse skill install # ~/.agents/skills/hypruse, linked into each agent that is installed
hypruse skill install --agent codex # one agent, created if absent
npx skills add IlyasKhallouki/hypruse -g
hypruse init 也会提供相同的安装选项。该技能仅预先批准观察类动词、doctor、--help 和读取捕获文件;执行操作的动词仍须通过 Agent 自带的审批提示,这正是 安全模型 所依赖的边界。
安装
要求:Hyprland(同时支持两种配置管理器:hyprland.conf,以及从 0.56 开始引入的 Lua 文件 hyprland.lua)、grim(在 Hyprland 0.54+ 上使用 grim 1.5+,窗口截图捕获的会是窗口本身;hypruse doctor 会告知你的环境是否支持)、wtype(大多数 Hyprland 配置中已经安装了前两者),以及 uv。辅助功能工具(ui/marks/click_ui)使用随 systemd 提供的 busctl 查找辅助功能总线,然后通过各自的单一连接与其通信。可选依赖:wl-clipboard,用于选择启用的剪贴板工具;imagemagick,用于带编号的 marks 捕获。
Arch Linux 用户可从 AUR 安装:
yay -S hypruse # or hypruse-git for main
然后让它自行完成设置,并验证环境:
hypruse init # detects your MCP clients, registers (asks first), offers the agent skill, runs doctor
hypruse doctor # just the diagnostics
手动注册,适用于 Claude Code:
claude mcp add -s user hypruse -- uvx hypruse
从源码检出目录安装:
claude mcp add -s user hypruse -- uv run --directory /path/to/hypruse hypruse
其他 MCP 客户端:运行 uvx hypruse,将其作为 stdio 服务启动。hypruse 也已收录在官方 MCP 注册表 中,名称为 io.github.IlyasKhallouki/hypruse,因此,支持浏览注册表的客户端可以直接从中安装。
**只读模式:**在服务配置中设置 HYPRUSE_READONLY=1,即可仅开放观察工具(desktop、screenshot、zoom、ui、marks、binds、wait_for)。Agent 可以查看并描述内容,但无法点击、输入或启动程序。很适合作为第一周的入门模式。
Claude Desktop(Linux 测试版)
Linux 测试版不包含 Anthropic 的第一方计算机使用功能,但 stdio MCP 服务可在聊天中使用,因此 hypruse 是一种变通方案。在 ~/.config/Claude/claude_desktop_config.json 中:
{
"mcpServers": {
"hypruse": {
"command": "uvx",
"args": ["hypruse"],
"env": { "HYPRUSE_SCREENSHOT_MODE": "image" }
}
}
}
两条仅适用于 Desktop 的说明:使用 image 模式(Desktop 会内嵌显示 MCP 图片,且没有文件读取工具);应用必须在 Hyprland 会话中原生运行,这样服务才能继承 WAYLAND_DISPLAY/HYPRLAND_INSTANCE_SIGNATURE;在 VM 或容器中运行时,应用无法访问你的合成器。如果你的 Desktop 安装绕过了工具审批提示,请务必启用 Waybar 指示器 + 紧急停止快捷键,不要将其视为可选项。
安全模型
安装前请阅读本节。**hypruse 会将鼠标、键盘、屏幕内容和应用启动器交给 Agent 使用。**以下各层机制共同确保安全:
- 审批: MCP 客户端会控制工具调用。在 Claude Code 中,将只读工具(
desktop、screenshot)加入允许列表;在你信任某个工作流之前,让pointer/keyboard/hypr/launch始终先询问。 - 可见性: 服务会维护活动指示文件(
$XDG_RUNTIME_DIR/hypruse/state.json);随附的 Waybar 模块在空闲时不可见,而当 Agent 正在操作你的桌面时会显示机器人指示图标。 - 中断: 点击指示图标,或绑定一个紧急停止键。通用写法适用于所有安装方式:
bind = SUPER SHIFT, BackSpace, exec, pkill -f hypruse。如果hypruse在你的 PATH 中(通过 AUR 或 pipx 安装),使用bind = SUPER SHIFT, BackSpace, exec, hypruse stop更好:它会通知服务正常关闭,释放任何按住的鼠标按键并清除活动指示文件。对于uvx安装,使用exec, uvx hypruse stop;对于源码检出,使用exec, uv run --directory /path/to/hypruse hypruse stop。无论哪种方式,在操作中途终止它都是安全的:按下/释放按键的组合不会跨越工具调用,而且即使是长按拖动时按住的鼠标键,也会在退出时释放。 - 座位是共享的。 只有一个光标和一个键盘焦点;Hyprland 的焦点跟随鼠标功能意味着,单独移动光标也可能改变按键输入的目标。Agent 正在操作你的窗口时不要打字;请留意指示图标。后台模式会让 Agent 避开你当前所在窗口之外的所有窗口。
- 范围: 仅使用 stdio(不监听网络);除活动指示文件、
$XDG_RUNTIME_DIR下有数量上限的屏幕截图缓存(tmpfs,保留最新 20 张),以及(如果启用)存放在$XDG_STATE_HOME下的操作日志(会轮换,仅保留一代,默认会对文本进行脱敏)外,不会持久化任何内容。除非你主动启用,否则不会访问剪贴板:HYPRUSE_CLIPBOARD=1会注册一个clipboard工具(只读模式下绝不会注册);剪贴板中可能包含密码,因此除非工作流需要,否则请保持关闭。屏幕截图能看到所有可见内容;窗口截图还会捕获隐藏工作区、scratchpad 中以及其他窗口下方的窗口:请将 Agent 会话视为共享整个桌面。只读模式和HYPRUSE_CONFINE限制的是 Agent 能做什么,而不是它能看到什么。会话锁定时,系统会拒绝窗口截图。 - Agent 读取的内容并不可信。 窗口标题、无障碍名称和值以及剪贴板文本都会原样进入 Agent 的上下文;任何网页、文件名或文档都可能在其中放入指令(提示词注入)。hypruse 无法净化内容的含义,因此审批层是最后一道防线:当 Agent 会查看不可信窗口时,请让重要工具(
launch、keyboard、clipboard)始终先询问;审核审批提示时,应将“屏幕上让我这么做”视为攻击者输入。 - 输入不会落到本来无法生效的位置。 三项始终启用的检查(没有环境变量开关)会拒绝操作或添加说明,而不会报告虚假的成功:目标位于启动器或屏幕键盘图层表面下方的点击(这些表面位于窗口上方,会拦截输入)、启动器占用键盘抓取时的键入,以及会话锁定期间的任何输入。锁屏由
ext-session-lock客户端实现,不会出现在窗口和图层列表中,因此 hypruse 会直接询问 Hyprland(hyprctl locked);此检查涵盖 hyprlock、swaylock、Omarchy 内置锁屏,以及崩溃后导致会话仍处于锁定状态的锁屏程序。锁定期间,pointer和不带window=的keyboard会拒绝操作,除非allow_auth=true表示用户希望 Agent 操作解锁提示(HYPRUSE_CONFINE下绝不允许);带window=的keyboard和click_ui则始终拒绝操作,因为发往窗口的输入无法穿过锁屏到达目标。这些检查旨在确保操作结果准确,并非沙箱:如果无法读取系统状态,锁定检查会默认放行,因此它们能加固常见场景,但不能作为可靠的安全边界。(启用HYPRUSE_AUTH_GUARD时,如果无法读取图层列表,pointer、click_ui和keyboard会拒绝操作,因为无法排除存在身份验证提示的可能。)
可选限制
七个可选的环境变量标志。前五个用于缩小 Agent 可操作的范围,且每个标志都会让操作倾向于更少;最后两个用于记录和演练,而非限制。它们都可以与上述各层组合使用:
HYPRUSE_CONFINE将输入限制在特定窗口范围内:launched(仅限 hypruse 在本次会话中打开的窗口)、class:firefox,kitty,或workspace:3,special:notes。超出范围时,键盘、click_ui和hypr窗口操作都会被拒绝;如果某个点下方有任何窗口不在范围内,则会拒绝pointer点击(Hyprland 的窗口列表未按 z 轴顺序排列,因此 hypruse 会采取默认拒绝,而不是猜测哪个窗口位于最上层)。这样,你就可以让 Agent 在后台工作,同时把密码管理器留在另一个工作区,使其无法触及密码管理器的点击和按键(但无法阻止它截图)。启用窗口限制时,会直接拒绝use_bind,因为按键绑定会运行无法限制到特定窗口的任意合成器操作。HYPRUSE_BACKGROUND=1提供后台模式保障:输入仅限于 Agent 自己工作区中的窗口(同时设置HYPRUSE_CONFINE时,也受其范围限制),并且会拒绝任何会控制你的光标、焦点或工作区的 hypruse 操作。但它无法限制通过launch启动的命令会执行什么操作。HYPRUSE_AUTH_GUARD(默认开启)会拒绝在系统身份验证对话框中点击或输入(polkit Agent,无论是 hyprpolkitagent 这样的窗口,还是 shell 作为图层绘制的提示词,例如 Omarchy 4 和 end-4 的 dots;GNOME 密钥环提示词;以及 Hyprland 自己的对话框,包括权限提示、应用无响应通知和安全模式通知,因为三者共用同一个窗口类),以防被操纵的 Agent 批准权限提升。如果此类对话框浮在要点击的控件上方,click_ui也会拒绝操作。无法读取图层列表时,hypruse 会拒绝操作,而不是猜测。shell 以自身普通窗口类打开的提示词(例如 DankMaterialShell)无法识别。设置HYPRUSE_AUTH_GUARD=strict,还会拒绝在普通窗口内的密码字段中输入(例如浏览器登录),并通过辅助功能树检测此类字段。对pointer/keyboard/click_ui的单次调用设置allow_auth=true可覆盖此保护;由于这会更改工具参数,因此覆盖操作会在批准提示中明确显示。HYPRUSE_AUTH_GUARD=0可禁用此保护。HYPRUSE_STRICT会在光标或焦点窗口自 hypruse 上次操作后发生移动时拒绝操作(这表示人或弹出窗口抢占了控制权):Agent 必须重新读取desktop/screenshot并重试,确保它不会在你刚切换到的窗口中输入内容。HYPRUSE_MARK会让 Agent 在桌面上的存在清晰可见:它会为 Agent 打开的每个窗口添加hypruse-owned标签,并在 Agent 打开窗口或截取屏幕时显示屏幕提示。它还会为该标签安装border_color窗口规则,让所属窗口显示彩色边框;但运行时规则能否生效取决于你的 Hyprland 版本和配置优先级(某些设置下规则不会生效)。如果规则完全无法安装,hypruse 会在 stderr 上说明,而不会留下一个悄然不起作用的标记图层。若要确保显示边框,可将规则添加到你自己的配置中,hypruse 添加的标签会与之匹配:在hyprland.conf中使用windowrule = border_color rgb(ff5555), tag hypruse-owned(较旧的 Hyprland 使用tag:hypruse-owned),或在hyprland.lua中使用hl.window_rule({ match = { tag = "hypruse-owned" }, border_color = "rgb(ff5555)" })。HYPRUSE_JOURNAL会记录 Agent 的操作:每次工具调用在$XDG_STATE_HOME/hypruse/journal.ndjson中记录一行 NDJSON(HYPRUSE_JOURNAL=1),也可以指定自定义路径。使用hypruse journal阅读记录,使用hypruse replay重新运行记录。参见下文的操作记录。HYPRUSE_DRYRUN用于演练:运行上述所有参数检查和保护措施,然后报告调用会执行什么操作,但不会实际执行任何操作。
操作记录:日志、试运行、重放
上述标志决定 Agent 此刻可以做什么,之后便不会再记得发生过这些操作。HYPRUSE_JOURNAL 就是记忆。每行一个 JSON 对象,因此 tail -f、grep 和 jq 都能处理正在写入的文件:
{"v":1,"seq":7,"ts":"2026-08-02T09:12:13.456Z","kind":"act","tool":"pointer",
"args":{"action":"click","x":800,"y":60},"outcome":"ok","ms":37,"result":"click ok"}
kind 将人们真正关心的两个问题区分开来:act 表示发送到桌面的输入,observe 表示 Agent 正在查看,这正是隐私审计所需要的(何时截取了屏幕,何时读取了剪贴板)。观察的结果不会被记录,只记录观察确实发生过,因此日志不会变成 Agent 所见内容的第二份副本。拒绝操作也会被记录,并附上防护机制自己的消息:这是信任层发挥作用的历史记录唯一存在的地方。
键入和复制的文本会记录其长度和简短摘要,而不是文本本身,因为按键可能是密码。只有在需要重放输入时,才需要设置 HYPRUSE_JOURNAL_TEXT=1,以原样记录文本。请注意摘要的作用与局限:它能证明两条记录输入了相同内容,但不会把你的密码泄露给读取者;不过它是未加盐的 SHA-256 前缀,旁边还带有精确字符数,因此四位数 PIN 可以轻易被还原。无论如何,都应将日志视为敏感数据。日志以 0600 权限写入 0700 目录,并在达到 HYPRUSE_JOURNAL_MAX_BYTES 时轮转(8 MiB,保留一个上一代文件,命名为 .1;设为 0 则永不轮转)。
日志是记录器,不是防护机制:如果无法写入,操作仍会执行,hypruse 会在 stderr 上警告一次,因为为了日志行而影响桌面并不是正确的取舍。它不会将 then= 观察单独记录为一条日志:包含该观察的操作调用会被记录,包括 then=screenshot,但截图本身不会再单独占一行。
使用 hypruse journal 查看日志(--acts 仅显示操作,--refused 显示被防护机制拦截的操作,-n N 查看末尾 N 条,-v 包含每条结果):
1 09:12:10 session start pid 4211 0.10.0 confine=launched auth_guard=1 strict=True
14 09:12:13 act pointer action=click x=800 y=60
16 09:12:15 act keyboard action=type text=<11 chars>
19 09:12:19 act hypr action=close_window target=0x5f2a10
REFUSED TrustError: 0x5f2a10 (Signal) is outside the agent's confinement scope
312 actions (0 dry), 604 observations, 1 refused by a trust layer, 0 errors
HYPRUSE_DRYRUN=1 会将同一会话变为演练模式。每个操作工具都会验证参数并运行所有信任防护机制,然后报告计划而不执行,因此演练模式拒绝的操作与真实运行时完全相同:
DRY RUN, nothing was delivered: would click push button 'Send' at (1204, 880) in signal
不会有任何内容到达桌面:既不会点击,也不会按键,甚至不会切换窗口焦点(通常在输入文字前会先切换焦点)。该机制会执行两次,一次在每个工具处,一次在输入路径本身,因此任何未被想到的代码路径都会大声报错,而不是在模拟过程中悄悄执行操作。Agent 会获知演练模式已开启,因此会报告计划,而不会重试“未成功”的操作。其适用范围是 Agent 的操作,而不是服务自身的启动过程:如果设置了 HYPRUSE_MARK,服务启动时仍会安装窗口规则。
hypruse replay <journal> 会通过相同的工具函数重新发出日志中的操作,因此重放也会应用相同的防护机制。它会打印计划并就此停止,除非你传入 --execute。在接管桌面之前,如果遇到以下情况,它会直接拒绝,而不是执行到一半失败、让你的桌面只完成了别人计划的一部分:某项操作由更新版本的 hypruse 记录;记录中的窗口已不存在(--skip-missing 会继续运行其余操作);键入的文本以摘要形式记录;条目是 click_ui(mark=N),其编号已随绘制该标记的会话结束而失效;条目是剪贴板写入,且未设置 HYPRUSE_CLIPBOARD;或者已设置 HYPRUSE_READONLY 或 HYPRUSE_DRYRUN。它会按照记录的时间间隔控制节奏,但受 --max-gap 限制并按 --speed 调整;它自己的操作也会被记录并标记,因此再次重放同一个文件时,执行的是原始计划,而不是原始计划加上重放操作。
需要坦诚说明的局限是窗口地址:它们是堆指针,因此昨天的日志大多指向已经不存在的窗口,而且某个地址之后甚至可能被另一个窗口复用,这一点任何预检查都无法发现。重放适用于在桌面仍与记录时相似的情况下重新运行一个工作流。
Dry run 和 replay 的组合方向很直观:让 Agent 使用 HYPRUSE_DRYRUN=1 工作,读取日志,然后在计划符合预期后使用 --execute 重放。
性能
在实时会话中测得(Hyprland 0.55,1080p,20 个窗口):desktop
约 20 ms(一次批量 hyprctl 调用),工作区/窗口分发约 10-20 ms,全屏截图约 65 ms
(默认使用快速 JPEG;如果请求无损 PNG,约为 800 ms,主要耗时来自 grim 的 zlib
路径),区域/缩放截图则快得多。如果工具调用感觉很慢,几乎可以肯定是每次调用前的 MCP 审批提示,而不是服务端。将你信任的工具加入允许列表,延迟就会消失。Claude Code(.claude/settings.json):
{
"permissions": {
"allow": [
"mcp__hypruse__desktop",
"mcp__hypruse__screenshot",
"mcp__hypruse__hypr"
// add pointer/keyboard/launch once you trust your workflows
]
}
}
坐标
所有操作都使用 Hyprland 的全局逻辑坐标,也就是 hyprctl cursorpos 和窗口 at 使用的坐标空间。截图使用像素坐标;每次截图都会返回 geometry 和 scale,因此 global = origin + pixel / scale。在缩放比例为 1.0 的显示器上(大多数配置如此),图像像素坐标就是全局坐标。
zoom 工具会为 Agent 完成精确计算:提供一个估算的全局坐标点,它就会在该点周围截取原生分辨率的区域,并将范围限制在屏幕内(或窗口内),同时遵循相同的元数据约定。这个两步循环——先在完整视图上估算,再根据缩放视图重新估算——是有研究支持的定位小控件的方法。
截图默认使用 JPEG q90:对于 1080p 画面,其编码速度约为 PNG 的 12 倍(主要耗时来自 grim 的 zlib 路径,实测约为 65 ms,而 PNG 约为 800 ms),文件也小 3-4 倍;而全分辨率 q90 能清晰呈现 UI 文本。在图像模式下,截图还会适配主机的结果大小限制(Claude Desktop 将工具结果上限设为 1 MB):由于 grim 的缩小滤镜比全分辨率截图更慢,因此会优先降低画质,而不是分辨率;同时会将长边限制为 HYPRUSE_MAX_IMAGE_EDGE 像素(默认值为 1568),以确保主机不会在模型收到图像前将其缩小。应用的缩放比例会纳入返回的元数据,因此坐标映射仍然精确;可通过 HYPRUSE_MAX_IMAGE_BYTES 调整,或传入 scale 来有意缩小视图。
默认情况下,截图工具会将图像写入 $XDG_RUNTIME_DIR/hypruse/ 并返回其路径;支持文件读取的 MCP 主机(例如 Claude Code 的 Read)会原生渲染该图像。之所以采用此默认设置,是因为某些主机(包括 Claude Code 2.1.x)会将内联 MCP 图像块序列化为模型无法查看的 base64 文本。HYPRUSE_SCREENSHOT_MODE=image 会切换为内联图像内容块,适用于能正确渲染这类内容的主机。
开发
uv sync --group dev
uv run pytest # unit tests, no compositor needed
uv run pytest -m e2e --override-ini addopts= # live seat-safe checks
uv run pytest -m background --override-ini addopts= # live: drives yad forms on the agent's workspaces
uv run python scripts/e2e_input.py # supervised: takes the seat ~10s
后台测试套件会在 Agent 的工作区中打开 yad 表单,在后台操作这些表单,并在每一步之后检查你的活动窗口、工作区和光标是否与之前完全一致,因此运行期间请勿操作鼠标和键盘。它还会检查 Hyprland 自身的事件;即使你继续工作,这些检查也会保持有效:它打开的窗口绝不会获得焦点,也不会切换到任何 Agent 工作区。
输入端到端测试刻意采用手动方式:它会借用你的光标和键盘,倒计时后通过读取目标终端屏幕(使用 kitty 远程控制)来验证点击、滚动和输入是否送达,并恢复你的焦点。
路线图
基于对热路径延迟的测量结果,以及 LLM 调用占计算机操作任务延迟 76% 至 96% 这一发现(OSWorld-Human),减少往返次数比节省几毫秒更有效。受这一思路推动的往返优化大多已经落地:sequence、执行并观察的 then=(包括 then='ui'),以及可通过名称定位控件、无需截图的无障碍树工具(ui、marks、click_ui)。剩余工作如下:
更快
- 通过原始线路实现进程内 wlr-screencopy(输入功能已经采用这种方式):降低小尺寸捕获时 grim 的进程派生开销,并添加基于损伤跟踪的等待稳定功能,在屏幕稳定后立即返回。
更少往返
- 语义屏幕差异:操作后只返回变化的内容(事件流中的窗口拓扑,或有界的变化区域裁剪图),而非完整画面。
wait_for背后的 socket2 事件扩展已经跟踪了大部分拓扑信息;缺少的是将这些信息整合进操作后的增量结果。
更深入地读取
- 扩大无障碍覆盖范围:填补
ui和marks工具目前遇到的缺口,主要是 GTK 较新的组合框既不公开文本也不公开选项(因此仍需通过截图读取渲染后的下拉值),以及 AT-SPI 值变更事件,以便then='ui'无需轮询即可报告控件已稳定。 - 通知:读取近期桌面通知的内容和历史记录,而不只是等待弹窗出现(
wait_for已能匹配通知命名空间中的layer_open)。
后台
- 通过浏览器桥接(一个扩展和一个原生消息传递主机)在后台使用网页。
信任
record工具:通过 wf-recorder(类似 grim 的 wlroots 系列二进制程序)录制 Agent 操作桌面的指定时段 GIF 或 mp4,作为 journal 的视觉补充。
平台
- 支持 sway / niri:线路客户端已经支持 wlr 协议;剩余工作是在
hyprctl.py旁边添加 IPC 层(欢迎贡献)。 - 在 CI 中进行无头端到端测试:需要 QEMU virtio-gpu 虚拟机,因为 Hyprland 的 aquamarine 后端需要真实的 GPU 渲染节点,而托管运行器不具备该节点。
测量
- 缩放循环精度基准测试:测量由粗到细循环对已知目标的点击准确度。
- Hyprland 端到端任务成功率基准测试(OSWorld 风格):这是延后的缩放循环微基准测试的更大型版本,通过真实 MCP 接口对完整的多步骤任务评分,以任务完成情况而非单纯延迟来评估无障碍与视觉方案以及往返优化。
相关项目
| 项目 | 方案 | 在 Hyprland 上的情况 |
|---|---|---|
| computer-use-linux | AT-SPI + portals,ydotool 回退 | 优先面向 GNOME;其偏好的 RemoteDesktop portal 未由 xdg-desktop-portal-hyprland 实现 |
| hyprmcp | hyprctl 封装 | 仅管理窗口;不支持截图或输入 |
| wayland-mcp | evemu 输入,VLM 分析 | 输入需要提升权限的设置;不支持 Hyprland 语义 |
| Anthropic computer-use-demo | Docker 中的 X11 + xdotool | 属于沙盒参考环境,而非实时桌面 |
| Cua (cua-driver) | 跨平台驱动;可选的 Hyprland 合成器插件可为 Agent 提供独立的输入座席 | 插件必须针对确切安装的 Hyprland 版本构建,其 README 将其称为实验性且尚未发布 |
研究
hypruse 不附带 OCR 引擎;它通用的精确定位机制是由粗到细的缩放循环:截取窗口截图,以原生分辨率重新捕获目标区域,再通过精确的坐标映射点击。这一选择遵循了 GUI Agent 领域形成的共识。Anthropic 的 computer use 根据原始像素确定点击位置,并提供 zoom 操作,作为文档中针对小字的解决方案;其针对点击位置偏差的故障排查指南建议放大并裁剪区域,而不是使用 OCR [1]。OpenAI 的 CUA 同样完全基于像素定位,并严格控制分辨率,完全没有 OCR 层 [2]。缩放也是经验证的有效手段:无需训练的迭代缩放可使高分辨率定位准确率大约翻倍(OS-Atlas-7B 在 ScreenSpot-Pro 上从 18.9 提升至 49.7)[3];该基准的官方测试框架实现了十多种定位模型适配器和四种缩放/裁剪策略,却没有任何 OCR 基线 [4]。仅靠视觉的 Agent 表现不逊于或优于还会读取 HTML 或辅助功能树的 Agent [5],而 Wayland 本就不保证提供这些信息;最先进的原生 Agent 也仅凭截图运行 [7]。hypruse 不采用 OCR,是因为 OCR 无法识别图标,而图标正是各定位模型最难处理的元素类别(SeeClick:图标识别率为 30-52%,文本为 56-78%)[6];在现代技术栈中仍保留 OCR 的场景里,它只是用于消除文本歧义的辅助机制,而非定位手段 [8]。
如果应用提供辅助功能树,hypruse 也会读取它(ui 工具,通过 D-Bus 使用 AT-SPI),从而按名称定位控件并获取精确坐标,无需截图。这遵循了 Linux 上最有力的先例:标准计算机使用基准 OSWorld 将桌面辅助功能树(在 Ubuntu 上通过 AT-SPI 获取)与截图一同作为一等观测数据,并报告称两者结合是效果最佳的配置 [9]。辅助功能树能提供精确的元素身份和坐标,而当前模型无法可靠地从像素中推断这些信息:Agent-S 为每个元素标注 ID,因为 MLLM“缺乏内部坐标系”,使 OSWorld 成功率从 11.2% 提升至 20.6% [10];Microsoft 的 UFO 通过 UI Automation 树操作 Windows,并将其与视觉信息融合 [11];浏览器 Agent 出于相同原因会读取辅助功能树(Playwright 会将其序列化为精简的 YAML),而不是读取像素 [12]。hypruse 针对 Wayland 的特殊处理是坐标映射:由于应用不知道自己的全局位置,Wayland 上的 AT-SPI 屏幕坐标并不可靠,因此 hypruse 使用窗口相对范围以及它已从 hyprctl 获取的窗口位置。覆盖情况本就参差不齐:canvas、游戏、终端,以及未启用相应标志的 Electron/Chrome 应用,可能几乎不提供信息或完全不提供信息 [13]。针对真实 GTK 和 Qt 应用测试这套实现,也进一步揭示了正反两方面的情况:输入框可以精确读回其中的内容,滑块和切换控件会报告其位置和状态;但 GTK 较新的组合框既不提供文本,也不提供选项,因此读取渲染后的下拉框值仍需要截图。工具包还会描述实际并未布局的控件(高度为零的滚动箭头、原点坐标达到数百万的未渲染标签页),hypruse 会依据 hyprctl 权威获知的窗口矩形将其排除。强大的视觉定位模型可以完全替代辅助功能树 [5],因此辅助功能树是对缩放循环的补充,而非替代;视觉方案始终是有保证的备用方案。
- Anthropic,计算机使用工具:平台文档(
computer_20251124、enable_zoom、分辨率指南) - OpenAI,计算机使用 Agent 和计算机使用指南
- DiMo-GUI:通过模态感知视觉推理提升 GUI 定位的测试时扩展能力,EMNLP 2025。arXiv:2507.00008
- Li 等人,ScreenSpot-Pro:面向专业高分辨率计算机使用的 GUI 定位。arXiv:2504.07981;官方测试框架
- Gou 等人,像人类一样探索数字世界:面向 GUI Agent 的通用视觉定位(UGround),ICLR 2025 口头报告。arXiv:2410.05243
- Cheng 等人,SeeClick:利用 GUI 定位构建先进的视觉 GUI Agent,ACL 2024。arXiv:2401.10935
- Qin 等人,UI-TARS:开创由原生 Agent 驱动的自动化 GUI 交互。arXiv:2501.12326
- Agyeya 等人,Agent S2:面向计算机使用 Agent 的组合式通用-专用框架(Tesseract 作为文本定位辅助组件)。arXiv:2504.00906
- Xie 等人,OSWorld:对真实计算机环境中的开放式任务进行多模态 Agent 基准测试。arXiv:2404.07972;在 Ubuntu 上通过 AT-SPI 获取 a11y 树(代码)
- Agashe 等人,Agent S:像人类一样使用计算机的开源 Agent 框架。arXiv:2410.08164
- Zhang 等人,UFO:面向 Windows OS 交互的 UI Agent(UI Automation + 视觉)。arXiv:2402.07939
- Playwright,ARIA 快照:将无障碍树作为精简的结构化文本
- Wang 等人,GUI Agent:综述(无障碍 API 覆盖范围存在缺口;a11y 可补充视觉)。arXiv:2412.13501
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。