Making a test a list of JSON actions removes the part that usually stops people writing end-to-end tests — there is no framework to learn and no build step, so a generated test is also a reviewable one. The visual verification path is the other draw: after the actions finish the runner captures a screenshot and returns its hash, so the model checks what rendered rather than trusting an assertion.
An end-to-end test runner whose test format is a JSON list of actions — `goto`, `type`, `click`, `assert_text`, `screenshot` — with an MCP server on top so an assistant can write and execute those tests for you. It drives a real browser, either a Chrome you already have running on a debug port, a single Obscura binary, or a Docker pool for parallel runs.
- Write and run: `e2e_create_test` and `e2e_create_module` produce test files, `e2e_run` executes all tests or one suite, `e2e_list` shows what exists
- See what the browser saw: `e2e_capture` screenshots any URL, `e2e_screenshot` retrieves one by hash, and `e2e_analyze` extracts a page's interactive elements, forms and headings and emits a test scaffold from them
- Debug a failure: `e2e_network_logs` queries the network traffic for a run and `e2e_learnings` reports stability insights built up across runs
- Go from a bug report to a test: `e2e_issue` fetches an issue and generates tests from it
- Run the dashboard and the environment: `e2e_dashboard_start`, `e2e_dashboard_stop`, `e2e_dashboard_restart`, `e2e_pool_status`, `e2e_app_pool_status`
- Keep state between tests: `e2e_vars` manages SQLite-backed project variables, `e2e_neo4j` manages the optional knowledge graph
Nothing beyond npm and a Chromium-family browser. The package is `@matware/e2e-runner` (1.5.1 in package.json; server.json publishes 1.5.0 for npm and a Docker image). The MCP entry point is `e2e-runner-mcp`, added with `claude mcp add --transport stdio --scope user e2e-runner -- npx -y -p @matware/e2e-runner e2e-runner-mcp`, or installed as a Claude Code plugin. Point it at a browser with `CHROME_POOL_URL` and `POOL_DRIVER`, or let the Docker pool start itself. Docker is only needed for the parallel pool, and that path also needs `baseUrl` set to `http://host.docker.internal:3000` so the container can reach your app. Pool start and stop are CLI-only, not exposed over MCP.
One command — npm install --save-dev @matware/e2e-runner
