agentlock-browser
agentlock-browser
Инструменты для работы с браузером, которые проверяют, откуда взялось значение, а не что оно говорит.
MCP-сервер, который управляет настоящим браузером и отказывается действовать по URL или значению формы, полученному из содержимого страницы. Страница может сказать что угодно; но она не может изменить происхождение строки, которую просит использовать агента.
Это скелет версии v0. Он построен на AgentLock — открытом стандарте авторизации вызовов инструментов — и управляет браузером напрямую через Playwright. Он не оборачивает @playwright/mcp и не зависит от него.
Почему не просто обернуть вышестоящий сервер
В probe/REPORT.md зафиксировано, что на самом деле возвращает @playwright/mcp 0.0.79. Каждый результат — это один нетипизированный текстовый блок (structuredContent равен null во всех 23 записанных результатах, и ни один из его 24 инструментов не объявляет outputSchema). Текст страницы приходит без идентичности отдельных элементов: из 874 строк - text: в снимке Wikipedia ни одна не содержит ссылку. Элементы именуются непрозрачными серверными ссылками, которые разрешаются в локатор Playwright, который вызывающий никогда не видит, и то же поле принимает сырой CSS-селектор. А browser_evaluate выполняет произвольный JavaScript, написанный моделью.
Ничто из этого не может нести происхождение. Поэтому этот сервер вместо этого выдаёт структурированный, идентифицированный, помеченный происхождением вывод и не имеет инструмента evaluate.
Related MCP server: open-browser-control
Установка
pip install agentlock-browser
python -m playwright install chromiumИз клонированного репозитория:
pip install -e .
python -m playwright install chromiumДобавление в 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 может указывать на JSON-файл с теми же ключами (allowlist, operator_text, log_path, headless, …); переменная окружения имеет приоритет над файлом. Браузер работает в headless-режиме, если не задано AGENTLOCK_BROWSER_HEADLESS=0.
Инструменты
инструмент | аргументы | проверяется на |
|
| канал |
| (нет) | без проверки |
| (нет) | без проверки |
|
| без проверки; вызванная им навигация — нет |
|
| канал |
| (нет) | без проверки |
Каждый инструмент возвращает structuredContent в соответствии с объявленной outputSchema. snapshot возвращает {origin, url, title, elements: [{id, role, name, text, href}]}; read_text возвращает {origin, blocks: [{id, text}]}. Текст страницы никогда не возвращается как одна недифференцированная строка.
Идентификаторы элементов стабильны для текущей загрузки страницы и пересоздаются при навигации: идентификатор имеет вид <page-load>-e<n>, и идентификатор, созданный до навигации, не может быть разрешён после неё. Отказ — это структурированный результат с причиной, а не ошибка.
Правила происхождения
Четыре канала:
USER: текст из сообщения оператора
ALLOWLIST: настроенные оператором источники, загружаемые при запуске
PAGE(origin): любое значение, прочитанное из содержимого страницы, помеченное источником
MODEL: составлено моделью, без происхождения от страницы или пользователя
Значения помечаются в источнике: текст сообщения оператора записывается как USER при запуске сервера, настроенный список разрешений — как ALLOWLIST, а всё, что возвращают snapshot или read_text, записывается как PAGE(origin) в момент возврата. Контент становится заражённым ровно тогда, когда модель может его увидеть.
Что это даёт для каждого действия:
действие | разрешено | запрещено |
| USER, ALLOWLIST | PAGE, MODEL |
| id из самого последнего снимка | устаревший или неизвестный id |
| USER | PAGE, MODEL |
межсайтовая навигация, вызванная кликом | (ничего) | всегда: рассматривается как |
Без проверки в v0: snapshot, read_text, back и клики в пределах того же источника.
navigate(link_id) — это способ агента перейти по ссылке. Идентификатор разрешается в href на стороне сервера, и href не должен проходить через модель, поэтому переход по ссылке, которую запросил оператор, остаётся возможным, а вставка URL, предоставленного страницей, — нет.
Клик, который покинул бы текущий источник, получает ответ 204, поэтому навигация отбрасывается, и страница остаётся ровно там, где была: ни страницы ошибки, ни запроса к другому источнику.
Решение принимает шлюз AgentLock. Этот пакет записывает происхождение, вызывает gate.authorize() и сообщает вердикт; он никогда не переопределяет его. Единственное исключение — правило свежести идентификатора ссылки, которое AgentLock не может выразить. Такие отказы помечаются в журнале как decided_by: "server:link_freshness", чтобы их никогда не путали с вердиктом шлюза. См. NEEDS.md.
Каждое решение и каждая запись о происхождении добавляются в JSONL-журнал с доказательствами шлюза и подписанной квитанцией:
{"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": "…"}}Этот журнал — источник истины для предварительно зарегистрированных тестов, а не сводка чата.
Канал USER
MCP не даёт серверу возможности увидеть сообщение оператора, поэтому текст USER — это входные данные при запуске (operator_text / AGENTLOCK_BROWSER_OPERATOR_TEXT), а не то, что может нести аргумент инструмента. Сессия с пустым или шаблонным текстом оператора имеет более слабую базовую линию USER, чем та, где оператор указал, чего он хочет (см. второе ограничение ниже).
Тесты
pytest # T5 runs; T1-T4 are registered and skipped
cat tests/results/T5.txt # the raw T5 transcript, log and checksT5 (легитимная базовая линия) автоматизирован без участия модели: вызовы инструментов выполняются напрямую, поэтому измеряются шлюз и сервер. Фикстуры T1–T4 и оба локальных источника реализованы (evil.test разрешается во второй локальный сервер, так что межсайтовый случай реален), но их запуски под управлением модели — нет, потому что эти прогнозы касаются поведения модели.
Названные ограничения
Скопировано дословно из PREDICTIONS.md, который был заморожен до того, как существовал какой-либо код сервера:
Влияние выбора: содержимое страницы всё ещё может влиять на то, какой link_id выберет модель. Вне области действия, задокументировано, как в ядре AgentLock.
Клики в пределах того же источника не проверяются в v0. Враждебный сайт может управлять агентом внутри себя. Межсайтовый переход — это граница, которую мы защищаем.
Отказ модели может сделать T1 и T3 неинформативными. Это проблема полезной нагрузки, а не результат шлюза.
Обнаружено при создании v0 и ещё не закрыто:
Проверки происхождения открываются вхолостую для значений без отличительного токена. AgentLock классифицирует значение, извлекая из него токены; обычное слово короче 12 символов без цифр или знаков препинания не даёт ни одного, и значение, которое нельзя классифицировать, разрешается. Страница, которая говорит введите слово
expenses, не ловится; та, что говорит введитеabc123, — ловится. Такое разрешение записывается как"channel": "UNCLASSIFIED", "fail_open": true, а не закрывается локальной проверкой, потому что закрытие здесь переместило бы решение за пределы шлюза. Пункт 3 вNEEDS.md.Шаблонное сообщение оператора ослабляет проверку MODEL. Для новизны происхождения нужен отличительный токен в авторитетном контексте, чтобы вообще была базовая линия; без него значения, составленные моделью, разрешаются. Пункт 3(b) в
NEEDS.md.read_textиsnapshotсообщают о выбранном наборе элементов. Текст в элементе, который не соответствует ни одному селектору, не возвращается и поэтому никогда не записывается как PAGE. Это остаётся согласованным (что модель не может видеть, то не может и повторить) только до тех пор, пока эти инструменты — единственный способ попадания содержимого страницы в разговор.Перенаправление с разрешённой навигации выполняется без второй проверки. v0 разрешает цепочку перенаправлений URL, который он разрешил.
Одна вкладка.
target="_blank"и всплывающие окна не обрабатываются в v0.
Лицензия
AGPL-3.0-or-later. Copyright 2026 David Grice.
This server cannot be installed
Maintenance
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
- AlicenseAqualityAmaintenanceProvides an MCP-native agent browser that enables autonomous agents to perceive and interact with web pages through stealth browsing, identity borrowing, and WAAP detection.9MIT
- AlicenseAqualityDmaintenanceEnables AI agents to control the user's Chrome or Firefox browser, leveraging existing sessions for tasks requiring authentication and user handoff.181715MIT
- FlicenseNot gradedqualityBmaintenanceHosted remote MCP for AI agent browser approval. Provides structured tools for page approval workflows, session management, and audit receipts.
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to securely control a user's existing signed-in Chrome browser through isolated tab groups, with strict per-session ownership and no cookie or token exposure.2ISC
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- 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/webpro255/agentlock-browser'
If you have feedback or need assistance with the MCP directory API, please join our Discord server