@agent-sh/computer-use-linux 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -0
- package/npm/README.md +33 -0
- package/package.json +1 -1
- package/pi/extension/generated-tools.ts +6 -6
- package/skills/computer-use-linux/SKILL.md +45 -0
package/README.md
CHANGED
|
@@ -61,6 +61,23 @@ Screenshot payloads are size-bounded by default before they are returned to the
|
|
|
61
61
|
- `press_key` — keys / chords; can focus a window or terminal first
|
|
62
62
|
- `type_text` — literal text input, optionally targeted at a window or terminal
|
|
63
63
|
|
|
64
|
+
For a plain left `click` by element index or selector, a recognized native
|
|
65
|
+
AT-SPI `click`, `press`, or `toggle` action takes precedence
|
|
66
|
+
over bounds. Entry `activate` and slider `jump` must be requested explicitly
|
|
67
|
+
with `perform_action`; they are never a substitute for a pointer click, even
|
|
68
|
+
when bounds are missing.
|
|
69
|
+
This avoids pointer conversion for GTK3 HiDPI
|
|
70
|
+
extents and GTK4 zero-origin bounds when the element exposes such an action.
|
|
71
|
+
The preference does not substitute an arbitrary action name for a coordinate
|
|
72
|
+
click. Explicit `x`/`y`, right clicks, and double/multiple clicks retain pointer
|
|
73
|
+
semantics. Re-check application state after either kind of activation.
|
|
74
|
+
|
|
75
|
+
For coordinate `click` or `scroll` with `relative: true`, select a target window
|
|
76
|
+
and measure from its clipped screenshot crop origin. Divide preview `x` and
|
|
77
|
+
`y` by the returned screenshot `scale` before passing them. These are not raw
|
|
78
|
+
GDK surface or widget-local coordinates; decorations and clipping can change
|
|
79
|
+
the origin. A missing window target is rejected.
|
|
80
|
+
|
|
64
81
|
Targeted `press_key`/`type_text` results append focused-element feedback from AT-SPI (role, name, editable) and warn when no editable element holds focus. Click/screenshot/input results warn when the target window or coordinate is partially or fully off-screen. `get_app_state` returns a compact readiness block by default; pass `verbose: true` for the full diagnostics report.
|
|
65
82
|
|
|
66
83
|
**Semantic actions**
|
|
@@ -75,6 +92,8 @@ Targeted `press_key`/`type_text` results append focused-element feedback from AT
|
|
|
75
92
|
|
|
76
93
|
**Conditional host execution**
|
|
77
94
|
|
|
95
|
+
- `complete_interaction` - optional desktop completion notification, registered only with `COMPUTER_USE_LINUX_NOTIFY_ON_COMPLETE=1`. Repeated calls can create repeated notifications; it does not provide desktop exclusivity.
|
|
96
|
+
|
|
78
97
|
- `run_shell` — same-user `/bin/sh -c` execution without login-profile loading, registered only when the server operator starts the MCP process with `COMPUTER_USE_LINUX_ENABLE_SHELL=1`. It is deliberately absent by default and is not a sandbox.
|
|
79
98
|
|
|
80
99
|
### MCP safety contract
|
|
@@ -99,6 +118,7 @@ The binary also exposes the same capabilities from the CLI for scripting and deb
|
|
|
99
118
|
computer-use-linux mcp # stdio MCP server
|
|
100
119
|
computer-use-linux doctor # JSON readiness report
|
|
101
120
|
computer-use-linux setup # enable AT-SPI
|
|
121
|
+
computer-use-linux guard-accessibility # explicit foreground GNOME accessibility guard
|
|
102
122
|
computer-use-linux setup-window-targeting # install GNOME Shell extension
|
|
103
123
|
computer-use-linux apps
|
|
104
124
|
computer-use-linux state [APP_NAME]
|
|
@@ -358,6 +378,7 @@ Most setups need none of these — `doctor` and the installers pick sensible def
|
|
|
358
378
|
|
|
359
379
|
| Variable | Effect |
|
|
360
380
|
| --- | --- |
|
|
381
|
+
| `COMPUTER_USE_LINUX_NOTIFY_ON_COMPLETE` | Set exactly to `1` to expose the optional `complete_interaction` notification tool. Requires `notify-send` and a desktop notification service; disabled by default. |
|
|
361
382
|
| `COMPUTER_USE_LINUX_COSMIC_HELPER` | Path to the `computer-use-linux-cosmic` helper when it isn't next to the binary or on `PATH`. |
|
|
362
383
|
| `CU_DISABLE_ABS_POINTER` | Disable the uinput absolute pointer and click through `ydotool` instead for setups where the abs-pointer device misbehaves. |
|
|
363
384
|
| `COMPUTER_USE_LINUX_FORCE_PORTAL_POINTER` / `…_KEYBOARD` | Always route pointer / keyboard through the RemoteDesktop portal on Wayland, skipping auto-detection. |
|
|
@@ -408,6 +429,44 @@ If you're running this on a shared workstation, set `ydotoold`'s socket permissi
|
|
|
408
429
|
|
|
409
430
|
## Troubleshooting
|
|
410
431
|
|
|
432
|
+
To receive an explicit completion cue, start the MCP server with
|
|
433
|
+
`COMPUTER_USE_LINUX_NOTIFY_ON_COMPLETE=1`. This exposes `complete_interaction`,
|
|
434
|
+
a parameter-free tool the agent calls once after finishing its desktop work.
|
|
435
|
+
It submits a notification through `notify-send` with a two-second execution
|
|
436
|
+
limit and bounded process cleanup. Missing services, errors, or timeouts return
|
|
437
|
+
`cue: "skipped"`; notification settings may suppress a submitted cue. This does
|
|
438
|
+
not reserve the desktop or prove that other clients have stopped sending input.
|
|
439
|
+
No sound or additional desktop settings are enabled by this option.
|
|
440
|
+
This option currently applies only to directly spawned MCP hosts. The native Pi
|
|
441
|
+
extension does not forward the flag or include this optional tool in its catalog.
|
|
442
|
+
|
|
443
|
+
`setup` and `setup_accessibility` write and read back GNOME's
|
|
444
|
+
`org.gnome.desktop.interface toolkit-accessibility` setting, even if AT-SPI
|
|
445
|
+
is already enabled at runtime. A runtime-only success is reported as a warning:
|
|
446
|
+
newly launched GTK apps may still have no tree. Enabling the saved key may
|
|
447
|
+
require restarting target apps. Other accessibility tools can change that key
|
|
448
|
+
later; setup does not continuously override user settings.
|
|
449
|
+
|
|
450
|
+
For an explicit foreground guard while using desktop automation, run:
|
|
451
|
+
|
|
452
|
+
```bash
|
|
453
|
+
computer-use-linux guard-accessibility
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
The guard registers a passive AT-SPI window-activation listener and watches
|
|
457
|
+
GNOME's saved `toolkit-accessibility` key. It re-enables the key after a reset
|
|
458
|
+
and verifies it by readback, with periodic checks as well as change monitoring.
|
|
459
|
+
This affects all applications using the current user's GNOME setting, not just
|
|
460
|
+
the target app. It does not start a screen reader or change focus.
|
|
461
|
+
|
|
462
|
+
`mcp`, `setup`, `setup_accessibility`, and `get_app_state` never start this guard.
|
|
463
|
+
Stop it with Ctrl-C or SIGTERM **before** intentionally disabling accessibility.
|
|
464
|
+
Stopping ends setting writes and removes its listener without disabling other
|
|
465
|
+
accessibility clients or restoring an old saved value. A reset and reassertion
|
|
466
|
+
are not atomic: an app launched in that interval may still need restarting.
|
|
467
|
+
This is an opt-in mitigation, not a guarantee that every GNOME toggle sequence
|
|
468
|
+
preserves application accessibility trees.
|
|
469
|
+
|
|
411
470
|
`computer-use-linux doctor` is the source of truth. Common failure modes and fixes:
|
|
412
471
|
|
|
413
472
|
- **`accessibility.at_spi_bus.ok = false`** — AT-SPI registry isn't running or the toolkit bridge is off. Fix: `computer-use-linux setup` (or call the `setup_accessibility` MCP tool). Restart the apps you want to drive.
|
|
@@ -419,9 +478,30 @@ If you're running this on a shared workstation, set `ydotoold`'s socket permissi
|
|
|
419
478
|
- **KWin / Hyprland / i3 / COSMIC / X11 windowing is unavailable** — check `doctor.windowing.backends`. KWin needs session-bus scripting; Hyprland needs `hyprctl`; i3 needs `i3-msg` and its IPC socket; generic X11 needs `wmctrl` and `xprop`. COSMIC needs `computer-use-linux-cosmic`, which the standard installers provide automatically; if you copied binaries by hand, copy the helper too or set `COMPUTER_USE_LINUX_COSMIC_HELPER`.
|
|
420
479
|
- **Screenshots return black frames on multi-monitor setups** — known portal / compositor edge case. Use `get_app_state` with `include_screenshot: false` and rely on AT-SPI until the portal backend is healthy.
|
|
421
480
|
- **`type_text` types into the wrong window** — pass an explicit target (`window_id`, `pid`, `wm_class`, `title`, or for terminals `tty` / `terminal_pid` / `terminal_command` / `terminal_cwd`). Without a target, input goes to whatever window currently has compositor focus.
|
|
481
|
+
- **Wayland pointer actions miss an unfocused window** — injected pointer input is subject to the compositor's input-focus rules. Call `activate_window` for the target before `click`, `drag`, or coordinate `scroll`; a pointer can land at the requested coordinate without the unfocused surface receiving the action.
|
|
422
482
|
|
|
423
483
|
If `doctor` is green and a specific tool still misbehaves, file an issue with the JSON output of `doctor` and the failing tool's request payload.
|
|
424
484
|
|
|
485
|
+
For coordinate calibration, launch [the GTK4 probe](examples/coordinate_probe.py)
|
|
486
|
+
in your test desktop and take a targeted screenshot. Choose the center of its
|
|
487
|
+
green 10x10 square from that screenshot, convert by `scale`, and click relative
|
|
488
|
+
to the same target window. The probe's delivered-event `hit: true` is the
|
|
489
|
+
acceptance condition. Do not pass its widget-local `(85, 85)` directly as a
|
|
490
|
+
window-relative click: margins and decorations belong to different spaces.
|
|
491
|
+
|
|
492
|
+
[The semantic-click regression](scripts/semantic_click_test.py) runs against a
|
|
493
|
+
built binary in an isolated graphical display and checks actual GTK3 button
|
|
494
|
+
activation through MCP at scales 1 and 2. This does not establish correctness
|
|
495
|
+
of Mutter 46 EWMH move/resize, all mixed-output layouts, or GNOME 50.4 pointer
|
|
496
|
+
clicks.
|
|
497
|
+
|
|
498
|
+
Native Wayland qualification on GNOME 50.1 at 133.3% display scale used the
|
|
499
|
+
same green target for both modes: crop-relative `(122, 145)` and desktop
|
|
500
|
+
`(2140, 193)` both delivered widget coordinates approximately `(84.81, 84.78)`
|
|
501
|
+
with `hit: true` through uinput. These are one capture's measured coordinates,
|
|
502
|
+
not reusable offsets. Raw surface coordinates must still be transformed before
|
|
503
|
+
comparing them with a widget-local target.
|
|
504
|
+
|
|
425
505
|
## Related
|
|
426
506
|
|
|
427
507
|
- [agent-workspace-linux](https://github.com/agent-sh/agent-workspace-linux) — the sibling MCP that gives an agent its **own** isolated Linux desktop (a hidden Xvfb display with its own apps and browser) instead of driving yours. It is the inverse of this project: `computer-use-linux` automates the desktop you are already on; `agent-workspace-linux` sandboxes the agent in a separate one. Use them together.
|
package/npm/README.md
CHANGED
|
@@ -9,6 +9,17 @@ mutating and can change real application state. The MCP tool list includes
|
|
|
9
9
|
`ToolAnnotations` so hosts can distinguish read-only observation from mutating
|
|
10
10
|
desktop actions.
|
|
11
11
|
|
|
12
|
+
Plain left `click` by element index or selector prefers a native AT-SPI
|
|
13
|
+
`click`, `press`, or `toggle` action over toolkit bounds,
|
|
14
|
+
avoiding pointer-coordinate conversion when that action is available. Explicit
|
|
15
|
+
`activate`/`jump` requests belong in `perform_action`, not `click`, even when
|
|
16
|
+
bounds are missing. Explicit
|
|
17
|
+
`x`/`y`, right clicks, and multi-clicks retain pointer semantics. For coordinate
|
|
18
|
+
`click` or `scroll` with `relative: true`, use the clipped target-window
|
|
19
|
+
screenshot crop origin and divide preview coordinates by screenshot `scale`.
|
|
20
|
+
Do not use widget-local or raw GDK surface coordinates. A window target is
|
|
21
|
+
required.
|
|
22
|
+
|
|
12
23
|
```bash
|
|
13
24
|
npm install -g @agent-sh/computer-use-linux
|
|
14
25
|
computer-use-linux doctor
|
|
@@ -20,6 +31,28 @@ hermes mcp test computer-use-linux
|
|
|
20
31
|
hermes mcp configure computer-use-linux
|
|
21
32
|
```
|
|
22
33
|
|
|
34
|
+
For an optional MCP completion notification, set
|
|
35
|
+
`COMPUTER_USE_LINUX_NOTIFY_ON_COMPLETE=1` in the server environment and have the
|
|
36
|
+
agent call `complete_interaction` after its desktop work. `notify-send` must be
|
|
37
|
+
installed with an available desktop notification service. The cue is best effort
|
|
38
|
+
and does not provide exclusive desktop ownership.
|
|
39
|
+
This cue is available only to directly spawned MCP hosts; the native Pi extension
|
|
40
|
+
does not yet forward the flag or include the tool in its catalog.
|
|
41
|
+
|
|
42
|
+
If accessibility is disabled, run `computer-use-linux setup`. Setup writes and
|
|
43
|
+
reads back GNOME's `toolkit-accessibility` setting and warns if only runtime
|
|
44
|
+
accessibility is available. Restart target apps if their trees remain empty.
|
|
45
|
+
|
|
46
|
+
To explicitly keep that saved setting enabled during desktop automation, run
|
|
47
|
+
`computer-use-linux guard-accessibility` in a foreground terminal. It registers
|
|
48
|
+
a passive AT-SPI window-activation listener and reasserts the current user's
|
|
49
|
+
GNOME `toolkit-accessibility` key after resets, verifying each write by readback.
|
|
50
|
+
This affects other apps using the same user setting. MCP, setup, and
|
|
51
|
+
`get_app_state` never start it automatically. Stop with Ctrl-C or SIGTERM before
|
|
52
|
+
disabling accessibility; stopping removes its listener and ends writes without
|
|
53
|
+
disabling other clients or restoring an old value. An app launched during a
|
|
54
|
+
reset may still need restarting, so this is not a complete GNOME toggle fix.
|
|
55
|
+
|
|
23
56
|
The generated Hermes config should look like this:
|
|
24
57
|
|
|
25
58
|
```yaml
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-sh/computer-use-linux",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Linux desktop-control MCP server: AT-SPI accessibility trees, Wayland/X11 input, screenshots, and compositor window targeting.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -7,9 +7,9 @@ export interface GeneratedMcpToolDefinition {
|
|
|
7
7
|
annotations: Record<string, unknown>;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export const GENERATED_SERVER_VERSION = "0.
|
|
11
|
-
export const GENERATED_TOOL_CATALOG_HASH = "
|
|
12
|
-
export const GENERATED_SHELL_TOOL_CATALOG_HASH = "
|
|
10
|
+
export const GENERATED_SERVER_VERSION = "0.6.0";
|
|
11
|
+
export const GENERATED_TOOL_CATALOG_HASH = "9107297df765ce3b907540db172cc7823b7664586255db1064a40a44483d6fd6";
|
|
12
|
+
export const GENERATED_SHELL_TOOL_CATALOG_HASH = "e0bc41db617ea6d10d812cbddce6ef78036e44251360f5fac9c207dd0d5ce392";
|
|
13
13
|
export const GENERATED_MCP_TOOLS =
|
|
14
14
|
[
|
|
15
15
|
{
|
|
@@ -102,7 +102,7 @@ export const GENERATED_MCP_TOOLS =
|
|
|
102
102
|
"openWorldHint": true,
|
|
103
103
|
"readOnlyHint": false
|
|
104
104
|
},
|
|
105
|
-
"description": "Click an element by index, semantic selector, or desktop coordinate pixels from screenshot metadata.",
|
|
105
|
+
"description": "Click an element by index, semantic selector, or desktop coordinate pixels from screenshot metadata. Plain left activation prefers a native AT-SPI click/press/toggle action, avoiding toolkit coordinate scaling. Entry activate and slider jump actions are not substituted for pointer clicks. Explicit coordinates, right clicks, and multi-clicks retain pointer semantics.",
|
|
106
106
|
"inputSchema": {
|
|
107
107
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
108
108
|
"properties": {
|
|
@@ -153,7 +153,7 @@ export const GENERATED_MCP_TOOLS =
|
|
|
153
153
|
},
|
|
154
154
|
"relative": {
|
|
155
155
|
"default": null,
|
|
156
|
-
"description": "Interpret `x`/`y`
|
|
156
|
+
"description": "Interpret `x`/`y` from the clipped window screenshot crop origin, in\ncoordinate pixels before preview resizing. Divide preview pixels by its\nscale first. This is not a toolkit widget or raw GDK surface origin.\nRequires a window target; missing targets are rejected.",
|
|
157
157
|
"type": [
|
|
158
158
|
"boolean",
|
|
159
159
|
"null"
|
|
@@ -1043,7 +1043,7 @@ export const GENERATED_MCP_TOOLS =
|
|
|
1043
1043
|
},
|
|
1044
1044
|
"relative": {
|
|
1045
1045
|
"default": null,
|
|
1046
|
-
"description": "Interpret `x`/`y`
|
|
1046
|
+
"description": "Interpret `x`/`y` from the clipped window screenshot crop origin, in\ncoordinate pixels before preview resizing. Divide preview pixels by its\nscale first. This is not a toolkit widget or raw GDK surface origin.\nRequires a window target; missing targets are rejected.",
|
|
1047
1047
|
"type": [
|
|
1048
1048
|
"boolean",
|
|
1049
1049
|
"null"
|
|
@@ -56,6 +56,31 @@ If `doctor` selects ydotool as the input backend, also enable its per-user daemo
|
|
|
56
56
|
|
|
57
57
|
On GNOME Wayland, log out and back in after `setup-window-targeting` if the GNOME Shell extension was newly installed.
|
|
58
58
|
|
|
59
|
+
For MCP hosts with `COMPUTER_USE_LINUX_NOTIFY_ON_COMPLETE=1`, call the optional
|
|
60
|
+
`complete_interaction` tool once after finishing desktop interaction. A skipped
|
|
61
|
+
cue is not a task failure. This notification does not guarantee exclusive
|
|
62
|
+
desktop ownership or that other clients have stopped sending input.
|
|
63
|
+
This applies only to directly spawned MCP hosts, not the native Pi extension.
|
|
64
|
+
|
|
65
|
+
`setup_accessibility` verifies the saved GNOME `toolkit-accessibility` key
|
|
66
|
+
separately from runtime AT-SPI. Inspect its warning and readback before assuming
|
|
67
|
+
new apps can expose trees. Other accessibility tools may change the key later;
|
|
68
|
+
setup does not hold it enabled continuously.
|
|
69
|
+
|
|
70
|
+
### Optional foreground accessibility guard
|
|
71
|
+
|
|
72
|
+
Skip unless: the user explicitly wants GNOME's saved `toolkit-accessibility`
|
|
73
|
+
setting kept enabled while desktop automation runs.
|
|
74
|
+
|
|
75
|
+
Run `computer-use-linux guard-accessibility` in a foreground terminal. It
|
|
76
|
+
registers a passive AT-SPI window-activation listener and watches/reasserts the
|
|
77
|
+
saved key with readback. The setting affects all apps for the current user.
|
|
78
|
+
`mcp`, setup, and `get_app_state` never start this guard automatically.
|
|
79
|
+
Stop with Ctrl-C or SIGTERM before intentionally disabling accessibility.
|
|
80
|
+
Stopping ends writes and removes its listener without disabling other clients
|
|
81
|
+
or restoring a previous saved value. Apps launched during a reset/reassertion
|
|
82
|
+
race may still need restarting; do not claim a complete GNOME toggle fix.
|
|
83
|
+
|
|
59
84
|
## Configure Your Agent
|
|
60
85
|
|
|
61
86
|
The `computer-use-linux` binary is an MCP server. Configure it as a stdio MCP server in your agent of choice:
|
|
@@ -87,6 +112,26 @@ If the binary is not on `PATH`, use the absolute path (typically `~/.local/bin/c
|
|
|
87
112
|
9. For text input, prefer `type_text` with a target selector (`window_id`, `pid`, `app_id`, `wm_class`, `title`, `tty`, `terminal_pid`, `terminal_command`, or `terminal_cwd`) rather than relying on current focus.
|
|
88
113
|
10. After mutating actions, re-check state with `get_app_state`, `focused_window`, or an app-specific readback.
|
|
89
114
|
|
|
115
|
+
Plain left element/index/selector `click` prefers native AT-SPI `click`,
|
|
116
|
+
`press`, or `toggle` over toolkit bounds, avoiding coordinate
|
|
117
|
+
conversion when available. This preference does not replace a coordinate click
|
|
118
|
+
with an arbitrary action name. Explicit `x`/`y`, right clicks, and double/multiple
|
|
119
|
+
clicks retain pointer semantics.
|
|
120
|
+
Use `perform_action` explicitly for entry `activate` or slider `jump`; `click`
|
|
121
|
+
never substitutes those actions, including when bounds are unavailable.
|
|
122
|
+
|
|
123
|
+
### Screenshot-relative coordinates
|
|
124
|
+
|
|
125
|
+
Skip unless: a coordinate `click` or `scroll` uses `relative: true`.
|
|
126
|
+
|
|
127
|
+
Select a target window and use its clipped screenshot crop origin. Divide
|
|
128
|
+
preview `x`/`y` by screenshot `scale` first. Widget-local and raw GDK surface
|
|
129
|
+
coordinates are not interchangeable with that origin; missing window targets
|
|
130
|
+
are rejected. For calibration, use the repository's
|
|
131
|
+
`examples/coordinate_probe.py`: select the green square from the screenshot
|
|
132
|
+
and require a delivered-event `hit: true`. Do not pass widget-local `(85, 85)`
|
|
133
|
+
directly to a window-relative click.
|
|
134
|
+
|
|
90
135
|
## Pitfalls
|
|
91
136
|
|
|
92
137
|
- Already-running GTK, Qt, and Electron apps may need a restart after AT-SPI is enabled.
|