mcpField
D
Deskwright

Deskwright

本地服务
github.com开发工具113 周前更新

关于 Deskwright

Deskwright 是面向 AI Agent 的 MCP 服务,可让其操作 GNOME Wayland 上的真实应用。它结合原生控件访问与视觉交互,也能运行独立虚拟桌面,避免占用用户屏幕。

主要功能

  1. 01启动并控制 GNOME 应用
  2. 02检查控件并执行受保护操作
  3. 03使用鼠标、键盘和剪贴板
  4. 04通过 OCR 读取屏幕文字并录屏
  5. 05在虚拟桌面运行具名会话

适用场景

  1. 01自动化 Linux 原生应用任务
  2. 02工作时让 Agent 使用独立桌面
  3. 03验证界面操作并等待状态变化
  4. 04在干净桌面会话中录制或测试工作流

MCP 相关

该 MCP 服务向 MCP 客户端提供桌面控制工具,涵盖应用、控件、窗口、输入、截图和会话操作。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"tristanmuzzu-deskwright": {
"command": "uvx",
"args": [
"deskwright"
],
"env": {
"DESKWRIGHT_SESSION": "<DESKWRIGHT_SESSION>",
"DESKWRIGHT_INPUT_BACKEND": "<DESKWRIGHT_INPUT_BACKEND>"
}
}
}
}
启动命令uvx deskwright
需要配置的环境变量
DESKWRIGHT_SESSIONWhich desktop to drive: 'primary' (the screen you are looking at), 'headless' for an invisible virtual-monitor session, or 'headless:<name>' to pick one of several.
DESKWRIGHT_INPUT_BACKENDForce the input path: 'mutter' for GNOME's org.gnome.Mutter.RemoteDesktop (no consent dialog), 'portal' for org.freedesktop.portal.RemoteDesktop (one consent, then persisted). Auto-selected when unset.

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

安装包
pypideskwright0.1.1

工具

33

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

此工具无需参数。

详细介绍

Deskwright

CI PyPI License GNOME Shell Wayland

面向 GNOME Wayland 上 AI Agent 的计算机操控能力。

让你的编码 Agent 使用 Linux 桌面。或者给它一个自己的桌面,这样它就 不会再抢你的鼠标。

安装  •  功能  •  独立桌面  •  遇到问题时  •  安全

Claude Code 可以编辑文件并运行命令,但它无法打开 GIMP、 点击设置对话框中的按钮,或读取原生应用显示的内容。 在 macOS 和 Windows 上,它可以通过计算机操控功能做到这些。在 Linux 上, 这项功能仍列在 Anthropic 的待办列表中。

本项目为 GNOME 填补了这一空白。它由一个 MCP 服务和一个小型 Shell 扩展组成, 可让 Agent 操控实际桌面:启动应用、读取控件、点击、输入、拖动、管理窗口、 OCR 和录屏。任何 MCP 客户端都能操控它,包括 Claude Code、Codex、Cursor 以及你自己的脚本。

大家通常最喜欢的功能是:DESKWRIGHT_SESSION=headless 可以在虚拟显示器上运行 所有操作,这个显示器不会出现在你的任何屏幕上。Agent 可以使用真正的 GNOME 桌面,同时不会抢占你的焦点。

Linux 混合模式 Beta:0.2.0b1

此 Beta 版本新增了受保护的原生控件、精确的多控件查询、自适应视觉回退,以及更短的已验证执行批次。它支持 GNOME Wayland;尚未实现 Windows 支持。请参阅交互指南 和测量结果与限制。

全新安装:

pipx install --system-site-packages 'deskwright==0.2.0b1'
deskwright-setup

对于现有的 pipx 安装,pipx upgrade --pip-args='--pre' deskwright 会保留现有的 system-site-packages 设置。运行 deskwright-setup 复制 更新后的扩展;如果安装程序报告扩展已更改,请注销并重新登录。 重启 MCP 连接以加载更新后的 Python 工具。 仅重启连接无法重新加载 GNOME Shell 扩展。

为什么要做这个项目

Wayland 会有意阻止应用查看或操作其他窗口。这条规则很好,也正因如此, xdotool、wmctrl 和 grim 在 GNOME 上要么毫无作用,要么以一种看似是你自己的错误的方式失败。我找到的每个 Linux 计算机操控项目,要么都附带运行 X11 的 Docker 容器,要么悄悄假定系统使用 X11,结果无法正常工作。

于是我开始寻找 GNOME 实际允许做什么,结果发现能做的事情相当多, 只是不在大家会去找的地方。Mutter 通过 D-Bus 响应请求。AT-SPI 是为屏幕阅读器打造的无障碍层,它会公开每个运行中的应用内的所有真实控件,包括控件名称、角色和执行的操作。而 Shell 扩展则运行在 gnome-shell 自身内部,其他组件也都在那里。

第二点的重要性比听起来更大。触发控件自身的无障碍操作,并不是一种更好的点击方式,而是完全不同的操作:不会点错,窗口移动后依然有效,而且完全不需要指针。Agent 以这种方式工作时,不必再猜测坐标,也不用每次操作后都截屏来确认结果。

安装

你需要在 Wayland 上运行 GNOME Shell。运行 echo $XDG_CURRENT_DESKTOP $XDG_SESSION_TYPE 检查,输出应包含 GNOME 和 wayland。

懒人方式:交给你的 Agent

打开 Claude Code、Codex 或你使用的其他工具,然后说:

在这台机器上设置 https://github.com/tristanmuzzu/deskwright, 按照 AGENTS.md 操作。

AGENTS.md 是为 Agent 编写的操作手册。其中列出了每条命令、如何检查命令是否执行成功、Debian、Fedora 和 Arch 对应的正确软件包名称,以及少数可能出错的情况及其修复方法。你的 Agent 会请你输入一次 sudo 密码,并告诉你注销一次。你只需要做这些。

手动操作:两条命令,然后注销
pipx install --system-site-packages deskwright
deskwright-setup

deskwright-setup 会逐步说明每项操作。它会启用辅助功能标志、安装捆绑的 Shell 扩展,并根据你的发行版给出对应的安装命令,告知你缺少哪些系统软件包,让你不必猜测软件包名称。它绝不会自行运行 sudo。

然后注销并重新登录。 一次即可。这个步骤无法省略:在 Wayland 上,gnome-shell 只会在会话启动时加载扩展。

最后一步,将你的客户端指向它:

claude mcp add deskwright --scope user -- deskwright

就这样。让你的 Agent 打开一个应用,它就会打开。

为什么要用 --system-site-packages,不用会有什么问题

PyGObject 不会向 PyPI 发布 wheel。它在各发行版中都是系统软件包(python3-gi、python3-gobject、python-gobject),所以隔离的 venv 无法导入它。若不启用这个标志,服务会正常启动,但第一次点击时就会因 input_backend_failed 而退出。

uvx 没有等效标志,这也是这里使用 pipx 的唯一原因。如果你不想用 pipx,也可以直接运行 python3 -m venv --system-site-packages,然后运行 pip install deskwright,效果完全相同。

改用 Claude Code 插件

该仓库也是一个插件市场。它会注册 MCP 服务和一项技能,教 Agent 优先使用哪个工具。

claude plugin marketplace add tristanmuzzu/deskwright
claude plugin install deskwright@deskwright

该插件会从自身的检出目录运行服务,因此无需通过 pip 安装。你仍需要安装系统软件包和扩展,所以请在 Claude Code 为你克隆的检出目录中运行一次设置命令:

~/.claude/plugins/marketplaces/deskwright/bin/deskwright-setup

然后像上面一样注销并重新登录。

从克隆的仓库开始,进行开发
git clone https://github.com/tristanmuzzu/deskwright
cd deskwright
bin/deskwright-setup
./mcp_server.py --self-test

./mcp_server.py 与 deskwright 命令使用相同的入口点,因为较早的注册项已经指向这个路径。 CONTRIBUTING.md 介绍了目录结构,以及哪些测试套件需要真实会话。

检查是否正常工作

DESKWRIGHT_SESSION=headless deskwright --self-test

你需要看到 18/18 passed。测试会在虚拟显示器上运行,而不是在你的屏幕上,因此你可以放心地一边工作一边运行。首次运行大约需要 20 秒,因为它必须启动第二个 gnome-shell。

移除 DESKWRIGHT_SESSION=headless,即可改为测试你的真实桌面。运行时请留意屏幕:自测会注入真实输入,因为它要检查用于拒绝危险按键组合的防护措施。

遇到问题时,让你的 Agent 调用 desktop_health。它会用一行话回答当前桌面是否可用,然后说明目前哪些机制有效,以及每种机制实际会执行什么操作。

可执行的操作

41 个工具。每个工具返回的信息都足够,无需再次调用即可了解发生了什么。下面的顺序就是 Agent 应该优先使用它们的顺序。在适当情况下使用原生控件和精确查询;进行视觉操作或处理无障碍信息不完整的情况时,使用截图和常规输入。

工具用途
ui_apps、ui_tree、ui_find查找内容。默认情况下,ui_find 会向下搜索 30 层,因为 GTK4 的嵌套深度远超预期。
ui_press通过索引路径调用控件的兼容性 API。需要 expect_name 或 expect_role;调用后请检查状态。优先使用 ui_action,以利用原生标识和模态框保护。
ui_observe、ui_snapshot、ui_query、ui_inspect、ui_action、ui_wait有范围限制的原生引用、受保护的操作和精确的完成检查。请参阅语义交互。
ui_set_text通过索引路径写入内容并进行精确回读的兼容性 API。优先使用 ui_action,以利用原生引用、当前值比较和模态框保护。
ui_read_text读取控件内容。用它来验证操作是否成功。
launch_app通过桌面 ID 启动应用,并在一次调用中等待其窗口出现。
screen_map查看所有内容的位置(以像素为单位):窗口按堆叠顺序从前到后排列;还会列出当前聚焦应用的每个可按控件,以及点击位置。每个控件都带有 ref: N,可直接传给 ui_press 或 pointer_click。无需复制坐标,使用时会重新验证标识。
pointer_click、pointer_move、pointer_drag、pointer_scroll在绝对屏幕坐标上执行真实指针输入。传入 expect_window 后,如果点击会落在其他位置,操作就会被拒绝,并指出阻挡窗口的名称,以便你在同一次调用中改换目标。
pointer_path按住一个按钮,沿一系列屏幕点绘制连续曲线,并限制持续时间且检查是否被中断。需要指定目标窗口。
window_at、pointer_position在点击前,查看某个点上的点击会命中什么;以及指针当前的位置,或如实说明目前只知道最近一次设置的位置。
find_text查找可见字符串的屏幕坐标。使用 OCR 查找一个窗口约需 0.3 秒,不会在对话记录中包含图像。对于 Chrome、Electron 和 Qt,这是合适的选择,因为这些程序几乎不会向 ui_find 暴露信息。
wait_for等待窗口、控件、文本、焦点变化或剪贴板,而不是猜测等待若干秒。
region_changed等待像素发生变化。适用于 wait_for 无法表达的情况,例如回复到达或加载指示器停止。
assert_state根据证据判断通过或失败,让长时间运行的流程自行决定是否已完成。
do_steps在一次调用中执行已知的一系列步骤。运行前会验证,并对每个步骤进行重试;结束时或出错步骤处会提供一张图片。
list_windows、activate_window、window_layout、window_manage管理窗口列表、焦点和布局。window_layout 无法关闭窗口;通用工具 window_manage 仍保留关闭功能。
screenshot、zoom获取图片,或截取单个窗口、区域或控件的全分辨率裁剪图。zoom 不会缩放,因此小字仍清晰可读。
screencast、frames用于查看动态内容,因为静态图无法展示动态。frames 还会报告逐帧差异序列,可据此判断滚动是平滑还是卡顿。
type_text、press_keys、hold_key通过合成器的按键符号执行键盘输入,并在输入前确认焦点。
clipboard_read、clipboard_write粘贴胜过敲击两千次按键;回读内容可以确认是否已成功粘贴。
journal记录 Agent 执行的所有操作:参数、结果、操作是否生效以及截图哈希。可用于审查无人值守的运行过程,或在上下文重置后确认当前状态。
desktop_health先用一行说明桌面是否可用,再提供详细信息。

工作时使用的第二个桌面

需要查看屏幕的 Agent,能发挥的作用只有一半。deskwright-headless 会在虚拟显示器上启动一个独立的 GNOME 会话,并为它配备独立的会话总线、独立的 gnome-shell --headless 和独立的运行时目录。绑定到该会话的服务可用同样的 41 个工具操控这个桌面,而你仍可使用实体桌面。

deskwright-headless start                    # about 200 MB of gnome-shell, idempotent
deskwright-headless status                   # liveness, memory, bus address
deskwright-headless stop                     # don't leave it idling on an 8 GB machine

将它注册为第二个 MCP 服务后,你就可以把耗时较长的任务交给它:

claude mcp add deskwright-headless --scope user --env DESKWRIGHT_SESSION=headless -- deskwright

会话有各自的名称,因此两个 Agent 可以各自拥有一个桌面,不必看着彼此的窗口移动:

deskwright-headless start --name work
deskwright-headless list                     # every session, memory used, memory free
DESKWRIGHT_SESSION=headless:work deskwright

为会话指定独立的主目录后,它启动的 GNOME 就是全新使用过的状态:没有桌面图标、没有会话恢复、没有最近打开的文件。录制演示或进行干净环境测试时,你就需要这样做,因为默认行为是共用主目录,编辑器会打开你上次的文档。

deskwright-headless start --name demo --home /tmp/demo-home

这里设有防护措施,因为每个会话都是一个实际的合成器,内存占用约为 205 MB:每个名称都有启动锁,避免两个 Agent 同时启动同一个会话;设有会话数量上限(DESKWRIGHT_HEADLESS_MAX,默认值为 4);并设有最低可用内存限制,若启动会导致机器使用交换空间,就会拒绝启动。可能导致这种情况的 Agent 无法预见这一点,所以由服务负责把关。

遇到问题时

扩展显示为 INACTIVE,或窗口工具无法使用。 你还没有注销。gnome-shell 必须重启会话才能加载扩展,没有其他解决办法。在此之前,你仍可使用 AT-SPI、指针、键盘和剪贴板,但无法使用窗口管理、扩展截图、指针位置或停止开关。

应用在 ui_tree 中没有显示任何控件。 在启用 toolkit-accessibility 时,该应用已经在运行。应用会在启动时读取此设置,因此请重启应用。

Chrome、Electron 或 Qt 应用看起来是空的。 从 AT-SPI 的角度来看,它们确实如此。请改用 find_text,它会对屏幕进行 OCR 并返回坐标。对于 Chrome,使用 --force-renderer-accessibility 启动它,就能获取真实的树结构,但会略微影响性能。

所有操作都因 input_backend_failed 失败。 pipx 未使用 --system-site-packages。请使用该标记重新安装:

pipx install --force --system-site-packages deskwright

每次调用 ui_* 都提示“Namespace Atspi not available”。 你安装了 python3-gi,但没有安装 AT-SPI typelib;它是一个独立的软件包:Debian 和 Ubuntu 上的 gir1.2-atspi-2.0,Fedora 和 Arch 上的 at-spi2-core。deskwright-setup --check 会检测到此问题并指出缺少的包。

工具返回 halted。 有人按下了 Super+Ctrl+Escape,也就是停止开关。再按一次即可解除停止状态。

屏幕锁定后,一半工具停止工作。 这是预期行为。GNOME 会卸载未声明 unlock-dialog 的扩展,因此在解锁之前,截图和窗口几何信息都不可用。AT-SPI 仍可正常工作,因此 ui_find、ui_press 和 ui_read_text 仍然可用。

本项目不会做什么

以下内容是项目有意排除的功能,而不只是默认关闭:

  • 不破解 CAPTCHA。 CAPTCHA 的用途是区分人和软件,而本项目就是软件。
  • 不提供输入凭据的功能。 本项目没有任何功能用于收集、存储或自动填充机密信息。操作日志不会记录输入的内容,只记录输入量。
  • 不规避检测。 不添加模仿人类操作的时间抖动,不伪造指纹,也不对抗反机器人措施。
  • 没有云服务、遥测或账户。 本项目是在会话总线上运行的本地进程,不会有任何数据离开本机。

在这条界线的另一边,设计上则刻意保持宽松。我们信任 Agent,工具的职责是增强它的能力,而不是限制它。所有安全预算都用于三件事:始终可由人触发的停止开关、防范无法撤销操作的防护措施,以及如实记录发生过的事情。SECURITY.md 会直言启用本项目实际上会开放哪些能力,建议你在让它访问真实屏幕之前先阅读。

实际工作原理

Wayland 会禁止 Wayland 客户端进行所有这些操作。它对 D-Bus 没有任何限制,而突破口就在这里。共有四种机制,大致按承担的工作量从多到少排列:

  1. AT-SPI,用于所有语义操作。真实的控件、真实的操作,无需指针。
  2. gnome-shell 扩展,通过 D-Bus 实现 gnome-shell 独有的功能:窗口枚举和控制、屏幕截图、指针位置,以及用于紧急停止开关的按键绑定捕获。
  3. org.gnome.Mutter.RemoteDesktop,用于指针和键盘。使用绝对坐标和按键符号,而非按键位置,因此键盘布局不会改变输入内容。
  4. xdg-desktop-portal,以标准化方式实现相同功能。这是连接非 GNOME 合成器的途径。

值得注意的是,第 2 种是其中唯一尚未开放的机制。Mutter 的 ScreenCast 和 RemoteDesktop 接口会响应会话总线上的任何客户端,且不会显示同意对话框。这就是为什么这里的录制无需权限弹窗,以及为什么 portal 是它们的调用方,而不是挡在它们前面的门禁。SECURITY.md 中列出了准确的命令,如果你想自己核实,而不是听我一面之词,可以查看。

docs/field-notes.md 是详细版本:一路上遇到的每道障碍、合成器拒绝了什么,以及塑造工具界面的测量结果。如果遇到行为异常,或准备修改代码,请阅读此文件。

要求

deskwright-setup --check 会给出准确答案。它会检测所有内容、给出适用于你所用发行版的软件包名称,并在缺少硬性要求时以非零状态码退出。简要说明如下:

平台状态
GNOME Shell 50 on Wayland已验证。 基于 50.1(Ubuntu 26.04)开发,每次变更都会针对它运行实时测试套件。
GNOME Shell 48 到 49应该可用。 D-Bus 和 AT-SPI 接口相同,但未经测试。欢迎反馈,请附上 desktop_health 输出。
KDE Plasma、Sway、Hyprland仅输入。 portal 后端可驱动指针和键盘,但窗口管理和屏幕截图需要针对每种合成器进行适配,目前尚未完成。desktop_health 会提示它不可用,这个提示是准确的。
X11非目标平台。xdotool 在该平台上已经能很好地完成这些工作。

使用 Claude Code,不要使用 Cowork。 在 Linux 上,桌面应用会在 QEMU/KVM 虚拟机中运行 Cowork 任务,因此它启动的 MCP 服务也运行在该虚拟机中,无法访问你的会话总线、gnome-shell 或屏幕。在那里,这里的一切都会失效。请通过 Claude Code CLI、Code 标签页,或任何运行在主机本身上的其他 MCP 客户端使用它。

使用 Claude Code,不要使用 Cowork。 在 Linux 上,桌面应用会在 QEMU/KVM 虚拟机中运行 Cowork 任务,因此它启动的 MCP 服务也运行在该虚拟机中,无法访问你的会话总线、gnome-shell 或屏幕。在那里,这里的一切都会失效。请通过 Claude Code CLI、Code 标签页,或任何运行在主机本身上的其他 MCP 客户端使用它。

软件包使用 Debian 名称(deskwright-setup 会显示你的软件包名称):python3-gi、gir1.2-atspi-2.0、python3-pil、libglib2.0-bin、wl-clipboard、tesseract-ocr。ydotool 是可选项,仅在输入回退时使用。无头会话还需要 gnome-shell 和 dbus-daemon 可执行文件,任何常规桌面环境都已包含它们。

贡献、安全与许可证

CONTRIBUTING.md 介绍了项目布局、测试套件及各自的运行要求。SECURITY.md 以直白的方式阐述了威胁模型。ROADMAP.md 按顺序说明了后续计划及其原因。

Apache-2.0。如果你成功在非 GNOME 合成器上运行它,或在早于 50 的 GNOME 版本上运行它,请提交 issue 并说明情况。这是任何人能提供的最有用的信息。

mcp-name: io.github.tristanmuzzu/deskwright

评论

支持 Markdown

第一次接触 MCP?

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

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