DemoMotion
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@DemoMotionrecord a 30-second demo of adding a client in my SaaS, then render it as MP4"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
The AI agent makes the demo video. All of it.
One prompt in. A finished .mp4 out. No human in the edit.

This clip was not edited by a human. An agent opened the app, scrolled it, filled the signup form, submitted it, and the pipeline produced the zooms, the cursor, the captions and the cuts. Full quality MP4 · the app in the clip ships with the repo, so you can reproduce this.
DemoMotion is a Model Context Protocol (MCP) server that turns an AI agent into a motion designer. The agent drives your web app, records the session as a frame-indexed timeline, decides where to zoom, cuts the dead time, and renders a polished product-demo video — programmatically. There is no timeline to drag and no human in the edit.
It exists to collapse this:
brief → human records → human edits in a video editor → exportinto this:
"Show how to add a client in my SaaS in 30 seconds."
↓ (one MCP call)
product-demo.mp4Why this is not just another screen recorder
Loom, Screen Studio and Recordly are built for a human to record and edit. DemoMotion is built for an agent to operate the product and author the edit as data. The difference is who is driving — and that everything the agent decides is structured, inspectable, and reproducible.
The core principle: capture what happened once; decide how it should look later. The raw recording and the interaction events are the source of truth. Every creative choice — zoom, framing, cuts, speed, callouts — lives in a project.json the agent edits and re-renders, never baked into the pixels.
Loom · Screen Studio · Recordly | DemoMotion | |
Who operates the app | a human | the AI agent |
Who makes the edit | a human, in a UI | the agent, as |
Zoom / framing | manual or heuristic on record | from real UI coordinates, editable after the fact |
Reproducible | no | yes — same input, same video |
Interface | a desktop app | an MCP tool surface |
License | proprietary | MIT |
Related MCP server: AIOProductOS Studio
How it works
prompt
│
▼
AI agent ──(MCP tools)──► DemoMotion server
│
┌──────────────────────┼───────────────────────┐
▼ ▼ ▼
deterministic structured event project compiler
screen capture ───► timeline (sourceMs) ───► project.json (editable)
(CDP screencast, │
constant fps) ▼
HyperFrames compositor
(camera · cuts · overlays)
│
▼
final .mp4Two design decisions do the heavy lifting:
The capture timeline is exact by construction. Frames are laid on a constant-fps grid from CDP screencast timestamps, so
frame i ⇔ sourceMs = i / fps × 1000. Events and frames share one clock — no guessing where a click landed by analysing the video afterward.One time model for every edit. Cuts and speed ramps collapse into a single
EditListof{sourceFromMs, sourceToMs, speed}segments. Zooms and callouts are anchored to when they happened, then projected onto output time — so cutting a boring stretch repositions everything after it automatically.
Quick start
Requires Node.js 22+, ffmpeg on PATH, and a Chromium.
node --version && ffmpeg -version | head -1Pick your client. Everything below was run on the machine that wrote it unless the block says otherwise.
claude mcp add demomotion \
-e DEMOMOTION_BROWSER_CHANNEL=chrome \
-e DEMOMOTION_ALLOWED_HOSTS=localhost,127.0.0.1 \
-- npx -y demomotionConfirm with claude mcp list — it should print demomotion: npx -y demomotion - ✔ Connected.
codex mcp add demomotion \
--env DEMOMOTION_BROWSER_CHANNEL=chrome \
--env DEMOMOTION_ALLOWED_HOSTS=localhost,127.0.0.1 \
-- npx -y demomotionOr by hand in ~/.codex/config.toml:
[mcp_servers.demomotion]
command = "npx"
args = ["-y", "demomotion"]
[mcp_servers.demomotion.env]
DEMOMOTION_BROWSER_CHANNEL = "chrome"
DEMOMOTION_ALLOWED_HOSTS = "localhost,127.0.0.1"codex mcp list shows Status: enabled and masks env values — that is config state, not a health check.
gemini mcp add -s user demomotion \
-e DEMOMOTION_BROWSER_CHANNEL=chrome \
-e DEMOMOTION_ALLOWED_HOSTS=localhost,127.0.0.1 \
npx -y demomotionWrites mcpServers into ~/.gemini/settings.json. On some hosts gemini mcp list reports Disconnected for every server, including known-good ones — treat that column as unreliable rather than as a verdict on this server.
All take the identical block, only the file differs:
{
"mcpServers": {
"demomotion": {
"command": "npx",
"args": ["-y", "demomotion"],
"env": {
"DEMOMOTION_BROWSER_CHANNEL": "chrome",
"DEMOMOTION_ALLOWED_HOSTS": "localhost,127.0.0.1"
}
}
}
}Client | File |
Cursor |
|
Claude Desktop |
|
Antigravity |
|
Windsurf |
|
Cline |
|
Gemini Code Assist |
|
Claude Desktop's config usually has no mcpServers key yet — add it as a new top-level key next to the ones already there. Its logs are in ~/Library/Logs/Claude/mcp*.log.
Cursor, Claude Desktop and Antigravity shapes were read from the real config files on a machine that has them installed; Windsurf and Cline were read from the applications' own bundles. None of the six was confirmed end-to-end through its UI.
.vscode/mcp.json in the project, or your user mcp.json:
{
"servers": {
"demomotion": {
"type": "stdio",
"command": "npx",
"args": ["-y", "demomotion"],
"env": {
"DEMOMOTION_BROWSER_CHANNEL": "chrome",
"DEMOMOTION_ALLOWED_HOSTS": "localhost,127.0.0.1"
}
}
}
}Copying an mcpServers example here silently does nothing. Read from VS Code's own bundle, not confirmed through the UI.
Zed changes its settings key between releases, so rather than print one that may be wrong: Agent Panel → Add Custom Server, and enter command npx, args -y demomotion, plus the two env vars.
Any stdio MCP client works the same way. To check the server by hand:
printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}\n' | npx -y demomotionThe first line of stdout must start with {.
The two env vars matter. DEMOMOTION_ALLOWED_HOSTS is a strict allowlist that defaults to localhost, 127.0.0.1, ::1 — to record any other host, add it there or the server refuses by design. DEMOMOTION_BROWSER_CHANNEL=chrome drives an installed browser, and is required on hosts where Playwright ships no bundled Chromium (macOS 13, for one).
The first run downloads ~400 MB, dominated by the renderer's onnxruntime-node. Sessions, captures and renders land under ~/.demomotion/sessions/ (DEMOMOTION_HOME overrides); every tool result returns absolute paths.
Your first video
The repo ships a showcase app, so you can get an MP4 without having an app of your own:
pnpm showcase # serves http://127.0.0.1:4322Then one call:
{ "tool": "demo_create", "arguments": {
"url": "http://127.0.0.1:4322/signup", "title": "Signup", "pacing": "product-demo",
"steps": [
{ "action": "fill", "selector": "[data-testid=\"signup-name-input\"]", "value": "Ada Lovelace", "label": "Your name opens the workspace" },
{ "action": "fill", "selector": "[data-testid=\"signup-email-input\"]", "value": "ada@example.com", "label": "One e-mail, no verification step" },
{ "action": "click", "selector": "[data-testid=\"signup-submit\"]", "label": "The workspace is ready" },
{ "action": "wait", "ms": 1200 }
] } }
→ { "video": "…/final.mp4", "project": "…/project.json", "capture": "…/capture.json", "durationMs": 11159, … }Pass "pacing": "social" and the same steps come out 1080×1920. A step that fails returns isError naming the step index, the selector and the cause — with the capture recorded so far kept, and no browser left running.
Editing needs no re-recording: project_update the project, then render_video again. demomotion render project.json --out demo.mp4 does it from the shell.
New here? docs/GETTING-STARTED.md walks the whole path per client. When something breaks, docs/TROUBLESHOOTING.md has the real error text and the fix.
Contributors: pnpm install && pnpm --filter demomotion exec playwright install chromium && pnpm typecheck && pnpm test && pnpm build; pnpm dev:mcp runs the server from source.
The MCP tool surface
The agent sees granular, auditable tools — not a black box — and demo_create composes them into one call — so any run can be debugged, retried or partially re-rendered.
Tool | Purpose |
| Start a deterministic recording session |
| Operate the product; clicks record normalized target coordinates, fills are redacted from metadata |
| Scroll, keyboard, intentional pacing |
| Compact inventory of interactive elements with stable selectors |
| Diagnostic checkpoints |
| Persist the recording + capture manifest (constant fps) |
| Compile a capture into an editable project + auto-zoom regions |
| Edit style, zooms, the edit list (cuts + speed ramps) and callouts — no re-recording |
| Render the final H.264 MP4 |
| One call → MP4: URL + explicit step list + pacing preset; runs the whole pipeline, fails with the step named and the capture kept |
| Stop → compile → render in one call |
An agent skill in skills/demomotion/SKILL.md tells the model how to use them: objective analysis, scene planning, capture, editing heuristics, render, validation.
What works today, and what's next
DemoMotion is early and honest about it. Everything below the line is proven by execution in the test suite; everything in Roadmap is not built yet.
Working and tested
Deterministic CDP screencast capture on a constant-fps grid (frame↔time exact by construction)
Structured event timeline with normalized interaction coordinates
EditList: cuts and constant-speed ramps in one modelCamera / zoom with real easing, correct aspect ratio (no silent crop), held final frame
Synthetic cursor layer — smoothed approach, click pulse, constant size under zoom
Word-by-word captions with a restrained karaoke highlight, auto-seeded from action labels
Transitions — crossfade at every cut, plus opening and closing fades
Timed callouts anchored in source time
Real H.264 MP4 render via the HyperFrames compositor
Render telemetry off by default (see below)
Every layer above — zoom, cursor, captions, callouts — is anchored to when it happened and projected through the edit list. Cut a boring stretch and all of them follow; anything whose source instant was cut simply does not appear.
Roadmap
Voiceover (TTS). The caption schema already stores per-word timings, so real audio alignment drops in without touching the compositor.
Automatic scene detection and pacing — deciding where to cut (the
EditListcan already express it)VLM-based visual validation of the rendered output
Native desktop capture behind the same tool surface
Known limitations
A crossfade shows ~180 ms of adjacent cut material under a partly transparent clip — that is what an NLE handle is. Set
cutTransitionMs: 0for hard cuts.Cutting inside a caption drops the words after the cut; place cuts between captions.
Determinism, security & telemetry
Reproducible renders. The same
project.jsonproduces a byte-identical MP4.project.jsonis the single source of truth — nothing travels as an unvalidated CLI variable.Host allowlist. Set
DEMOMOTION_ALLOWED_HOSTSto restrict navigation. Onlyhttp/httpsare accepted.Redaction. Values sent through
browser_fillare stripped fromcapture.json. (A target app may still display them on screen — use seeded demo data and dedicated accounts.)No phoning home. HyperFrames sends anonymous render telemetry to its vendor. Because DemoMotion renders on its users' behalf, it sets
HYPERFRAMES_NO_TELEMETRY=1in the render process by default. Set the variable yourself (to any value) and DemoMotion keeps your choice.
See docs/GETTING-STARTED.md for per-client setup, docs/TROUBLESHOOTING.md for the failures this produces in practice, .env.example for every supported variable, and docs/ARCHITECTURE.md for the full design.
Repository layout
apps/mcp-server/ MCP control plane + deterministic capture + render driver
packages/compositor/ project.json → HyperFrames HTML (pure, no I/O)
packages/core/ editing heuristics + the sourceMs ⇄ outputMs bridge (EditList)
packages/schema/ shared project/action schemas (Zod)
skills/demomotion/ the agent workflow skillContributing
Issues and PRs are welcome. The test discipline is strict on purpose: every behaviour is proven by a test that was seen to fail first, and both halves of a guarantee are asserted (the abuse is rejected and the legitimate case still passes). See CONTRIBUTING.md.
License
DemoMotion source: MIT. The HyperFrames compositor on the render path is Apache-2.0. Both are permissive — DemoMotion adds no per-seat cost for the teams that adopt it.
This server cannot be deployed
Maintenance
Related MCP Connectors
Make videos and docs with your AI agent — describe what you need, every output stays editable.
Turn a product URL into a narrated cinematic demo video, launch video, or deck.
AI-powered web automation. Navigate websites using AI agents for one page or a thousand
AI-powered web automation. Navigate websites using AI agents for one page or a thousand
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI coding agents to capture screen and voice recordings, extract timestamped frames, and receive structured Markdown reports with context for bug fixing and UI feedback.17 npm18MIT

AIOProductOS Studioofficial
AlicenseAqualityBmaintenanceTurns your AI host into a product videographer — scripted screen recordings of your own web app with a gliding cursor, camera zooms, highlight callouts, captions, and branded transitions, plus marketing-grade screenshots. Automatic dark-frame cleanup and MP4/GIF export. Free, MIT, 100% local — no account, no API keys.1489 npm3MIT- AlicenseAqualityAmaintenanceYour coding agent makes the demo video — turns a storyboard.json into a narrated, captioned product-demo MP4; deterministic replay re-renders it in CI at ~$0.2337 npm7MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to create polished product demo videos by controlling a real Chromium browser, recording actions, and rendering 1080p MP4s with narration, captions, and styled overlays.1MIT