web-ui-tester
web-ui-tester
MCP-сервер, который позволяет ИИ быстро управлять реальными веб-страницами и исследовать их в браузерных сессиях, которые остаются активными между вызовами инструментов.
Быстроту обеспечивают две вещи. Страницы представляются в виде дерева доступности со ссылками на элементы, а не скриншотов или сырого HTML, поэтому модель может находить элементы и кликать их, не тратя контекст на разметку и не дожидаясь анализа изображений. А сессии сохраняются — cookies, состояние страницы и история переживают вызовы, так что длинное взаимодействие — это серия дешёвых шагов, а не повторные холодные старты.
Кроме того, он умеет диагностику уровня DevTools — консоль, сеть с телами ответов, выполнение JS, вычисленные стили, — чтобы ИИ мог разобраться, почему что-то сломано, а не просто констатировать поломку.
Быстрый старт
claude mcp add web-ui-tester -- npx -y web-ui-testerС ключом для встроенного агента (см. run_task):
claude mcp add web-ui-tester \
-e GOOGLE_GENERATIVE_AI_API_KEY=your-key \
-- npx -y web-ui-testerИли в конфигурационном файле любого MCP-клиента:
{
"mcpServers": {
"web-ui-tester": {
"command": "npx",
"args": ["-y", "web-ui-tester"],
"env": { "GOOGLE_GENERATIVE_AI_API_KEY": "your-key" }
}
}
}Chromium поставляется через Playwright. Если он ещё не установлен:
npx playwright install chromiumКак работают сессии
browser_start → sessionId, kept alive across calls
browser_navigate → page state + snapshot with [ref=eN] handles
browser_click ref=e12 → act on what the snapshot showed you
browser_snapshot → fresh refs after the page changes
browser_close → done (or let it idle out after 30 minutes)Всё после browser_start использует этот sessionId. Снимок — главное, к чему стоит привыкнуть:
- generic [ref=e1]:
- heading "Signup" [level=1] [ref=e2]
- textbox "Name" [ref=e5]:
- /placeholder: Your name
- combobox "Plan" [ref=e7]
- button "Create account" [ref=e10]
- link "Go to second page" [ref=e12] [cursor=pointer]:
- /url: /second.htmlЭти ссылки напрямую уходят в browser_click, browser_type и остальные инструменты. Они привязаны к состоянию страницы, которое их создало: после навигации или изменения DOM сделайте новый снимок снова. Когда инструмент сообщает, что ссылка больше недействительна, делайте новый снимок, а не повторяйте попытку — об этом явно сказано в сообщении. Инструменты адресации элементов также принимают css или role + name, если вы уже знаете селектор и предпочитаете пропустить снимок.
Инструменты
Сессия — browser_start (параметры: userAgent, viewportWidth, viewportHeight, headless, baseUrl, url, model), browser_list, browser_close.
Взаимодействие — browser_navigate, browser_click, browser_type, browser_press_key, browser_hover, browser_select_option, browser_scroll, browser_wait_for, browser_go_back, browser_handle_dialog.
Действия сообщают, к чему привели: навигация, новые ошибки консоли, количество запросов и любой появившийся диалог возвращаются в результатах. Поэтому клик, который тихо что-то сломал, не выглядит как успех.
Про диалоги нужно пояснить отдельно. alert/confirm/prompt блокирует страницу, пока не получит ответ, поэтому действие, которое его открыло, не может одновременно на него ответить — неотвеченный диалог закрывается автоматически, не подвешивая клик, и в результате это будет сообщено. Чтобы принять такой диалог или заполнить поле prompt, вызовите browser_handle_dialog до действия, которое его запускает, — и ответ будет готов повешен для следующего диалога.
Инспекция — browser_snapshot (можно ограничить областью по элементу, с лимитом по depth, interactiveOnly, постранично через offset), browser_query (поиск по роли/имени, тексту или CSS — возвращает ссылки и состояние), browser_read_text (отрисованный текст страницы или одного поддерева), browser_screenshot (доступен, но дерево обычно всё равно удобнее).
Диагностика — browser_console (сообщения плюс необработанные перехваченные ошибки со стеками), browser_network (статусы, размеры, тайминги), browser_request_detail (заголовки, тайминг-разбивка, запрос и тела ответов), browser_evaluate (выполнение JS на странице), browser_inspect_element (вычисленные стили, блочная модель, состояние формы).
Каждый результат ограничен по символам, а крупные (browser_snapshot, browser_read_text, тела) разбиваются на страницы с offset, а не молча обрезаются.
Встроенный агент
run_task передаёт сессию быстрой модели, которая сама управляет браузером и возвращает отчёт:
run_task(sessionId, "Log in as demo@example.com / hunter2 and check the
dashboard loads without errors")Смысл — в отчётности. Возвращается структурированный вердикт, а не просто текст:
status: success
model: google:gemini-flash-lite-latest
Logged in and opened the dashboard. The revenue widget rendered empty.
findings (3):
[error] Request failed: GET 500 [observed by the harness]
where: https://app.example.com/api/revenue
evidence: HTTP 500
[error] Console exception on the page [observed by the harness]
where: app.js:214:9
evidence: TypeError: Cannot read properties of undefined (reading 'total')
[warning] The revenue widget shows no empty state, just blank space
where: #revenue-card
evidence: card is present but contains no textНаходки приходят из двух источников, и различие важно. Агент вызывает report_finding по ходу работы — поэтому прогон, упёршийся в лимит шагов, всё равно вернёт всё, что удалось найти к этому моменту. Затему обвязка записывает каждый показываемый в сессии console, каждый упавший запрос и каждый диалог и сообщает о них вне зависимости от того, упомянул ли их агент, с пометкой [observed by the oks]. Модель, которая пропустила 500-ю или забыла упомянуть исключение, не сможет этого скрыть.
Тот же отчёт возвращается как structuredContent по объявленной схеме вывода, поэтому вызывающий ИИ может разойти по findings[].severity, а не разбирать текст. Задача может быть успешной и содержать находки; success отражает, выполнена ли задача, а не то, была ли страница чистой.
Это единственная часть, требующая API-ключ. По умолчанию используется Gemini Flash Lite ради низкой задержки; Anthropic тоже подходит:
Модель по умолчанию | Ключ | |
|
| |
Anthropic |
|
|
Настройте WUT_MODEL, чтобы выбрать (anthropic, или google:gemine-flash-latest, или любой provider:modelId). Сессия может переопределить это через model в browser_start, а отдельный разговор — через model в run_task. Все остальные инструменты работают без ключа.
HTTP-режим
web-ui-tester --port 7399
claude mcp add --transport http web-ui-tester http://127.0.0.1:7399/mcpВ этом режиме сессии браузера живут в долго работающем сервере, а не в процессе-клиенте, поэтому они переживают перезапуски клиента и переподключения — снова подключитесь, передайте тот же sessionId, и страница всё ещё на месте. GET /health возвращает количество сессий и подключений.
По умолчанию он привязывается к 127.0.0.1, где действует защита от DNS-ребindingа. --host расширяет этот диапазон, и сервер предупреждает об этом: аутентификации не предусмотрено, и любой, кто может обратиться к серверу, может запустить браузер и выполнять через него JavaScript. Поместите его за прокси или файрволом.
Конфигурация
Переменная | По умолчанию | Назначение |
|
| Модель для |
| — | Ключ для Gemini |
| — | Ключ для Anthropic |
|
| User-Agent по умолчанию для новых сессий |
|
| Фоновый режим по умолчанию (headless) |
|
| Закрывать сессии, бездействующие так долго |
|
| Лимит символов на результат инструмента |
|
| Таймаут на одно действие с элементом |
|
| Бюджет шагов по умолчанию для |
| — | Явный исполняемый файл Chromium |
| — | Где Playwright ищет браузеры |
Флаги командной строки: --port, --host, --headless / --no-headless, --idle-timeout, --version, --help.
Если нужная Playwright ревизия Chromium не установлена, но есть другая, сервер найдёт и использует её, а не завершится ошибкой — удобно в предварительно собранных контейнерах. WUT_EXECUTABLE_PATH полностью переопределяет этот поиск.
Разработка
npm install
npm run build
npm test # agent loop (mocked model) + full end-to-end suite
npm run typechecknpm test прогоняет цикл агента на сценарной мок-модели, затем ведёт собранный сервер настоящим MCP-клиентом из обеих транспортов против локального приложения-фикстуры — покрывая ссылки (refs), обработку устаревших ссылок, диагностику, сохранение сессий при переподключениях и вычистку бездействующих сессий. npm run test:agent:live дополнительно прогоняет run_task против реального провайдера и автоматически пропускается, если ключ не задан.
Лицензия
MIT
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 Connectors
Reliable web access for AI agents: smart HTTP, rotating proxies, and full-browser rendering.
Live browser debugging for AI assistants — DOM, console, network via MCP.
Browser-backed QA with evidence and fix-ready reports for coding agents.
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/hofmeister/web-ui-tester'
If you have feedback or need assistance with the MCP directory API, please join our Discord server