Deskwright について
Deskwrightは、GNOME Wayland上の実アプリを操作するAIエージェント向けMCPサーバーです。ネイティブなウィジェット操作と画面上の操作を組み合わせ、別の仮想デスクトップで実行することもできます。
主な機能
- 01GNOMEアプリの起動と操作
- 02ウィジェットの確認とガード付き操作
- 03ポインター、キーボード、クリップボードの操作
- 04OCRによる画面テキストの読み取りと録画
- 05仮想デスクトップでの名前付きセッション
活用シーン
- 01Linuxネイティブアプリのタスク自動化
- 02作業中に別デスクトップでエージェントを実行
- 03UI操作の検証と状態変化の待機
- 04クリーンなデスクトップでのワークフロー記録やテスト
MCP 対応
MCPサーバーとして、アプリ、ウィジェット、ウィンドウ、入力、スクリーンショット、セッションを操作するツールをMCPクライアントに提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx deskwrightDESKWRIGHT_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 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
33掲載時のツール一覧 · 2 週間前に更新
このツールにパラメーターはありません。
詳細
Deskwright
GNOME Wayland 上で AI エージェントがコンピューターを操作できます。
コーディングエージェントに Linux デスクトップを使わせましょう。または、エージェント専用のデスクトップを用意して、マウスを奪われないようにしましょう。
インストール • できること • 作業中に使える専用デスクトップ • うまく動かないとき • セキュリティ
Claude Code はファイルを編集し、コマンドを実行できます。しかし、GIMP を開いたり、設定ダイアログのボタンをクリックしたり、ネイティブアプリに何が表示されているかを読み取ったりはできません。macOS と Windows では、コンピューター操作を通じてこれができます。Linux では、まだ Anthropic の対応予定リストにあります。
これは GNOME 上でそのギャップを埋めます。MCP サーバーと小さなシェル拡張機能で構成され、アプリの起動、ウィジェットの読み取り、クリック、入力、ドラッグ、ウィンドウ管理、OCR、画面録画など、実際のデスクトップをエージェントに操作させます。どの MCP クライアントからでも操作できます。Claude Code、Codex、Cursor、自作のスクリプトなどに対応します。
多くの人が特に気に入っているのは、DESKWRIGHT_SESSION=headless を設定すると、どの画面にも表示されない仮想モニター上ですべてが動作する点です。エージェントは作業用の本物の GNOME デスクトップを使え、あなたの操作を妨げることはありません。
Linux ハイブリッドベータ:0.2.0b1
このベータ版では、保護付きネイティブコントロール、複数コントロールの正確なクエリ、適応型のビジュアルフォールバック、検証済み実行バッチの短縮が追加されています。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 を実行して更新された拡張機能をコピーし、拡張機能に変更があったとセットアップで報告された場合は、ログアウトして再度ログインしてください。更新された Python ツールを読み込むには、MCP 接続を再起動します。接続を再起動するだけでは、GNOME Shell の拡張機能は再読み込みされません。
なぜ作られたのか
Wayland は意図的に、アプリケーションがほかのウィンドウを見たり操作したりできないようにしています。これは適切なルールです。そのため、GNOME では xdotool、wmctrl、grim が何もしないか、自分の操作ミスのように見える形で失敗します。私が見つけた Linux 向けコンピューター操作プロジェクトは、どれも X11 を実行する Docker コンテナーを同梱しているか、ひそかに X11 を前提としていて動作しませんでした。
そこで GNOME で実際に許可されていることを調べたところ、思いのほか多くのことが可能でした。ただし、誰も調べない場所にあるだけです。Mutter は D-Bus で応答します。スクリーンリーダー向けに構築されたアクセシビリティレイヤーの AT-SPI は、実行中のすべてのアプリにある実際のウィジェットを、その名前、ロール、実行するアクションとともに公開します。そして、シェル拡張機能は gnome-shell 自体の内部で動作し、ほかの機能もそこにあります。
この真ん中の仕組みは、見た目以上に重要です。ウィジェット独自のアクセシビリティアクションを実行するのは、クリックをより便利にしたものではありません。まったく別の方法です。クリックを外すことがなく、ウィンドウを移動しても機能し、ポインターも必要ありません。この方法で作業するエージェントは、座標を推測しなくなり、何が起きたかを確認するために毎回スクリーンショットを撮る必要もなくなります。
インストール
Wayland 上の GNOME Shell が必要です。echo $XDG_CURRENT_DESKTOP $XDG_SESSION_TYPE を実行して確認してください。GNOME と wayland が表示されるはずです。
手軽な方法:エージェントに任せる
Claude Code、Codex、または普段使っているものを開いて、次のように伝えます:
このマシンに https://github.com/tristanmuzzu/deskwright をセットアップして、 AGENTS.md に従ってください。
AGENTS.md は、エージェント向けに書かれた手順書です。すべてのコマンド、それぞれの実行が成功したか確認する方法、Debian、Fedora、Arch 用の正しいパッケージ名、そしてよくある問題とその修正方法が記載されています。エージェントから sudo パスワードを一度求められ、ログアウトするよう一度案内されます。あなたがすることはそれだけです。
手動で行う方法:コマンドを2つ実行してログアウト
pipx install --system-site-packages deskwright
deskwright-setup
deskwright-setup が各手順を説明します。アクセシビリティフラグを有効にし、同梱のシェル拡張機能をインストールします。また、不足しているシステムパッケージがあれば、お使いのディストリビューションに適したインストールコマンドを案内するので、パッケージ名を推測する必要はありません。sudo を実行することはありません。
その後、ログアウトして再度ログインしてください。 1回だけです。これだけは避けられません。Wayland では、gnome-shell が拡張機能を読み込むのはセッション開始時だけです。
最後に、クライアントから接続します:
claude mcp add deskwright --scope user -- deskwright
これで完了です。エージェントにアプリを開くよう頼めば、開いてくれます。
--system-site-packages が必要な理由と、指定しない場合に起きること
PyGObject は PyPI にホイールを公開していません。どのディストリビューションでもパッケージとして提供されています
(python3-gi、python3-gobject、python-gobject)。そのため、隔離された venv からは
インポートできません。このフラグを省くと、サーバーは正常に起動した後、最初のクリックで
input_backend_failed を出して終了します。
uvx に同等のフラグがないため、ここでは pipx を使っています。pipx を使わない場合は、
python3 -m venv --system-site-packages の後に
pip install deskwright を実行すれば、同じように動作します。
代わりに Claude Code プラグインとして使う
このリポジトリはプラグインマーケットプレイスでもあります。サーバーに加えて、 エージェントが最初に使うべきツールを教えるスキルも登録します。
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 と表示されれば成功です。画面ではなく仮想モニター上で実行されるため、
作業中でも安全に実行できます。2つ目の gnome-shell を起動する必要があるため、
初回の実行には約20秒かかります。
DESKWRIGHT_SESSION=headless を外すと、実際のデスクトップをテストできます。
画面を見ながら実行してください。セルフテストでは、危険なキーの組み合わせを拒否する
ガードを確認するため、実際の入力を送信します。
問題が起きたときは、エージェントに desktop_health を呼び出すよう頼んでください。
このデスクトップが使用可能かどうかを1行で回答し、現在動作している仕組みと、
それぞれが実際に何をするかを伝えます。
できること
41 個のツールがあります。どのツールも、何が起きたかを把握するために二度目の呼び出しが必要ないほど十分な情報を返します。以下の順序は、エージェントがツールを使う順序です。 必要に応じてネイティブコントロールと正確なクエリを使い、視覚的な操作やアクセシビリティ情報が不完全な場合は、スクリーンショットと通常の入力を使います。
| ツール | 用途 |
|---|---|
ui_apps、ui_tree、ui_find | 対象を見つけます。GTK4 のネストは想像以上に深いため、ui_find はデフォルトで 30 階層まで検索します。 |
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 でアプリを起動し、1 回の呼び出しでウィンドウが表示されるまで待ちます。 |
screen_map | 画面上のすべての要素をピクセル単位で示します。スタックの最上部にあるウィンドウに加え、フォーカス中のアプリで押下可能なすべてのウィジェットと、クリックする位置を表示します。それぞれに ref: N が付いており、そのまま ui_press または pointer_click に渡せます。座標をコピーする必要はなく、使用時に識別情報が再確認されます。 |
pointer_click、pointer_move、pointer_drag、pointer_scroll | 絶対スクリーン座標で実際のポインター入力を行います。expect_window を指定すると、クリックが別の場所に当たる場合は拒否され、遮っているウィンドウが示されるため、同じ呼び出しで行き先を変更できます。 |
pointer_path | 画面上の複数の点を通る連続した曲線を、ボタンを 1 回押して描画します。実行時間に上限があり、中断を確認します。対象ウィンドウの指定が必要です。 |
window_at、pointer_position | クリックする前に、その座標でクリックした場合に何が対象になるかを確認します。また、ポインターの現在位置、あるいは最後に設定した位置だけがわかっていることを示す正確な注記を確認できます。 |
find_text | 画面上に表示されている文字列の位置を、スクリーン座標で示します。OCR による検索で、ウィンドウあたり約 0.3 秒かかり、トランスクリプトに画像は含まれません。ui_find ではほとんど情報が得られない Chrome、Electron、Qt には、このツールを使います。 |
wait_for | 推測した秒数だけ待つのではなく、ウィンドウ、ウィジェット、テキスト、フォーカスの変化、クリップボードを待ちます。 |
region_changed | ピクセルの変化を待ちます。返信の到着やスピナーの停止など、wait_for では表現できない場合に使います。 |
assert_state | 根拠とともに成功または失敗を返すため、長時間の実行でも完了を自動的に判断できます。 |
do_steps | 既知の一連の手順を 1 回の呼び出しで実行します。実行前に検証し、手順ごとに再試行します。最後、または失敗した手順の時点で画像を 1 枚取得します。 |
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 | 2,000 回キー入力するより貼り付けるほうが効率的です。読み戻すことで、正しく貼り付けられたかを確認できます。 |
journal | エージェントが行ったすべての操作の記録です。引数、結果、操作が反映されたかどうか、スクリーンショットのハッシュが含まれます。無人実行の確認や、コンテキストのリセット後に現在の状態を把握する際に使います。 |
desktop_health | このデスクトップが使用可能かどうかを 1 行で示し、続けて詳細を表示します。 |
作業中に使える2つ目のデスクトップ
画面が必要なエージェントは、それだけでは力を半分しか発揮できません。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
2つ目の MCP サーバーとして登録すれば、時間のかかる作業を任せられます。
claude mcp add deskwright-headless --scope user --env DESKWRIGHT_SESSION=headless -- deskwright
セッションには名前を付けられるので、2つのエージェントがそれぞれ専用のデスクトップを持ち、互いのウィンドウが動くのを見ることなく作業できます。
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を使用する実際のコンポジターであるため、いくつかのガードを設けています。名前ごとの起動ロックにより、2つのエージェントが同じセッションを同時に起動するのを防ぎます。また、セッション数の上限(DESKWRIGHT_HEADLESS_MAX、デフォルトは4)と、マシンがスワップに陥るような起動を拒否する最低空きメモリー量を設定しています。それを引き起こすエージェント自身には事前にわからないため、サーバーが制御します。
問題が起きた場合
拡張機能が INACTIVE と表示される、またはウィンドウ関連ツールが動作しない。 まだログアウトしていません。gnome-shell はセッションを再起動しないと拡張機能を読み込めず、回避策もありません。それまでは AT-SPI、ポインター、キーボード、クリップボードを利用できます。ウィンドウ管理、拡張機能によるスクリーンショット、ポインター位置、停止スイッチは利用できません。
ui_tree にアプリのウィジェットが表示されない。 toolkit-accessibility を有効にした時点で、そのアプリはすでに起動していました。アプリは起動時にこの設定を読み込むため、アプリを再起動してください。
Chrome、Electron、Qt アプリの中身が空に見える。 AT-SPI から見ると、実際に空です。代わりに、画面を OCR して座標を返す find_text を使ってください。Chrome の場合は、--force-renderer-accessibility を指定して起動すれば、わずかなパフォーマンス低下と引き換えに、実際のツリーを取得できます。
すべての操作が input_backend_failed で失敗する。 --system-site-packages を指定せずに pipx を使っています。次のフラグを指定して再インストールしてください。
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 は人間とソフトウェアを見分けるために存在します。これはソフトウェアです。
- 認証情報の入力機能。 ここには、秘密情報を収集、保存、自動入力するためのものはありません。ジャーナルに記録されるのは入力内容ではなく、入力した量だけです。
- 検出回避。 人間らしく見せるためのタイミングの揺らぎも、フィンガープリントの偽装も、ボット対策をさらに回避する仕組みもありません。
- クラウド、テレメトリー、アカウント。 セッションバス上で動作するローカルプロセスであり、マシンの外に情報が出ることはありません。
その一線の向こう側では、設計を意図的に寛容にしています。エージェントは信頼されており、ツールの役割はエージェントを制限することではなく、能力を高めることです。安全対策のすべては、常に人間が操作できる停止スイッチ、取り消せない操作に対するガード、そして発生したことを正直に記録する仕組みの3つに注がれています。この機能を有効にすると実際に何が使えるようになるのか、SECURITY.md には率直に書かれています。実際の画面に使う前に、ぜひお読みください。
実際の仕組み
Wayland は Wayland クライアントに対して、これらすべてを拒否します。D-Bus については何も規定しておらず、そこに抜け道があります。仕組みは 4 つあり、おおよそ負担の大きい順に並べています。
- AT-SPI は、セマンティックな操作に使います。本物のウィジェットと本物のアクションを扱うため、ポインターは不要です。
- gnome-shell 拡張機能 は、gnome-shell が内部に留めている機能を D-Bus 経由で扱います。ウィンドウの列挙と制御、スクリーンショット、ポインター位置、そして停止スイッチ用のキー割り当ての取得です。
org.gnome.Mutter.RemoteDesktopは、ポインターとキーボード用です。絶対座標を使い、キーの位置ではなく keysym を送るため、キーボードレイアウトによって入力内容が変わることはありません。xdg-desktop-portalは、同じ機能を標準化したものです。GNOME 以外のコンポジターに対応するための手段です。
知っておくべき点として、これらのうち 2 だけが、まだオープンになっていません。Mutter の ScreenCast インターフェースと RemoteDesktop インターフェースは、同じセッションバス上のあらゆるクライアントに対して、同意ダイアログなしで応答します。そのため、ここでの録画には許可のポップアップが不要であり、ポータルはその前に立ちはだかるゲートではなく、これらを呼び出す側になっています。ご自身で確かめたい場合は、私の言葉を鵜呑みにするより、SECURITY.md に記載された正確なコマンドをご確認ください。
docs/field-notes.md には、ここに至るまでにぶつかったあらゆる壁、コンポジターが拒否した内容、ツールの設計に影響した測定結果を詳しく記載しています。動作がおかしいときや、コードを変更する前に読むファイルです。
要件
実際の確認には deskwright-setup --check を使ってください。すべてを検出し、お使いのディストリビューションに対応するパッケージ名を表示します。必須要件が不足している場合は、ゼロ以外の終了コードで終了します。要点は次のとおりです。
| プラットフォーム | 状態 |
|---|---|
| Wayland 上の GNOME Shell 50 | 検証済みです。 50.1(Ubuntu 26.04)上で開発しており、変更のたびに実際のテストスイートを実行しています。 |
| GNOME Shell 48~49 | 動作するはずです。 D-Bus と AT-SPI のインターフェースは同じですが、テストはしていません。報告を歓迎します。desktop_health の出力を添付してください。 |
| KDE Plasma、Sway、Hyprland | 入力のみです。 ポータルのバックエンドでポインターとキーボードを操作できますが、ウィンドウ管理とスクリーンショットにはコンポジターごとの対応が必要で、まだ実装されていません。desktop_health は使用できないと表示しますが、そのとおりです。 |
| X11 | 対象外です。X11 では xdotool がすでに優れた機能を提供しています。 |
Cowork ではなく、Claude Code を使用してください。 Linux では、デスクトップアプリが QEMU/KVM 仮想マシン内で Cowork タスクを実行するため、そこで起動した MCP サーバーはその仮想マシン内で動作し、ホストのセッションバス、gnome-shell、画面にアクセスできません。ここにある機能はすべて動作しません。Claude Code CLI、Code タブ、またはホスト上で直接動作する他の MCP クライアントから使用してください。
Cowork ではなく、Claude Code を使用してください。 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 以外のコンポジター、または GNOME 50 より古いバージョンで動作させられた場合は、ぜひ issue を作成してお知らせください。それが何より役立つ報告です。
mcp-name: io.github.tristanmuzzu/deskwright
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。