Dale a Claude, Cursor, Copilot o VS Code el poder de abrir Chrome, depurar la app y auditar su rendimiento
Chrome DevTools MCP es el servidor Model Context Protocol (MCP) oficial del equipo de Chrome DevTools: convierte a tu agente de código en un desarrollador con manos y ojos dentro del navegador. Automatiza acciones (clic, formularios, navegación), depura de verdad (mensajes de consola con stack traces source-mapped, peticiones de red) y mide rendimiento (trazas con Core Web Vitals y datos reales de CrUX). 50.000+ estrellas, Apache-2.0. En este curso lo instalas en tu agente favorito, automatizas tu primera tarea web y auditas una página de principio a fin.
Un agente de código (Claude Code, Cursor, Copilot…) es excelente leyendo y editando tu código fuente, pero la aplicación que construyes vive en otro sitio: en el navegador. Para arreglar un bug de layout, entender por qué una petición falla o comprobar si la página carga rápido, el agente necesita ver la app corriendo de verdad.
Sin esta pieza, el flujo típico es frustrante: el agente adivina el comportamiento de la página, tú le pegas capturas de pantalla, y el ciclo de feedback es lento y manual. Con Chrome DevTools MCP el agente abre Chrome él mismo, inspecciona el DOM, lee la consola, mira la pestaña Network y ejecuta JavaScript real en la página.
Casos donde marca la diferencia:
El propio Chrome DevTools lleva años exponiendo un protocolo de depuración remota (CDP). Chrome DevTools MCP no inventa nada nuevo: empaqueta ese superpoder en herramientas que un LLM sabe llamar con seguridad y fiabilidad.
Chrome DevTools for agents (chrome-devtools-mcp) es un proyecto oficial del equipo de Chrome DevTools que deja que tu agente de código controle e inspeccione un Chrome vivo. Actúa como un servidor MCP: el agente (cliente MCP) habla con él en JSON-RPC y él habla con Chrome vía DevTools Protocol, usando Puppeteer para automatizar y esperando automáticamente a que las acciones terminen.
Tres capacidades clave (del README oficial):
| Capacidad | Qué hace |
|---|---|
| Performance insights | Graba trazas de DevTools y extrae insights accionables (Core Web Vitals: LCP, INP, CLS). |
| Advanced debugging | Analiza peticiones de red, hace screenshots y lee mensajes de consola con stack traces source-mapped. |
| Reliable automation | Automatiza acciones en Chrome con Puppeteer y espera automáticamente a los resultados. |
En total expone más de 60 herramientas MCP organizadas por categorías:
| Categoría | Ejemplos de herramientas |
|---|---|
| Navegación | new_page, navigate_page, list_pages, select_page, close_page, wait_for |
| Input | click, fill, fill_form, press_key, type_text, hover, upload_file |
| Debugging | take_snapshot, take_screenshot, list_console_messages, evaluate_script |
| Network | list_network_requests, get_network_request |
| Performance | performance_start_trace, performance_stop_trace, performance_analyze_insight, lighthouse_audit |
| Emulación | emulate, resize_page |
| Extras (flags) | Memoria (heap snapshots), extensiones, PWA, WebMCP, screencast de vídeo |
El servidor expone al cliente MCP el contenido del navegador: puede inspeccionar, depurar y modificar cualquier dato de la página. No compartas con el agente información sensible o personal que no quieras que vea.
Requisitos mínimos: Node.js LTS, npm y Google Chrome (stable o Chrome for Testing). Solo se soportan oficialmente Chrome y Chrome for Testing; otros navegadores Chromium pueden funcionar pero sin garantías.
La configuración universal es un bloque JSON en el fichero de MCP servers de tu cliente:
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["-y", "chrome-devtools-mcp@latest"]
}
}
}
En el chat de tu agente, escribe:
Check the performance of https://developers.chrome.com
El cliente debería abrir Chrome y grabar una traza de rendimiento. El navegador arranca bajo demanda: conectar el servidor MCP no lo abre; se abre en cuanto se llama a una herramienta que lo necesita.
Google recoge estadísticas de uso por defecto y las trazas pueden consultar CrUX. Opt-out si lo prefieres:
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["-y", "chrome-devtools-mcp@latest", "--no-usage-statistics", "--no-performance-crux"]
}
}
}
La recogida también se desactiva si existe la variable CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS o CI. Y CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS desactiva el aviso periódico de versiones nuevas.
Usar chrome-devtools-mcp@latest garantiza que tu cliente siempre use la última versión. Si solo necesitas tareas básicas de navegación, añade --slim --headless y tendrás una superficie mínima de 3 herramientas (navegar, evaluar, screenshot).
El servidor no arranca el navegador al conectarse: es normal. Si tu primer prompt no hace nada, llama primero a una herramienta que requiera página (p.ej. new_page) o pide explícitamente "abre una página nueva".
Cada cliente MCP tiene su vía de instalación. La guía oficial cubre Antigravity, Bob, Claude Code, Cline, Cursor, Devin CLI, Gemini CLI, Copilot/VS Code y más. Los ejemplos más usados:
claude mcp add chrome-devtools --scope user npx chrome-devtools-mcp@latest
Ve a Cursor Settings → MCP → New MCP Server y pega la configuración base del paso 3 (command npx, args ["-y", "chrome-devtools-mcp@latest"]).
Puedes usar el botón "Install Server" de la documentación (enlace vscode://) o el CLI:
code --add-mcp '{"name":"io.github.ChromeDevTools/chrome-devtools-mcp","command":"npx","args":["-y","chrome-devtools-mcp"],"env":{}}'
Instala el servidor custom y, como Antigravity ya trae navegador integrado, conéctalo a él en vez de lanzar otro:
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["chrome-devtools-mcp@latest", "--browserUrl", "http://127.0.0.1:9222"]
}
}
}
En ese modo el servidor no lanza Chrome: debes arrancar el navegador de Antigravity primero (icono de Chrome arriba a la derecha).
En Claude Code existe también la instalación como plugin (MCP + Skills), que además de las herramientas adjunta skills de experto que enseñan al agente a usarlas bien. Si ya lo tenías instalado por CLI, desinstálalo antes para evitar conflictos.
El paquete incluye una CLI experimental (chrome-devtools) ideal para depurar o para que un agente genere scripts de automatización. Se instala global y actúa de cliente contra un daemon en segundo plano:
npm i chrome-devtools-mcp@latest -g
chrome-devtools status # comprueba si el daemon está vivo
El daemon se arranca solo en la primera llamada y conserva el estado del navegador (pestañas, cookies) entre comandos:
# Abre una página nueva
chrome-devtools new_page "https://example.com"
# Navega la página 1 a otra URL
chrome-devtools navigate_page 1 --url "https://web.dev"
# Screenshot de la página 1 a un fichero
chrome-devtools take_screenshot 1 --filePath screenshot.png
# Para cuando termines
chrome-devtools stop
Dentro del agente, las herramientas de navegación equivalentes son new_page, navigate_page (con soporte para back/forward/reload y handleBeforeUnload), list_pages, select_page, close_page y wait_for. Cada página tiene un pageId: las herramientas reciben siempre el id para saber sobre qué pestaña actuar.
Con --slim --headless el servidor expone solo tres herramientas — navigate, evaluate y screenshot — perfectas cuando el agente solo necesita "mirar" una web sin tocar nada:
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["-y", "chrome-devtools-mcp@latest", "--slim", "--headless"]
}
}
}
El CLI acepta las mismas tools del servidor sin argumentos extra: chrome-devtools <tool> [argumentos posicionales] [--flags]. Los argumentos obligatorios van posicionales (pageId el primero) y los opcionales como flags (--filePath, --fullPage).
Aquí es donde el agente deja de ser un lector y empieza a usar la web. El patrón central: el agente toma un snapshot de accesibilidad (take_snapshot), que devuelve los elementos de la página con un identificador único (uid), y luego actúa sobre esos uids.
# 1. Toma el snapshot: cada elemento tiene un uid (p.ej. "input-uid-456")
take_snapshot(pageId=1)
# 2. Rellena un campo del formulario
fill(pageId=1, uid="input-uid-456", value="mi-busqueda")
# 3. Haz clic en el botón de enviar
click(pageId=1, uid="button-uid-789")
Para formularios con varios campos, la documentación recomienda siempre fill_form antes que varias llamadas a fill/click: es más rápido, más fiable y reduce el número de turnos del agente.
| Herramienta | Para qué |
|---|---|
fill | Escribir en input, textarea o elegir opción de un <select> |
fill_form | Rellenar varios campos a la vez (inputs, selects, checkboxes, radios) |
click / dblClick | Clic simple o doble sobre un elemento por uid |
hover | Pasar el ratón por encima (menús desplegables, tooltips) |
press_key | Atajos de teclado: "Enter", "Control+A", "Control+Shift+R" |
type_text | Escribir por teclado en el input enfocado, con submitKey opcional |
drag / upload_file | Arrastrar elementos y subir ficheros locales |
handle_dialog | Aceptar o rechazar diálogos beforeunload, alerts, etc. |
En el CLI se ve igual de directo:
chrome-devtools click 1 "element-uid-123"
chrome-devtools fill 1 "input-uid-456" "search query"
Los uids del snapshot cambian con cada navegación: usa siempre el snapshot más reciente. Si el agente intenta hacer clic con un uid viejo, la herramienta fallará o hará clic en el elemento equivocado.
Para flujos largos, pide al agente que combine wait_for(texto) después de cada acción: espera a que aparezca un texto concreto en la página antes de continuar. Así la automatización no se adelanta a la carga de la SPA.
El debugging clásico de DevTools — pestañas Console y Network — está expuesto como herramientas que el agente puede consultar cuando algo falla.
# Lista los mensajes de consola desde la última navegación
list_console_messages(pageId=1, includeStackTraces=true)
# Detalle de un mensaje concreto (con stack trace source-mapped)
get_console_message(pageId=1, msgid=42)
La clave: los stack traces llegan source-mapped, así que el agente ve el error apuntando a tu código fuente (TSX, TS, etc.), no al bundle minificado. Con includePreservedMessages=true ves también los mensajes de las últimas 3 navegaciones.
# Últimas peticiones desde la última navegación
list_network_requests(pageId=1)
# Detalle de una petición: headers, cookies, respuesta
get_network_request(pageId=1, reqid=7)
get_network_request permite inspeccionar headers de la petición (incluida Cookie) y de la respuesta (incluida Set-Cookie y directivas) — justo lo que necesitas para depurar autenticación o CORS.
# Ejecuta una función dentro de la página; el resultado vuelve como JSON
evaluate_script(pageId=1, function="() => document.title")
El valor devuelto debe ser JSON-serializable. Es la herramienta comodín para leer estado de la app, comprobar variables globales o forzar condiciones.
Pide al agente: "Abre https://tuapp.com, navega al dashboard y dime por qué falla la carga de datos".
Navegar, listar peticiones de red, filtrar las que devuelven 404/500 y leer get_network_request para mostrarte la URL exacta y el error.
Tras corregir el código, pide "recarga y comprueba que la petición ya responde 200" — el agente navega, espera y confirma.
Prefiere take_snapshot (árbol de accesibilidad en texto) sobre take_screenshot (imagen) para entender el estado de la página: consume menos tokens y da uids accionables. Las capturas quedan para cuando necesitas ver el diseño real.
El análisis de rendimiento es la joya del proyecto: usa DevTools para grabar trazas y extraer insights accionables, no solo métricas crudas.
# Empieza a grabar una traza en la página
performance_start_trace(pageId=1)
# ... el agente interactúa, recarga, etc. ...
# Para la traza y recibe los insights
performance_stop_trace(pageId=1)
# Pide detalle de un insight concreto
performance_analyze_insight(insightName="LCPBreakdown")
Los insights cubren los Core Web Vitals (LCP, INP, CLS) y desgloses como DocumentLatency o LCPBreakdown. Además, las URLs de las trazas se envían a la API de CrUX para cruzar los datos de laboratorio con datos reales de usuarios (desactivable con --no-performance-crux).
Para accesibilidad, SEO, buenas prácticas y "agentic browsing", la herramienta es lighthouse_audit. Ojo: Lighthouse excluye performance — para eso están las trazas:
# Auditoría Lighthouse en modo navegación (o snapshot)
lighthouse_audit(pageId=1, device="desktop")
Una sesión típica de auditoría con el agente:
lighthouse_audit sobre la misma URL.Los screenshots que devuelve el servidor se envían al modelo como imágenes y consumen tokens en proporción a sus dimensiones. Para sesiones largas configura --screenshotFormat=jpeg (3-5× más pequeño que PNG) y --screenshotMaxWidth/--screenshotMaxHeight para que el servidor reduzca las capturas antes de enviarlas.
Si el agente dice "he auditado el rendimiento" pero solo te da una nota Lighthouse, le falta la traza: pídele explícitamente performance_start_trace + performance_stop_trace durante una recarga. La nota de Lighthouse no incluye performance.
Cuando dominas lo básico, el servidor tiene un segundo nivel de potencia.
# Emula modo oscuro, throttling de CPU o un dispositivo concreto
emulate(pageId=1, colorScheme="dark", cpuThrottlingRate=6)
# Cambia el tamaño de la ventana para probar responsive
resize_page(pageId=1, width=390, height=844)
También puedes fijar el viewport inicial de arranque con --viewport=1280x720 (en headless el máximo es 3840x2160).
En vez de lanzar una instancia nueva, puedes atarte al Chrome del usuario. Dos vías:
--autoConnect: se conecta automáticamente al Chrome local (Chrome 144+) que tenga activada la depuración remota en chrome://inspect/#remote-debugging. El navegador muestra un diálogo pidiendo permiso.--browserUrl/--wsEndpoint: conexión manual a una instancia con puerto de depuración (típico http://127.0.0.1:9222). El endpoint WebSocket se consulta en http://127.0.0.1:9222/json/version (campo webSocketDebuggerUrl).{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["chrome-devtools-mcp@latest", "--browserUrl", "http://127.0.0.1:9222"]
}
}
}
Con --wsHeaders puedes añadir headers de autenticación al WebSocket (p.ej. {"Authorization":"Bearer token"}), útil en entornos controlados.
| Flag | Qué hace |
|---|---|
--isolated | Crea un perfil temporal de Chrome que se limpia al cerrar (ideal para CI y pruebas repetibles) |
--userDataDir | Perfil persistente en una ruta concreta (sesiones con login guardadas) |
--channel | Elige canal: canary, dev, beta o stable |
--pageIdRouting | Ruteo por pageId (activado por defecto): imprescindible con varios agentes concurrentes |
--executablePath | Ruta a un ejecutable de Chrome concreto |
--acceptInsecureCerts | Ignora certificados autofirmados/caducados (¡con cuidado!) |
--proxyServer | Proxy para el tráfico del navegador |
Funcionalidades adicionales tras flags: --experimentalVision habilita click_at(x,y) por coordenadas (para modelos computer-use), --memoryDebugging expone análisis de heap snapshots, --categoryExtensions gestiona extensiones de Chrome, --categoryPwa instala/lanza PWAs, --experimentalScreencast graba vídeo de la página (requiere ffmpeg), y hay guía oficial para depurar Chrome en Android.
Extensiones y PWA solo funcionan con conexión por pipe: autoConnect, browserUrl y wsEndpoint no son compatibles con esas categorías (hasta Chrome 149+). Si activas --categoryExtensions y no ves las tools, revisa el método de conexión.
El servidor está pensado para agentes locales de confianza, pero ofrece controles para reducir la superficie:
| Control | Qué hace |
|---|---|
--redactNetworkHeaders | Oculta headers sensibles antes de devolverlos al cliente |
--blockedUrlPattern / --allowedUrlPattern | Restringe el acceso de red del navegador por patrones URL (estándar URLPattern) |
--javascriptEvaluation=false | Desactiva la ejecución de JavaScript: elimina evaluate_script, el initScript y las URLs javascript:/data: |
--workspace / --filesystemRoot | Limita a qué directorios pueden escribir las tools de ficheros (por defecto: solo el temp del sistema) |
--slim | Reduce todo el servidor a 3 herramientas |
evaluate_script.Error [ERR_MODULE_NOT_FOUND] — caché de npm corrupta o versión antigua: reinstala o usa @latest.Target closed — la página se cerró o navegó a una URL bloqueada; revisa --blockedUrlPattern y vuelve a tomar snapshot.chrome-devtools stop y reintenta; para logs verbosos: DEBUG=* chrome-devtools list_pages.Regla de oro de privacidad: el agente ve todo lo que hay en el navegador conectado. Para tareas con datos personales usa --isolated con un perfil limpio y no conectes el servidor a tu perfil principal de Chrome con sesiones abiertas.
No. Cualquier cliente MCP puede conectarse: agentes de terminal (Claude Code, Gemini CLI), editores (Cursor, VS Code Copilot), asistentes (Antigravity) y tus propias aplicaciones que hablen MCP. Además incluye una CLI independiente (chrome-devtools) para usarlo sin MCP.
No. Es un proyecto open-source (Apache-2.0) que corre en tu máquina: solo necesitas Node.js LTS, npm y Chrome. El tráfico al LLM es el de tu agente habitual. Ojo: por defecto envía estadísticas de uso a Google y las trazas consultan CrUX; puedes desactivarlo con --no-usage-statistics y --no-performance-crux.
Oficialmente Google Chrome y Chrome for Testing (última versión de Extended Stable). Otros navegadores basados en Chromium pueden funcionar, pero el equipo no lo garantiza: úsalos bajo tu responsabilidad.
Sí, con un perfil persistente (--userDataDir) el navegador guarda las sesiones entre ejecuciones; o conéctate a tu Chrome ya abierto (--autoConnect o --browserUrl) y el agente trabajará con tus sesiones activas — recuerda que verá todo su contenido.