MCP server that lets an AI agent operate your web app, record it deterministically and render a polished product-demo MP4 — no human in the edit.
Strong tool definitions with comprehensive schemas and clear descriptions. All 15 tools have explicit input schemas with type constraints, descriptions, and parameter documentation. Naming follows verb_noun convention (session_start, browser_click, project_build). Descriptions average ~150 chars and explain WHAT, WHEN, and side effects. Key strengths: parameter constraints (min/max for numeric, format validation for URIs), security-conscious design (host allowlist, redaction of sensitive values), and composition clarity (tools chain logically). Gaps: no output schemas documented, limited error recovery guidance, no tool annotations (readOnlyHint/destructiveHint), and some descriptions could be more LLM-optimized. Error handling is implicit rather than explicit, tools don't return structured error guidance.
Click a visible element while recording. Prefer stable data-testid or accessible selectors. The selector is resolved across frames — main frame first, then the other frames in attachment order, first match wins — so a control inside an <iframe> is reachable with the same plain selector.
Fill an input while recording. BY DEFAULT the value is TYPED character by character, because a field that jumps from empty to complete in a single frame is the most rushed-looking thing in a form demo — a viewer reads typing as a person, and an instant fill as a machine. Set typeDelayMs: 0 to go back to an instant fill for values nobody wants to watch being typed: a UUID, an API token, a long opaque id. Typing lengthens the capture (roughly value.length * typeDelayMs), so budget for it when planning the demo's duration. The value is redacted from the timeline manifest either way. The selector is resolved across frames on the same rule as browser_click.
Navigate the recorded browser to a URL. Only http/https, and only to a host in AUTODEMO_ALLOWED_HOSTS (default: localhost, 127.0.0.1, ::1 — every port). A URL off the allowlist fails BY DESIGN with a message naming the host and the variable; redirects, links, fetches and WebSockets to hosts off the allowlist are blocked at the network layer and listed in session_status as blockedRequests. Do not work around it: ask the operator to extend the allowlist.
Inspect the current page and return a compact list of interactive elements with stable selector candidates. Covers EVERY frame, not just the top document: each element carries the `frameUrl` it came from, and a frame that could not be read is reported in `skippedFrames` instead of failing the call.
No output schemas documented. Tools return JSON but LLMs cannot plan downstream calls without knowing response structure. E.g., session_start, browser_inspect, session_stop lack documented return types.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). LLMs cannot distinguish safe reads from destructive writes without explicit hints. browser_click, browser_fill, session_stop, project_build, render_video should be marked destructive.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | 2026-07-28+ | v2 |
Press a keyboard key or Playwright key chord while recording.
Capture a diagnostic screenshot during the session.
Scroll the recorded page and persist the action in the timeline. When the top document has nothing left to scroll, the wheel is aimed at the largest frame that does.
Wait during a recording only when needed for an animation, network operation or intentional pacing.
Create a complete demo in one call: start a session, run a sequence of actions, stop the session, build the project, and optionally render the video.
Build a project from a capture artifact and timeline, generating an edit list, auto-zooms, and synthetic captions with per-word timing.
Update a project's metadata, styling, edit list, captions, zooms, and callouts. All fields are optional; omitted fields are left unchanged.
Render a project to a final MP4 video using HyperFrames.
Start a browser recording session. Call this before navigating the product demo.
Inspect current session duration, URL, action count, the active host allowlist and blockedRequests — every request the network policy refused (navigation, redirect, sub-resource or WebSocket), with the host and the reason. A non-empty list after a step means the page tried to reach somewhere off the allowlist.
Stop the recording session and return the capture artifact and timeline.
Error handling lacks recovery guidance. Tools do not return structured error responses with actionable next steps. E.g., browser_goto blocks off-allowlist hosts but error message format is not specified; browser_click/browser_fill do not document selector resolution failures.
project_update and demo_create have nested object parameters (output, style, zooms, editList, captions) with minimal schema documentation. Nested structures lack type definitions for inner fields, forcing LLMs to guess valid structures.
browser_wait description is minimal (18 chars: 'Wait during a recording only when needed for an animation, network operation or intentional pacing.'). Does not explain when LLM should call it vs letting async operations complete naturally.