Vercel agent-desktop: computer use through the accessibility tree, not screenshots, and what it still needs from AUX
An agent that reads the app’s own list of buttons instead of guessing from a picture. What the tool does unusually well, where it runs, how it compares, and the trust layer a business still has to put above it.
agent-desktop is an open-source (Apache-2.0) command-line tool and C library from Vercel Labs that lets any AI agent see and operate native desktop applications on macOS, Windows and Linux by reading the operating system’s accessibility tree instead of taking screenshots. It returns the UI as JSON with a reference (a “ref”) for every element the agent can act on; the agent clicks or types on a ref, reads the UI again to confirm, and repeats. It contains no model and ships as a CLI, a C library and, since 3 November 2026, a built-in MCP server. It is not a Vercel cloud product: it runs on the machine whose desktop it drives. It does the mechanics of computer use unusually well: fail-closed targeting, honest delivery reporting, headless-by-default actions, password-field protection, append-only traces. What it deliberately leaves out is everything auxfirst calls the trust layer: which actions an agent may take on its own, who approves the hot ones, how the human sees what was done, and how a business proves it afterwards.
One guesses from a picture; the other reads the app’s own structure
Two tracks
Who this is for, and how to read it
Two audiences read auxfirst.com, so this piece runs on two tracks. Business track sections explain what the tool changes for teams that run on desktop software, what it costs, where the risk sits, and which decisions remain yours. Technical track sections go into the architecture, the observe-act-verify loop, error semantics, the MCP server, the C library, and how to run it anywhere, including far from Vercel’s cloud.
Both tracks meet in section 08, where we hold agent-desktop up against what auxfirst preaches: the Action Heat Ladder, agent-first design, the four kinds of trust in Agentic User Experience, and the question we keep asking on behalf of brands: can I prove what the agent did?
Business track
What agent-desktop is
Every modern operating system keeps a hidden, structured description of what is on screen. It exists so that a screen reader can tell a blind user “Button: Send” instead of “a blue rectangle at pixel 812, 44”. That description is the accessibility tree. agent-desktop reads it and hands it to an AI agent as a list: this is a text field called Subject, this is a button called Send, this is a checkbox called Remember me, and it is currently unchecked. Each item carries a short handle, a “ref”, the agent can act on.[1]
Three consequences follow, and they are the whole business case.
- No guessing from pictures. The agent does not look at a screenshot and estimate where “Send” is. It acts on the element the app itself calls “Send”. Theme changes, window moves, high-DPI screens and dark mode stop mattering.
- No stolen mouse. By default, actions are “headless”: they go through the accessibility API without moving your cursor or taking keyboard focus.[1] A person can keep working in another window while the agent fills in a form behind it.
- Far fewer tokens. Reading a tree of names is much cheaper than sending a model a full-resolution screenshot every step. The builder’s own figures, as reported by CellCog from his launch post: a single look at Apple Maps dropped from 3,811 tokens for the full window to 273 for a skeleton-and-drill read, and a simulated 52-step task from about 198k tokens to about 31k.[7] Treat these as vendor figures until an independent benchmark exists; there is none yet.
What it is not: it is not an agent, has no model inside, has no GUI, and does not automate web pages; that is the job of its sibling, agent-browser.[1][5] It is a tool an agent calls, one command at a time. The thinking, what to do, when to stop, when to ask a human, lives in whatever drives it: Claude Code, Codex, Cursor, a custom script, or your own agent runtime.
The facts a buyer needs, in one block
| Fact | Value, verified 4 November 2026 |
|---|---|
| Maker | Vercel Labs, the experimental arm of Vercel. The project began as an individual repository (lahfir/agent-desktop, created 19 February 2026, shown on Hacker News on 2 May 2026) and moved under Vercel Labs before 1.0. |
| License | Apache-2.0: free for commercial use, modification and redistribution. |
| Language and form | Rust CLI; C library libagent_desktop_ffi; npm package agent-desktop; Homebrew formula. |
| Platforms | macOS 13+ (Intel and Apple Silicon); Windows 10 1809+ and Server 2019+ (x64, ARM64); Ubuntu 24.04+ (x86_64, aarch64, X11 or Wayland). |
| OS APIs used | macOS AX API; Windows UI Automation (UIA); Linux AT-SPI. |
| Commands | 60 command names, 56 operational. Four “hold a key or button” commands refuse to run until a daemon exists. |
| Integration surfaces | Shell CLI; MCP server (agent-desktop mcp); C FFI; bundled skills an agent reads at runtime. |
| Version reviewed | 1.1.0, released 3 November 2026 (changelog dated 2 November). 1.0.0 published 28 October 2026, 1.0.2 on 30 October. |
| Adoption signal | About 13,900 GitHub stars and 950 forks on 4 November 2026; about 6,900 stars on 2 November per DEV Community. |
| Model dependency | None in the core tool. An optional helper skill (JEV) can send screen descriptions to a third-party model endpoint. |
| Cost | Free. You pay only for whatever model drives it. |
Sources for this table: the repository README, CHANGELOG, Cargo manifest and release list; the GitHub API for star and fork counts; DEV Community, 2 November 2026.[1][2][8]
Business track
Why it matters now
Three things converged in late October 2026.
First, “computer use” stopped being a demo. Anthropic, OpenAI and Microsoft all ship agents that can operate a screen. Almost all of them see the screen as pixels: a screenshot goes to a vision model, the model returns coordinates, the harness clicks there. That works, but it is slow, expensive and brittle. Anthropic’s own documentation puts one screenshot at roughly 1,000 to 1,800 input tokens, before the model has reasoned about it.[6] Vercel’s bet is that for the large majority of business software, the accessibility tree already contains everything the agent needs, at a fraction of the cost.
Second, the long tail of enterprise work still runs on desktop software. ERP clients, accounting packages, claims systems, lab software, hospital front-ends, trading terminals, design tools, legacy Win32 and WPF line-of-business apps: a vast amount of knowledge work happens inside windows no browser agent can reach. This is where robotic process automation (RPA) vendors have earned their keep for fifteen years, by scripting clicks against those same accessibility trees. agent-desktop puts that capability in an open, model-agnostic, scriptable tool that any LLM harness can drive.
Third, Vercel is a credible open-source maintainer with distribution. The repository roughly doubled its stars in the three days after launch. The project ships a documentation site, probe corpora with findings ledgers per platform, a C ABI with versioned headers, and an npm package that bundles native binaries.[1][3] This is not a weekend hack; it is nine months of releases that got a very large megaphone.
From one developer’s repository to a three-platform 1.x release in nine months
Technical track
How it works
The seven-layer chain
The documentation describes one chain from caller to app, and the code matches it:[3]
- Your agent: a model loop or script. It runs a command and reads one JSON envelope.
- The
agent-desktopCLI, or the C library when called in-process. agent-desktop-core: commands, theRefStore, snapshot building, and every shared type.PlatformAdapter: a Rust trait, the only door from core to an operating system.- One platform crate, macOS, Windows or Linux, chosen at compile time.
- The OS accessibility API: AX, UIA or AT-SPI.
- The app, which exposes its UI through that API.
Core never imports a platform crate; platform crates never import each other. A binary drives exactly the OS it was built for. This is the kind of boundary discipline that makes a tool portable and auditable: you can read the core crate and know that every OS interaction passes through one trait.
Seven layers, one door to the operating system
The loop in four commands
agent-desktop snapshot --app "Notes" --skeleton -i --compact # 1. map: shallow skeleton, interactive nodes only
agent-desktop snapshot --root @s8f3k2p9:e3 -i --compact # 2. drill: expand one region into the same snapshot
agent-desktop click @s8f3k2p9:e12 # 3. act on a qualified ref
agent-desktop snapshot --root @s8f3k2p9:e3 -i --compact # 4. verify by reading, not by trusting ok:true
Every command prints one JSON envelope: ok, command, and either data or error. A trimmed snapshot, from the README:[1]
{
"version": "2.6", "ok": true, "command": "snapshot",
"data": {
"app": "Finder", "snapshot_id": "s8f3k2p9", "ref_count": 59, "complete": true,
"tree": { "role": "window", "name": "Downloads", "children": [
{ "role": "treeitem", "name": "Documents", "ref_id": "@s8f3k2p9:e8", "available_actions": ["Click"] }
] }
}
}
The design choices that make this trustworthy, in order of importance:
Refs are qualified and short-lived. A ref is @<snapshot_id>:e<N>. A bare @e8 is rejected with INVALID_ARGS. Refs are valid for one snapshot; after any UI change the agent re-reads. On macOS a ref carries the element’s own accessibility address, so identical twins each keep their ref. On Windows and Linux a ref resolves only if it was unique in the window when captured (by role, native id, stable name and description) and exactly one live element still matches. Zero matches is STALE_REF; two or more is AMBIGUOUS_TARGET. The tool refuses to guess.[2][3]
Skeleton and drill-down keep token cost down. --skeleton reads only a few levels deep; cut containers report a child count and get a drill ref. snapshot --root <ref> then reads one region into the same snapshot id. A “web wrapper” rule skips the anonymous container chains Electron and Chromium apps are made of, so a dense web app fits a default depth budget instead of understating its content by an order of magnitude.[3]
Evidence is tri-state. Every property an adapter reads is Known, Absent or Unknown, and the three are never collapsed. Absent means the provider was asked and does not have it. Unknown means the read failed. Only a positive claim grants a role, state or action.[3] This sounds academic until you realize it is the difference between “the Send button is disabled” and “I could not tell whether the Send button is disabled”, a distinction most automation stacks throw away.
Actionability, delivery and retry: the honest-failure model
Before any action dispatches, core runs an actionability battery against the live element: visible, stable, enabled, supports the action, allowed by policy, editable, and actually receiving events (a five-point hit test, so a partially covered control still passes). Transient checks are polled for up to 5,000 ms by default; terminal checks fail fast.[3]
Then comes the part every agent builder should steal. Every action result and every error carries a disposition:[4]
| delivery | retry | Meaning |
|---|---|---|
| not_delivered | safe | Input never reached the app. Repeating cannot duplicate an effect. |
| delivery_uncertain | unsafe | Input may have landed; nothing proves either way. |
| delivered_unverified | unsafe | Input was dispatched; its effect was not confirmed. |
| delivered_verified | unsafe | Input was dispatched and the effect was read back. Repeating would apply it twice. |
| unknown | unknown | The command established nothing about delivery, for example a timeout on an operation that may already have landed. |
The rule the bundled skill gives agents is blunt: Retry or substitute an action only when
[2] A repeated click can submit a form twice; a repeated toggle undoes itself. Where the tool cannot prove whether a click landed, it says so and tells the agent to go and look. There are 16 error codes, each with a documented “what to do”, and a disposition.retry is safe. Only not_delivered is safe.recovery object (refresh_snapshot_then_retry_original and friends) appears only when retrying is safe.[4]
On Windows this honesty goes further. The SendInput API reports success whether or not User Interface Privilege Isolation blocked the input, so agent-desktop never treats that return value as delivery evidence. It compares process integrity tokens first and refuses with PERM_DENIED when the target runs elevated.[3][9]
Headless by default, headed by permission
Ref actions are headless: semantic accessibility calls with no focus steal, no cursor movement, no synthetic keystrokes, no clipboard. If no semantic path exists, the action fails closed with POLICY_DENIED. The global --headed flag is a permission to use physical input (real clicks, real keys), and the skill tells agents: Never switch to headed mode to recover from a headless failure.
[2] Which commands need --headed differs by OS. On Windows, for example, type has no semantic path, so set-value is the headless way to write text; double-click, hover, drag and right-click are physical everywhere.[3][9]
A machine-wide interaction lease serializes physical input, so two agents on one machine cannot interleave keystrokes. Headless semantic actions do not need the pointer at all, which is what lets several agents work in parallel on one desktop.[3]
Two safety rails that come for free
- Secure fields. Once the OS marks a field as a password field (
IsPasswordon Windows, the AT-SPI password role, macOS secure text), agent-desktop withholds its value on the read side and never echoes an attempted or observed value on the action side: not in messages, not in details, not in post-state. It can type into a password field; it cannot leak one.[3] - Protected processes. It refuses to close session-critical processes (Finder,
explorer.exeand the like) on every surface, with exact-name matching so look-alikes stay closable.[3]
Sessions, traces and the cursor overlay
- A session (
session start) is an on-disk container holding snapshot refmaps, asession.jsonmanifest and atrace/directory. Lookups are confined to the session namespace.[3] - Traces are append-only JSONL files, one per OS process, each opening with a
trace.metaheader;trace showmerges them into a deterministic timeline andtrace exportwrites HTML. The schema is additive-only. Opt-in replay artifacts store pre- and post-action PNGs, unredacted, so the documentation tells you to treat them like screenshots.[3] - The agent cursor overlay draws a labeled, colored cursor that moves like a human hand to each verified action target, plays a ripple on click, and shows a caret after typing. It never moves the real pointer and never changes what the action does. With
--multi-agenteach sub-agent gets its own labeled cursor.[3] This is presentation only, but it is the first time we have seen a computer-use tool ship a disclosure affordance for the human watching.
Every agent is visibly on screen; none of them touch your mouse
The agent learns the tool from the binary
agent-desktop skills get desktop prints the core guide (the loop, refs, verification and retry rules); skills get platform prints the OS-specific one. The same skill is published on skills.sh, and the README suggests two lines for your AGENTS.md:[1]
Use `agent-desktop` to see and operate desktop apps. Before the first use, run
`agent-desktop skills get desktop` and `agent-desktop skills get platform`, and follow them.
The skills are versioned with the binary, so the agent never reads instructions for a release it does not have. This is the SKILL.md practice done properly: a procedure that loads when the work calls for it, kept in step with the tool it describes.
MCP: every command as a tool, new on 3 November 2026
agent-desktop mcp serves every command as an MCP tool over stdio. Tools are named desktop_ plus the command (desktop_snapshot, desktop_click, desktop_session_start); arguments mirror the CLI flags. The tool list is generated from the CLI’s own definitions, so it always matches the installed binary. Client configuration is one line:[1][5]
{ "mcpServers": { "agent-desktop": { "command": "agent-desktop", "args": ["mcp"] } } }
Design notes worth knowing before you wire it into a harness:[5]
- Global flags (
--session,--headed,--trace) are set once on the server command line; a tool cannot set them. That is a deliberate control point: the model cannot escalate itself to headed mode. - Results come back as
structuredContentplus text;isErrormirrorsok: false, so clients branch onerror.codeanderror.dispositionexactly as with the CLI. - The server runs at most 8 tool calls at once, refuses messages over 4 MiB, and on cancellation sends
SIGTERMfirst so a held key or button is released. - The security paragraph in the MCP guide is the most important sentence in the whole project:
Treat the server like a shell for the signed-in user. Keep your client’s confirmation on for actions, and remember that text read from the screen is untrusted input to the model.
More on that below.
C library, for everything that is not a shell
Each release ships libagent_desktop_ffi (dylib, so, dll) with a versioned C ABI, major 7 as of 1.1.0. Python via ctypes, Swift, Go, Ruby and Node hosts can call the same core in-process, with the same strict ref resolution, actionability and policy semantics as the CLI; the project calls this “FFI ref-action parity”.[1][3]
Electron and Chromium apps: hand the web part to agent-browser
For an app you can launch fresh, launch --cdp starts it with a loopback-only Chrome DevTools port and returns the endpoint. agent-browser, or any CDP client, drives the web contents; agent-desktop keeps the native menu bar, file dialogs, notifications and window management. The two tools are designed as a pair, and the guide is candid that the web contents of such apps can be dense and slow to walk
.[10]
Technical track with a business summary
Running it outside Vercel’s cloud
A common misreading, given the maker: agent-desktop is not a Vercel-hosted service and does not need a Vercel account. It is a native binary that must run on the machine whose desktop it drives, inside an interactive graphical session.[1][9] That constraint decides where it can and cannot live.
| Environment | Does it work? | Notes |
|---|---|---|
| A developer’s Mac, Windows PC or Ubuntu desktop | Yes, the primary target | macOS needs the Accessibility permission for the app that launches agent-desktop, usually the terminal; Windows needs nothing for apps at the terminal’s integrity level; Linux needs a running AT-SPI bus. |
| An employee’s work laptop, driven by an IT-approved agent | Yes | Headless actions let the person keep working; the interaction lease prevents two agents fighting over the mouse. |
| A Windows VM or physical box in your data center, signed in with an interactive session | Yes | Must be the signed-in user’s desktop. Session 0, Server Core, a locked desktop, the secure UAC desktop and another user’s session are explicitly unsupported.[9] |
| An Ubuntu 24.04 VM with a desktop session (GNOME on X11 or Wayland) | Yes | The cursor overlay needs X11 and Wayland refuses raw coordinate clicks. Chromium needs --force-renderer-accessibility to join the bus.[2][10] |
| A macOS CI runner with a logged-in session | Yes | The project’s own release pipeline runs on hosted runners. |
| Vercel Sandbox (Firecracker Linux microVM) | Not as-is | Sandbox runs headless Linux for code and CLIs; it has no display server or AT-SPI session. You would have to bring a virtual display plus at-spi2-core and a desktop app into a custom image. agent-browser has first-class Sandbox support; agent-desktop does not, and nothing in the docs claims it does.[11][12] |
| Serverless functions, Lambda, plain containers | No | Same reason: no interactive desktop. |
| Citrix or RDP-published apps, games, canvas-only UIs | Partially or no | The tool sees only what the accessibility tree exposes. A remote-desktop window is one big image to the local tree; a pixel-only UI is invisible. |
Think of agent-desktop as something you install on endpoints, the way IT deploys an RPA runner, not as something you subscribe to from Vercel. That is good news for regulated and confidentiality-bound organizations: nothing leaves the machine unless your agent harness sends it somewhere. It is also why the model you pair it with is a separate decision. A locally hosted model, a private endpoint, or a frontier API all work equally well, because the tool never talks to a model itself.
Three deployment patterns we would actually propose
- Supervised desktop co-worker. Claude Code or Codex on a knowledge worker’s machine, agent-desktop over MCP, the harness confirmation prompt left on, a named session with tracing. Use: data entry into desktop-only ERP or CRM clients, reconciliations across two apps, report assembly from legacy tools.
- Fleet of unattended runners. A pool of Windows or Linux VMs, each with one interactive session and one agent, multi-agent cursors for the human supervisor’s dashboard, traces shipped to central storage. Use: nightly back-office batches that previously ran on RPA licenses.
- Desktop app QA in CI. Your own app, driven through the accessibility tree on a macOS or Windows runner, with
waitpredicates instead of sleeps and traces as the test log. A pleasant side effect: if agent-desktop cannot see a control, neither can a screen reader, so your accessibility backlog and your agent-readiness backlog become the same list.
Business track Technical track
How it compares
How each tool sees the screen is the axis that matters.
| agent-desktop (Vercel Labs) | Claude computer use (Anthropic) | OpenAI computer use | Microsoft UFO | Fazm | |
|---|---|---|---|---|---|
| What it is | CLI, C library and MCP server; a tool, not an agent | Model-side toolset in the Claude API; also in Claude’s desktop products | API tool returning click, type and scroll actions your code executes | Full Windows agent framework | Open-source macOS agent |
| How it sees the UI | OS accessibility tree (AX, UIA, AT-SPI) | Screenshots, pixel coordinates | Screenshots | UIA plus a visual hybrid | Accessibility tree, screenshots as fallback |
| Model bundled | None; any model, any harness | Claude models | OpenAI models | Configurable | Configurable |
| Platforms | macOS, Windows, Linux | Any environment you host | Browser or desktop you host | Windows | macOS |
| Moves your cursor | No by default; --headed opts in | Yes | Yes | GUI and API actions | Varies |
| Cost per “look” | 273 tokens for a skeleton-and-drill read (builder’s figure, Apple Maps) | Roughly 1,000 to 1,800 tokens per screenshot (Anthropic documentation) | Not disclosed | Not disclosed | Not disclosed |
| License | Apache-2.0 | Proprietary API | Proprietary API | MIT | Open source |
| Where it is weak | Apps with no accessibility tree; dense Electron trees; no independent benchmark yet | Token cost, drift, latency of the vision loop | Same vision-loop costs | Windows only | macOS only |
Figures from the agent-desktop documentation, Anthropic’s computer-use documentation, the Microsoft UFO repository and the Fazm roundup.[6][7][13] The honest reading: the accessibility-tree approach wins on cost, determinism and privacy wherever the app publishes a good tree, and loses wherever it does not. The two approaches are complements, not rivals. A mature harness will use the tree first and fall back to vision for the canvas, the game, the remote desktop, and the badly built app.
Where the real differentiation is
Most commentary has focused on the token savings. We think the deeper differentiator is the project’s evidence culture, because it is the thing enterprises will care about once the novelty fades:[3]
- Every platform adapter was built against a committed probe corpus: raw OS scripts whose redacted captures sit beside the code, cited by row id (
A15-7on Windows,L32-39on Linux) in a findings ledger that records whether each measurement confirms or contradicts what the project assumed. - A mandatory measurement gate fails a probe run that declared a measurement and did not produce it, and fails one that declared nothing, because “asserted nothing” is indistinguishable from “all clean”.
- Dogfood runs drive the shipped binary against real software nobody on the project wrote, and report what was not exercised rather than presenting uniform verification.
That is a burden-of-proof discipline most AI tooling simply does not have. It is also, as we will argue, applied only to the tool’s own correctness, not yet to the work the agent does with it.
Business track
Who should use it, and for what
| Audience | What agent-desktop gives them | What they still have to bring |
|---|---|---|
| Enterprise IT and operations leaders | A free, open, model-agnostic engine for desktop automation that runs on-premises and reports honestly when it is unsure. | A mandate per workflow, an owner, an approval path for consequential actions, and a decision on which model drives it. |
| RPA and automation centers of excellence | A credible open alternative to licensed bot runners for accessibility-exposed apps, with a far better error model than most scripted bots. | Vision fallback for the ugly 20% of apps; re-platforming effort; governance that RPA tools bundle and this one does not. |
| Agencies and brand teams | A way for agents to operate the design, DAM, production and finance desktop tools that web agents cannot touch. | Brand and authorship controls: an agent that can operate your production tools can also publish the wrong thing. |
| Software vendors | A test: if agent-desktop can drive your app well, you are agent-operable; if it cannot, your accessibility tree is the reason. | An honest look at how much of your UI is unnamed Group and Custom nodes with no actions. |
| Agent builders and AI product teams | Computer use as a composable primitive (CLI, MCP or FFI) with retry-safety semantics you can build policy on. | The policy itself: when to ask, when to stop, how to show the human what happened. |
| Accessibility and QA teams | A second reason, with budget attached, to fix accessibility: screen-reader users and agents now read the same tree. | Nothing new. This is the dividend. |
Concrete use cases we would scope first
- Finance back office: posting approved invoices into a desktop accounting client; the agent reads the approved list from one app and types into another, headless, while the controller keeps working.
- Healthcare and life sciences: moving results between a lab information system and a reporting tool where only desktop clients exist, with every write behind a named approver, because the blast radius is a patient record.
- Advertising operations: trafficking approved creative into desktop ad-serving or production tools, with the agent’s cursor overlay visible on a supervisor’s screen and the trace retained per campaign.
- Internal IT: provisioning steps in admin consoles that have no API, run from an elevated session that matches the target’s integrity level.
- Desktop QA: regression suites for Electron, Qt, WPF and native apps that no longer depend on brittle image matching.
Business track Technical track
Where agent-desktop does what we preach, and where it stops
auxfirst exists to design the relationship between people and agents: what an agent may do, when it must ask, what it remembers, how people take control back, and how a business proves what happened. We score tools against that, not against a feature list. Here is agent-desktop on that scale.
Where it does a great job
01It fails closed, and says so
Narrow allowlists and hard caps, at the lowest possible layer
Strict ref resolution refuses missing, stale and ambiguous matches instead of guessing. A read that could not answer stays Unknown rather than becoming No. This is the de-escalator the Action Heat Ladder calls narrow allowlists and hard caps, implemented where the action happens. When a tool refuses to click one of two identical “Delete” buttons rather than pick one, blast radius is being limited by the tool, not by hope.
02It separates “I pressed” from “it worked”
Burden of proof, made executable
The delivery disposition (not delivered, uncertain, delivered-unverified, delivered-verified) is the most precise statement of burden of proof we have seen shipped in an agent tool. ok: true is explicitly not proof the UI changed; the loop ends with a read. This is the verification-before-trust principle from Agentic User Experience turned into a return value.
03Headless by default is a de-escalator by design
The tool refuses to raise its own authority
No focus steal, no cursor hijack, no clipboard use unless explicitly permitted, and the rule that an agent must never escalate itself to physical input to recover from a failure. In Heat Ladder terms, the tool refuses to raise its own authority dimension. The person stays in the room and keeps working.
04It protects the two things people fear most
Enforced where the action happens, on every surface
Password fields are never echoed, even in post-state, even in traces. Session-critical processes cannot be killed. Both are enforced identically across CLI, FFI and MCP, so no consumer can route around them.
05It keeps a record
The receipt exists, for an engineer
Append-only, per-process trace segments with a versioned, additive-only schema; a merged timeline; optional before-and-after screenshots. For the CIO’s question, what did the agent do on that machine at 02:14?, the receipt exists.
06It shows the human something
A disclosure affordance nobody else has shipped
The labeled cursor overlay, with one cursor per sub-agent, lets a person watching the screen see that an agent, and which agent, is acting and where. In the computer-use space, that is new.
07It teaches the agent its own rules
The operating rules travel with the tool
Skills versioned with the binary, an AGENTS.md snippet, and MCP server instructions that point the model to those skills first.
08It applies burden of proof to itself
Few AI projects would survive their own standard
Probe corpora, findings ledgers, measurement gates that fail on “asserted nothing”, dogfood reports that list what was not exercised.
Where agent-desktop already behaves the way we ask agents to behave
Where it still needs what we preach
All of these are by design. Vercel built a tool, not an agent, and says so. That is the right call for the tool. It is also exactly the gap an organization has to fill before this runs on real work.
01Every action is the same temperature
No notion of an action’s heat
To agent-desktop, click on “Expand” and click on “Send to 40,000 customers” are the same command with the same semantics. The Action Heat Ladder scores five dimensions, reversibility, blast radius, exposure, commitment and authority, and the hottest sets the control posture, from auto-run to human-executes. That scoring has to live in the harness or the policy layer above the tool. The MCP guide’s advice to keep your client’s confirmation on is a blanket gate; it needs to become a graduated one, where cool actions flow and hot ones queue for a named approver.
02There is no approval surface, only a confirmation prompt
A dialog in a coding assistant is not a queue a business owner can run
Agent-first design asks for per-responsibility supervision modes, from human-only through approve-each-action and review-before-act to act-and-notify and autonomous, visible and reversible as trust changes. agent-desktop gives you the primitives to implement each mode (headless versus headed, sessions, waits) but not the mode itself.
03The cursor is a label, not an identity
It says that an agent is acting, not who owns it
The overlay tells a person that an agent is acting and which sub-agent. It does not tell them who owns it, what it is allowed to do, or what it will refuse. That is the job of an agent identity card and an AI agent operating model: the named person with decision rights, the mandate, the stop conditions. Nothing in the tool stops you from attaching those; nothing in it prompts you to.
04A trace is a log, not a receipt
Excellent evidence for an engineer, illegible to everyone else
The JSONL timeline is not legible to a brand manager, a compliance officer or a customer, and it is explicitly unredacted when screenshots are on. Our argument in Can I prove what the agent did? applies verbatim: a control plane that keeps the receipt answers the permission question; it does not answer whether the output was on-brand, safe, or genuinely approved by a human. That needs an authorship layer on top.
05Screen text is an injection vector, and the tool leaves it to you
Correctly: it does not pretend it can solve this
The MCP guide says it plainly: text read from the screen is untrusted input to the model. A desktop agent reads emails, documents, chat windows and web pages inside Electron apps, all of which can contain instructions aimed at the agent. The organization deploying it must supply scoped mandates, allowlisted apps per task, hot actions behind human approval regardless of what the agent “read”, and the rule that nothing observed on screen can widen the mandate. This is the first thing our AI agent readiness assessment checks.
06Supervision throughput is nobody’s problem yet
A tool this efficient makes it easy to outrun the humans
Headless, parallel, labeled cursors make it easy to run many agents on many desktops. Nothing in the stack asks how many actions a human supervisor can actually verify per hour. On our five-step path to an agentic enterprise, the test of a healthy agentic organization is a supervision cost that stays proportionate as usage grows.
07Trust has four stages; the tool addresses one and a half
Functional trust, and part of judgment trust
In Agentic User Experience we describe functional, contextual, judgment and advocacy trust, earned in that order. agent-desktop is a serious contribution to functional trust (it works, reliably, and tells you when it did not) and a partial one to judgment trust (it knows when it cannot act safely). Whether the agent knows when not to act, understands the user’s situation, and is legibly working for the user is entirely a property of what you build above it.
The tool stops here; accountability starts here
agent-desktop is the best-engineered open primitive for desktop computer use we have reviewed, and the first one whose failure semantics are good enough to build real policy on. Put a mandate, an owner, a heat-scored approval path and a human-readable receipt above it, and you have a desktop agent a business can own. Skip that layer and you have a very efficient way to click “Send” twice.
Business track
A 30-day path to a defensible pilot
- Pick one desktop-only workflow with cool actions. Reads, drafts, internal-only writes with an undo. Score it on the heat ladder before anyone installs anything.
- Name the owner. One person with decision rights over the agent’s behavior. Not the vendor. Not “AI”.
- Install on one endpoint, headless only, with a named session and tracing on.
--headedstays off until the mandate explicitly allows physical input for a listed action. - Wire it over MCP to a harness that supports per-tool confirmation, and keep confirmation on for every mutating tool. Then graduate: move listed cool actions to auto-run, keep medium ones at propose-and-approve, keep hot ones human-executed.
- Write the owner’s manual: mandate, allowlisted apps, stop conditions, what the agent must never touch, what to do when a screen contains instructions.
- Measure supervision cost weekly. Actions taken, actions reviewed, time to review, exceptions. If review time grows faster than value, you have outrun your humans; narrow the mandate.
- Audit the target apps. If the accessibility tree is poor, fix the app, or choose vision fallback deliberately, before scaling.
Questions people ask
What is Vercel agent-desktop?
An open-source (Apache-2.0) Rust CLI, C library and MCP server from Vercel Labs that lets AI agents read and operate native desktop apps on macOS, Windows and Linux through the OS accessibility tree. It returns the UI as JSON with a ref per actionable element; it contains no model and runs no loop of its own.
Does agent-desktop use screenshots?
Not for targeting. Actions address elements in the accessibility tree. A separate screenshot command exists for humans, debugging and optional replay artifacts, and an app that publishes no accessibility tree is invisible to the tool.
Is agent-desktop a Vercel cloud service?
No. It is a native binary installed on the machine whose desktop it drives, via npm, Homebrew or a release archive. It needs an interactive graphical session, which Vercel Sandbox, serverless functions and plain containers do not provide out of the box. Its sibling agent-browser does have first-class Vercel Sandbox support.
Which AI models work with agent-desktop?
Any. It is model-agnostic: drive it from Claude Code, Codex, Cursor, a local model, or your own agent runtime via the CLI, the MCP server or the C library. The optional JEV helper skill is the only component that calls a remote model endpoint, and it is not part of the installed package.
How does agent-desktop compare to Claude computer use or OpenAI's computer-using agent?
Those see the screen as pixels through a vision model and click coordinates. agent-desktop reads the accessibility tree and acts on named elements, so it is cheaper per step (the builder reports 273 tokens per look instead of 3,811 in one Apple Maps example), deterministic, and does not need to move the mouse. Vision agents still win on apps with no accessibility tree, games, canvases and remote desktops.
What happens when the UI changes mid-task?
Refs are tied to the snapshot that produced them. A changed or removed element returns STALE_REF; a duplicate returns AMBIGUOUS_TARGET. The agent takes a fresh snapshot and acts on new refs. The tool never guesses.
Can two agents share one computer?
Yes. Headless actions do not need the pointer, so several agents can act in parallel. A machine-wide interaction lease serializes physical (headed) input, and the multi-agent cursor mode gives each sub-agent its own labeled on-screen cursor.
Is it safe to point agent-desktop at a company laptop?
Technically, with care: it never echoes password fields, refuses to kill session-critical processes, and runs headless by default. Organizationally, only with a mandate: the tool has no concept of which actions are consequential, text read from the screen is untrusted input to the model, and the trace is an engineering log rather than a business receipt. That governance layer is what auxfirst designs.
What does agent-desktop cost?
Nothing. It is free under Apache-2.0. You pay for the model and the machines you run it on.
What is the difference between agent-desktop and agent-browser?
agent-browser automates web pages and runs in Vercel Sandbox; agent-desktop automates native desktop apps. For Electron and Chromium apps, agent-desktop can launch the app with a DevTools port and hand the web contents to agent-browser while keeping the native UI itself.
Glossary for the business reader
- Accessibility tree
- The operating system’s structured description of what is on screen (roles, names, states, actions), built for screen readers and now read by agents.
- Ref
- A short handle, tied to one snapshot, for one element an agent may act on.
- Snapshot, skeleton, drill-down
- A read of the tree; a shallow read; a deeper read of one region.
- Headless versus headed
- Acting through the accessibility API without touching the mouse, versus permitted physical input.
- Disposition
- The tool’s statement of whether an input reached the app and whether repeating it is safe.
- Trace and session
- The append-only record of what the tool did, and the container that holds it.
- MCP
- Model Context Protocol, the standard way to expose tools to AI assistants; agent-desktop speaks it natively.
- Action heat
- auxfirst’s score for how consequential an action is, which sets how much human control it needs.
Sources & further reading
Method · Every claim about the tool’s behavior was checked against the 1.1.0 source, the bundled skill and the documentation on 4 November 2026, not against coverage. Every token-saving figure is self-reported by the project’s builder and has not been independently benchmarked; we have labeled it as such wherever it appears, and dropped one percentage range from our draft that we could not trace to a source. Behavior may change in later releases; we will re-verify at 1.2.