Computer use for AI agents that clicks real UI elements instead of guessed pixels. The model reads a pruned accessibility tree and says click e14. Works on macOS, Windows, Linux, and Chromium, through one MCP server.
0.2.0 adds OCR refs for apps with no accessibility tree, a mission runner for long multi-app jobs, and macOS menu and file-dialog tools. Live-verified on this release: OCR of the real screen (about 0.5 s), TextEdit menus through the accessibility menu bar, and Figma's tree through the Electron fix. The full agency mission in
docs/missions/has not been run end to end yet.
Install
uvx a11y-computer-use doctor # try it, no install
pip install a11y-computer-use # extras: [browser] [windows] [linux]
Add it to Claude Code, Claude Desktop, Cursor, or any MCP host:
claude mcp add a11y-computer-use -- uvx a11y-computer-use mcp
{ "mcpServers": { "a11y-computer-use": { "command": "uvx", "args": ["a11y-computer-use", "mcp"] } } }
For a browser tab instead of the desktop, start Chrome with --remote-debugging-port=9222 and set A11Y_COMPUTER_USE_DRIVER=browser.
What the model sees
[snap-7] com.apple.TextEdit (window)
e1 window "Untitled"
e2 textarea ="Hello" (edit,focus)
e3 button "Save" (click)
Then it acts: click(ref="e3"), type("hello"), set_value(ref="e2", value="..."). Ref clicks go through the accessibility API and leave your pointer alone. A stale ref comes back as stale_ref with the nearest live candidates. Re-observing as a diff costs about 10 tokens. Apps with no accessibility tree (Telegram, canvases) get OCR refs o1..oN from on-device text recognition, and click(ref="o7") works the same way (docs/ocr-refs.md).
21 tools: desktop_snapshot, find, screen_text, screenshot, zoom, click, type, key, scroll, drag (with waypoint paths for strokes), wait_for, wait_until, act, set_value, scroll_to_find, notes, menu, file_dialog, app, window, clipboard, plus console and network on the browser. Menus and file dialogs stay reachable even in custom-drawn apps (docs/macos-primitives.md). Details: docs/agent-loop.md and the tool docstrings.
Why not the alternatives
| Approach | Native desktop | Any model | Embeddable | |
|---|---|---|---|---|
| Claude Desktop built-in | pixel loop | ✅ | ❌ | ❌ |
| browser-use, Playwright MCP | a11y tree | ❌ browser only | ✅ | ✅ |
| UI-TARS-desktop | pixel / vision | ✅ | partial | app |
| Windows-MCP, Terminator | a11y (UIA) | Windows only | ✅ | ✅ |
| a11y-computer-use | a11y tree + vision fallback | ✅ macOS, Linux, Windows*, Chromium | ✅ local too | ✅ MCP, CLI, Python |
Same planner, 13 browser tasks, one round: refs finished 13/13 with 0 misclicks for $7.04; screenshot coordinates finished 7/13 with 27 misclicks for $11.74 (full results). Run it yourself with a11y-computer-use bench h2h.
Platforms
| Observe | Ref actions | Type, keys | Coordinates, screenshot | Verified | |
|---|---|---|---|---|---|
| macOS (AX) | ✅ | ✅ | ✅ | ✅ | live on a granted Mac |
| Linux (AT-SPI2) | ✅ | ✅ | ✅ | ✅ X11, ❌ Wayland | CI + real desktop VM |
| Browser (CDP) | ✅ | ✅ | ✅ | ✅ | CI, headless Chrome |
| Windows (UIA)* | ✅ | ◐ press only | ✅ | ❌ | CI, Notepad |
*Windows is partial: ref re-resolution, capture, and coordinate input are not implemented yet. Exact gates per platform: docs/ci.md, docs/windows-port.md, docs/linux-port.md.
Safety
- Per-app grants (
read,click,full) in~/.a11y-computer-use/permissions.json. No tool can grant itself access. - Clicks on destructive labels ask the host to confirm. No confirmation channel means the click is blocked.
- Password fields are never read, typed into, or clicked. Every action is checked against the frontmost window right before it fires.
- Everything is logged to
~/.a11y-computer-use/audit/as JSONL, with secrets redacted.
Report security issues privately: SECURITY.md.
Embed it
from a11y_computer_use import safety, server
store = safety.PermissionStore()
store.set_tier("com.apple.TextEdit", safety.Tier.FULL)
rt = server.Runtime(store=store)
print(rt.desktop_snapshot("com.apple.TextEdit", mode="interactive"))
rt.click(ref="e3", verify=True)
Existing Anthropic or OpenAI computer-use loops can run through it unchanged via a11y_computer_use.adapters (docs/provider-adapters.md). A reference agent loop ships as a11y-computer-use agent --task "..." and works with Anthropic, OpenAI-compatible endpoints (Ollama included), or the Claude Code CLI.
Long jobs across several apps run as missions: phases with their own app grants, step budgets, runner-side checks (a file exists, a URL answers, text is on screen), retries, and a wall-clock timeline for video cuts.
a11y-computer-use mission run examples/missions/agency-demo.toml --provider claude-cli
Format and checks: docs/missions.md. The example mission is the design-agency reel described in docs/missions/agency-demo.md.
Docs
Agent loop · Missions · OCR refs · macOS menus and dialogs · Adapters · Observation cost · Benchmark · Browser backend · Linux · Windows · Real-desktop test bed · CI · Decision records · Changelog · Contributing
Apache-2.0. Copyright 2026 Perception Dynamics, Inc.
Release files for a11y-computer-use 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| a11y_computer_use-0.2.0.tar.gz | 570.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| a11y_computer_use-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 858.4 kB
Release files / a11y_computer_use-0.2.0.tar.gz
| Download URL | a11y_computer_use-0.2.0.tar.gz |
|---|---|
| Size | 570.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
372261820f24b86aa64b25ab5c34d7c2871612e5d03b9e43d93d014707a6f5f2
|
|
BLAKE2b-256 checksum How to use checksums |
3149cce1815ca21dec0b12444f2dc2cb3600f18b1b056b640ab09f72626d30e4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.
Transparency logRelease files / a11y_computer_use-0.2.0-py3-none-any.whl
| Download URL | a11y_computer_use-0.2.0-py3-none-any.whl |
|---|---|
| Size | 287.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
30d6d997e0c9ddfbd89016a8fd0ac7bf6eab84ea3d79ad285e56efbbafd9e407
|
|
BLAKE2b-256 checksum How to use checksums |
8260329baf8f03500b1e177ec23de5124f501afbfe8a9ba766e9d49adb8ffd77
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.
Transparency log