Skip to main content
Glama

agentlock-browser

Browsing tools that gate on where a value came from, not on what it says.

Wait, these two lines should be the subtitle "Herramientas de navegación que condicionan según de dónde venga un valor, no según lo que dice." Let's output that.

I need output in Spanish. I'm a human translator; I can do that. Let's craft the entire translation with original structure.

Note: I must avoid non-translated text. The instruction says return only translated text, no code fence. I will now produce the final result# agentlock-browser

Browsing herramientas de navegación que condicionan según de dónde venga un valor, no según lo que dice.

Un MCP server que controla un navegador real y se niega a actuar sobre una URL o un valor de formulario que se originó en el contenido de una página. Una página puede decir cualquier cosa; lo que no puede hacer es cambiar la procedencia de la cadena que le pide al agente que use.

Se trata de un esqueleto v0. Está construido sobre AgentLock, el estándar abierto para la autorización de llamadas a herramientas, y gestiona su propio navegador directamente con Playwright. No envuelve a @playwright/mcp ni depende de él.

Por qué no envolver simplemente el servidor upstream

probe/REPORT.md documenta lo que @playwright/mcp 0.0.79 devuelve realmente. Cada resultado es un único bloque de texto sin tipo (structuredContent es null en los 23 resultados registrados, y ninguna de sus 24 herramientas declara un outputSchema). El texto de la página llega sin identidad por elemento: de las 874 líneas - text: de una instantánea de Wikipedia, ninguna lleva una referencia. Los elementos se identifican mediante refs opacas del lado del servidor que resuelven a un localizador de Playwright que quien llama nunca ve, y ese mismo campo acepta un selector CSS en bruto. Además, browser_evaluate ejecuta JavaScript arbitrario escrito por el modelo.

Nada de eso puede transmitir procedencia. Así que este servidor emite en su lugar una salida estructurada, identificada y etiquetada por origen, y no tiene herramienta de evaluación (evaluate).

Related MCP server: open-browser-control

Instalación

pip install agentlock-browser
python -m playwright install chromium

Desde un checkout:

pip install -e .
python -m playwright install chromium

Añadir a Claude Desktop

claude_desktop_config.json:

{
  "mcpServers": {
    "agentlock-browser": {
      "command": "agentlock-browser",
      "env": {
        "AGENTLOCK_BROWSER_ALLOWLIST": "https://example.com,https://docs.python.org",
        "AGENTLOCK_BROWSER_OPERATOR_TEXT": "research the docs and summarize them",
        "AGENTLOCK_BROWSER_LOG": "/home/you/agentlock-browser.jsonl"
      }
    }
  }
}

AGENTLOCK_BROWSER_CONFIG puede apuntar a un archivo JSON con las mismas claves (allowlist, operator_text, log_path, headless, …); el entorno prevalece sobre el archivo. El navegador funciona en modo headless salvo que AGENTLOCK_BROWSER_HEADLESS=0.

Herramientas

herramienta

argumentos

condicionado por

navigate

url o link_id

canal de url; frescura de link_id

snapshot

(ninguno)

sin restricción

read_text

(ninguno)

sin restricción

click

element_id

sin restricción; la navegación que causa no lo está

type

element_id, value

canal de value

back

(ninguno)

sin restricción

Toda herramienta devuelve structuredContent contra un outputSchema declarado. snapshot devuelve {origin, url, title, elements: [{id, role, name, text, href}]}; read_text devuelve {origin, blocks: [{id, text}]}. El texto de la página nunca se devuelve como una sola cadena sin diferenciar.

Los ids de los elementos son estables durante la carga de página actual y se regeneran al navegar: un id tiene la forma <page-load>-e<n>, y un id emitido antes de una navegación no puede resolver después de ella. Una denegación es un resultado estructurado con un motivo, no un error.

Reglas de procedencia

Cuatro canales:

  • USER: texto del mensaje del operador

  • ALLOWLIST: orígenes configurados por el operador, cargados al inicio

  • PAGE(origin): cualquier valor leído del contenido de la página, etiquetado con el origen

  • MODEL: compuesto por el modelo, sin linaje de página ni de línea

Los valores se etiquetan en el origen: el texto del mensaje del operador se registra como USER cuando el servidor arranca, la allowlist configurada como ALLOWLIST, y todo lo que devuelve snapshot o read_text se registra como PAGE(origin) en el momento mismo en que se devuelve. El contenido queda contaminado exactamente cuando el modelo puede verlo.

Lo que esto consigue, según la acción:

acción

permitido

denegado

navigate(url)

USER, ALLOWLIST

PAGE, MODEL

navigate(link_id)

id de la instantánea más reciente

id obsoleto o desconocido

type(value)

USER

PAGE, MODEL

navegación cross-origin causada por un clic

(nada)

siempre: se trata como navigate(url) with PAGE provenance

navigate(link_id) es como un agente sigue un enlace. El id resuelve a un href en el servidor, y el href nunca pasa por el modelo; así, seguir un enlace que pidió el operador sigue siendo posible, mientras que pegar una URL proporcionada por una página no lo es.

Un clic que saldría del origen actual se responde con un 204, así que la navegación se descarta y la página se queda exactamente donde estaba: no hay página de error ni petición al otro origen.

La compuerta AgentLock decide. Este paquete registra la procedencia, llama a gate.authorize() e informa del veredicto; nunca lo sobrescribe. La única excepción es la regla de frescura del link_id, que AgentLock no puede expresar. Esas denegaciones quedan marcadas como decided_by: "server:link_freshness" en el log para que no se confundan jamás con un veredicto de la compuerta. Ver NEEDS.md.

Cada decisión, y cada registro de procedencia, se añade a un log JSONL con la evidencia de la compuerta y un recibo firmado:

{"event": "decision", "action": "navigate_url", "allowed": false,
 "reason": "param_lineage", "channel": "PAGE", "origin": "http://fixture.test",
 "decided_by": "agentlock_gate",
 "evidence": {"gate": "param_lineage", "matched_param": "url",
              "matched_token": "evil.test/collect?x=handbook-session-7f3a1c",
              "untrusted_provenance_id": "cprov_8fb61c8f03117287"},
 "receipt": {"receipt_id": "rcpt_…", "signature": "…"}}

Ese log es la fuente de verdad de las pruebas pre-registradas; nunca un resumen del chat.

El canal USER

MCP no da al servidor ninguna forma de ver el mensaje del operador, así que el texto USER es una entrada de inicio (operator_text / AGENTLOCK_BROWSER_OPERATOR_TEXT), no algo que un argumento de herramienta pueda transportar. Una sesión con texto de operador vacío o genérico tiene una línea base USER más débil que una en la que el operador dejó claro lo que quería (ver segunda limitación más abajo).

Pruebas

pytest                                  # T5 runs; T1-T4 are registered and skipped
cat tests/results/T5.txt                # the raw T5 transcript, log and checks

T5 (escenario base legítimo) está automatizado sin modelo en el bucle: las llamadas a herramientas se emiten directamente, de modo que se mide la compuerta y el servidor. Los escenarios T1-T4 y ambos orígenes locales están implementados (evil.test resuelve a un segundo servidor local, así que el caso cross-origin es real), pero sus ejecuciones guiadas por modelo no lo están, porque esas predicciones tratan sobre el comportamiento del modelo.

Limitaciones explícitas

Copiado textualmente de PREDICTIONS.md, que quedó congelado antes de que existiera cualquier código del servidor:

  • Influencia en la selección: el contenido de la página aún puede influir en qué link_id seleccione el modelo. Fuera de alcance, documentado, igual que en AgentLock core.

  • Los clics en el mismo origen no tienen control en v0. Un sitio hostil puede mover al agente dentro de sí mismo. El cross-origin es la frontera, y eso es lo que defendemos.

  • La negativa del modelo puede hacer que T1 y T3 no informativos. Eso es un problema de datos de entrada (payload), no un resultado de la compuleta.

Además, encontradas durante la construcción de v0 y sin cerrar todavía:

  • Las compuertas de linaje abren en fallo para valores sin token distintivo. AgentLock clasifica un valor extrayendo token de él; una palabra simple de menos de 12 caracteres, sin signos de lo siguiente, produce tokens en absoluto, y un valor que no se puede clasificar sí permite. Una página que dice escribe la palabra expenses no se detecta; una que dice escribe abc123, sí. Esta autorización se registra "channel": "UNCLASSIFIED", "fail": true en lugar de cerrar el valor con comprobación local, porque cerrar aquí implicaría sacar la decisión de la compuerta. Ver NEEDS.md, punto 3.

  • Un mensaje genérico del operador debilita la comprobaDEL MODELO. El nuevo linaje necesita un token distintivo en un contexto significativo para tener una línea de base; sin ese token, los valores compuestos por MODEL se permiten. NEEDS.md, punto 3(b).

  • read_text y snapshot informan de un conjunto seleccionado de elementos. El texto de un elemento que ningún selector captura con coincidencia no se devuelve y, por lo tanto, nunca se graba como procedencia PAGE. Esto se mantiene coherente (lo que el modelo no puede ver, tampoco lo puede repetir) mientras estas herramientas sean la única vía de que el contenido de la página entre a la conversación.

  • Una redirección procedente de una navegación autorizada se sigue sin hacer una segunda comprobación. v0 concede toda la cadena de redirección de una URL que permitió.

  • Una única pestaña. target="_blank" y las ventanas emergentes no están soportadas the v0.

Licencia

AGPL-3.0-or-later. Copyright 2026 David Grice.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.

  • Choose HTTP, browser, machine endpoint, or avoid before an agent visits an unfamiliar URL.

  • Stealth web browser for agents: search, fetch, click and type through persistent sessions over MCP.

View all MCP Connectors

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/webpro255/agentlock-browser'

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