🚫 Why screenshots break 0:00
The standard computer-use loop takes a picture of your screen, guesses where the button is, moves the mouse to a pixel, clicks, and takes another picture. It is slow, it burns tokens on images, and if a window moves a little the whole thing breaks.
agent-desktop from Vercel Labs takes the other route: it reads the operating system's accessibility tree — the same structured data screen readers use — where every button, field, checkbox and menu item already exists as data with a role, a name, and the actions it supports. Written in Rust, Apache-2.0, macOS / Windows / Linux.
🔄 The loop, and where it lives 1:18
Three commands, repeated: snapshot --app Notes returns JSON where every actionable element carries a ref; the agent acts on a ref; a new snapshot verifies the result. Observe, act, observe.
🔖 Refs: identity, and refusal 1:42
A ref is scoped to the snapshot it came from — it looks like @s8f3k2p9:e8, a snapshot id, a colon, and an element number. That scoping is what makes the tool safe:
| Situation | What agent-desktop does | What the agent must do |
|---|---|---|
| The UI changed and the ref now points elsewhere | Returns STALE_REF — refuses to click | Take a new snapshot |
| Several windows could match | Returns AMBIGUOUS_TARGET, with candidate window ids in error.details | Re-issue with an explicit window |
| A bare element number is used without a snapshot id | Rejects with INVALID_ARGS | Always use the full ref |
| The ref is valid | Performs the action | Snapshot again to verify |
That ordering — refuse, then let the agent recover — is what separates a demo from something you would point at a real account. An agent that guesses is worse than an agent that stops.
👻 Headless, and skeleton mode 2:08
Two defaults do most of the practical work, and neither is about intelligence.
| Default | What it means | Why it matters |
|---|---|---|
| Headless by default | Ref-based actions go through the accessibility API — no pointer movement, no focus stealing. A global --headed flag enables physical input. | You keep working in another window while the agent drives a background app |
| Skeleton mode | snapshot --skeleton --app Slack -i --compact gives a shallow map; snapshot --root @s8f3k2p9:e3 -i --compact drills into one region | Keeps snapshots small: fewer tokens, less confused model |
⌨️ 60 commands, four that refuse 2:43
The surface is bigger than "click and type", and the breakdown is worth seeing because it tells you what the designers thought a real workflow needs.
| Category | Commands |
|---|---|
| Observe | snapshot, find, get, screenshot |
| Act on a ref | click, double-click, triple-click, right-click, type, set-value, clear, focus, select, toggle, check, uncheck, expand, collapse, scroll, scroll-to |
| Keyboard and mouse | Key presses, text entry with --interval-ms, physical input under --headed |
| Apps and windows | App listing, window management, notifications, clipboard |
| Orchestration | await, batch (many actions in one call) |
| Sessions | session, trace, cursor-overlay |
key-down, key-up, mouse-down, mouse-up — refuse to run until a daemon can release a held key or button. Shipping the names as explicit failures rather than leaving them out means an agent gets a clear error instead of inventing a fallback like "hold shift by typing shift repeatedly".
🧾 The error envelope 3:05
Every command prints one JSON envelope: ok, plus either data or an error. The errors carry a code, usually a suggestion, and a retry field — and the agent should only retry when that field says it is safe.
🆕 What actually changed in 1.1 3:21
The video lists the 1.1 highlights. Checked against the release notes, most hold — but one item is bigger than it is made to sound, and the version is already one ahead.
| Change | Verified | Why it matters |
|---|---|---|
| Dock, menu-bar status items and system panels reachable on macOS | Yes — v1.1.0 | Apps that live only in the menu bar become drivable |
type --interval-ms to type at a steady pace | Yes — v1.1.0 | Fixes apps that drop characters on instant paste |
| Cursor overlay: label pill, click ripple, insertion caret | Yes — v1.1.0 | Human-readable supervision of a headless run |
| Every CLI call runs in its own process; the old macOS command host is gone | Yes — v1.1.0 | No shared long-lived host to go stale or crash |
| Refs re-identified through the element's own accessibility address; Linux and Windows refs resolved through a capture rule | Yes — v1.1.0 | The real headline: refs survive UI churn better, so fewer restart-the-loop rounds |
| Sessions and tracing, optionally with before/after screenshots per action | Yes — session, trace | You can see exactly which step broke a run |
| A C library so you can call it without starting the CLI each time | Yes — libagent_desktop_ffi ships per release | Removes per-call process overhead entirely |
| "Just hit version 1.1" | Correct but stale | v1.2.0 followed on 5 November: list-row selection, and the cursor overlay drawing above menus |
| "More than 10,000 stars" | Understated | ~17,900 stars at the time of writing; first commit 19 February 2026 |
📦 A binary that carries its own docs 4:11
Installation is one npm package; the interesting part is how the tool teaches the agent to use it.
| Step | Command / requirement |
|---|---|
| Install | npm install -g agent-desktop, then agent-desktop version (Homebrew also available on macOS and Linux) |
| Permissions | agent-desktop permissions --guide walks through the macOS accessibility grant; Windows usually needs none; Linux uses AT-SPI in your graphical session |
| Teach the agent | agent-desktop skills get desktop prints the loop, the ref rules and the retry rules matched to the installed version; skills get platform prints what differs on your OS |
| Wire it in | Install the skill (npx skills add) or add two lines to AGENTS.md telling the agent to read those skills first |
skills get desktop is the pattern worth stealing. The binary ships the documentation for agents, version-matched to the build, printed on demand. That removes the classic failure where the model reads an outdated README and calls flags that no longer exist — and it costs one subcommand.
🕳 What the video leaves out 4:55
Two interfaces and three platform facts are missing from the walkthrough, and they change who can use this.
| Omitted | Detail | Why you care |
|---|---|---|
| MCP server | agent-desktop mcp serves every command as an MCP tool over stdio — desktop_snapshot, desktop_click, desktop_session_start — with global flags like --session, --headed, --trace applying to every call | Any MCP client gets computer use without a shell or a skill file; no per-agent integration work |
| C library | libagent_desktop_ffi ships with each release; call it in process via ctypes/FFI | Turns per-action process startup into a function call — the difference for high-frequency loops |
| Platform mapping | macOS AX API, Windows UI Automation, Linux AT-SPI — one core, one platform crate per build | Explains why capabilities differ per OS instead of being bugs |
| Window-pinned refs | After an action, the wait observes the ref's original process; refs from a sheet, alert, popover or Linux menu stay pinned to their window | Avoids verifying against the wrong window's state |
| PowerShell quoting | On Windows, quote every ref ('@s8f3k2p9:e8') because a bare @ token is the splatting operator | A five-minute debugging session avoided |
💰 The cost shape of computer use 5:25
The second half of the video is sponsored, promoting a subscription and two desktop products, with pricing and links that are excluded here. The technical argument underneath is worth keeping, because it is not about the sponsor at all:
| Loop style | Payload per step | Model requirement |
|---|---|---|
| Screenshot loop | A full image | A vision-capable model, at image-token prices, every step |
| Accessibility-tree loop | A JSON fragment with refs | A text model — a cheap, fast open model is enough |
🖱 Many cursors, one lease 6:50
Multi-agent mode gives each agent its own cursor and an agent id: --cursor plus --multi-agent. Their cursors move at the same time, but their actual actions take turns, so two agents never type into each other.
The video pairs this with an orchestrator that splits a desktop task across workers and reviews the results. Architecturally that is fine; check licences before adopting, since the orchestration tool promoted here declares no OSI licence.
🚧 Limitations 7:33
| Limitation | Consequence |
|---|---|
| It is only as good as the app's accessibility tree | Games, canvas-based apps and apps with bad labels are hard or impossible |
| macOS requires the accessibility grant | That is effectively full control of your apps — scope what you let it run |
| Hover, drag and double-click may need headed mode | Then the agent takes your real mouse and focus |
| Linux has gaps, e.g. mouse input only on X11 | Wayland workflows are partly out of reach |
| Snapshots and traces contain whatever is on screen | Treat them as sensitive; keep them out of public logs and CI artefacts |
| An optional helper sends screen descriptions to an external model provider | Read what it transmits before enabling it |
⚖️ Verdict 8:09
His summary: reads the tree instead of guessing pixels, gives every element a ref, headless by default, tells the agent when retrying is safe, works on all three platforms, free and open source, and fits any agent that can run a command.
Agreed, with one qualification. The strengths are protocol decisions — ref scoping, refusal over guessing, retryability per error, shallow-then-deep snapshots — and those are copyable by anyone building a similar tool. The weakness is structural and not fixable in software: apps that expose nothing to the accessibility tree are invisible to it, and on macOS the permission it needs is the key to everything else.
STALE_REF and stops gives you a log you can reason about; a tool that clicks the wrong pixel gives you a mystery. For anything touching real accounts, that difference is the whole product.
✅ Claims checked
| Claim | Verdict | Evidence |
|---|---|---|
| agent-desktop is from Vercel Labs, written in Rust, Apache-2.0, macOS/Windows/Linux | Correct | Repo vercel-labs/agent-desktop: Rust, Apache-2.0, created 19 Feb 2026 |
| It reads the accessibility tree instead of pixels, and ships no model | Correct | README: AX API on macOS, UI Automation on Windows, AT-SPI on Linux; "the loop lives in your agent" |
Refs are scoped to a snapshot; STALE_REF / AMBIGUOUS_TARGET instead of random clicks | Correct | README documents both codes, plus INVALID_ARGS for a bare ref and candidate window ids in error.details |
Headless by default; --headed for physical input | Correct | README, global flags |
| 60 command names, 56 operational | Correct | README: "60 command names, 56 operational commands"; the four that refuse are key-down, key-up, mouse-down, mouse-up |
Skeleton mode: shallow map, then drill with --root | Correct | README example with Slack |
Errors carry a code, a suggestion and a retry field | Correct | JSON envelope: ok plus data or error |
v1.1 added dock/menu-bar reach, --interval-ms, better cursor overlay, per-call processes, sessions/tracing, C library | Correct, mostly v1.1.0 | Release notes v1.1.0 (3 Nov 2026): type --interval-ms, insertion caret, label pill, "remove the macOS command host", dock/menu-bar/system panels, ref re-identification via the element's accessibility address; session/trace/C library documented in README |
| "Just hit version 1.1" | Stale by a day | v1.2.0 released 5 Nov 2026 (list-row selection; cursor overlay above menus and system panels) |
| "More than 10,000 stars" | Understated | ~17,965 stars at the time of writing |
| Multi-agent mode: per-agent cursors, actions take turns | Correct | --cursor / --multi-agent; an interaction lease serialises actuation |
| Linux mouse input only on X11; hover/drag may need headed | Video's claim, plausible | Consistent with the platform pages; not individually re-tested here |
| Sponsor pricing, bundled models and rate limits | Commercial claims | Sponsored segment — excluded, not repeated as fact |
| The orchestration tool promoted at the end is open source | Not as declared | It carries a NOASSERTION licence on GitHub — source-available, not OSI open source |
Basis note. Built from the full 8:43 transcript, then verified against the repository README, the GitHub releases API (v1.0.0 through v1.2.0) and the live repo metadata. Two figures in the video are out of date by a day or two and are corrected above; the four non-operational commands, the MCP server, the C library and the window-pinning behaviour are additions from the source repository that the video does not cover. Sponsor material is excluded.
🔑 Key takeaways
- Refuse rather than guess.
STALE_REFandAMBIGUOUS_TARGETturn a silent wrong click into a recoverable error — the single most important design choice in the tool. - Scope refs to their snapshot. A bare element number is rejected; validity is explicit, so the agent must re-observe before acting.
- Encode retryability per error. A
retryfield that says whether retrying is safe prevents double-submitted forms — the worst bug class in computer use. - Headless by default changes the workflow, not just the plumbing. The agent drives a background app while you keep your mouse and focus.
- Skeleton mode is context management. Shallow map, then drill into one subtree — bounded context instead of a thousands-line tree.
- Ship the docs inside the binary.
skills get desktopprints version-matched instructions for the agent, so the model never reads a stale README. - v1.1's real headline is ref identity: re-identifying refs through each element's own accessibility address means fewer restarts after the UI shifts.
- Two interfaces the video misses:
agent-desktop mcpexposes all 60 commands as MCP tools over stdio, andlibagent_desktop_ffilets you call it in process from Python or C. - Text instead of pixels changes the cost shape: many cheap steps on a fast text model, instead of many expensive image steps on a frontier vision model.
- Concurrency on a shared desktop needs a lease: cursors may move together, but actuation must take turns — otherwise two agents type into the same field.
- Treat snapshots and traces as credentials. A structured dump of your desktop is sensitive; encrypt it and set a retention limit.
- Check versions and licences before quoting a demo. The video is one release behind (v1.2.0 shipped two days later) and both promoted companion tools deserve a licence check.
🔗 Resources
- The source video — AISeeKing, "Vercel's New Opensource Library might have solved Computer USE!", 8:43, 6 November 2026
- vercel-labs/agent-desktop — Apache-2.0, Rust, CLI + C library + MCP server
- Releases — v1.0.0 (28 Oct) through v1.2.0 (5 Nov); the v1.1.0 notes list every change discussed here
- Command reference — each of the 60 commands, per platform
- Snapshots and refs — the ref format and the failure codes
- Earlier deep dive on the 1.0 launch — the snapshot format, the repository tour and the accessibility-tree debate