Skip to main content
Glama

web-ui-tester

Ein MCP-Server, der einer KI erlaubt, reale Webseiten schnell zu steuern und zu inspizieren – über Browsersitzungen, die zwischen Tool-Aufrufen aktiv bleiben.

Zwei Dinge machen ihn schnell. Seiten werden als Accessibility-Baum mit Element-Refs dargestellt, nicht als Screenshots oder rohes HTML, damit das Modell Dinge finden und anklicken kann, ohne Kontext für Markup zu verbrauchen oder auf Bilderkennung zu warten. Sitzungen bleiben erhalten – Cookies, Seitenzustand und Verlauf überdauern Aufrufe, sodass eine lange Interaktion aus einer Reihe günstiger Schritte besteht statt aus wiederholten Kaltstarts.

Er bringt außerdem Diagnose-Möglichkeiten auf DevTools-Niveau mit – Konsole, Netzwerk mit Antwort-Bodies, JS-Auswertung, berechnete Styles – damit die KI herausfinden kann, warum etwas kaputt ist, und nicht nur, dass es kaputt ist.

Schnellstart

claude mcp add web-ui-tester -- npx -y web-ui-tester

Mit einem Schlüssel für den integrierten Agenten (siehe [run_task](#the built-in agent)):

claude mcp add web-ui-tester \
  -e GOOGLE_GENERATIVE_AI_API_KEY=your-key \
  -- npx -y web-ui-tester

Oder in der Konfigurationsdatei eines beliebigen MCP-Clients:

{
  "mcpServers": {
    "web-ui-tester": {
      "command": "npx",
      "args": ["-y", "web-ui-tester"],
      "env": { "GOOGLE_GENERATIVE_AI_API_KEY": "your-key" }
    }
  }
}

Chromium kommt von Playwright. Falls es noch nicht installiert ist:

npx playwright install chromium

So funktioniert eine Sitzung

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)

Alles nach browser_start verwendet diese sessionId. Der Snapshot ist das zentrale Konzept:

- 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

Diese Refs gehen dann direkt in browser_click, browser_type und die übrigen Tools ein. Sie gehören zu dem Seitenzustand, der sie erzeugt hat: Nach einer Navigation oder einer DOM-Änderung erneut einen Snapshot erstellen. Wenn ein Tool eine Ref als nicht mehr gültig meldet, einen neuen Snapshot erstellen, statt erneut zu versuchen – die Meldung weist ausdrücklich darauf hin.

Die Tools, die Elemente adressieren, akzeptieren auch css oder role + name, wenn der Selektor bereits bekannt ist und ein Snapshot übersprungen werden soll.

Tools

Sessionbrowser_start (Optionen: userAgent, viewportWidth, viewportHeight, headless, baseUrl, url, model), browser_list, browser_close.

Interaktionbrowser_navigate, browser_click, browser_type, browser_press_key, browser_hover, browser_select_option, browser_scroll, browser_wait_for, browser_go_back, browser_handle_dialog.

Aktionen melden zurück, was sie verursacht haben: Navigation, neue Konsolenfehler, Request-Zähler und ein eventuell erschienener Dialog kommen mit dem Ergebnis zurück. Ein Klick, der still etwas kaputt macht, sieht dadurch nicht wie ein Erfolg aus.

Bei Dialogen ist eine Sache zu beachten. Ein alert/confirm/prompt blockiert die Seite, bis er beantwortet wird. Die Aktion, die ihn geöffnet hat, kann ihn daher nicht gleichzeitig beantworten – ein unbeantworteter Dialog wird automatisch verworfen, statt den Klick zu blockieren, und das Ergebnis sagt das auch. Um einen Dialog zu bestätigen oder ein prompt auszufüllen, wird browser_handle_dialog vor der auslösenden Aktion aufgerufen; die Antwort ist dann für den nächsten Dialog scharf.

Inspektionbrowser_snapshot (per Element eingrenzbar, über depth begrenzt, interactiveOnly, mit offset umseitig), browser_query (find via role/name, Text oder CSS – gibt Refs und Zustand zurück), browser_read_text (angezeigter Text der Seite oder eines Teilbaums), browser_snapshot (verfügbar, aber der Baum ist normalerweise das bessere Werkzeug).

Diagnosebrowser_console (Messages plus uncaught errors mit Stacks), browser_network (Status, Größen, Timings), browser_request_detail (Header, zeitliche Auflösung, Anforderungs- und Antwort-Bodies), browser_evaluate (JavaScript auf der Seite ausführen), browser_inspect_element (berechnete Styles, Box-Modell, Formularzustand).

Jedes Ergebnis ist durch ein Zeichenbudget begrenzt, und die umfangreichen (browser_snapshot, browser_read_text, Bodies) lassen sich über offset blättern, statt still abgeschnitten zu werden.

Der integrierte Agent

run_task übergibt eine Sitzung an ein schnelles Modell, das den Browser selbst steuert und berichtet:

run_task(sessionId, "Log in as demo@example.com / hunter2 and check the
                     dashboard loads without errors")

Auf das Reporting kommt es an. Es liefert ein strukturiertes Ergebnis, nicht nur Fließtext:

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

Findings stammen aus zwei Quellen, und der Unterschied ist wichtig. Der Agent ruft report_finding parallel zum Lauf auf – so liefert ein Lauf, das sein Schrittelimit erreicht, trotzdem all bisher gefundenen. Außerdem zeichnet das Harness jeden Konsolenfehler, jeden fehlgeschlagenen Request und jeden Dialog während des Laufs auf und meldet diese unerabhängig davon, ob der Agent sie erwähnt, markiert mit [observed by the harness]. Ein Modell, das einen 500erJugend oder eine Exception nicht erwähnt, kann ihn damit nicht verbergen.

Dieselbe Meldung wird als structuredContent gegen ein deklariertes Output-Schema zurückgegeben, sodass eine aufrufende KI über findings[].severity verzweigen kann, statt Text zu parsen. Eine Aufgabe kann erfolgreich sein und trotzdem Findings enthalten; success reflequeert, ob die Aufgabe erledigt ist, nicht die Sau sauber oder die Seite.

Das ist der einzige Teil, der einen API-Schlüssel benötigt. Standardmäßig wird der Latenz wegen Gemini Flash Lite verwendet; Anthropic funktioniert ebenfalls:

Standardmodell

Schlüssel

Google

gemini-flash-lite-latest

GOOGLE_GENERATIVE_AI_API_KEY

Anthropic

claude-haiku-4-5

ANTHROPIC_API_KEY

WUT_MODEL setzen, um zu wählen (anthropic, oder google:gemini-flash-latest, oder jede beliebige provider:modelId). Eine Sitzung kann das eigene über model in browser_start außer Acht, ein einzelner Aufruf über model in run_task. Jedes andere Tool funktioniert ohne Schlüssel.

HTTP-Modus

web-ui-tester --port 7399
claude mcp add --transport http web-ui-tester http://127.0.0.1:7399/mcp

In diesem Modus leben die Browsersitzungen im längerlaufenden Server statt im Client-eigenen Prozess, sie überleben also Client-Neustarts und Wiederverbindungen – reconnecte, danach derselbe sessionId, und die Seite ist noch da. GET /health meldet Sitzungs- und Verbindungszahlen.

Der Server bindet standardmäßig an 127.0.0.1, einem DNS-Rebinding-Schutz in carries. --host erweitert das, und der Server mahnt, wenn man das tut: Es gibt keine keine Authentifizierung, und jeder, der den Port erreichen kann, hat damitein Browser and JavaScript-Bots access erlangt. Hänge ihn hinter einen Proxy oder eine Firewall.

Konfiguration

| Variable | Standard | Zweck | | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | WUT_MODEL | google:gemini-flash-lite-latest | Agent-Modell für run_task, als provider[:modelId] | | GOOGLE_GENERATIVE_AI_API_KEY | – | Schlüssel für Gemini | | ANTHROPIC_API_KEY | – | Schlüssel für Anthropic | | WUT_USER_AGENT | AITester/1.0 | Standard-User-Agent für neue Sitzungen | | WUT_HEADLESS | true | Standardmodus Headless | | WUT_IDLE_TIMEOUT_MS | 1800000 | Sitzungen schliessen, die eine so lange Zeit ungenutzt sind | | WUT_MAX_OUTPUT_CHARS | 15000 | Zeichenlimit pro Tool-Ergebnis | | WUT_ACTION_TIMEOUT_MS | 5000 | Zeitüberschreitung Mood für eine einzelne Elementaktion | | WUT_AGENT_MAX_STEPS | 20 | Standard-Schrittbudget für run_task | | WUT_EXECUTABLE_PATH | – | Explizites Chromium-Binary | | PLAYWRIGHT_BROWSERS_PATH | – | Ort, an dem Playwright nach Browsern sucht |

CLI-Optionen: --port, --host, --headless / --no-headless, --idle-timeout, --version, --help.

Falls die von Playwright erwartete Chromium-Version nicht installiert ist, aber eine andere vorhanden ist, findet der Server sie auch und verwendet sie, dass er danach oft nicht scheitert – nützlich in vorgefertigten Containern. WUT_EXECUTABLE_PATH aufgehoben die Suche vollständig.

Entwicklung

npm install
npm run build
npm test          # agent loop (mocked model) + full end-to-end suite
npm run typecheck

npm test führt die Agentenschleife gegen ein Mock-Modell aus und testet dazu den gebauten Server als echten MCP-Client über beide Transports against a local fixture App – abgedeckt sind Refs, stale-ref-Handling, Diagnosistics, Session-Persistenz über Reconnects und das Freigeben inaktiver Sitzungen. npm run test:agent:live testet zusätzlich run_task against a realer Provider und überspringt den Test, wenn kein Schlüssel eingerichtet ist.

Lizenz

MIT

-
license - not tested
Not graded
quality - not tested
C
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 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.

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/hofmeister/web-ui-tester'

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