feat: P0 LLM-readiness — Chrome aislado (9333), tab_select determinista, page_get_text, page_perceive
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
name: browser_mcp
|
||||
lang: go
|
||||
domain: infra
|
||||
version: 0.1.0
|
||||
description: "Servidor MCP que expone control total del navegador via CDP (33 tools: navegación, DOM, cookies, iframes, teclado/scroll, diálogos, estado de sesión) reusando funciones del dominio browser del registry con un pool de conexiones CDP vivas."
|
||||
version: 0.2.0
|
||||
description: "Servidor MCP que expone control total del navegador via CDP (36 tools: navegación, DOM, cookies, iframes, teclado/scroll, diálogos, estado de sesión, selección determinista de pestaña + lectura compacta texto/AX) reusando funciones del dominio browser del registry con un pool de conexiones CDP vivas. Por defecto opera sobre un Chrome aislado (puerto 9333) separado del navegador diario."
|
||||
tags: [mcp, browser, cdp, automation, scraping]
|
||||
uses_functions:
|
||||
- chrome_launch_go_browser
|
||||
@@ -39,6 +39,9 @@ uses_functions:
|
||||
- cdp_get_frame_html_go_browser
|
||||
- cdp_save_storage_state_go_browser
|
||||
- cdp_load_storage_state_go_browser
|
||||
- cdp_get_text_go_browser
|
||||
- cdp_connect_target_go_browser
|
||||
- cdp_perceive_outline_py_pipelines
|
||||
uses_types: []
|
||||
framework: ""
|
||||
entry_point: "main.go"
|
||||
@@ -71,17 +74,33 @@ Por eso reusamos la conexión por puerto.
|
||||
|
||||
- `connPool.get(port)` devuelve la conexión cacheada o abre una nueva.
|
||||
- `connPool.drop(port)` cancela el handler de diálogo (si lo hay) y cierra la conexión.
|
||||
- `connPool.connectTarget(port, match)` descarta la conexión actual y reconecta a un target
|
||||
determinista (por id o substring de URL). Es lo que usa `tab_select` para fijar la pestaña.
|
||||
- `connPool.setCancel(port, cancel)` registra el cancel del auto-handler de `handle_dialog`.
|
||||
- `connPool.closeAll()` se ejecuta con `defer` en `main()`.
|
||||
- `deps.withConn(port, fn)` ejecuta `fn` con la conexión del pool y, si el error indica
|
||||
conexión muerta (`isConnErr`: connection close, broken pipe, use of closed, ws read, EOF),
|
||||
descarta la conexión y reintenta UNA vez (Chrome pudo cerrar la tab entre tools).
|
||||
|
||||
Toda tool con argumento `port` usa `portOr(a.Port)` (default 9222). Las tools de tabs
|
||||
(`tab_list`, `tab_new`, `tab_close`, `tab_activate`) usan el endpoint HTTP `/json` de CDP
|
||||
directamente (host `localhost`), no el pool, porque no requieren una sesión WebSocket viva.
|
||||
Toda tool con argumento `port` usa `portOr(a.Port)` (default 9333). Las tools de tabs
|
||||
(`tab_list`, `tab_new`, `tab_close`, `tab_activate`, `tab_select`) usan el endpoint HTTP `/json`
|
||||
de CDP directamente (host `localhost`), no el pool, porque no requieren una sesión WebSocket viva.
|
||||
|
||||
## Tools (33)
|
||||
## Seguridad: Chrome aislado por defecto (puerto 9333)
|
||||
|
||||
**El default del MCP es operar sobre su PROPIO Chrome aislado, no sobre el navegador diario.**
|
||||
|
||||
En este ecosistema el chromium diario del usuario tiene CDP habilitado globalmente en el
|
||||
puerto **9222** (via `/etc/chromium.d/cdp`). Si el MCP usara 9222 por defecto, el agente
|
||||
podría manipular pestañas ajenas del usuario (banca, correo). Para evitarlo:
|
||||
|
||||
- `portOr` devuelve **9333** por defecto (no 9222) — el Chrome dedicado del MCP.
|
||||
- `browser_launch` sin `user_data_dir` usa un perfil DEDICADO y aislado:
|
||||
`<tmp>/browser_mcp_userdata` (se crea si hace falta) en el puerto 9333.
|
||||
- Para adjuntarte deliberadamente al navegador diario, pasa `port: 9222` explícito en cada
|
||||
tool. Hazlo solo con cuidado.
|
||||
|
||||
## Tools (36)
|
||||
|
||||
### Sesión (`tools_session.go`)
|
||||
- `browser_launch` (MUTA) — lanza Chrome con CDP. args: port, headless, user_data_dir, url.
|
||||
@@ -94,6 +113,9 @@ directamente (host `localhost`), no el pool, porque no requieren una sesión Web
|
||||
- `tab_new` (MUTA) — abre tab via `PUT /json/new`. args: port, url.
|
||||
- `tab_close` (MUTA) — cierra tab por ID. args: port, tab_id.
|
||||
- `tab_activate` — pone tab en foreground. args: port, tab_id.
|
||||
- `tab_select` — fija la pestaña sobre la que operan las siguientes tools, eligiéndola por id
|
||||
o por substring de su URL (determinista). Usar tras `tab_list` para no operar sobre la
|
||||
pestaña equivocada. args: port, match.
|
||||
- `nav_back` (MUTA) — atrás en el historial. args: port.
|
||||
- `nav_forward` (MUTA) — adelante en el historial. args: port.
|
||||
- `page_wait_load` — espera el evento load. args: port, timeout_ms (default 10000).
|
||||
@@ -101,6 +123,14 @@ directamente (host `localhost`), no el pool, porque no requieren una sesión Web
|
||||
|
||||
### Lectura (`tools_read.go`)
|
||||
- `page_get_html` — HTML serializado (truncado a 200000 chars). args: port.
|
||||
- `page_get_text` — texto visible (innerText) de la página o de un elemento (selector CSS),
|
||||
truncado a `max_bytes`. Preferir sobre `page_get_html` cuando solo necesitas leer contenido
|
||||
— no revienta el contexto. args: port, selector (opcional), max_bytes (default 20000).
|
||||
- `page_perceive` — outline indentado y accionable del árbol de accesibilidad (roles, nombres,
|
||||
`#ref`): la forma compacta de que el agente "perciba" la página sin reventar el contexto.
|
||||
Implementado por subprocess (`fn run cdp_perceive_outline`). Si `tab_id` se omite, usa la
|
||||
primera pestaña page. args: port, tab_id (opcional), max_chars (default 20000).
|
||||
**Gotcha:** requiere el binario `fn` y el venv de Python del registry disponibles en runtime.
|
||||
- `page_eval_js` (MUTA) — `Runtime.evaluate`. args: port, expression.
|
||||
- `page_screenshot` — captura a archivo. args: port, path, full_page.
|
||||
|
||||
@@ -152,11 +182,11 @@ Transporte HTTP (Streamable HTTP):
|
||||
### Flag `--read-only`
|
||||
|
||||
Con `--read-only`, el servidor NO registra las tools mutantes (marcadas MUTA arriba):
|
||||
solo expone las 14 tools de lectura (`browser_connect`, `browser_disconnect`, `tab_list`,
|
||||
`tab_activate`, `page_wait_load`, `page_wait_idle`, `page_get_html`, `page_screenshot`,
|
||||
`dom_find_by_text`, `dom_wait_element`, `cookie_get`, `frame_list`, `frame_get_html`,
|
||||
`storage_save`). Útil para sesiones de inspección sin riesgo de modificar el estado del
|
||||
navegador.
|
||||
solo expone las 17 tools de lectura/control (`browser_connect`, `browser_disconnect`, `tab_list`,
|
||||
`tab_activate`, `tab_select`, `page_wait_load`, `page_wait_idle`, `page_get_html`, `page_get_text`,
|
||||
`page_perceive`, `page_screenshot`, `dom_find_by_text`, `dom_wait_element`, `cookie_get`,
|
||||
`frame_list`, `frame_get_html`, `storage_save`). Útil para sesiones de inspección sin riesgo de
|
||||
modificar el estado del navegador.
|
||||
|
||||
## Omitido en v1
|
||||
|
||||
@@ -166,9 +196,17 @@ Funciones del dominio `browser` que NO se exponen como tools en esta versión, c
|
||||
larga duración (registrar handlers + un punto de "stop" que devuelve los datos
|
||||
acumulados); no encaja en el modelo request/response de una tool MCP simple. Pendiente
|
||||
de un diseño con tool de start + tool de stop.
|
||||
- **`cdp_get_ax_tree`** — el árbol de accesibilidad se obtiene hoy via un pipeline Python;
|
||||
futuro a exponer via `fn run` en vez de duplicar la lógica aquí.
|
||||
- **`cdp_get_ax_tree`** — ya expuesto desde v0.2.0 via la tool `page_perceive`, que invoca
|
||||
el pipeline `cdp_perceive_outline` por subprocess (`fn run`) en vez de duplicar la lógica aquí.
|
||||
- **Funciones de perfiles Chrome (Bash: create/delete/appearance/reset)** — requieren que
|
||||
Chrome esté CERRADO para modificar el `Local State` / `Preferences` del perfil; son
|
||||
incompatibles con un MCP cuyo propósito es controlar un Chrome vivo. Quedan disponibles
|
||||
como `fn run` aparte.
|
||||
|
||||
## Capability growth log
|
||||
|
||||
- v0.2.0 (2026-06-06) — P0 LLM-readiness. Seguridad: Chrome aislado por defecto (puerto 9333
|
||||
+ perfil dedicado `<tmp>/browser_mcp_userdata`), separado del navegador diario en 9222.
|
||||
Nuevas tools: `tab_select` (selección determinista de pestaña por id/URL), `page_get_text`
|
||||
(lectura compacta de innerText), `page_perceive` (outline AX via `fn run cdp_perceive_outline`).
|
||||
33 → 36 tools.
|
||||
|
||||
Reference in New Issue
Block a user