Files
browser_mcp/app.md
T

8.2 KiB

name, lang, domain, version, description, tags, uses_functions, uses_types, framework, entry_point, dir_path, repo_url
name lang domain version description tags uses_functions uses_types framework entry_point dir_path repo_url
browser_mcp go infra 0.1.0 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.
mcp
browser
cdp
automation
scraping
chrome_launch_go_browser
cdp_connect_go_browser
cdp_close_go_browser
cdp_navigate_go_browser
cdp_list_tabs_go_browser
cdp_new_tab_go_browser
cdp_close_tab_go_browser
cdp_activate_tab_go_browser
cdp_nav_back_go_browser
cdp_nav_forward_go_browser
cdp_wait_load_go_browser
cdp_wait_idle_go_browser
cdp_get_html_go_browser
cdp_evaluate_go_browser
cdp_screenshot_go_browser
cdp_click_go_browser
cdp_click_human_go_browser
cdp_click_text_go_browser
cdp_type_text_go_browser
cdp_find_by_text_go_browser
cdp_wait_element_go_browser
cdp_press_key_go_browser
cdp_scroll_go_browser
cdp_handle_dialog_go_browser
cdp_set_cookie_go_browser
cdp_get_cookies_go_browser
cdp_delete_cookies_go_browser
cdp_clear_cookies_go_browser
cdp_list_frames_go_browser
cdp_eval_in_frame_go_browser
cdp_get_frame_html_go_browser
cdp_save_storage_state_go_browser
cdp_load_storage_state_go_browser
main.go projects/web_scraping/apps/browser_mcp

browser_mcp

Servidor MCP (Model Context Protocol) en Go que expone el control de navegador via CDP del registry fn_registry como tools MCP. Cualquier cliente MCP (Claude Code, otros agentes) puede manejar un Chrome/Chromium vivo: navegar, leer el DOM, hacer clicks, gestionar cookies, evaluar JavaScript, operar iframes y persistir/restaurar sesiones.

Clona el patrón de apps/registry_mcp/ (librería github.com/mark3labs/mcp-go v0.52.0, server.NewMCPServer + server.ServeStdio, tools con mcp.NewTool + handlers tipados via mcp.NewTypedToolHandler, transporte stdio por defecto + HTTP opcional con --http, slog a stderr porque stdout pertenece al JSON-RPC).

Arquitectura: pool de conexiones CDP

A diferencia de registry_mcp (que abre la DB una vez), browser_mcp mantiene un pool de conexiones CDP vivas indexado por puerto (pool.go). Razón: browser.CdpConnect(port) hace un handshake WebSocket contra una tab "page" de Chrome (~50-200ms) y esa conexión ES una sesión viva (soporta Page.*, Runtime.*, Input.*). El agente llama muchas tools seguidas (navigate → wait → click → eval); reconectar en cada tool pagaría el handshake repetidamente y perdería estado entre tools (los event handlers persistentes, como el de handle_dialog, viven mientras la conexión esté viva). 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.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.

Tools (33)

Sesión (tools_session.go)

  • browser_launch (MUTA) — lanza Chrome con CDP. args: port, headless, user_data_dir, url.
  • browser_connect — abre/poolea la conexión CDP del puerto. args: port.
  • browser_disconnect — cierra y descarta la conexión del puerto (no mata Chrome). args: port.

Navegación + tabs (tools_nav.go)

  • tab_navigate (MUTA) — Page.navigate. args: port, url.
  • tab_list — lista targets via GET /json. args: port.
  • 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.
  • 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).
  • page_wait_idle — espera red idle. args: port, timeout_ms (default 15000).

Lectura (tools_read.go)

  • page_get_html — HTML serializado (truncado a 200000 chars). args: port.
  • page_eval_js (MUTA) — Runtime.evaluate. args: port, expression.
  • page_screenshot — captura a archivo. args: port, path, full_page.

DOM (tools_dom.go)

  • dom_click (MUTA) — click por selector. args: port, selector.
  • dom_click_human (MUTA) — click con movimiento humano. args: port, selector.
  • dom_click_text (MUTA) — click sobre el primer elemento con ese texto. args: port, text.
  • dom_type (MUTA) — escribe texto en el elemento enfocado. args: port, text.
  • dom_find_by_text — devuelve un selector CSS único para un texto visible. args: port, text.
  • dom_wait_element — espera a que aparezca un selector. args: port, selector, timeout_ms (default 10000).

Input (tools_input.go) — todas MUTA

  • press_key — presiona una tecla nombrada (Enter/Tab/Escape/ArrowDown/...). args: port, key.
  • scroll — scroll por (delta_x, delta_y). args: port, delta_x (default 0), delta_y (default 300).
  • handle_dialog — arma un auto-handler de diálogos JS (vive en la conexión del pool). args: port, accept (default true), prompt_text.

Cookies (tools_cookies.go)

  • cookie_get — todas las cookies como JSON. args: port.
  • cookie_set (MUTA) — set cookie. args: port, name, value, domain, path, http_only.
  • cookie_delete (MUTA) — borra cookies por nombre. args: port, name, domain.
  • cookie_clear (MUTA) — borra todas las cookies. args: port.

Iframes (tools_frames.go)

  • frame_list — lista frames con sus IDs. args: port.
  • frame_eval (MUTA) — evalúa JS dentro de un frame. args: port, frame_id, expression.
  • frame_get_html — HTML de un frame (truncado a 200000). args: port, frame_id.

Estado de sesión (tools_storage.go)

  • storage_save — guarda cookies + localStorage a JSON. args: port, path.
  • storage_load (MUTA) — carga cookies + localStorage desde JSON. args: port, path.

Cómo lanzarlo

Transporte stdio (default, para clientes MCP):

cd projects/web_scraping/apps/browser_mcp
go build -o browser_mcp .
./browser_mcp

Transporte HTTP (Streamable HTTP):

./browser_mcp --http :7740                 # bind 127.0.0.1:7740
./browser_mcp --http :7740 --bind 0.0.0.0  # requiere REGISTRY_API_TOKEN (bearer auth)

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.

Omitido en v1

Funciones del dominio browser que NO se exponen como tools en esta versión, con su razón:

  • cdp_har_record_go_browser — graba el tráfico de red (HAR). Requiere un callback de 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í.
  • 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.