Skip to main content
Glama
compnew2006

Browser Controller

by compnew2006

Qué problema resuelve este proyecto

Envías una corrección. Tu agente dice "hecho, por favor verifica". Cambias a Chrome con Alt+Tab, navegas a la página, inicias sesión, haces clic por aquí y por allá, encuentras el error.

Tu agente acaba de escribir el código. También podría verificarlo. Ya tiene tu navegador abierto ahí mismo. Simplemente no puede verlo.

Ahora puede. Browser Controller le da a cualquier agente de IA compatible con MCP (Cursor, Claude Desktop, Windsurf, …) control directo sobre el navegador que ya tienes abierto — tus sesiones reales, tus inicios de sesión, tus cookies. Sin navegador headless, sin perfil nuevo, sin volver a autenticarte.

Related MCP server: Tabryn

Capacidades clave

  • Varios agentes a la vez. Cursor puede manejar la pestaña 10 mientras Claude maneja la pestaña 11 — ambos a través de un mismo daemon compartido, sin que uno bloquee al otro.

  • Segmentación por pestaña, no "la pestaña activa". Cada acción nombra un tabId. Mueve el ratón, cambia de pestaña, mira YouTube — el agente sigue trabajando en la pestaña que le indicaste. Nunca secuestra la página que estás leyendo.

  • Aislamiento por pestaña. Las referencias a elementos, los registros de consola y los búferes de red están limitados a cada pestaña. Una referencia de la pestaña 10 nunca puede hacer clic en algo de la pestaña 20.

  • Concurrencia por pestaña. Dos acciones en la misma pestaña se serializan (sin condiciones de carrera); las acciones en pestañas diferentes se ejecutan en paralelo.

  • Bloqueo de pestañas. Un agente puede reclamar una pestaña para que otros hagan cola detrás en lugar de competir (browser_tabs { action: "lock" }). Los bloqueos sobreviven al reciclaje del service worker de Chrome (chrome.storage.session).

  • Escudo de control del agente. Mientras un agente trabaja en una pestaña, ves un marco interior azul translúcido y tu entrada en esa pestaña queda bloqueada (ratón, teclado, rueda) — la insignia muestra agent <name> controlling the tab y desaparece cuando la acción termina. Bloquear una pestaña mantiene un marco simple durante toda la duración del bloqueo.

  • Penetración de iframes del mismo origen. Las interfaces heredadas o empresariales que viven dentro de iframes (p. ej. una consola ONT en iframe#mainFrame) son accesibles: todas las herramientas de localización buscan en los documentos de los iframes, y find/click_text recorren todos los marcos.

  • Rescate de diálogos abiertos. Un alert/confirm/prompt nativo congela el hilo JS de la página — browser_handle_dialog lo descarta fuera de banda mediante CDP, sin necesidad de JS de la página, lo que también desbloquea todas las demás herramientas de esa pestaña. browser_tabs close/focus siempre funcionan, incluso en una pestaña congelada.

  • Conexión local autenticada. Token + secreto de inscripción de un solo uso, para que ningún otro proceso local pueda manejar tu navegador en silencio. Todo permanece en localhost — sin nube, sin telemetría.

  • Sin banner de depuración. browser_evaluate se ejecuta en el mundo MAIN de la página mediante chrome.scripting — sin banner amarillo de "esta pestaña se está depurando", y los valores reales cruzan la frontera de mundos de MV3.

  • Errores honestos. Cada fallo de herramienta llega a tu agente como un resultado isError real con la carga útil completa — sin respuestas de "éxito" que oculten fallos a mitad del flujo de trabajo.


Cómo funciona

Tres piezas, todas en tu máquina. Nada sale de localhost.

  Agent (Cursor / Claude / Windsurf)        ── other agents connect too ──┐
                  │ stdio (MCP protocol)                                   │
                  ▼                                                        ▼
  ┌─────────────────────────────┐   ┌─────────────────────────────────────────┐
  │  thin MCP client            │   │  thin MCP client                        │
  │  (node mcp-server/dist/     │   │  (node mcp-server/dist/                 │
  │   index.js)                 │   │   index.js)                             │
  │  - speaks MCP over stdio    │   │  - spawns daemon if not running         │
  │  - forwards calls to daemon │   │  - gets its own sessionId               │
  └──────────────┬──────────────┘   └────────────────────┬───────────────────┘
                 │ local IPC socket (AF_UNIX / named pipe, token-auth)     │
                 ▼                                                          ▼
  ┌──────────────────────────────────────────────────────────────────────────┐
  │  DAEMON (single long-running process, owns port 7225)                     │
  │  - multiplexes N clients → 1 extension                                    │
  │  - tags every call with the client's sessionId                            │
  │  - heartbeat eviction, per-session rate limiting                          │
  └──────────────────────────────┬───────────────────────────────────────────┘
                                 │ WebSocket ws://127.0.0.1:7225 (token-auth)
                                 ▼
  ┌──────────────────────────────────────────────────────────────────────────┐
  │  Chrome Extension (Manifest V3 service worker)                            │
  │  - resolves the target tabId (never "the active tab" implicitly)          │
  │  - serializes same-tab actions, parallelizes cross-tab actions            │
  │  - executes click/type/snapshot/evaluate against the named tab            │
  └──────────────────────────────────────────────────────────────────────────┘

Idea clave: la primera vez que cualquier agente se ejecuta, el cliente ligero inicia un daemon en segundo plano que posee el puerto 7225 y la conexión con la extensión. Cada agente posterior (incluso desde un cliente MCP diferente) se conecta a ese mismo daemon a través de un socket IPC local y recibe su propio sessionId. La extensión ve una conexión estable y enruta cada llamada a la pestaña exacta que especificó el llamante.


Inicio rápido

El proyecto no está en Chrome Web Store ni en npm — se instala desde este repositorio. Dos partes: el servidor MCP (se ejecuta en tu máquina, habla con tu agente de IA) y la extensión de Chrome (vive en tu navegador, ejecuta comandos).

Requisitos previos: Node.js ≥ 20 y Chrome/Chromium/Edge.

1. Clonar y compilar

git clone https://github.com/compnew2006/browser-controller.git
cd browser-controller
npm install
npm run build        # compiles TypeScript → mcp-server/dist/

2. Cargar la extensión de Chrome

  1. Abre chrome://extensions y activa el modo de desarrollador (interruptor en la esquina superior derecha)

  2. Haz clic en Cargar descomprimida y selecciona la carpeta extension/ del repositorio clonado

  3. Fija el icono de Browser Controller en tu barra de herramientas

Punto gris = esperando al daemon. Verde = conectado.

3. Añadir el servidor MCP a tu cliente

Cursor: Configuración → MCP → "Añadir nuevo servidor MCP". Claude Desktop: edita claude_desktop_config.json. Windsurf: Configuración → MCP. Cualquier cliente compatible con MCP funciona.

Sustituye /path/to/browser-controller por la ruta absoluta de tu clon (Windows: usa C:\\path\\to\\browser-controller\\mcp-server\\dist\\index.js):

{
  "mcpServers": {
    "browser-controller": {
      "command": "node",
      "args": ["/path/to/browser-controller/mcp-server/dist/index.js"]
    }
  }
}

Por defecto, el daemon nombra cada conexión según su IDE principal ("Cursor", "Claude", …). Para anularlo — p. ej. cuando varios agentes comparten un mismo IDE, o para etiquetarlos por proyecto — pasa --agent <name> en los argumentos. Tiene prioridad sobre cualquier detección automática:

{
  "mcpServers": {
    "browser-controller": {
      "command": "node",
      "args": ["/path/to/browser-controller/mcp-server/dist/index.js", "--agent", "My Project Agent"]
    }
  }
}

El nombre aparece en la lista Connected Agents de la ventana emergente. (También puedes establecer la variable de entorno MCP_AGENT_NAME — es equivalente.) Reconectar con el mismo nombre reemplaza la entrada anterior, así los reinicios del IDE no acumulan duplicados.

4. Vincular la extensión con el daemon

El daemon usa dos secretos, ambos generados en la primera ejecución en ~/.browser-controller/ (Windows: %USERPROFILE%\.browser-controller\). Inícialo una vez pidiendo a tu agente que "liste mis pestañas del navegador", y luego:

  1. Lee los secretos:

    cat ~/.browser-controller/enrollment.json   # one-time pairing secret
    cat ~/.browser-controller/token.json        # WebSocket auth token

    (El secreto de inscripción también se imprime en el registro del cliente MCP en la primera ejecución.)

  2. Haz clic en el icono de la extensión → pestaña Settings → pega el Enrollment Secret y el Auth Token (deja el puerto en 7225 a menos que hayas cambiado WS_PORT).

Punto verde = estás conectado. Tu agente ya puede ver tu navegador.

Estos secretos evitan que cualquier otro proceso local abra un WebSocket y maneje tus sesiones de navegador autenticadas. Para rotarlos, detén tus clientes MCP, elimina la carpeta, y la siguiente ejecución recrea ambos secretos. Consulta SECURITY.md para el modelo de amenazas completo.


Uso

El modelo es primero la pestaña: el agente siempre dice sobre cuál pestaña actuar. Nunca asume "la pestaña activa".

Flujo de trabajo básico

  1. Lista las pestañas para obtener un tabId:

    browser_tabs { action: "list" }
    → [{ id: 15, url: "...", title: "...", active: true, lockedBy: null }, ...]
  2. Haz una instantánea de esa pestaña para ver su estructura y obtener referencias a elementos:

    browser_snapshot { tabId: 15 }
    → { tree: [ { ref: "e3", role: "button", name: "Sign in" }, ... ] }

    Las referencias son válidas solo para este tabId. Si navegas o el DOM cambia, vuelve a hacer la instantánea. Los elementos nuevos desde la última instantánea se marcan con isNew: true — después de que una acción abra una superposición o un menú desplegable, el agente puede centrarse solo en esos en lugar de releer todo el árbol.

  3. Interactúa usando la referencia y el mismo tabId:

    browser_click { tabId: 15, ref: "e3" }
    browser_type  { tabId: 15, ref: "e5", text: "hello@example.com" }
    browser_press_key { tabId: 15, key: "Enter" }

    Si una referencia está obsoleta pero el elemento sigue existiendo, se encuentra automáticamente mediante un selector robusto + escaneo de texto/rol (la respuesta lleva via: "fallback"). Si el elemento se ha desplazado completamente fuera de la vista (feeds virtualizados), la respuesta lleva freshRefs: [...] con una instantánea nueva integrada — reintenta con una de esas referencias nuevas en el mismo paso, sin necesidad de una instantánea aparte.

  4. Verifica — haz una instantánea o vuelve a leer el texto después de la acción.

Coordinación multiagente (dos agentes, dos pestañas)

  1. El agente A lista las pestañas, elige la pestaña 10 y opcionalmente la bloquea: browser_tabs { action: "lock", tabId: 10 }

  2. El agente B lista las pestañas, elige la pestaña 11 y la bloquea: browser_tabs { action: "lock", tabId: 11 }

  3. Ambos trabajan en paralelo. Las llamadas de cada agente se serializan contra su propia pestaña; las dos pestañas nunca interfieren entre sí.

  4. Al terminar: browser_tabs { action: "unlock", tabId: 10 }.

La ventana emergente es tu panel de control

Un shell con pestañas de altura fija (el cuerpo nunca se desplaza, solo las listas):

  • Tabs — cada pestaña abierta con su propietario de bloqueo, más Unlock all en la barra de herramientas para liberar todo con un clic si un agente se bloqueó a mitad de camino.

  • Agents — cada agente conectado con su nombre, id de sesión, tiempo de actividad y una ✕ para desconectarlo inmediatamente (elimina un zombi que el heartbeat aún no ha reclamado).

  • Settings — puerto del WebSocket, Auth Token, Enrollment Secret.

  • Activity bar — una franja plegable en la parte inferior que muestra la actividad de herramientas más reciente; expándela para ver el registro continuo.

Cosas que debes saber

  • ¿Olvidaste el tabId? Recibirás un error claro: tabId is required. Call browser_tabs list first.

  • Páginas protegidas (chrome://, la Web Store, devtools) no se pueden scriptear — recibirás Cannot access protected page (chrome://...) en lugar de un cuelgue silencioso.

  • browser_navigate es la única herramienta donde tabId es opcional (por defecto usa la pestaña activa) — pero por seguridad en entornos multiagente, pásalo explícitamente. Los cambios solo de hash (p. ej. /page/page#section) se resuelven en cuanto se establece la URL, sin esperar un evento complete (las SPA no se recargan al cambiar el hash, así que ese evento nunca se dispara).

  • browser_evaluate se ejecuta en el mundo MAIN de la página (sin banner de depuración, seguro con CSP) y devuelve valores reales (serializados en JSON a través de la frontera de mundos). Es potente pero no idempotente — no se reintentará automáticamente en caso de timeout.

  • Desplazamiento de feeds virtualizados (Facebook/Instagram/Twitter): browser_scroll devuelve refsMayBeStale: true porque esos sitios reciclan nodos del DOM. Haz una nueva instantánea antes de tu siguiente interacción.

  • Elementos duplicados: cuando varios elementos comparten texto+rol (p. ej. 3 botones "Me gusta"), el resolvedor de respaldo elige el correcto por ordinal (nth), no solo la primera coincidencia.

  • Una pestaña congelada (diálogo nativo bloqueando) no te deja sin salida: browser_handle_dialog lo descarta mediante CDP, y browser_tabs { action: "close" } siempre funciona como vía de escape garantizada.


🧠 Enseña a tu agente

El agente puede usar las 22 herramientas de serie, pero funciona mejor cuando conoce el flujo de trabajo primero la pestaña. Desde la raíz del repositorio:

npm run setup:cursor   # or: node mcp-server/dist/index.js --setup cursor

Esto instala:

  • ~/.cursor/rules/browser-controller.mdc — el flujo de trabajo de segmentación por pestañas, manejo de menús desplegables, cuándo bloquear pestañas

  • ~/.cursor/commands/check-browser.md — añade /check-browser a tu chat de Cursor

Después de eso, escribe /check-browser en cualquier chat. O simplemente di "comprueba el resultado en mi navegador" y el agente sabrá qué hacer.

npm run setup:claude

Añade un AGENTS.md a la raíz de tu proyecto. Claude Code lo descubre automáticamente.

Consulta agent-config/ para la instalación manual o para personalizar las reglas.


Qué puede hacer

22 herramientas. Cada herramienta de interacción con la página requiere un tabId (la única excepción es browser_navigate, donde es opcional).

Ver

Herramienta

Qué hace

browser_snapshot

Árbol de accesibilidad con referencias a elementos. El modo compacto (predeterminado) devuelve solo elementos interactivos. Recorre shadow DOM e iframes.

browser_screenshot

Captura una pestaña como imagen (activa la pestaña primero para capturarla)

browser_text

Extrae texto sin formato de la página o de un elemento

browser_find

Consulta elementos por lenguaje natural: también recorre iframes del mismo origen

Interactuar

Herramienta

Qué hace

browser_click

Haz clic por referencia o selector CSS: atraviesa iframes del mismo origen

browser_click_text

Haz clic por texto visible. Funciona a través de portales y superposiciones de React

browser_type

Escribe en campos de entrada y campos contenteditable

browser_press_key

Combinaciones de teclas (Enter, Escape, Ctrl+A)

browser_scroll

Desplaza páginas y contenedores virtuales

browser_hover

Activa información sobre herramientas y menús desplegables

browser_select

Selecciona de menús desplegables nativos <select>

browser_wait

Espera a que los elementos aparezcan o desaparezcan

browser_fill_form

Rellena varios campos de formulario en una sola llamada (setters seguros para React/Vue)

browser_drag

Arrastra de elemento a elemento (usa CDP para mayor fiabilidad)

browser_upload_file

Sube archivos a través de <input type="file"> (usa CDP, seguro para CSP estricto)

browser_upload_file inyecta archivos locales en un <input type="file"> como si el usuario los hubiera seleccionado: el diálogo nativo nunca se abre, y los eventos input/change se disparan después para que los formularios de React/Vue reaccionen.

browser_upload_file { tabId: 15, selector: "#resume", filePath: "/Users/me/resume.pdf" }
browser_upload_file { tabId: 15, ref: "e12", files: ["/tmp/a.png", "/tmp/b.png"] }

Las rutas son absolutas y locales a la máquina que ejecuta el navegador. Omite ref/selector para apuntar automáticamente al primer input de archivo de la página; varios archivos a la vez necesitan un input con multiple.

Navegar

Herramienta

Qué hace

browser_navigate

Ir a una URL en una pestaña (tabId opcional, por defecto la activa)

browser_tabs

Listar / crear / cerrar / enfocar / bloquear / desbloquear pestañas

Depuración y avanzado

Herramienta

Qué hace

browser_console

Salida de consola (log, warn, error) — por pestaña, limitada a 200 entradas

browser_network

Solicitudes XHR/fetch con códigos de estado — por pestaña, limit opcional

browser_evaluate

Ejecuta JavaScript en el mundo MAIN de la página (sin banner, seguro para CSP)

browser_handle_dialog

Descartar/aceptar una alerta/confirmación/aviso abierta mediante CDP (funciona en páginas congeladas)

browser_run_action

Ejecuta un objeto de acción JS autocontenido mediante CDP


Cómo se comparan otros

Browser Controller

Playwright MCP

Chrome DevTools MCP

Usa tu navegador existente

No, lanza uno nuevo

Parcial, necesita puerto de depuración

Sesiones y cookies

Ya están ahí

Perfil nuevo

Configuración manual

Funciona detrás de SSO corporativo

No

Depende

Múltiples agentes, múltiples pestañas

No

No

Apuntar a pestañas (no secuestra la pestaña activa)

N/D

No

Conexión local autenticada

N/D

No

Configuración

Compilar desde el código fuente + extensión

Navegador sin interfaz

Chrome con --remote-debugging-port


Configuración

Variable de entorno

Predeterminado

Qué hace

WS_PORT

7225

Puerto WebSocket que usa el daemon para la conexión de la extensión

BROWSER_CONTROLLER_PROGRESSIVE

(sin establecer)

Establécelo en 1 para habilitar la divulgación progresiva de herramientas: solo la metaherramienta browser_tools es visible al inicio (~150 tokens en lugar de ~4200 para las 22 definiciones). El agente descubre herramientas mediante browser_tools {action:"list"/"search"} y las activa con {action:"details", tool:"…"}. El valor predeterminado (sin establecer) muestra todas las herramientas de antemano: seguro para agentes cuyas instrucciones llaman a herramientas directamente.

MCP_AGENT_NAME

(auto: nombre del IDE)

Anula el nombre del agente que se muestra en la ventana emergente (igual que --agent)

Archivos de estado del daemon

El daemon guarda todo en ~/.browser-controller/ (Windows: %USERPROFILE%\.browser-controller\):

Archivo

Propósito

enrollment.json

Secreto de emparejamiento único para la extensión (modo 0600)

token.json

Token de autenticación que la extensión debe presentar en cada conexión WebSocket (modo 0600)

daemon.sock

El socket IPC al que se conectan los clientes ligeros (AF_UNIX en mac/linux; tubería con nombre en Windows)

daemon.json

Metadatos del daemon (pid, puerto, hora de inicio) — se usa para detectar un daemon en ejecución

daemon.log

Salida estándar/error del daemon cuando lo genera un cliente

Para restablecer por completo: detén tus clientes MCP, elimina la carpeta y la siguiente ejecución la recreará con secretos nuevos.

Fiabilidad

  • El daemon se genera automáticamente la primera vez que se ejecuta cualquier cliente y se deja en ejecución de forma independiente.

  • Las caídas de conexión usan retroceso exponencial (1s → 30s), comprobaciones de salud ping/pong cada 10s; un cliente que pierde 3 pongs es expulsado.

  • Un límite de velocidad de 120 llamadas/min por sesión protege al daemon de un bucle de agente descontrolado.

  • Tiempos de espera por herramienta (5–15s para la mayoría de las acciones, 60s para navegación), ubicados junto con la definición de cada herramienta para que no se desvíen del registro.

  • Las herramientas de lectura idempotentes (snapshot, screenshot, text, find) se reintentan en caso de tiempo de espera; las herramientas con efectos secundarios (click, type, navigate, evaluate) — y console/network (que mutan con clear:true) — nunca se reintentan, por lo que un clic no puede dispararse dos veces.

  • Si otro proceso ya ocupa el puerto 7225, el daemon se niega a iniciarse en lugar de matar un proceso que no generó: informa del conflicto para que puedas resolverlo deliberadamente.

Ejecuta dos daemons en puertos diferentes estableciendo WS_PORT por cliente:

{
  "mcpServers": {
    "browser-work": {
      "command": "node",
      "args": ["/path/to/browser-controller/mcp-server/dist/index.js"]
    },
    "browser-personal": {
      "command": "node",
      "args": ["/path/to/browser-controller/mcp-server/dist/index.js"],
      "env": { "WS_PORT": "9333" }
    }
  }
}

Actualiza el puerto en cada ventana emergente de la extensión para que coincida.


Arquitectura

Todo permanece en tu máquina. La extensión se conecta al daemon mediante un WebSocket autenticado en localhost; los clientes MCP se conectan al daemon mediante un socket IPC local. Sin nube, sin proxy, nada sale de tu navegador.

browser-controller/
├── mcp-server/          MCP server (TypeScript)
│   └── src/
│       ├── daemon.ts        Single multi-client daemon (owns WS :7225)
│       ├── daemon-config.ts IPC protocol, paths, auth/enrollment tokens
│       ├── index.ts         Thin stdio MCP client (spawns daemon, multiplexes)
│       ├── bridge.ts        Extension WS server + cross-platform port probe
│       ├── register-tools.ts Progressive-disclosure wiring
│       └── tools/           One file per tool (22), registry pattern
├── extension/           Chrome extension (Manifest V3, plain JS, ES modules)
│   ├── background.js        Wiring only (~30 lines): inject router, register events, connect
│   ├── lib/                 state (buffers/locks/persistence), connection (WS lifecycle),
│   │                        router (dispatch + mutex/locks + control shield), page-exec,
│   │                        overlay, lock-ops, tab-concurrency (pure, unit-tested)
│   ├── handlers/            Tool implementations: navigation, interaction, inspection, tabs, cdp
│   ├── utils/               navigation + smart-selector fallback resolution
│   ├── events.js            chrome.* listeners (console capture, popup, webRequest, lifecycle)
│   ├── content.js           Console capture
│   └── popup/               Fixed tabbed shell (Tabs · Agents · Settings) + collapsible activity bar
├── agent-config/        Pre-built configs for Cursor + Claude Code
│   ├── cursor/              Rules and commands
│   ├── skills/              Browser automation skill
│   └── setup.mjs            One-command installer
└── tests/               15 suites / 215 tests

Stack: TypeScript (estricto) · MCP SDK · WebSocket · Chrome Extension Manifest V3 · Vitest

Desarrollo

git clone https://github.com/compnew2006/browser-controller.git
cd browser-controller
npm install
npm run build
npm test

Comando

Qué hace

npm run build

Compila TypeScript → mcp-server/dist/

npm run dev

Modo de observación

npm test

Ejecuta la suite de pruebas completa (215 pruebas)

npm run typecheck

Comprobación de tipos sin emitir

npm run setup:cursor

Instala la regla y el comando de Cursor

npm run setup:claude

Instala AGENTS.md de Claude Code

La suite cubre el puente WebSocket (incluido el rechazo de autenticación por token y el canal de errores unificado), el registro de herramientas, el ciclo de vida del daemon (expulsión por latido, limitación de velocidad, autenticación IPC), la concurrencia por pestaña (serialización en la misma pestaña + paralelismo entre pestañas) y el comportamiento de la extensión mediante una API chrome simulada (despacho de enrutador, semántica de escudo, ida y vuelta de evaluate, penetración de iframes, rescate de diálogos). CI ejecuta la suite en Node 20 y 22, además de análisis de CodeQL y Scorecard.

Actualizar una instalación existente

git pull
npm install
npm run build

Luego dos pasos manuales: recarga la extensión en chrome://extensions (un service worker en ejecución nunca detecta los cambios de archivos por sí solo) y reinicia el daemon — es de larga duración y tampoco recarga dist/ (mátalo, o simplemente reinicia tu cliente MCP, y la siguiente ejecución lo volverá a generar con la nueva compilación).


Preguntas frecuentes

Ese es el punto. La extensión se ejecuta dentro de tu Chrome real: las mismas cookies, las mismas sesiones, el mismo almacenamiento local. No se necesita reautenticación.

No. Los clientes MCP, el daemon y la extensión se comunican todos a través de localhost (socket IPC + WebSocket). Nada sale de tu máquina. No hay análisis, ni telemetría, ni componente en la nube. Consulta SECURITY.md para conocer el modelo de amenazas, el diseño de autenticación y la ventana TOFU del primer contacto.

Cualquier cliente compatible con MCP. Cursor, Claude Desktop, Claude Code, Windsurf, Cline y cualquier otra cosa que hable el protocolo MCP. Varios de ellos pueden ejecutarse a la vez contra el mismo daemon.

Sí. Cada agente se conecta al daemon compartido, obtiene su propio sessionId y apunta a un tabId específico. Las acciones en la misma pestaña se serializan mediante un mutex por pestaña; las acciones en pestañas diferentes se ejecutan en paralelo. Opcionalmente, un agente puede lock una pestaña para reclamar acceso exclusivo; otros agentes hacen cola detrás del bloqueo en lugar de fallar.

No puede — no en silencio. Cada herramienta de interacción con la página requiere un tabId, y si falta, obtienes un error claro de tabId is required. El agente nunca puede actuar accidentalmente en la pestaña que estás mirando. (La única excepción es browser_navigate sin tabId, que usa la pestaña activa — pero para uso multiagente siempre debes pasar tabId).

Sin ellos, cualquier proceso local en tu máquina podría abrir un WebSocket al puerto 7225 y controlar tus sesiones de navegador autenticadas (tu banco, tu correo electrónico, el SSO de tu empresa). El secreto de enrollment empareja la extensión con el daemon exactamente una vez (fuera de banda, antes de que exista cualquier WebSocket); el token de autenticación autentica entonces cada conexión. Ambos viven en ~/.browser-controller/ con modo 0600.

Lanzan una nueva instancia del navegador desde cero — sin estado, sin cookies, sin sesiones. Tienes que repetir el flujo completo de inicio de sesión cada vez. Esto se conecta al navegador que ya tienes abierto con todo ya cargado.


Contribuciones

Los informes de errores, las solicitudes de funciones y los PRs son bienvenidos en el rastreador de incidencias. Abre una incidencia primero para cambios más grandes.

Seguridad

Consulta SECURITY.md — arquitectura solo localhost, diseño de token + enrollment, modelo de amenazas y guía de notificación.

Licencia

MIT

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityActive
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables CLI coding agents to interact with your live browser tabs via MCP, using your real sessions and cookies without a sandbox.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Connects AI agents to your Chrome browser via MCP, enabling real-time control of existing tabs, sessions, and application state for development workflows.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI to control a real browser through MCP tools for clicking, typing, navigation, screenshots, and more. It supports a follow mode that tracks the active tab, plus fixed mode for controlling specific tabs.
    18
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/compnew2006/browser-controller'

If you have feedback or need assistance with the MCP directory API, please join our Discord server