The inspect_localhost_ui tool
VibeLens exposes exactly one tool. One tool with a small, bounded schema is called correctly far more often than a family of narrow ones — the reasoning is in ADR 0004.
Parameters#
| Parameter | Type | Default | Description |
|---|---|---|---|
url | string, required | — | Local URL such as http://localhost:3000/dashboard. A missing scheme is assumed to be http://. |
viewport | desktop | tablet | mobile | desktop | desktop 1920x1080, tablet 820x1180 at 2x, mobile 390x844 at 2x with touch emulation. |
delay | number, 0 to 15000 | 1000 | Milliseconds to wait after load, for hydration, animation or data fetching. |
fullPage | boolean | false | Capture the whole scrollable page instead of the viewport. |
What it returns#
Two MCP content blocks. First an image block containing a base64 JPEG at
quality 75, then a text block containing JSON:
{
"summary": {
"url": "http://localhost:3000/health",
"pageTitle": "Service health",
"viewport": "desktop (1920x1080)",
"fullPage": false,
"waitedMs": 1000,
"captureMs": 1253,
"consoleErrors": 1,
"consoleWarnings": 0,
"uncaughtPageErrors": 0,
"failedRequests": 1,
"domTruncated": false
},
"consoleLogs": [
{ "level": "error", "text": "Hydration failed...", "location": "http://localhost:3000/app.js:42:13" }
],
"uncaughtPageErrors": ["TypeError: Cannot read properties of undefined"],
"failedRequests": [
{ "url": "http://localhost:3000/avatar.png", "method": "GET", "failure": "HTTP 404", "status": 404 }
],
"simplifiedDOM": "<body class=\"...\">...</body>"
}The DOM snapshot comes last because it is by far the largest field: putting the diagnostics first means they survive any client-side truncation.
Limits it enforces#
| Limit | Value | Why |
|---|---|---|
| DOM snapshot | 20,000 chars | Hard cap, with an in-band marker so the model knows the tree is partial. |
| Text node | 160 chars | Long body copy adds tokens but no layout signal. |
| Attribute | 300 chars | Kills base64 blobs and generated inline data. |
| Console entries | 40 | Per capture. |
| Console message | 600 chars | Per entry. |
| Failed requests | 20 | Deduplicated by URL and failure. |
| Navigation | 30s | Bounded so a hung page cannot hang the session. |
It is read-only#
The tool is annotated readOnlyHint. It observes a page: it cannot click,
hover, type, scroll, submit a form or reach a public host. That constraint
shapes every skill in the plugin — hover and :focus-visible styles are read
from the source rather than observed, and anything behind an interaction has to
be rendered by you first.
Errors you can act on#
Every failure comes back as a tool error carrying a code and a next step, never
a stack trace: INVALID_URL, CONNECTION_REFUSED, DNS_FAILURE,
UNSAFE_PORT, TIMEOUT, BROWSER_NOT_INSTALLED, BROWSER_LAUNCH_FAILED,
UNKNOWN. Each one is documented with its cause and fix in
Troubleshooting.
Prompts that work well#
Check localhost:3000 on mobile and tell me what breaks.
Look at localhost:5173/settings - the cards aren't aligned. Fix it.
Does localhost:3000/checkout throw anything in the console?
This page looks AI-generated. Tell me why, then fix the worst of it.
The accent is just default Tailwind blue - give me a real palette.
Compare localhost:3000 on desktop vs mobile and make the nav responsive.