Chromewright
Automatización de navegador mediante el Protocolo de Chrome DevTools
Documentación
chromewright
Chromewright es un servidor MCP de automatización de navegador local-first construido sobre el Protocolo de DevTools de Chrome (CDP). Expone un navegador Chrome o Chromium real a clientes MCP a través de stdio o HTTP streamable de bucle local, con herramientas de alto nivel para navegación, lectura de páginas, gestión de pestañas, capturas de pantalla, emulación de viewport e interacción acotada. La compilación predeterminada también incluye un navegador de terminal semántico y un compañero MCP de bucle local co-alojado para su estado de documento en vivo.
Use Chromewright cuando un agente necesite estado del navegador desde un navegador real sin incorporar una pila de automatización de Node.js ni escribir llamadas CDP crudas. Chromewright no es un ejecutor de pruebas de extremo a extremo; es una capa de control del navegador para agentes de IA y clientes MCP.
Cuándo usar Chromewright
- Adjuntar un cliente MCP a un perfil de Chrome o Chromium existente en un endpoint de DevTools.
- Lanzar una sesión de navegador local dedicada para trabajo de agentes.
- Leer páginas mediante instantáneas, extracción de markdown, inspección dirigida e inventario de enlaces.
- Explorar el DOM semántico de una página localmente en la terminal, con un compañero MCP co-alojado para su documento activo y estado de selección.
- Impulsar interacciones acotadas como clic, entrada, selección, pasar el cursor, pulsación de teclas, desplazamiento y espera.
- Capturar capturas de pantalla PNG gestionadas sin permitir que los llamadores elijan rutas de salida arbitrarias.
- Reutilizar identificadores
cursorcon ámbito de revisión de instantáneas en lugar de depender solo de selectores CSS.
Instalación
Chromewright requiere Rust 1.88 o más reciente cuando lo instala o compila con Cargo.
Instale desde crates.io:
cargo install chromewright
Instale con Homebrew:
brew install bnomei/chromewright/chromewright
Instale desde el código fuente:
git clone https://github.com/bnomei/chromewright.git
cd chromewright
cargo install --path .
También puede descargar archivos precompilados desde GitHub Releases y colocar el binario chromewright en su PATH.
Verifique que el binario esté disponible:
chromewright --version
Salida esperada:
chromewright <version>
Inicio rápido
Esta ruta inicia un perfil de Chrome visible con DevTools habilitado, luego sirve Chromewright sobre HTTP de bucle local en http://127.0.0.1:3000/mcp.
Requisitos previos
chromewrighten suPATH- Chrome, Chromium u otro navegador compatible con CDP
- Un cliente MCP que admita servidores HTTP streamable o stdio
1. Inicie un perfil de navegador dedicado
En macOS, ejecute:
open -na "Google Chrome" --args \
--remote-debugging-port=9222 \
--user-data-dir="$HOME/.chromewright-agent-profile"
Use un perfil dedicado cuando no desee que la automatización del agente se adjunte a su sesión de navegador personal. El modo de adjuntar predeterminado de Chromewright espera DevTools en http://127.0.0.1:9222.
2. Inicie Chromewright
Ejecute el servidor HTTP streamable:
chromewright serve
Línea de registro esperada:
Ready to accept MCP connections at http://127.0.0.1:3000/mcp
3. Conecte un cliente MCP
Para clientes configurados con JSON que admitan HTTP streamable:
{
"mcpServers": {
"chromewright": {
"transport": "streamable_http",
"url": "http://127.0.0.1:3000/mcp"
}
}
}
Para Codex sobre stdio, deje que el cliente inicie el servidor:
[mcp_servers.chromewright]
command = "/absolute/path/to/chromewright"
enabled = true
Para Codex contra el servidor HTTP de larga duración del paso 2:
[mcp_servers.chromewright]
url = "http://127.0.0.1:3000/mcp"
enabled = true
4. Verifique con el cliente
Use su cliente MCP para llamar a tab_list. Una sesión conectada debería devolver al menos una pestaña con un tab_id estable. Si ninguna pestaña activa es útil, llame a new_tab antes de llamar a snapshot.
Modos de navegador
Chromewright tiene dos modos de navegador:
| Modo | Cómo iniciar | Qué hace |
|---|---|---|
| Adjuntar | Ejecute chromewright o chromewright serve sin banderas de lanzamiento. | Se conecta a http://127.0.0.1:9222 de forma predeterminada. |
| Adjuntar a otro endpoint | Pase --ws-endpoint <URL>. | Se conecta a una URL WebSocket del navegador o a un origen HTTP de DevTools como http://127.0.0.1:9333. |
| Lanzar | Pase cualquier bandera de lanzamiento como --user-data-dir, --headless, --executable-path o --debug-port. | Inicia una sesión de navegador local. El modo de lanzamiento es con interfaz gráfica a menos que pase --headless. |
Ejemplos:
# Default: attach to http://127.0.0.1:9222 and serve MCP over stdio.
chromewright
# Serve streamable HTTP on the default loopback endpoint.
chromewright serve
# Serve streamable HTTP on a custom port and path.
chromewright serve --port 3333 --http-path /browser
# Attach to a different DevTools endpoint.
chromewright --ws-endpoint http://127.0.0.1:9333
# Launch a visible browser with a dedicated profile.
chromewright --user-data-dir /tmp/chromewright-profile
# Launch a headless browser and serve streamable HTTP.
chromewright --headless --user-data-dir /tmp/chromewright-profile serve
# Seed two managed tabs at startup. This works with attach, launch, serve, and tui modes.
chromewright --url https://example.com --url https://example.org serve
--url es repetible y siembra una pestaña gestionada separada para cada valor, en el orden suministrado; la última pestaña sembrada se vuelve activa. Acepta URLs absolutas http:, https: y about:. Las URLs relativas, inseguras y relativas a protocolo se rechazan antes de que se abra cualquier pestaña de inicio. En modo de adjuntar, las pestañas existentes no se tocan; solo las pestañas sembradas se vuelven gestionadas por chromewright.
Referencia de CLI
| Opción o comando | Predeterminado | Descripción |
|---|---|---|
chromewright | transporte stdio | Inicia el servidor MCP sobre stdio. |
chromewright serve | 127.0.0.1:3000/mcp | Inicia el servidor MCP sobre HTTP streamable de bucle local. |
serve --port <PORT>, serve -p <PORT> | 3000 | Establece el puerto HTTP. |
serve --http-path <PATH> | /mcp | Establece la ruta del endpoint HTTP. |
--ws-endpoint <URL> | http://127.0.0.1:9222 cuando no hay banderas de lanzamiento presentes | Se conecta a una URL WebSocket de navegador existente o a un origen HTTP de DevTools. Esto entra en conflicto con las banderas de lanzamiento. |
--headless | false | Lanza un nuevo navegador en modo sin interfaz gráfica. |
--executable-path <PATH> | auto-detectado por el backend del navegador | Usa un ejecutable de navegador específico en modo de lanzamiento. |
--user-data-dir <DIR> | predeterminado del backend | Usa un directorio de perfil de navegador persistente en modo de lanzamiento. |
--debug-port <PORT> | auto-seleccionado | Usa un puerto de DevTools específico para un navegador lanzado localmente. |
--url <URL> | ninguno; repetible | Siembra cada URL segura suministrada en su propia pestaña de inicio gestionada. La última pestaña sembrada está activa. |
chromewright tui | (característica tui, activada por predeterminado) | Inicia el navegador de terminal semántico contra la misma sesión de navegador. Siempre co-aloja un compañero MCP de bucle local. |
tui --config <PATH> | $XDG_CONFIG_HOME/chromewright/tui.toml o ~/.config/chromewright/tui.toml | Mapa de teclas TOML más superposiciones opcionales [theme] y [layout]. Una ruta explícita debe existir y analizarse; un archivo predeterminado faltante mantiene los enlaces integrados. |
tui --companion-port <PORT> | 0 (efímero) | Puerto de bucle local para el compañero MCP HTTP streamable co-alojado. |
tui --companion-path <PATH> | /mcp | Ruta HTTP para el compañero co-alojado. |
--browser-session <reuse|restart> | reuse con --headless tui | Reutiliza o reemplaza el navegador sin interfaz gráfica gestionado propiedad de Chromewright. Solo es válido con --headless tui. |
Fuente: src/bin/mcp_server.rs.
Navegador de terminal (TUI)
La compilación predeterminada incluye un navegador de terminal semántico. Se adjunta a la misma sesión de navegador de Chromewright y renderiza solo contenido DOM semántico (no píxeles, CSS ni diseño del navegador).
# Attach to an existing DevTools endpoint (default http://127.0.0.1:9222).
chromewright tui
# Managed private headless Chrome for the normal terminal-browser flow.
chromewright --headless tui
Para conectar un cliente MCP al compañero co-alojado, elija un puerto de bucle local fijo; el 0 predeterminado selecciona un puerto efímero que el TUI no imprime.
chromewright --headless tui --companion-port 3334
[mcp_servers.chromewright_tui]
url = "http://127.0.0.1:3334/mcp"
enabled = true
El compañero expone ocho herramientas de coordinación tui_* y recursos semánticos acotados. Los valores semantic_ref están vinculados a una revisión de documento; la captura activa más las ocho revisiones anteriores se retienen, mientras que las referencias obsoletas o desalojadas fallan de forma segura. Los mensajes de atención se limitan a 512 caracteres. Los recursos semánticos de Markdown se paginan a 32,000 caracteres por predeterminado y tienen un límite de 200,000; los recursos JSON fallan en lugar de devolver un documento truncado.
El encabezado es una sola barra similar a un navegador: ordinal de pestaña (2/5) a la izquierda de las flechas de historial, luego ubicación/título, con un glifo de ciclo de vida a la derecha. Los enlaces de teclado no se muestran en el cromo de la terminal. Los predeterminados son compatibles con Vimari. Las secuencias de múltiples teclas como gg y gi esperan el acorde completo; un prefijo no vinculado se rechaza en lugar de volver a disparar la última tecla.
Mapa de teclas predeterminado
Predeterminados de navegador primero (Vimari), con alias estilo md-tui donde no colisionan. Superponer una acción reemplaza todas sus secuencias (primaria + alias).
| Tecla | Nombre de la acción | Comportamiento |
|---|---|---|
f / s | link_hints_follow | Activa el modo de pistas sobre enlaces y controles de formulario visibles en el viewport; escribe la etiqueta de dos teclas. Los enlaces se abren en la pestaña actual; los campos de texto inician el modo de edición; otros controles se seleccionan. Una etiqueta por objetivo (solo la primera línea si está envuelto). (s = md-tui select-link.) |
F / S | link_hints_new_tab | Mismos objetivos que f; los enlaces se abren en una pestaña nueva (el modo de pistas permanece abierto para encadenar hasta Esc). Los objetivos de formulario aún se seleccionan/editan en la pestaña actual. (S = md-tui select-link alt.) |
j / ↓ | scroll_down | Desplaza o mueve la selección un bloque hacia abajo. |
k / ↑ | scroll_up | Desplaza o mueve la selección un bloque hacia arriba. |
h | scroll_left | Desplazamiento horizontal a la izquierda cuando el contenido se desborda. (No es md-tui half-page; las tablas/código del navegador necesitan paneo.) |
l | scroll_right | Desplazamiento horizontal a la derecha cuando el contenido se desborda. |
u / → | half_page_up | Desplaza la vista media página hacia arriba (la selección no cambia). |
d / ← | half_page_down | Desplaza la vista media página hacia abajo (la selección no cambia). |
Ctrl-u | page_select_up | Mueve la selección hacia arriba aproximadamente media página. |
Ctrl-d | page_select_down | Mueve la selección hacia abajo aproximadamente media página. |
gg | go_top | Salta al inicio del documento. (Una sola g no está vinculada para que gi siga disponible.) |
G | go_bottom | Salta al final del documento. |
gi | focus_first_input | Enfoca el primer control de formulario e inicia la edición. |
H / b | history_back | Retrocede en el historial del navegador. (b = md-tui back.) |
L | history_forward | Avanza en el historial del navegador. |
r | reload | Recarga la página activa. |
[ | prev_tab | Cambia a la pestaña anterior del navegador. |
] | next_tab | Cambia a la siguiente pestaña del navegador. |
x | close_tab | Cierra la pestaña actual. |
t | new_tab | Abre una pestaña nueva. |
o | open_url | Abre el prompt de entrada de URL con un buffer vacío. Mientras editas, Tab / Shift-Tab aceptan o recorren el historial local de URLs (el sufijo fantasma muestra la mejor coincidencia). |
O | edit_url | Abre el prompt de entrada de URL precargado con la dirección actual (edita desde el final). Misma finalización de historial con Tab que o. |
/ | search | Inicia la búsqueda hacia adelante por contenido semántico exacto. (md-tui también vincula f a la búsqueda; mantenemos f para las pistas de enlaces.) |
n | search_next | Repite la última búsqueda hacia adelante. |
N | search_previous | Repite la última búsqueda hacia atrás. |
Space | collapse | Contrae o expande el bloque seleccionado. |
zw | toggle_wrap | Alterna el ajuste de línea suave (activado por defecto). Cuando está activado, las líneas largas se ajustan al viewport y el paneo horizontal h/l queda deshabilitado. |
zs | toggle_structure | Alterna prosa (por defecto) vs proyección de estructura. La prosa oculta el chrome de landmarks/listas/grupos y aplana la sangría; la estructura muestra contenedores tipo DOM. Contraer (Space) solo funciona en modo estructura. |
i | inspect | Abre un panel de inspección compacto bajo el bloque seleccionado; el título es la ruta DOM completa (main > … > tag#id), el cuerpo tiene campos de acción y ref/rev; sigue la selección hasta Esc. |
y | copy_block | Copia la selección: URL de enlace/imagen (resuelta), o el texto del bloque renderizado (OSC 52). |
Y | copy_ref | Copia el semantic_ref opaco (OSC 52). |
Tab | tab_next | Siguiente control enfocable; escribe el campo que se abandona en el DOM en vivo + parche del mismo documento, luego mueve el foco. |
Shift-Tab | tab_prev | Control enfocable anterior; mismo comportamiento de escritura al salir que Tab. |
Enter | confirm | Entrada de texto: aplica el valor al DOM en vivo + parche del mismo documento (sin necesidad de enviar; la búsqueda en vivo funciona). Checkbox/radio: alterna. Select: recorre opciones. Botón de envío: escribe los campos preparados + clic + recaptura. Enlace/otro: activa. |
Esc | escape | Sale del prompt, las pistas o el modo de inspección. En modo Normal, también limpia el pie de página fijo /search (/{query} n/m). Tras una acción de página fallida, descarta Error y vuelve a Ready (la página retenida permanece) para que las teclas funcionen de nuevo. |
w | toggle_full_width | Alterna contenido de ancho completo vs la columna content_max_width configurada (100 por defecto, limitada por defecto). |
e | edit_external | Abre el markdown semántico de la página actual en $VISUAL, luego $EDITOR, luego vi (solo lectura; la TUI se suspende como Nereid). |
q / Ctrl-c | quit | Sale de la TUI. |
Las pistas usan etiquetas deterministas de dos teclas del alfabeto asdfgqwertzxcvb (por ejemplo aa, as), asignadas a enlaces y controles de formulario visibles en el viewport (una etiqueta por objetivo; pintada solo en la primera línea cuando un objetivo se envuelve).
Después de que la navegación o el seguimiento de un enlace se asiente, un fragmento de URL como #section mueve la selección de la TUI al componente coincidente (id, luego ancla nombrada), expande los ancestros contraídos y lo desplaza a la vista. Los fragmentos sin coincidencia mantienen la selección anterior.
El panel de contenido usa una paleta de roles ANSI-16 nativa del terminal (escalera de encabezados H1–H6 más clara, enlaces azules, formularios cian claro, pistas amarillas) con selección en vídeo inverso aplicada al final. Los colores heredan el tema claro/oscuro del terminal; anula roles individuales en [theme] dentro de tui.toml. Por defecto, el área de markdown/contenido tiene 1 columna de padding izquierdo/derecho y está limitada a 100 columnas (centrada; el encabezado y el pie permanecen a ancho completo); pulsa w para ancho completo. Una barra de desplazamiento de bloque estilo Amp de una columna se sitúa en el extremo derecho de la banda de contenido. Anula el diseño en [layout] dentro de tui.toml.
El modo de lectura por defecto es prosa (similar a markdown): sin ▾ [main] / ol / chrome de grupo, líneas completamente planas. Pulsa zs para estructura (esquema tipo DOM). El ajuste (zw) y la estructura (zs) no se muestran en la barra de encabezado; la retroalimentación de alternancia aparece en la línea de estado.
La búsqueda sigue la semántica de Vim: una nueva /pattern comienza después de la selección actual y envuelve al final; n repite hacia adelante, N repite hacia atrás, y enviar un prompt / vacío repite el patrón anterior. El pie de página muestra la línea de comandos mientras escribes (/…) y mantiene /{pattern} n/m mientras una búsqueda está activa — pulsa Esc en modo Normal para limpiarla (Esc mientras escribes /… solo cancela el prompt y mantiene el patrón anterior para n/N). Las pistas de enlaces (f / F) también usan el pie de página (f as) en lugar del encabezado. El pegado entre corchetes solo se acepta en modos de entrada de URL, búsqueda y formulario, y está limitado a 4096 caracteres.
Mapa de teclas personalizado
Los enlaces se pueden reemplazar por nombre de acción. --config PATH tiene prioridad; si se omite, Chromewright lee $XDG_CONFIG_HOME/chromewright/tui.toml, con respaldo en ~/.config/chromewright/tui.toml. Un archivo predeterminado ausente conserva los integrados; un archivo solicitado explícitamente debe analizarse correctamente.
# Only list keys you want to change. Unknown names or conflicting
# bindings abort startup rather than partially applying the overlay.
[keymap]
reload = "ctrl-r"
quit = "ctrl-q"
tab_prev = "shift-tab"
# Optional content-pane padding + column width (header/footer stay full width).
# Defaults: 1 col L/R, 0 row T/B, content_max_width = 100 (0 = always full).
# Press w to toggle full width vs the capped column.
[layout]
# content_padding_x = 1
# content_padding_y = 0
# content_max_width = 100
[theme]
# Optional ANSI names, reset, or #rrggbb — defaults already use a clear ladder.
# link = "blue"
# h1 = "lightblue"
# h2 = "green"
# h3 = "magenta"
# h4 = "cyan"
# h5 = "yellow"
# h6 = "lightred"
# form_control = "lightcyan"
# hint_label = "yellow"
Las especificaciones de enlace aceptan teclas individuales (r, space, esc, enter, tab), secuencias de letras de varias teclas (gg, gi) y acordes con separadores -, + o espacio (ctrl-c, C-c, shift-tab). Las teclas nombradas compatibles incluyen esc, enter, tab, backtab / shift-tab, backspace, teclas de flecha, home, end, pageup / pgup, pagedown / pgdn, space y teclas de función como f1.
Roles de tema: link, h1–h6, landmark, group, list, image, form_control, hint_label, muted, chrome_ready, chrome_loading, chrome_error, chrome_mode, attention_fg, attention_bg.
Claves de diseño: content_padding_x, content_padding_y (inserción simétrica solo alrededor del panel de markdown/contenido), content_max_width (100 por defecto; 0 deshabilita el límite; w alterna completo vs limitado).
La fuente de verdad para los valores predeterminados es src/tui/keymap.rs y src/tui/action.rs.
Flujo de trabajo de herramientas
Un flujo de trabajo típico de agente es:
- Llama a
tab_listonew_tabpara establecer una pestaña activa. - Llama a
snapshotpara leer la página actual y recopilar nodos accionables. - Prefiere un
cursorfresco desnapshotoinspect_nodeal apuntar a acciones de seguimiento. - Usa
inspect_node,get_markdown,extractoread_linkspara lecturas más enfocadas. - Usa
click,input,select,hover,press_key,scroll,waito herramientas de pestañas para interacción acotada. - Llama a
snapshotde nuevo después de la navegación, acciones que cambian el DOM, cambios de viewport o recuperación de objetivos ambiguos.
snapshot admite estos modos:
| Modo | Úsalo cuando |
|---|---|
viewport | Quieres la relectura local predeterminada del ámbito visible actual. |
delta | Quieres la superficie local cambiada cuando existe una base de instantánea previa compatible. |
full | Necesitas una lectura exhaustiva de toda la página. |
Las herramientas dirigidas a DOM aceptan un objeto público target:
{
"target": {
"kind": "selector",
"selector": "h1"
}
}
o:
{
"target": {
"kind": "cursor",
"cursor": "<cursor from snapshot or inspect_node>"
}
}
Las cadenas de selector aún se aceptan por compatibilidad en las herramientas que usan el tipo de objetivo público, pero la forma de objeto es el contrato canónico.
Superficie de herramientas MCP de producción
Las sesiones MCP de producción registran las herramientas de alto nivel predeterminadas más la herramienta de operador protegida evaluate.
| Categoría | Herramientas |
|---|---|
| Navegación | navigate, go_back, go_forward, wait |
| Interacción y viewport | click, input, select, hover, press_key, scroll, set_viewport |
| Pestañas y ciclo de vida | new_tab, tab_list, switch_tab, close_tab, close |
| Lectura e inspección | snapshot, inspect_node, get_markdown, extract, read_links |
| Artefactos gestionados | screenshot |
| Diagnósticos de operador | evaluate |
evaluate ejecuta JavaScript en la página activa y requiere confirm_unsafe = true en cada llamada. Está disponible para diagnósticos e inspección de escape cuando las herramientas acotadas no pueden responder una pregunta específica de la página.
Fuente: src/tools/core/mod.rs y src/browser/session.rs.
Capturas de pantalla y emulación de viewport
Usa screenshot cuando un llamador necesita un artefacto PNG gestionado. La herramienta acepta:
mode:viewport,full_page,elementoregionscale:deviceocsstab_idopcionaltargetopcional para capturaselementregionopcional para capturasregionLas llamadas exitosas devuelven metadatos de artefactos gestionados, incluyendoartifact_uri,artifact_path,mime_type,byte_count, dimensiones de imagen, dimensiones CSS, relación de píxeles del dispositivo, escala de píxeles,revealed_from_offscreeny datos de recorte opcionales. Los llamadores no proporcionan rutas de salida.
Usa set_viewport para emular puntos de interrupción responsivos mediante CDP. Las llamadas exitosas devuelven viewport_metrics_after; las llamadas posteriores a snapshot exponen las métricas en vivo bajo scope.viewport.
Límites de seguridad
- El modo de conexión puede ver las pestañas, cookies y estado autenticado en el perfil del navegador al que te conectas.
- Usa un perfil de navegador dedicado para el trabajo de agentes cuando no quieras que la automatización se adjunte a una sesión de navegador personal.
evaluaterequiereconfirm_unsafe = trueporque ejecuta JavaScript arbitrario en la página activa.navigateynew_tabpermitenhttp:,https:,about:y rutas relativas del mismo origen por defecto.data:,file:, otros esquemas absolutos y URLs relativas al protocolo requierenallow_unsafe = true.go_backygo_forwardaplican la misma barrera de esquemas no seguros y revierten los movimientos de historial rechazados.close_tabrequiereconfirm_destructive = trueantes de cerrar una pestaña activa no gestionada en una sesión conectada.closerequiereconfirm_destructive = trueantes de expandir la limpieza de sesiones conectadas de pestañas gestionadas a todas las pestañas.- Los objetivos de
cursorynode_refestán limitados a la revisión. Después de acciones de navegación o cambios en el DOM, actualiza consnapshot.
Métricas de operación
Los resultados de herramientas finalizadas incluyen metadatos de operation_metrics cuando una herramienta registra métricas distintas de cero. operation_metrics.output_bytes es opcional; aparece solo cuando una ruta de herramienta mide el tamaño exacto de la salida serializada.
Las rutas medidas pueden incluir:
- recuento de evaluaciones del navegador
- iteraciones de sondeo
- recuento de extracción del DOM y tiempo de extracción
- último recuento de nodos del DOM
- tiempo de renderizado de instantáneas
- recuento y tiempo de reconstrucción de traspaso
- tamaño exacto de la salida serializada cuando se mide
Ejecuta las pruebas enfocadas de métricas de operación:
cargo test --locked --all-features operation_metrics
Desarrollo local
Compila desde el código fuente:
cargo build
Ejecuta la suite de pruebas normal:
cargo test
Ejecuta la suite de pruebas de humo del navegador desde la raíz del repositorio:
scripts/browser-smoke.sh
El script de humo ejecuta:
cargo test --test browser_smoke -- --nocapture
Las comprobaciones de humo del navegador lanzan un navegador local y están destinadas a las estaciones de trabajo de los mantenedores. CI cubre formato, clippy, MSRV, cargo check, pruebas y empaquetado sin requerir un objetivo de conexión de navegador en vivo.
Anclas de código fuente
- Metadatos del paquete y versión de Rust: Cargo.toml
- Banderas CLI y transportes: src/bin/mcp_server.rs
- Registro de herramientas: src/tools/core/mod.rs
- Manejador MCP: src/mcp/handler.rs
- Contrato público de objetivos: src/contract/target.rs
- Contrato de capturas de pantalla: src/tools/screenshot.rs
- Mapa de teclas predeterminado y acciones de TUI: src/tui/keymap.rs, src/tui/action.rs
- Script de humo del navegador: scripts/browser-smoke.sh
Licencia
MIT