agent-desktop de Vercel: tu agente maneja apps de escritorio

Tabla de contenidos

Tu agente ya sabe editar ficheros, lanzar comandos y abrir un navegador. Pero le pides que cambie un ajuste en Preferencias del Sistema, que rellene un formulario en una app de escritorio o que pulse un botón en Finder… y se queda mirando la pared.

Ahí se le acaba el repertorio.

agent-desktop es la respuesta de Vercel Labs a ese hueco. Un CLI (y una librería en C) que lee el árbol de accesibilidad de cualquier app de escritorio en macOS, Windows o Linux, lo devuelve como JSON y le da a cada botón, campo o casilla una referencia sobre la que tu agente puede actuar. Sin capturas de pantalla. Sin adivinar píxeles.

En este artículo vas a encontrar:

  • Qué es agent-desktop y en qué se diferencia del computer use basado en capturas
  • Cómo se instala y qué permisos necesita en cada sistema operativo
  • El bucle observar → actuar → verificar, con comandos reales
  • Las refs, los errores y las reglas de reintento que evitan que el agente pulse dos veces
  • Qué puedes conseguir: formularios, menús, diálogos, apps Electron, varios agentes a la vez

¿Qué es agent-desktop?

agent-desktop es una herramienta de computer use para agentes de IA que opera apps de escritorio a través de la API de accesibilidad del sistema operativo. Lee la interfaz de una app, te la devuelve como un árbol JSON con una ref por cada elemento accionable, y ejecuta acciones (clic, escribir, marcar, desplegar) sobre esas refs.

Lo publica Vercel Labs bajo licencia Apache-2.0 y llegó a su versión 1.0.0 el 27 de octubre de 2026, el día en que se añadió el soporte de Linux y las tres plataformas quedaron integradas en el mismo paquete (fuente: CHANGELOG del repositorio). Está escrito en Rust y se distribuye por npm.

El README lo resume así:

🔑 agent-desktop no tiene ningún modelo dentro. Es una herramienta, no un agente. El bucle de observar, actuar y verificar vive en tu agente.

No es otro “agente autónomo” que compite con Claude Code o Codex. Es un par de manos y un par de ojos que le das a tu agente, el que ya usas. Igual que git o curl: un binario que hace una cosa y devuelve una salida predecible.

¿De dónde sale?

Si te suena el apellido, es porque viene de la misma casa que agent-browser, el CLI de Vercel para que los agentes manejen un navegador con localizadores semánticos en lugar del DOM completo. La documentación de agent-desktop vive, de hecho, dentro de agent-browser.dev/desktop. Y la propia FAQ lo deja claro: agent-desktop no automatiza páginas web; para eso está agent-browser.

Son dos herramientas hermanas con el mismo planteamiento. Una para el navegador, otra para todo lo demás. Y forman parte de una tendencia más amplia: herramientas rehechas para que las use un agente y no una persona, como Lightpanda, el navegador que ahorra tokens a los agentes.

¿Por qué el árbol de accesibilidad y no capturas de pantalla?

Porque el árbol de accesibilidad ya sabe lo que hay en pantalla, y lo sabe con nombres. Las capturas obligan al modelo a interpretar píxeles, adivinar dónde está cada botón y hacer clic en unas coordenadas que dejan de valer en cuanto la ventana se mueve un centímetro.

Todos los sistemas operativos tienen una capa pensada para los lectores de pantalla: VoiceOver en macOS, Narrador en Windows, Orca en Linux. Esa capa describe cada elemento con su rol (button, textfield, checkbox), su nombre (“Guardar”, “Buscar”), su estado (activado, marcado, enfocado) y las acciones que admite.

agent-desktop se sienta encima de esa capa:

Plataforma Requisito API de accesibilidad
macOS macOS 13 o superior, Intel o Apple Silicon AX API
Windows Windows 10 1809 o superior, x64 o ARM64 UI Automation
Linux Ubuntu 24.04 o superior, x86_64 o aarch64, X11 o Wayland AT-SPI

Piensa en la diferencia entre dar indicaciones con un mapa o con una foto borrosa tomada desde un avión. Con la foto (“el edificio gris a la derecha del árbol”) te equivocas en cuanto cambia la luz. Con el mapa (“calle Mayor, número 12”) llegas aunque llueva.

Comparado con los enfoques más habituales de computer use, el reparto queda así:

Enfoque Cómo localiza los elementos Fragilidad ante cambios de layout Qué necesita el modelo
Capturas + visión Coordenadas en una imagen Alta Visión y mucho contexto por imagen
Scripts tipo AppleScript / AutoHotkey Rutas o coordenadas escritas a mano Media-alta Nada: no hay modelo, lo programas tú
agent-desktop Refs sobre el árbol de accesibilidad Baja (se re-identifica el elemento antes de actuar) Leer JSON, que es lo que mejor hace

⚠️ El reverso de la moneda: una app que no publica árbol de accesibilidad es invisible para agent-desktop. La FAQ lo dice sin rodeos. Si la app es un lienzo pintado a mano sin accesibilidad (algunos juegos, algunas apps muy antiguas), aquí no hay nada que rascar.

Y no es un caso raro. Según la encuesta WebAIM Million de 2025, el 94,8% de las páginas de inicio analizadas tenía fallos de accesibilidad detectables (fuente: WebAIM Million 2025). En escritorio no hay un estudio equivalente tan conocido, pero la intuición es la misma: cuanto mejor cuida una app su accesibilidad, mejor la va a manejar tu agente. Es un argumento más, y bastante egoísta, para que tus propias apps sean accesibles.

¿Cómo se instala agent-desktop?

Con npm y un par de comprobaciones. El paquete trae los binarios nativos de cada plataforma, así que no necesitas compilar nada.

npm install -g agent-desktop

# Plataforma, permisos y superficies soportadas
agent-desktop status

# macOS: te guía para conceder el permiso de Accesibilidad
agent-desktop permissions --guide

Lo que cambia según el sistema:

  • macOS: la terminal desde la que lanzas el agente necesita el permiso de Accesibilidad, y el de Grabación de pantalla si vas a hacer capturas. permissions --guide abre Ajustes del Sistema en el sitio exacto, con un panel que te dice qué app arrastrar a la lista.
  • Windows: no hay diálogo de permisos para apps con el mismo nivel de integridad que tu terminal. Si quieres manejar una app que se ejecuta como administrador, la terminal también tiene que estar elevada.
  • Linux: tienes que ejecutarlo dentro de la sesión gráfica del usuario, con at-spi2-core funcionando. status debe decir que accessibility está granted.

Desde la versión 1.0.2, si npm bloquea los scripts de instalación, el lanzador te avisa una vez por stderr con el comando que enlaza el binario nativo (fuente: CHANGELOG). Un detalle pequeño que te ahorra media tarde preguntándote por qué todo va lento.

¿Cómo le enseño a mi agente a usarlo?

El binario lleva dentro sus propias instrucciones, versionadas con él.

# El bucle, las refs y las reglas de verificación y reintento
agent-desktop skills get desktop

# Lo que cambia en el sistema operativo donde se ejecuta
agent-desktop skills get platform

# Flags de un comando concreto
agent-desktop snapshot --help

Así el agente nunca lee una guía de la versión 0.9 mientras ejecuta la 1.1. Tienes tres formas de conectarlo:

  1. Como Agent Skill, desde skills.sh:
npx skills add https://github.com/vercel-labs/agent-desktop --skill agent-desktop
  1. Desde tu AGENTS.md o CLAUDE.md, con dos líneas que el propio README propone:
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.
  1. Como librería en C (libagent_desktop_ffi), si quieres llamarlo dentro de tu propio programa sin lanzar procesos. Lo vemos más abajo.

Si las skills son nuevas para ti, tienes la explicación completa en qué son las Agent Skills y en qué se diferencian de prompts y MCP.

Curso gratis por email

Instalar la skill de agent-desktop es el primer paso: aprende a crear las tuyas

Un minicurso por email, a tu ritmo, para dejar de repetirle lo mismo a tu agente: instalas skills y creas la tuya.

Apúntate al minicurso →

¿Cómo funciona el bucle observar, actuar y verificar?

Funciona en tres tiempos que se repiten: haces un snapshot para ver la interfaz, actúas sobre una ref, y vuelves a hacer snapshot para comprobar que el cambio ocurrió. Ese tercer paso no es opcional. Sin él, el agente cree que ha guardado el documento y tú te enteras el lunes.

El ejemplo mínimo del README, con Finder:

# 1. Observar: solo elementos interactivos, cada uno con su ref
agent-desktop snapshot --app Finder -i

# 2. Actuar sobre una ref de ese snapshot
agent-desktop click @s8f3k2p9:e8

# 3. Volver a observar para verificar
agent-desktop snapshot --app Finder -i

Cada comando imprime un único sobre JSON. Un snapshot recortado tiene esta pinta:

{
  "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"] }
      ]
    }
  }
}

Fíjate en tres cosas:

  • ref_id es la dirección del elemento: @<snapshot_id>:e<N>. Lleva dentro el id del snapshot del que salió.
  • available_actions le dice al agente qué puede hacer con ese elemento antes de intentarlo.
  • complete: true indica que el árbol se leyó entero. Si se agota el tiempo, el comando no falla: devuelve complete: false con lo que alcanzó a ver.

¿Qué pasa con apps enormes como Slack o VS Code?

Que un snapshot completo de una app Electron puede tener cientos de nodos, y meter eso en el contexto del modelo es tirar tokens. Para eso está el patrón esqueleto → taladrar:

# Mapa superficial: profundidad 3 y children_count en las ramas cortadas
agent-desktop snapshot --skeleton --app "Slack" -i --compact
# group "Channels" @s8f3k2p9:e2 (children_count: 42)

# Entra solo en la región que te interesa
agent-desktop snapshot --root @s8f3k2p9:e2 -i --compact

# Actúa
agent-desktop click @s8f3k2p9:e18

# Verifica releyendo la misma región, no la ventana entera
agent-desktop snapshot --root @s8f3k2p9:e2 -i --compact

La skill recomienda este patrón para cualquier app con más de unos 50 elementos interactivos. Y si ya sabes qué buscas, ni siquiera hace falta el mapa:

# Busca por rol y nombre exacto, devuelve solo las coincidencias
agent-desktop find --app "TextEdit" --role button --name "OK" --exact

find con --root o --surface cuesta “unos cientos de bytes en lugar de un volcado completo”, según la referencia de comandos de observación. Es la diferencia entre preguntar en recepción por una persona o recorrer el edificio planta por planta.

💡 Una app Chromium o Electron “en frío” puede tardar entre 10 y 25 segundos en exponer su árbol web. Si el primer snapshot sale raquítico, sube --timeout-ms y vuelve a intentarlo antes de concluir que la app no es accesible.

Cada semana aparecen herramientas nuevas para que los agentes hagan más cosas por ti. Cada domingo seleccionamos 12 recursos sobre IA aplicada al desarrollo para más de 7.200 developers, gratis.

Quiero esa dinamita 🧨

¿Qué son las refs y por qué fallan a propósito?

Una ref es un identificador de un elemento válido para un snapshot concreto. Si la interfaz cambia, la ref deja de servir, y agent-desktop prefiere negarse a actuar antes que pulsar el botón equivocado.

Parece una incomodidad. Es lo que te libra de archivar el correo equivocado.

Imagina una lista de correos con un botón “Archivar” en cada fila. El agente toma un snapshot, decide archivar el tercer correo, y justo en ese momento entra uno nuevo arriba. Con coordenadas, archivarías el correo equivocado. Con agent-desktop, antes de actuar se re-identifica el elemento y, si ya no es el mismo, el comando devuelve un error:

Código Qué significa Qué hace el agente
STALE_REF El elemento ya no existe o no coincide Nuevo snapshot y nueva ref
AMBIGUOUS_TARGET Ha aparecido un elemento idéntico, o la ref no se pudo probar única Actuar sobre un control único en la ventana
SNAPSHOT_NOT_FOUND El snapshot ha caducado Snapshot de nuevo
TIMEOUT (resolution_identity_unknown) Una lectura no respondió; no se envió nada Reintentar

Un detalle de plataforma que conviene saber: en macOS cada ref apunta a la dirección del propio elemento, así que dos botones idénticos tienen cada uno su ref. En Windows y Linux una ref solo resuelve si el elemento era único en la ventana (por rol, id nativo, nombre y descripción). Los gemelos idénticos allí no tienen ref; la única salida es un clic físico por coordenadas.

Y otra regla que cuesta un mensaje de error aprender: una ref sin su snapshot (@e8 a secas) falla con INVALID_ARGS. Siempre la forma completa.

¿Cuándo es seguro reintentar una acción?

Solo cuando disposition.retry es safe. Cada resultado de acción trae un campo disposition con dos datos: delivery (si la acción llegó) y retry (si repetirla es seguro).

El único valor de delivery que garantiza que puedes repetir es not_delivered. Cualquier otro significa que la acción puede haber llegado. Repetir un clic puede enviar un formulario dos veces, y repetir un toggle puede deshacerse a sí mismo.

🛡️ Si una acción no vuelve como retry: safe, el agente no repite a ciegas: lee el estado real con get, is o un snapshot nuevo, y decide desde ahí. Es la misma disciplina que aplicarías a un pago con tarjeta: si no sabes si se cobró, no le das otra vez al botón.

Por esta misma razón la skill recomienda check y uncheck en vez de toggle. Son idempotentes: si la casilla ya está marcada, check la deja como está.

Tu IA puede mentirte

Que el agente diga que lo ha hecho no significa que lo haya hecho

Verás métodos prácticos para revisar y verificar lo que hacen los agentes: skills, pruebas en navegador, casos Gherkin y adversarial review entre modelos.

Entrar a la masterclass →

Métodos en directo + casos Gherkin

¿Qué significa que las acciones sean “headless”?

Que por defecto agent-desktop no mueve el ratón, no cambia el foco y no sintetiza teclas. Usa llamadas semánticas de accesibilidad: le dice al botón “púlsate” en lugar de mover el cursor encima y hacer clic.

En la práctica, puedes seguir trabajando en tu editor mientras el agente maneja otra app por detrás. No te roba el teclado ni te mueve el ratón a mitad de una frase.

Cuando no existe un camino semántico, la acción falla cerrada en lugar de improvisar. Para la entrada física real existe el flag global --headed:

# Arrastrar y soltar siempre es físico
agent-desktop --headed drag --from @s8f3k2p9:e3 --to @s8f3k2p9:e8

La skill es tajante con dos reglas: usa --headed solo cuando el usuario haya permitido entrada física, y nunca cambies a modo headed para recuperarte de un fallo headless. Si el camino limpio no funciona, el agente tiene que pensar otra estrategia, no forzar la puerta.

Qué necesita --headed cambia según el sistema:

Acción macOS Windows Linux
click, set-value, check Headless Headless Headless
type (escribir en un campo) Headless Necesita --headed (en headless, usa set-value) Headless, vía EditableText
double-click, hover, drag Necesita --headed Necesita --headed Necesita --headed, y el puntero solo en X11 (Wayland lo rechaza)

agent-desktop skills get platform le da al agente la tabla exacta del sistema donde se ejecuta, así que no tienes que memorizarla tú.

¿Qué puedes conseguir con agent-desktop?

Bastante más que pulsar botones sueltos. Son 60 nombres de comando (56 operativos) agrupados en observar, actuar sobre refs, teclado y ratón, apps y ventanas, notificaciones, portapapeles, esperas, sesiones y sistema (fuente: README). Estos son los casos de uso que salen de la documentación oficial.

Rellenar formularios de apps nativas

El patrón básico para cambiar un ajuste, con set-value como opción preferida:

agent-desktop snapshot --app "System Settings" -i --compact
agent-desktop set-value @s8f3k2p9:e3 "My MacBook Pro"
agent-desktop click @s8f3k2p9:e8
# Verifica en la UI: delivered_verified solo confirma el valor del campo
agent-desktop snapshot --app "System Settings" -i --compact

Ojo con la letra pequeña: delivered_verified confirma que el campo tiene el valor, no que la app lo haya aceptado. Por eso el último snapshot.

Los menús y diálogos son “superficies” (menu, sheet, alert, popover) que se observan aparte de la ventana. Guardar un documento con otro nombre:

# Un solo ref del menú, sin volcar la barra entera
agent-desktop find --app "TextEdit" --surface menubar --name "Save As…" --exact --first
agent-desktop click @s8f3k2p9:e5

# Espera a la ventana en lugar de un sleep fijo
agent-desktop wait --window "Save" --app "TextEdit"
agent-desktop snapshot --app "TextEdit" --surface sheet -i
agent-desktop set-value @s8f3k2p9:e2 "my-document.txt"
agent-desktop click @s8f3k2p9:e5

Cuando una acción abre un menú o un diálogo, el resultado lo anuncia en data.surfaces, y el agente sabe que su siguiente objetivo es esa superficie.

Esperar a que pasen cosas, sin sleep

wait es de los comandos más útiles y menos vistosos. Espera por tiempo, por elemento (que exista, que esté habilitado, que tenga un valor), por ventana, por texto, por menú o por eventos como window-opened o app-terminated:

agent-desktop click @s8f3k2p9:e5
agent-desktop wait --text "Download complete" --app "App" --timeout 30000

La skill lo dice con una frase que vale para cualquier automatización: un sleep fijo es una condición de carrera.

Encadenar pasos con batch

Para secuencias cortas, batch ejecuta varios comandos en un solo proceso, con --stop-on-error para parar en el primer fallo:

agent-desktop batch '[
  {"command":"click","args":{"ref_id":"@s8f3k2p9:e1"}},
  {"command":"wait","args":{"event":"window-opened","app":"TextEdit","timeout":5000}}
]' --stop-on-error

No es una transacción (si falla el segundo paso, el primero ya ocurrió), pero ahorra procesos y vueltas al modelo.

Manejar apps Electron con dos herramientas

Slack, VS Code, Discord, Obsidian o Notion están construidas sobre Chromium. Su contenido web es denso y lento de recorrer por accesibilidad. Para ellas existe launch --cdp, que arranca la app con un puerto de depuración local:

agent-desktop launch "Obsidian" --cdp
# devuelve http_endpoint y websocket_url en 127.0.0.1
agent-browser connect 9229

agent-desktop nunca habla con ese puerto: se lo pasa a un cliente CDP como agent-browser, Playwright o Puppeteer. Y sigue encargándose de lo nativo: barra de menús, diálogos de ficheros, ventanas, notificaciones y capturas. Una app, dos herramientas, cada una en lo suyo.

⚠️ Mientras ese puerto está abierto, cualquier proceso local de tu usuario puede controlar el contenido web de la app. La documentación recomienda pedir --cdp solo para el paso que lo necesita y cerrar la app al terminar.

Notificaciones, portapapeles, ventanas y la barra de menús

El resto del catálogo cubre lo que haces a diario sin pensarlo:

  • Notificaciones: listar, descartar o pulsar una acción (“Responder”) en el Centro de Notificaciones de macOS, el Centro de Actividades de Windows o la lista de mensajes de GNOME.
  • Portapapeles: leer y escribir texto, imágenes o rutas de ficheros.
  • Ventanas: listar, enfocar, mover, redimensionar, minimizar.
  • macOS en la versión 1.1.0: acceso al Dock y a los iconos de la barra de menús con --surface dock y --surface menu-bar-extras, y a apps sin ventana como el Centro de Control (fuente: CHANGELOG 1.1.0, del 2 de noviembre de 2026).

Varios agentes en el mismo escritorio, cada uno con su cursor

Aquí está la parte más vistosa. Una sesión es un contenedor en disco con sus snapshots y, si lo activas, una traza de todo lo que pasó:

export AGENT_DESKTOP_SESSION="$(agent-desktop session start --name "invoice-bot" | jq -r '.data.session_id')"

# ...el agente trabaja...

# Visor HTML autocontenido con la línea temporal de eventos
agent-desktop trace export --out trace.html
agent-desktop session end "$AGENT_DESKTOP_SESSION"

Con session start --cursor --multi-agent (macOS y Windows), cada subagente pasa su propio --agent-id y aparece en pantalla con su cursor dibujado, su etiqueta y su color. Los cursores viajan a la vez; las acciones se turnan para no pisarse. Es un overlay de presentación: no mueve tu ratón real, solo te enseña quién está haciendo qué.

Ideal para grabar una demo, y también para depurar: ver a dos agentes trabajando en paralelo te dice en dos segundos lo que una traza JSON tarda diez minutos en contar.

Usarlo desde tu propio programa con la librería en C

Cada release incluye libagent_desktop_ffi, así que cualquier lenguaje con FFI puede llamar a agent-desktop en proceso. El ejemplo del README, en Python con ctypes:

import ctypes

# Carga la librería nativa (en Linux, .so; en Windows, .dll)
lib = ctypes.CDLL("./lib/libagent_desktop_ffi.dylib")
lib.ad_adapter_create.restype = ctypes.c_void_p
lib.ad_adapter_destroy.argtypes = [ctypes.c_void_p]

# 7 es la versión mayor de la ABI en la release 1.1.0
assert lib.ad_init(7) == 0
adapter = lib.ad_adapter_create()
lib.ad_adapter_destroy(adapter)

Esto abre la puerta a meter computer use de escritorio en tu propio harness, sin depender de que el agente lance un CLI.

Darle el escritorio a un agente es de esos cambios que conviene entender antes de adoptarlos. En la newsletter de cada domingo compartimos lo que vamos probando y lo que cuentan los +7.200 developers que participan.

Quiero esa dinamita 🧨

¿Y si no quiero que el árbol entre en el contexto del agente?

Para eso el repositorio trae una skill extra, jev-desktop. En lugar de que tu agente lea el árbol JSON, le das un objetivo en lenguaje natural y un script se encarga del bucle:

node scripts/jev/run.mjs --app Finder "open the Applications folder"

Cada turno lee la pantalla, pide a un modelo de decisión una operación (CLICK, TYPE_TEXT, CHECK, SCROLL, DRILL, DONE, BLOCKED…) y su objetivo, la ejecuta y vuelve a leer. Hay una variante, act.mjs, para resolver un solo paso y quedarte tú con el plan.

Dos cosas que debes saber antes de usarla:

  1. Necesita un clon del repositorio (los scripts no van en el paquete de npm) y una TYPESAFE_API_KEY.
  2. Manda una descripción de tu pantalla a un servicio externo en cada turno (api.typesafe.ai por defecto): roles, nombres, hasta 60 caracteres del valor de cada campo y el título de la ventana. Los campos de contraseña nunca salen, y --no-values retiene el resto de valores, pero la propia skill avisa de que eso basta para enviar el contenido de un documento privado.

El CLI nativo, en cambio, no necesita ningún servicio remoto.

¿Qué riesgos tiene darle el escritorio a un agente?

Los mismos que darle tus llaves de casa a alguien muy rápido y muy obediente. agent-desktop está bien pensado en seguridad, pero no puede pensar por ti.

La documentación insiste en un punto que se olvida enseguida: snapshots, lecturas del portapapeles, notificaciones, capturas y trazas contienen el contenido privado de tu escritorio. Las notificaciones se devuelven literales, sin redactar. Las capturas que guardan las sesiones con --screenshots no están censuradas. Las trazas sí redactan campos como text, value o title, pero pueden conservar artefactos.

Mi lista de mínimos antes de dejarlo suelto:

  • 🛡️ Nada de logs públicos. Ni trazas, ni capturas, ni transcripciones del agente en un issue de GitHub.
  • 🛡️ Headless por defecto. Activa --headed solo cuando haga falta y lo hayas decidido tú.
  • 🛡️ Permisos acotados. En macOS, el permiso de Accesibilidad va a la terminal; piensa qué más se ejecuta desde ella.
  • 🛡️ Respeta disposition. Un agente que reintenta lo que no es safe acabará enviando algo dos veces.

Si te interesa por qué los agentes se van a acercar cada vez más a tu máquina, el análisis de Open Interpreter y su arnés local es un buen complemento: allí ya aparecía la idea de manejar apps nativas como parte del QA.

¿Cuándo usar agent-desktop y cuándo otra herramienta?

Usa agent-desktop cuando la tarea vive en una app de escritorio y esa app expone un árbol de accesibilidad decente. Para todo lo que pasa dentro de una página web, agent-browser o Playwright siguen siendo mejores. Para lo que puedas hacer con una API o un CLI, hazlo con la API o el CLI: siempre será más rápido y más fiable que cualquier interfaz gráfica.

Situación Mejor opción
Página web o app web en el navegador agent-browser o Playwright
App con API o CLI propios La API o el CLI, sin interfaz
App nativa accesible (Ajustes, Finder, Notas, apps de oficina) agent-desktop
App Electron (Slack, VS Code, Obsidian) agent-desktop para lo nativo + --cdp y un cliente CDP para el contenido
App sin árbol de accesibilidad Capturas y visión, o nada

Y una pregunta que te conviene hacerte antes de automatizar nada: ¿esto lo haces más de tres veces por semana? Si no, quizá el agente tarde más en aprenderlo que tú en hacerlo.

TL;DR

  • 🖥️ agent-desktop es un CLI y una librería en C de Vercel Labs que da computer use a tu agente leyendo el árbol de accesibilidad de macOS, Windows y Linux, sin capturas ni píxeles.
  • 🔁 El bucle es siempre snapshot → acción sobre una ref → snapshot para verificar; en apps grandes, esqueleto y --root para no inundar el contexto.
  • 🛡️ Las refs fallan a propósito (STALE_REF, AMBIGUOUS_TARGET) antes que pulsar el elemento equivocado, y solo se reintenta lo marcado como retry: safe.
  • 🤫 Las acciones son headless por defecto: no te roban el ratón ni el foco; --headed solo cuando tú lo permitas.
  • 🚀 Sirve para formularios, menús, diálogos, notificaciones, portapapeles, apps Electron con CDP y hasta varios agentes con su propio cursor en pantalla.

Preguntas frecuentes

¿Qué es agent-desktop de Vercel?

Es un CLI y una librería en C, de código abierto (Apache-2.0), que permite a un agente de IA ver y manejar apps de escritorio en macOS, Windows y Linux. Lee el árbol de accesibilidad del sistema operativo y lo devuelve como JSON, con una ref por cada elemento accionable.

¿agent-desktop usa capturas de pantalla?

No para actuar. Los comandos que reciben una ref localizan el elemento en el árbol de accesibilidad, no por coincidencia de píxeles. Existe un comando screenshot aparte, útil como evidencia, pero la documentación aclara que una captura no prueba que una acción haya funcionado.

¿agent-desktop incluye un modelo de IA?

No. Es una herramienta, no un agente: el bucle de observar, actuar y verificar lo ejecuta tu agente (Claude Code, Codex o el que uses). Solo la skill opcional jev-desktop consulta un modelo externo de decisión.

¿Cómo se instala agent-desktop?

Con npm install -g agent-desktop. Después, agent-desktop status muestra plataforma y permisos, y en macOS agent-desktop permissions --guide te lleva a conceder el permiso de Accesibilidad a tu terminal.

¿Funciona agent-desktop en Windows y Linux?

Sí. En Windows 10 1809 o superior usa UI Automation; en Linux (Ubuntu 24.04 o superior, X11 o Wayland) usa AT-SPI. Algunas acciones cambian según la plataforma, y agent-desktop skills get platform explica las diferencias del sistema donde se ejecuta.

¿Cómo conecto agent-desktop con Claude Code?

Instala la skill con npx skills add https://github.com/vercel-labs/agent-desktop --skill agent-desktop, o añade a tu CLAUDE.md o AGENTS.md una instrucción para ejecutar agent-desktop skills get desktop y agent-desktop skills get platform antes del primer uso.

¿Qué es una ref en agent-desktop?

Es el identificador de un elemento dentro de un snapshot, con la forma @s8f3k2p9:e8. Solo vale para ese snapshot: si la interfaz cambia, la acción devuelve STALE_REF o AMBIGUOUS_TARGET y el agente tiene que tomar un snapshot nuevo.

¿Qué diferencia hay entre agent-desktop y agent-browser?

agent-browser automatiza páginas web en un navegador; agent-desktop maneja apps de escritorio y no automatiza páginas web. Se combinan en apps Electron: agent-desktop launch --cdp abre un puerto de depuración y agent-browser se conecta a él para el contenido web.

¿agent-desktop mueve el ratón mientras trabajo?

No por defecto. Las acciones son headless: usan llamadas de accesibilidad sin mover el cursor ni cambiar el foco. Solo con el flag --headed hay entrada física, necesaria para cosas como arrastrar y soltar o el doble clic.

¿Es seguro usar agent-desktop con datos privados?

El CLI nativo no envía nada a servicios remotos, pero snapshots, notificaciones, portapapeles, capturas y trazas contienen lo que hay en tu escritorio. Mantén esos ficheros y las transcripciones del agente fuera de logs públicos, y ten en cuenta que jev-desktop sí manda descripciones de pantalla al proveedor que configures.

Fuentes

🧨 Última oprtunidad para recibir la dinamita que mereces sobre programación con IA el próximo domingo: Suscríbete gratis a Web Reactiva en https://webreactiva.com/newsletter

Imagen de Daniel Primo
Claude, IA de Anthropic

Escrito con la ayuda de la IA generativa de Claude, fuentes fidedignas y con un human in the loop:
Dani Primo.

CEO en pantuflas de Web Reactiva. Programador y formador en tecnologías que cambian el mundo y a las personas. Activo en linkedin, en substack y canal @webreactiva en telegram

12 recursos para developers cada domingo en tu bandeja de entrada

Además de una skill práctica bien explicada, trucos para mejorar tu futuro profesional y una pizquita de humor útil para el resto de la semana. Gratis.