Browser-MCP Navigator
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| MCP_HOST | No | SSE bind address | 0.0.0.0 |
| MCP_PORT | No | SSE port | 3067 |
| CHROME_PATH | No | Explicit path to chrome.exe | auto |
| MCP_API_KEY | No | API key header; empty = no auth | |
| MCP_TRANSPORT | No | Transport mode: stdio (local) or sse (Docker/remote) | stdio |
| CHROME_EXTRA_ARGS | No | Extra Chrome flags | |
| Browser-MCP_HEADLESS | No | Set to 1 for headless mode | 0 |
| Browser-MCP_HUMAN_DELAYS | No | Set to 0 to remove human-like delays (faster) | 1 |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| browser_startB | Lanza (o reconecta) Chrome con CDP. Debe llamarse antes que las demas tools. |
| navigateC | Navega a una URL y espera (none|load|networkidle). Devuelve snapshot. |
| snapshotC | Captura el arbol de accesibilidad como texto compacto con refs @eN. |
| clickC | Clic humano (por coordenadas) sobre el elemento @eN. Devuelve snapshot nuevo. |
| js_clickB | JS element.click() directo — mas confiable para React SPAs y Angular. Usar cuando click() no dispara el handler (ej: botones con React 17+ delegation). |
| fillC | Enfoca @eN, limpia y escribe text. submit=True presiona Enter al final. |
| press_keyB | Presiona una tecla nombrada (Enter, Tab, ArrowDown...). ref opcional para enfocar. |
| select_optionB | Selecciona una opcion de un por value o por label visible. |
| hoverA | Mueve el mouse al centro de @eN (dispara menus/tooltips hover). |
| get_textA | Devuelve innerText del elemento @eN, o del body completo si ref es None. |
| wait_forA | Espera hasta que aparezca text en la pagina (o agota timeout_ms). |
| read_consoleA | Devuelve los mensajes de consola capturados. clear=True vacia el buffer. |
| read_networkB | Lista requests capturadas (opcional filtra por substring de URL). |
| screenshotA | Escape hatch: PNG en base64 (usa snapshot de texto por defecto, no esto). |
| current_urlA | Devuelve URL y titulo actuales (barato, sin snapshot). |
| browser_stopB | Cierra la conexion CDP. kill=True ademas termina el proceso Chrome. |
| js_evalA | Ejecuta JavaScript arbitrario en la pagina. Devuelve resultado + snapshot. ref=None → evalua Ejemplos basicos: scroll abajo: js_eval("window.scrollBy(0, 500)") drag elemento: js_eval("el.dispatchEvent(new DragEvent('dragstart',...))", ref="@e5") leer atributo: js_eval("return this.getAttribute('data-id')", ref="@e12") click forzado: js_eval("this.click()", ref="@e7") esperar async: js_eval("return await fetch('/api').then(r=>r.json())") RENDIMIENTO — operaciones en lote: Cada tool call = un round-trip LLM. Para crear/editar/extraer N elementos, escribe UN loop async en JS en lugar de llamar N veces a click/fill/js_eval. Ejemplo — rellenar y enviar un formulario 20 veces en UNA llamada: js_eval(""" (async () => { const users = [ {name:'Ana',user:'ana01',role:'Operador'}, {name:'Luis',user:'luis02',role:'Supervisor'}, ]; const set = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set; const fire = (el,v) => { set.call(el,v); el.dispatchEvent(new Event('input',{bubbles:true})); }; const results = []; for (const u of users) { document.querySelector('button.agregar, [aria-label*=gregar]').click(); await new Promise(r => setTimeout(r, 400)); const inp = document.querySelectorAll('input:not([type=checkbox])'); fire(inp[0], u.name); fire(inp[1], u.user); document.querySelector('button[type=submit], button.crear').click(); await new Promise(r => setTimeout(r, 300)); results.push(u.user); } return results; })() """) Para datasets grandes usa js_eval_loop() que inyecta items automaticamente. |
| cdp_callA | Llama cualquier metodo del protocolo CDP directamente. method — dominio.metodo, ej: "Input.dispatchKeyEvent", "DOM.querySelector" params — JSON string con los parametros, ej: '{"type":"keyDown","key":"Enter"}' use_session— True (default) para el contexto de la pagina actual; False para nivel browser Ejemplos de acciones que no tienen tool dedicada: Drag & drop real: cdp_call("Input.dispatchDragEvent", '{"type":"dragEnter",...}') Subir archivo: cdp_call("DOM.setFileInputFiles", '{"files":["/ruta/archivo.pdf"]}') Emular dispositivo: cdp_call("Emulation.setDeviceMetricsOverride", '{"width":375,...}') Interceptar red: cdp_call("Fetch.enable", '{"patterns":[{"urlPattern":"*"}]}') Geolocation: cdp_call("Emulation.setGeolocationOverride", '{"latitude":4.7,...}') |
| set_valueA | Establece el valor de un input/select usando el setter nativo de JS. Necesario para React, Vue y Angular: los inputs controlados no responden a .value= directo porque el framework sobreescribe el setter. Este tool usa Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set y dispara eventos input+change para que el framework detecte el cambio. Usar para: date pickers, spinbuttons, selects custom, inputs con validacion. |
| js_eval_loopA | Ejecuta La variable USAR ESTO en lugar de llamar js_eval/click/fill N veces para operaciones bulk. Cada tool call = un round-trip LLM. Un loop aqui = 50-100x mas rapido para N>5. Parametros:
items — lista de objetos, uno por iteracion
script — JS a ejecutar por item; puede usar await; Ejemplo — crear 20 usuarios en una sola llamada: js_eval_loop( items=[ {"name": "Ana Garcia", "user": "agarcia", "phone": "3101234567", "email": "ana@corp.com", "area": "TI", "role": "Operador"}, ... ], script=""" document.querySelector('button[aria-label*="gregar"], button.agregar').click(); await new Promise(r => setTimeout(r, 400)); const inp = document.querySelectorAll('input:not([type=checkbox]):not([type=radio])'); const s = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set; const fire = (el,v) => { s.call(el,v); el.dispatchEvent(new Event('input',{bubbles:true})); el.dispatchEvent(new Event('change',{bubbles:true})); }; fire(inp[0], item.name); fire(inp[1], item.user); fire(inp[2], item.phone); fire(inp[3], item.email); fire(inp[4], item.area); const sel = document.querySelectorAll('select')[0]; const ss = Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype,'value').set; ss.call(sel, item.role); sel.dispatchEvent(new Event('change',{bubbles:true})); document.querySelector('button[type=submit], button.crear').click(); return item.user; """ ) |
| scrollA | Desplaza la pagina o un elemento especifico. ref=None → window.scrollBy(x, y) ref=@eN → scrollIntoView del elemento + scrollBy(x, y) relativo y>0 baja, y<0 sube; x>0 derecha, x<0 izquierda. Ejemplos: scroll() — baja 400px scroll(y=-400) — sube 400px scroll(y=99999) — va al final de la pagina scroll(ref="@e5", y=0) — centra elemento en viewport |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/ingjohnfigueroablanco/Fast-browser-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server