@agent-sh/computer-use-linux 0.4.10 → 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.
@@ -1,14 +1,15 @@
1
1
  ---
2
2
  name: computer-use-linux
3
- description: "Linux desktop observation and control via the computer-use-linux MCP server: accessibility trees, screenshots, window targeting, and input synthesis (click, type, scroll). Works with any MCP host."
3
+ description: "Linux desktop observation and control via native Pi tools or the computer-use-linux MCP server: accessibility trees, screenshots, window targeting, and input synthesis (click, type, scroll)."
4
4
  author: agent-sh
5
5
  license: MIT
6
6
  platforms: [linux]
7
+ compatibility: "Native Pi tools require Pi 0.84.4+ and Node.js 22.19+; the standalone CLI/MCP server supports Node.js 18+."
7
8
  ---
8
9
 
9
10
  # computer-use-linux
10
11
 
11
- Use `computer-use-linux` when an agent needs to observe or operate a local Linux desktop through MCP: inspect the accessibility tree, list/focus windows, take screenshots, click, scroll, type, press keys, or invoke AT-SPI actions.
12
+ Use `computer-use-linux` when an agent needs to observe or operate a local Linux desktop: inspect the accessibility tree, list/focus windows, take screenshots, click, scroll, type, press keys, or invoke AT-SPI actions.
12
13
 
13
14
  ## When to Use
14
15
 
@@ -23,6 +24,12 @@ Do not use this for remote browsers, websites, or headless automation when a bro
23
24
 
24
25
  ## Install
25
26
 
27
+ Pi users need only the package:
28
+
29
+ ```bash
30
+ pi install npm:@agent-sh/computer-use-linux
31
+ ```
32
+
26
33
  Preferred install:
27
34
 
28
35
  ```bash
@@ -49,6 +56,31 @@ If `doctor` selects ydotool as the input backend, also enable its per-user daemo
49
56
 
50
57
  On GNOME Wayland, log out and back in after `setup-window-targeting` if the GNOME Shell extension was newly installed.
51
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
+
52
84
  ## Configure Your Agent
53
85
 
54
86
  The `computer-use-linux` binary is an MCP server. Configure it as a stdio MCP server in your agent of choice:
@@ -69,20 +101,43 @@ If the binary is not on `PATH`, use the absolute path (typically `~/.local/bin/c
69
101
 
70
102
  ## Procedure
71
103
 
72
- 1. Start every desktop-control session with `doctor`.
73
- 2. If `can_build_accessibility_tree` is false, run `setup` and restart the target app.
74
- 3. If `can_query_windows` is false on GNOME Wayland, run `setup-window-targeting` and ask the user to log out and back in if setup says the shell extension needs a reload.
75
- 4. Before targeted input, call `list_windows` or `focused_window` and verify the intended window by title, app id, pid, or wm class.
76
- 5. Prefer semantic targeting from `get_app_state`: use element indices or role/name/text/states selectors.
77
- 6. Use coordinates only when the UI surface has no useful accessibility tree.
78
- 7. 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.
79
- 8. After mutating actions, re-check state with `get_app_state`, `focused_window`, or an app-specific readback.
104
+ 1. In Pi, call `computer_use_linux_tools` with the exact tools or capability you need. Enabled tools use the `computer_use_linux_<name>` prefix, appear starting on the next model turn, and remain active for the session.
105
+ 2. Begin every desktop-control turn with `get_app_state`; use `include_screenshot: false` when the accessibility tree is sufficient. Its compact readiness block identifies missing setup.
106
+ 3. Use `doctor` only when you need the full diagnostic report.
107
+ 4. If `can_build_accessibility_tree` is false, run `setup_accessibility` and restart the target app.
108
+ 5. If `can_query_windows` is false on GNOME Wayland, run `setup_window_targeting` and ask the user to log out and back in if setup says the shell extension needs a reload.
109
+ 6. Before targeted input, call `list_windows` or `focused_window` and verify the intended window by title, app id, pid, or wm class.
110
+ 7. Prefer semantic targeting from `get_app_state`: use element indices or role/name/text/states selectors.
111
+ 8. Use coordinates only when the UI surface has no useful accessibility tree.
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.
113
+ 10. After mutating actions, re-check state with `get_app_state`, `focused_window`, or an app-specific readback.
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.
80
134
 
81
135
  ## Pitfalls
82
136
 
83
137
  - Already-running GTK, Qt, and Electron apps may need a restart after AT-SPI is enabled.
84
138
  - GNOME may show a portal prompt on the first screenshot or `get_app_state` call with screenshots enabled.
85
139
  - Desktop input is stateful. Avoid concurrent tool calls against this MCP server.
140
+ - Pi serializes the native Computer Use tools and keeps one process for the session. If that process exits, do not replay an ambiguous mutating call; obtain a fresh `get_app_state` before another element-based action.
86
141
  - `click`, `drag`, `press_key`, `type_text`, `perform_action`, and `set_value` can change real application state.
87
142
  - When ydotool is selected, `ydotoold` should run as a per-user service with its socket under `/run/user/$UID`, not as a system-wide service.
88
143
  - The optional ydotool backend requires version 1.0.3 or newer; `doctor` rejects older or semantically incompatible CLIs even when `ydotoold` is running.
@@ -1,57 +1,128 @@
1
1
  ---
2
2
  name: pi-setup
3
- description: "Pi coding agent setup for the computer-use-linux MCP server."
3
+ description: "Pi coding agent setup for native computer-use-linux tools."
4
4
  ---
5
5
 
6
6
  # Pi Setup
7
7
 
8
- ## Prerequisites
8
+ ## Install
9
9
 
10
- You need both of these installed:
10
+ Install one package:
11
11
 
12
12
  ```bash
13
- pi install npm:pi-mcp-adapter
14
13
  pi install npm:@agent-sh/computer-use-linux
15
14
  ```
16
15
 
17
- > **Note:** `pi-mcp-adapter` is a separate extension that provides MCP protocol support in pi. The `@agent-sh/computer-use-linux` package auto-registers the desktop MCP server into pi-mcp-adapter's config.
16
+ Restart Pi or run `/reload`. No separate MCP adapter or MCP configuration is
17
+ required.
18
18
 
19
- After installing both, restart pi or run `/reload`.
19
+ The integration is designed for current Pi releases with additive dynamic tool
20
+ loading. Update Pi and installed packages when needed:
20
21
 
21
- ## Verify
22
+ ```bash
23
+ pi update --all
24
+ ```
22
25
 
23
- The `mcp()` proxy tool should now be available. Call it from any prompt:
26
+ ## How tool loading works
24
27
 
25
- ```bash
26
- mcp({ search: "doctor" })
28
+ Pi initially sees one small loader:
29
+
30
+ ```text
31
+ computer_use_linux_tools
27
32
  ```
28
33
 
29
- Or start with the readiness check (note the server-prefixed tool name):
34
+ Enable exact tools:
30
35
 
31
- ```bash
32
- mcp({ tool: "computer_use_linux_doctor" })
36
+ ```text
37
+ computer_use_linux_tools({ tools: ["doctor", "list_windows"] })
33
38
  ```
34
39
 
35
- Search for available tools:
40
+ Or search by capability:
36
41
 
37
- ```bash
38
- mcp({ server: "computer-use-linux" })
42
+ ```text
43
+ computer_use_linux_tools({ query: "inspect a window and type text" })
44
+ ```
45
+
46
+ The selected native tools appear starting on the next model turn with their
47
+ full upstream schemas and remain active for the session:
48
+
49
+ ```text
50
+ computer_use_linux_doctor({})
51
+ computer_use_linux_list_windows({})
52
+ computer_use_linux_type_text({ text: "hello", title: "Notes" })
39
53
  ```
40
54
 
55
+ Pi does not start the desktop process when the loader runs. The first real tool
56
+ call starts one computer-use-linux process, and the package reuses it for the
57
+ session so `get_app_state` element indices and portal sessions remain valid.
58
+
59
+ ## Safe operating loop
60
+
61
+ 1. Enable `get_app_state`, `list_windows`, and any likely action tools.
62
+ 2. Call `computer_use_linux_get_app_state`, using
63
+ `include_screenshot: false` when accessibility data is enough.
64
+ 3. Inspect the returned readiness block; enable/call `doctor` only for full
65
+ diagnostics.
66
+ 4. Identify the target with `computer_use_linux_list_windows` or
67
+ `computer_use_linux_focused_window`.
68
+ 5. Enable and call the required action tool.
69
+ 6. Re-observe after the UI changes.
70
+
71
+ Native Computer Use tools execute sequentially. Cancellation is forwarded to
72
+ the MCP request. If the server process exits, the failed call is never replayed
73
+ automatically; call `get_app_state` again before another element-based action.
74
+
75
+ ## Migration from the adapter-based package
76
+
77
+ Older releases required `pi-mcp-adapter` and wrote a
78
+ `computer-use-linux` entry into `mcp.json` under the configured Pi agent
79
+ directory.
80
+
81
+ The native integration does not write MCP configuration. It reads only the
82
+ legacy entry location to show a migration notice. After updating:
83
+
84
+ 1. Remove only the `computer-use-linux` entry from the Pi agent `mcp.json` if
85
+ it is still present.
86
+ 2. Keep `pi-mcp-adapter` if you use it for other MCP servers; otherwise remove
87
+ it with `pi remove npm:pi-mcp-adapter`.
88
+ 3. Run `/reload`.
89
+
90
+ The package reports a non-destructive migration notice when it detects the
91
+ legacy entry.
92
+
41
93
  ## If the binary is not found
42
94
 
43
95
  The extension looks for `computer-use-linux` in this order:
44
96
 
45
- 1. `COMPUTER_USE_LINUX_BIN` environment variable
46
- 2. The npm-bundled binary (from `npm install -g @agent-sh/computer-use-linux`)
47
- 3. `$PATH`
97
+ 1. `COMPUTER_USE_LINUX_BIN`
98
+ 2. The binary downloaded inside the installed npm package
99
+
100
+ Reinstall the package if the bundled binary is missing:
101
+
102
+ ```bash
103
+ pi remove npm:@agent-sh/computer-use-linux
104
+ pi install npm:@agent-sh/computer-use-linux
105
+ ```
48
106
 
49
- If none are found, install it:
107
+ Users with a separate build can set:
50
108
 
51
109
  ```bash
52
- npm install -g @agent-sh/computer-use-linux
53
- # or
54
- cargo install computer-use-linux
110
+ export COMPUTER_USE_LINUX_BIN=/absolute/path/to/computer-use-linux
55
111
  ```
56
112
 
57
- Then restart pi or run `/reload`.
113
+ ## Verification
114
+
115
+ Enable and call the readiness tool:
116
+
117
+ ```text
118
+ computer_use_linux_tools({ tools: ["doctor"] })
119
+ computer_use_linux_doctor({})
120
+ ```
121
+
122
+ Ready output has:
123
+
124
+ - `can_register_mcp_tools: true`
125
+ - `can_build_accessibility_tree: true`
126
+ - `can_query_windows: true`
127
+ - `can_send_development_input: true`
128
+ - `blockers: []`