chrome-devtools-mcp-ocarina
June 29, 2026 ยท View on GitHub
Synthetic health checks for a web page, written as YAML and run against a real headless Chrome through the MCP server, with no LLM. Load a page, fail on any console error or any failed request, assert the page rendered.
This drives Google's official chrome-devtools-mcp with Ocarina. A rondo is a declarative health spec you can commit and run in CI.
A health spec you can commit
The rondo reads a real headless Chrome through its own DevTools surface: the rendered page, the full console, every network request. It asserts on them directly. Load the page, fail on a console error, fail on a 4xx or 5xx, confirm the title rendered. The whole file is the spec, and the spec is the test. Point it at any URL with -e, drop it in CI, and keep it in the repo next to the thing it guards.
Prerequisites
- Ocarina:
go install github.com/msradam/ocarina@latest - Node.js (for
npx).npxfetches the Chrome DevTools MCP server and a headless Chrome on first run.
Run
git clone https://github.com/msradam/chrome-devtools-mcp-ocarina
cd chrome-devtools-mcp-ocarina
ocarina play rondos/health-check.yaml
Point it at your own site with -e:
ocarina play rondos/health-check.yaml -e url=https://your-site.example
Or use the Makefile: make smoke, make health, make test.
What each rondo does
| Rondo | What it checks |
|---|---|
rondos/smoke.yaml | Chrome is reachable and loads a page. |
rondos/health-check.yaml | The page loads, the console has no errors, no request returned 4xx or 5xx, and the page rendered its title. |
rondos/multi-page.yaml | One reusable page check, run across three pages. |
rondos/flow.yaml | A navigation flow that captures diagnostics on failure and always dumps the console. |
Reuse one check across pages (motifs)
A motif is a reusable, parameterized fragment. rondos/motifs/page-check.yaml loads a URL and asserts the rendered page contains some text. rondos/multi-page.yaml pulls it in once per page and passes the params with with::
rondo:
- name: example.com
motif: motifs/page-check.yaml
with:
url: "https://example.com"
expect_text: "Example Domain"
- name: example.org
motif: motifs/page-check.yaml
with:
url: "https://example.org"
expect_text: "Example Domain"
ocarina play rondos/multi-page.yaml
Error handling (block, rescue, always)
rondos/flow.yaml wraps a navigation flow in block, captures console and network diagnostics in rescue if a step fails, and always dumps the console as teardown:
ocarina play rondos/flow.yaml # happy path
ocarina play rondos/flow.yaml -e url=https://httpstat.us/500 # rescue fires
The block stops at the first failed step, rescue runs only on failure, and always runs either way.
Make it fail
Point the check at a page that returns an error and watch it fail and exit non-zero:
ocarina play rondos/health-check.yaml -e url=https://httpstat.us/500
How it works
No model in the loop. Each step calls a Chrome DevTools tool (navigate_page, list_console_messages, list_network_requests, evaluate_script), and expect asserts on the result, including CEL rules like !output.contains('[404]'). See the Ocarina docs.
License
MIT.