Skip to content

Automatiza el navegador desde la terminal con Chrome DevTools MCP CLI

Published:

Llevar Chrome DevTools al terminal no es nuevo. Puppeteer, Playwright, chrome --remote-debugging-port… herramientas que funcionan bien pero que requieren escribir código, gestionar dependencias y mantener scripts. La CLI de chrome-devtools-mcp toma otro camino: un daemon persistente y un único binario que expone algunas de las herramientas de DevTools como subcomandos de shell.

Es experimental, pero ya cubre suficientes casos de uso para que valga la pena tenerla instalada.

Instalación

npm i chrome-devtools-mcp@latest -g
chrome-devtools status

El daemon arranca automáticamente la primera vez que ejecutas cualquier comando. A partir de ahí, el mismo proceso de Chrome se reutiliza en todas las llamadas siguientes: las páginas abiertas, las cookies y el estado de la sesión persisten entre comandos.

# Parar el daemon cuando hayas terminado
chrome-devtools stop

Por defecto opera en modo headless y con contexto aislado. Si necesitamos un perfil de usuario real, lo podemos hacer así:

chrome-devtools start --no-headless --userDataDir ~/Library/Application\ Support/Google/Chrome

Los comandos de navegación son el punto de entrada para cualquier flujo automatizado.

# Abrir una nueva pestaña
chrome-devtools new_page "https://joanleon.dev"

# Navegar en la pestaña activa
chrome-devtools navigate_page --type url --url "https://web.dev"

# Recargar ignorando la caché
chrome-devtools navigate_page --type reload --ignoreCache

# Historial: atrás y adelante
chrome-devtools navigate_page --type back
chrome-devtools navigate_page --type forward

# Ver todas las pestañas abiertas
chrome-devtools list_pages

# Cambiar de pestaña activa
chrome-devtools select_page 2

# Cerrar una pestaña
chrome-devtools close_page 2

navigate_page admite un initScript: JavaScript que se inyecta en cada documento nuevo antes de que cargue cualquier otro script. Útil para interceptar APIs o modificar el entorno antes de que llegue el código de la página.

chrome-devtools navigate_page --type url --url "https://joanleon.dev" \
  --initScript "window.__PERF_MARK = Date.now()"

Emulación

La emulación permite cambiar las condiciones de la página sin tocar el navegador manualmente.

# Emular red lenta
chrome-devtools emulate --networkConditions "Slow 3G"

# Throttling de CPU (factor 4x)
chrome-devtools emulate --cpuThrottlingRate 4

# Emular dispositivo móvil (viewport + touch)
chrome-devtools emulate --viewport "390x844x3,mobile,touch"

# Dark mode
chrome-devtools emulate --colorScheme dark

# Geolocalización (Madrid)
chrome-devtools emulate --geolocation "40.4168x-3.7038"

# User agent personalizado
chrome-devtools emulate --userAgent "Mozilla/5.0 (iPhone; ...)"

# Resetear todas las emulaciones
chrome-devtools emulate --networkConditions ""

# Cambiar tamaño de la ventana
chrome-devtools resize_page --width 1440 --height 900

Combinar throttling de red + CPU antes de ejecutar una auditoría reproduce con más fidelidad la experiencia en dispositivos de gama media, que es donde suelen aparecer los problemas de rendimiento reales.


Interacción y automatización de input

Para interactuar con la página, primero necesitas los UIDs de los elementos. take_snapshot devuelve el árbol de accesibilidad con un identificador único para cada elemento.

# Obtener el árbol de accesibilidad con UIDs
chrome-devtools take_snapshot

# Hacer clic en un elemento
chrome-devtools click "element-uid-123"

# Doble clic
chrome-devtools click "element-uid-123" --dblClick

# Hover (útil para menús y tooltips)
chrome-devtools hover "element-uid-456"

# Rellenar un input
chrome-devtools fill "input-uid-789" "texto de búsqueda"

# Pulsar Enter después de rellenar
chrome-devtools press_key "Enter"

# Shortcut de teclado
chrome-devtools press_key "Control+Shift+R"

# Escribir texto en un input ya enfocado
chrome-devtools type_text "query" --submitKey "Enter"

# Subir un fichero
chrome-devtools upload_file --filePath "/ruta/archivo.png" --uid "input-file-uid"

# Aceptar o descartar diálogos del navegador
chrome-devtools handle_dialog "accept"

take_snapshot es preferible a take_screenshot cuando el objetivo es interactuar: el árbol de accesibilidad es más ligero y da los UIDs directamente. take_screenshot tiene sentido para capturas visuales o para comparar estados.


Depuración

Consola

list_console_messages expone los mensajes del panel Console sin abrir el navegador. Útil para detectar errores de JavaScript, warnings de terceros o logs de rendimiento después de una navegación automatizada.

# Listar todos los mensajes de consola
chrome-devtools list_console_messages

# Solo errores
chrome-devtools list_console_messages --types '["error"]'

# Obtener un mensaje concreto por ID
chrome-devtools get_console_message 42

# Incluir mensajes de las últimas 3 navegaciones
chrome-devtools list_console_messages --includePreservedMessages

Ejecutar JavaScript

evaluate_script ejecuta una función en el contexto de la página y devuelve el resultado como JSON:

# Título de la página
chrome-devtools evaluate_script "() => document.title"

# Número de imágenes sin atributo alt
chrome-devtools evaluate_script "() => document.querySelectorAll('img:not([alt])').length"

# Tamaño del DOM
chrome-devtools evaluate_script "() => document.querySelectorAll('*').length"

Los scripts inline funcionan para casos simples, pero no escalan. La CLI no incluye un flag --file nativo por el momento (issue #1775), pero la sustitución de comandos de shell resuelve exactamente eso:

# Ejecutar un script desde un archivo local
chrome-devtools evaluate_script "() => { $(cat scripts/medir-lcp.js) }"

# Ejecutar cualquier script del repositorio WebPerf Snippets
chrome-devtools evaluate_script "() => { $(cat ~/.claude/skills/webperf-core-web-vitals/scripts/LCP.js) }"

evaluate_script espera una función, no un bloque de código suelto. El wrapper () => { ... } es necesario cuando el script contiene múltiples sentencias.

Este es el comando que conecta directamente con los WebPerf Snippets. Cualquier snippet del repositorio puede leerse con $(cat) y pasarse a evaluate_script sin copiar su contenido ni abrir DevTools.

El flujo que describe el post WebPerf Snippets y Agent SKILLs usa exactamente esta mecánica: el agente lee el script del SKILL (por ejemplo scripts/LCP.js) y lo ejecuta vía evaluate_script en la página que está analizando. La diferencia entre hacerlo desde un agente y hacerlo desde la shell es mínima.

Capturas

take_screenshot guarda el estado visual de la página en disco. Sirve para documentar resultados de auditorías, comparar estados antes y después de un cambio, o capturar elementos concretos por UID.

# Screenshot del viewport
chrome-devtools take_screenshot --filePath screenshot.png

# Página completa
chrome-devtools take_screenshot --filePath full.png --fullPage

# Solo un elemento (por UID)
chrome-devtools take_screenshot --filePath element.png --uid "hero-image-uid"

# Formato y calidad
chrome-devtools take_screenshot --filePath compressed.webp --format webp --quality 80

Lighthouse

lighthouse_audit lanza una auditoría completa desde la terminal. Por defecto recarga la página en modo navegación, aunque también puede analizar el estado actual sin recargar.

# Auditoría en modo navegación (recarga la página)
chrome-devtools lighthouse_audit

# Auditoría del estado actual sin recargar
chrome-devtools lighthouse_audit --mode snapshot

# En móvil
chrome-devtools lighthouse_audit --device mobile

# Guardar el reporte en una carpeta
chrome-devtools lighthouse_audit --outputDirPath ./reports

Importante: lighthouse_audit cubre accesibilidad, SEO y mejores prácticas. Para métricas de rendimiento (Core Web Vitals, LCP, INP, CLS) hay que usar las tools de Performance.


Red

Analizar las peticiones de red desde la terminal es útil para detectar recursos sin caché, third-parties inesperados o respuestas lentas, sin necesidad de abrir el panel Network de DevTools.

# Listar todas las peticiones de red desde la última navegación
chrome-devtools list_network_requests

# Solo imágenes
chrome-devtools list_network_requests --resourceTypes '["image"]'

# Solo scripts y estilos
chrome-devtools list_network_requests --resourceTypes '["script","stylesheet"]'

# Paginación (100 primeras)
chrome-devtools list_network_requests --pageSize 100 --pageIdx 0

# Incluir peticiones de las últimas 3 navegaciones
chrome-devtools list_network_requests --includePreservedRequests

# Detalles de una petición concreta (por reqid)
chrome-devtools get_network_request 15

# Guardar la respuesta en disco
chrome-devtools get_network_request 15 --responseFilePath response.json

Performance

Performance es el área con más profundidad de análisis: traza completa, insights automáticos y métricas Core Web Vitals desde la terminal.

# Navegar primero a la URL que quieres analizar
chrome-devtools navigate_page --type url --url "https://joanleon.dev"

# Iniciar la traza (con recarga automática)
chrome-devtools performance_start_trace --reload --autoStop

# O controlar manualmente cuándo parar
chrome-devtools performance_start_trace --reload
# ... interactuar con la página ...
chrome-devtools performance_stop_trace

# Guardar la traza en disco
chrome-devtools performance_stop_trace --filePath trace.json.gz

Una vez finalizada la traza, performance_analyze_insight da detalle sobre cada insight detectado:

# El resultado de performance_stop_trace incluye los insight sets disponibles
# Analizar un insight concreto
chrome-devtools performance_analyze_insight "LCPBreakdown" --insightSetId "set-id-del-resultado"
chrome-devtools performance_analyze_insight "DocumentLatency" --insightSetId "set-id-del-resultado"

Los insights incluyen métricas como LCPBreakdown, DocumentLatency, RenderBlocking, SlowCSSSelector y otras que corresponden exactamente a lo que Chrome DevTools muestra en el panel Performance Insights.

Memoria

take_memory_snapshot genera una captura del heap de JavaScript en disco. El archivo resultante puede abrirse directamente en Chrome DevTools (panel Memory > Load) para analizar la distribución de objetos y detectar fugas de memoria sin haber tenido el navegador abierto durante la sesión.

# Captura del heap de JavaScript
chrome-devtools take_memory_snapshot --filePath heap.heapsnapshot

Conexión con WebPerf Snippets y el WebPerf Skill

La CLI de chrome-devtools-mcp y los WebPerf Snippets resuelven el mismo problema desde ángulos distintos.

En el post WebPerf Snippets + WebMCP describí cómo los snippets pueden exponerse como herramientas estructuradas para agentes de IA vía WebMCP. En WebPerf Snippets y Agent SKILLs detallé cómo los SKILLs convierten esos mismos scripts en capacidades autónomas que un agente ejecuta en el navegador con Chrome DevTools MCP.

La CLI cierra el ciclo para uso manual: los mismos scripts que un agente lee del SKILL pueden ejecutarse directamente desde la shell con evaluate_script, sin necesidad de un LLM de por medio.

# Ejemplo: medir el LCP desde la terminal usando el script del SKILL
chrome-devtools navigate_page --type url --url "https://joanleon.dev"
chrome-devtools evaluate_script "() => { $(cat ~/.claude/skills/webperf-core-web-vitals/scripts/LCP.js) }"

El WebPerf Skill actúa como capa de orquestación cuando tienes un agente. La CLI actúa como capa de ejecución directa cuando trabajas sin agente. La lógica de medición, los umbrales y los scripts son los mismos en ambos casos.


Salida en JSON y composición

La mayoría de comandos devuelven texto formateado por defecto. Con --output-format=json la salida es parseable, lo que permite componerla con jq o alimentar otros scripts de análisis.

chrome-devtools list_pages --output-format=json
chrome-devtools list_network_requests --output-format=json | jq '.[] | select(.status >= 400)'

Depuración de la propia CLI

Si la CLI se queda colgada o no conecta al daemon:

chrome-devtools stop
chrome-devtools status

Para ver logs detallados:

DEBUG=* chrome-devtools list_pages

Conclusión

La CLI de chrome-devtools-mcp no reemplaza Puppeteer ni Playwright para flujos de automatización complejos. Pero para inspección rápida, auditorías puntuales y scripts de CI ligeros, elimina casi todo el boilerplate: un daemon persistente, subcomandos directos y salida JSON cuando la necesitas.

En combinación con los WebPerf Snippets y el WebPerf Skill, tienes tres capas de acceso al mismo conjunto de herramientas de medición: la CLI para uso manual desde la terminal, los SKILLs para flujos autónomos con agentes, y WebMCP para cuando el estándar W3C madure en los navegadores.


Next Post
Procesamiento de imágenes en el browser con WebGPU