npm @tandryukha/aidemostdioMITupdated 27d ago
Tell your coding agent "record a 45s demo of the checkout flow" โ get back a polished MP4 with voiceover, synced captions, and auto-zoom. Any MCP-capable agent (Claude Code, Codex CLI, Gemini CLI) writes one storyboard.json; the headless engine drives a real Chrome, records a deterministic replay, voices it, captions it, and trims the dead time. Because the replay is deterministic, the demo re-renders itself in CI when the product changes โ no re-recording, no API key, about $0 a render.
What can you do with aidemo?
aidemo โ your coding agent makes the demo video
aidemo.top ยท watch a real 51s output โถ ยท authoring guide ยท render in CI
Tell your coding agent "record a 45s demo of the checkout flow" โ get back a
polished MP4 with voiceover, synced captions, and auto-zoom. Any MCP-capable
agent (Claude Code, Codex CLI, Gemini CLI) writes one storyboard.json; the
headless engine drives a real Chrome, records a deterministic replay, voices
it, captions it, and trims the dead time. Because the replay is deterministic,
the demo re-renders itself in CI when the product changes โ no re-recording,
no API key, about $0 a render. An open-source (MIT) alternative to Screen
Studio, Clueso, or Demosmith for when you'd rather your coding agent make the
demo.
Install: Claude Code /plugin marketplace add tandryukha/aidemo ยท CI uses: tandryukha/aidemo@stable ยท CLI npx -y @tandryukha/aidemo ยท Homebrew brew install tandryukha/aidemo/aidemo
Published on the GitHub Marketplace, npm, a Homebrew tap, and the MCP Registry.
Real output โ a ~51 s self-narrated tour of Wikipedia (portal search โ
Ada Lovelace โ focus-zoom โ click through to the Analytical Engine โ glide
scroll), authored by Claude from one storyboard.json and recorded as a
deterministic replay. The preview GIF is silent;
watch the full version with narration โถ.
Three ways to use it
- From your coding agent โ the fastest path. In Claude Code:
/plugin marketplace add tandryukha/aidemothen/plugin install record-demo@aidemo(bundles the skill and the MCP server). In Codex / Gemini / any MCP agent:npx -y github:tandryukha/aidemo#stable repo-init. Then just say "record a 45s demo of <flow>" and the agent authors + renders it. - Locally, free & offline โ
AIDEMO_TTS_PROVIDER=local aidemo render <dir> --headless. An in-process voice model + script-timed captions mean no API key, ~$0, fully offline. See docs/LOCAL_MODELS.md. - In CI, self-maintaining โ drop
uses: tandryukha/aidemo@stableinto a workflow. When the product changes, it replays the committed storyboard and commits fresh media โ no key, no LLM tokens, ~$0 on free runner minutes. See docs/CI.md.
Free & open source. MIT-licensed. Runs on GitHub's free Actions tier, or fully local at $0 with the in-process voice โ no API key, no cloud upload, no telemetry. Works against localhost and auth-walled apps (your own Chrome).
From one sentence to a narrated MP4
You type a sentence, the agent writes an artifact you can read and edit, the engine records and cuts it:
1 ยท What you type โ one line to any MCP-capable agent (Claude Code here):
claude "record a 45s demo touring Wikipedia: search for Ada Lovelace,
open the Analytical Engine, then glide down the article"
2 ยท What the agent authors โ a plain, editable storyboard.json (excerpt:
narration + a fixed browser action-spec, side by side โ no generated code):
{
"title": "A quick tour of Wikipedia",
"zoom": {}, // Screen-Studio-style auto-zoom
"scenes": [
{ "id": "search",
"narration": "Start at the Wikipedia portal and search for Ada Lovelace.",
"actions": [
{ "op": "goto", "url": "https://www.wikipedia.org/" },
{ "op": "type", "target": { "selector": "#searchInput" }, "text": "Ada Lovelace" },
{ "op": "click", "target": { "selector": "button[type=submit]" } } ] },
{ "id": "engine",
"narration": "Her notes on Babbage's Analytical Engine hold the first computer program.",
"actions": [
{ "op": "focus", "target": { "selector": "#firstHeading" } },
{ "op": "click", "target": { "selector": "a[href*='Analytical_Engine']" } },
{ "op": "scrollBy", "dy": 900, "easing": "glide" } ] }
]
}
3 ยท How it's recorded + cut โ aidemo render drives a real Chrome (smooth
animated cursor, human-cadence typing, auto-zoom), then trims the dead time and
syncs to the narration:
storyboard.json
โ voice OpenAI / ElevenLabs / local TTS โ audio/narration.mp3 + voice.json
โ record drives Chrome, animated cursor โ recordings/raw.{webm,mp4} + timeline.json
โ captions Whisper word timestamps โ generated/captions.{srt,vtt,cues.json}
โ compose trim idle ยท sync ยท auto-zoom ยท cards ยท caption ยท mux โ output/final-demo.mp4
4 ยท What you get โ output/final-demo.mp4, plus a README-ready GIF
(aidemo gif) and named stills (aidemo stills) from the same take. UI changed?
Re-run against the same storyboard โ no re-recording by hand.
The design goal: demos that look human-made and snappy, not like an AI clicking around and waiting between screenshots โ by separating authoring (slow, one-time โ figure out the flow) from recording (a fast deterministic replay with a smooth animated cursor).
What teams render with it
- GitHub README demos โ
aidemo gif demos/onboarding, drop the autoplaying GIF into the readme (the GIFs on this page are exactly that). - Landing-page hero videos โ the muted-autoplay MP4 on aidemo.top is a rendered demo, poster frame and all.
- Release / what-shipped demos โ narrate the new feature, then
gh release upload v1.4.0 demos/whats-new/output/final-demo.mp4. - Customer & prospect demos โ personalized flows against your real app: localhost, auth walls, your own logged-in Chrome; nothing leaves the machine.
Render in CI (self-maintaining demos)
Commit a storyboard and the aidemo GitHub Action keeps its demo media in sync โ a fresh narrated, captioned MP4 (and GIF) on every relevant change. Deterministic replay + a local voice mean no API key, no LLM tokens, about $0 (just free runner minutes). It's the loop a screen recorder can't run: your demo maintains itself.
# .github/workflows/demo.yml
- uses: actions/checkout@v4
- run: sudo apt-get update && sudo apt-get install -y ffmpeg # ubuntu ships Chrome, not ffmpeg
- uses: tandryukha/aidemo@stable
with:
demos: demos/*
tts: local # in-process voice โ no keys, no tokens
gif: "true"
Full recipe, templates (auto-commit / PR-comment / cron-refresh), and the always-fresh-embeds trick: docs/CI.md, docs/EMBEDS.md, docs/recipes/.
Quick start (self-contained smoke test)
A bundled fixture store (search โ results โ cart โ checkout) that renders a finished demo with zero external dependencies:
npm install # Node 20+, system Chrome, ffmpeg on PATH
node examples/local-demo/serve.mjs # terminal 1: fixture on :8787
node bin/aidemo.mjs render examples/local-demo --headless # terminal 2
open examples/local-demo/output/final-demo.mp4 # xdg-open on Linux, start on Windows
Voice/captions need OPENAI_API_KEY in .env โ or AIDEMO_TTS_PROVIDER=local
(no key, offline), or OPENAI_BASE_URL at a local server. See
docs/LOCAL_MODELS.md. No Playwright browser download is
needed โ the engine uses your system Chrome (channel: "chrome").
The bundled fixture rendered end-to-end โ narrated, captioned, auto-trimmed. Silent preview; full version โถ.
CLI
Each step is independently runnable and re-runnable โ regenerate voice without re-recording, recompose without re-transcribing, etc.
aidemo init <name> # scaffold demos/<name>/ with a starter storyboard
aidemo voice <dir> # per-scene TTS โ narration.mp3 + voice.json
aidemo record <dir> # drive Chrome โ raw video + timeline.json
aidemo probe <dir> # record-only dry run (verify selectors), no key needed
aidemo captions <dir> # Whisper โ captions.{srt,vtt,cues.json} (--offline for no network)
aidemo compose <dir> # trim + sync + zoom + cards + caption + mux โ final-demo.mp4
aidemo gif <dir> # final-demo.mp4 โ README-ready GIF (autoplays on GitHub)
aidemo render <dir> # voice โ record โ captions โ compose
aidemo guide # print the canonical authoring guide
aidemo doctor # check Node, ffmpeg, Chrome, voice endpoint
Add --headless for CI/fixtures; omit it for real sites that need your
logged-in session. --profile <dir> picks the Chrome user-data dir;
--capture native|obs switches to high-fidelity screen capture. voice/render
skip TTS for unchanged scenes, and record salvages a failed take (keeps
the footage + drops a screenshot/frame-dump in logs/).
Agent interface (MCP)
aidemo mcp runs a stdio MCP server (no network listener) exposing the engine
to any MCP client. The Claude Code plugin bundles it; aidemo repo-init registers
it agent-neutrally (.mcp.json for Claude Code, .gemini/settings.json for
Gemini; codex mcp add aidemo -- npx -y github:tandryukha/aidemo#stable mcp for
Codex).
- Authoring tools โ
get_authoring_guideserves docs/AUTHORING.md version-matched from the engine (can't go stale);get_storyboard_schema,validate_storyboard,init_demo,doctor. - Pipeline tools run as jobs โ
probe/record/render/voice/captions/compose/gifreturn ajobIdimmediately;job_statusreports stage, per-scene progress, and (on failure) the screenshot/frame-dump paths.
Why it's built this way
- Deterministic replay, not an LLM in the loop. The recording runs a fixed action-spec at full speed, so the video is smooth. The agent only authors the storyboard (and confirms selectors once), never during capture.
- Declarative action-spec + fixed player (not generated
spec.ts). Safer, editable, and it emits a timeline for free โ compose fits each scene's video to its narration by trimming/speeding only the idle parts, freeze-holding a static page for any remainder instead of ugly slow-motion. - Captions via overlaid PNGs, not libass. Many ffmpeg builds lack
subtitles/drawtext; aidemo rasterizes each caption with headless Chrome and overlays it with time-gatedenableโ works on any ffmpeg withoverlay. - Cinematic polish is compose-time, not record-time โ a bad zoom is a recompose, never a re-record. See docs/POLISH.md.
Deeper docs
- docs/AUTHORING.md โ the canonical storyboard schema, action vocabulary, and demo-director principles (served by the engine).
- docs/LOCAL_MODELS.md โ no-key rendering: in-process Kokoro voice, local speech servers (speaches), ElevenLabs, offline captions.
- docs/POLISH.md โ auto-zoom, scroll easing, music ducking, intro/outro cards, motion blur, cursor control, native/OBS high-fidelity capture.
- docs/CHATGPT_APPS.md โ recording ChatGPT Apps SDK
widgets (dedicated profile, nested iframes,
waitForWidget). - docs/CI.md ยท docs/EMBEDS.md ยท docs/recipes/ โ CI rendering, always-fresh embeds, agent-in-CI recipes.
Setup
Prereqs: Node 20+, Google Chrome, ffmpeg + ffprobe on PATH.
Developed and tested on macOS; Linux works for the default (Playwright) capture
and --capture obs. Run aidemo doctor to check your setup.
npm install
cp .env.example .env # add OPENAI_API_KEY, or use AIDEMO_TTS_PROVIDER=local (no key)
Project layout (per demo)
demos/<name>/ โ your working area (untracked; scaffold with `aidemo init`)
input/ brief.md
generated/ storyboard.json timeline.json captions.{srt,vtt,cues.json}
recordings/ raw.webm (or raw.mp4 for native/OBS capture)
audio/ scene-*.mp3 narration.mp3 voice.json
output/ final-demo.mp4
logs/ <command>.log fail-<scene>-<n>.{png,json} (on a failed action)
Security & trust
- No telemetry, no analytics, no install-time scripts (
package.jsonhas nopostinstall/preinstall). - Network is user-initiated only:
api.openai.com(onlyvoice/captions, your key โ or a local server viaOPENAI_BASE_URL),api.elevenlabs.io(opt-in),huggingface.co(download-only, once, forAIDEMO_TTS_PROVIDER=local), andgithub.com(your owngh, foraidemo feedback). Recording/composing are fully local. The MCP server is stdio-only โ no listener. - Small, auditable surface: ~20 source files, 7 runtime deps, MIT. Pin an
immutable ref if you're wary of the moving
#stabletag:npx -y github:tandryukha/aidemo#v0.8.0. - Full detail: docs/LOCAL_MODELS.md ยท report vulnerabilities privately per SECURITY.md.
Roadmap
- Comments on the video (pause & comment) and in-place transcript editing:
captions map to scenes, so editing a line marks that scene dirty and
aidemo voice --scene <id>+composeregenerates only the delta. - Web UI, project history, brand kits, changelog integrations.
- Hosted public MCP (see docs/plans/public-mcp.md).
Shipped: the GitHub Action (CI re-render), cinematic polish (auto-zoom, scroll easing, music ducking, intro/outro cards, motion blur, post-hoc cursor control), native/OBS capture, the agent-neutral MCP server + authoring guide, ElevenLabs and in-process local voice providers, and the Claude Code plugin.
Contributing
Issues and PRs welcome โ see CONTRIBUTING.md for dev setup, the
smoke test, and the DCO sign-off requirement. Recording-session feedback has a fast
path: aidemo feedback demos/<name> pre-fills a structured issue.
License
MIT ยฉ Andrii Taran
Install
Add aidemo to your client. Pick the one you use.
claude mcp add aidemo -- npx -y @tandryukha/aidemocodex mcp add aidemo -- npx -y @tandryukha/aidemoamp mcp add aidemo -- npx -y @tandryukha/aidemo{
"mcpServers": {
"aidemo": {
"command": "npx",
"args": [
"-y",
"@tandryukha/aidemo"
]
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"aidemo": {
"command": "npx",
"args": [
"-y",
"@tandryukha/aidemo"
]
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
code --add-mcp '{"name":"aidemo","command":"npx","args":["-y","@tandryukha/aidemo"]}'Or add the block manually to `.vscode/mcp.json` under `servers`.
{
"mcpServers": {
"aidemo": {
"command": "npx",
"args": [
"-y",
"@tandryukha/aidemo"
]
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
{
"mcpServers": {
"aidemo": {
"command": "npx",
"args": [
"-y",
"@tandryukha/aidemo"
]
}
}
}Add to `cline_mcp_settings.json` via the MCP Servers panel.
{
"mcpServers": {
"aidemo": {
"command": "npx",
"args": [
"-y",
"@tandryukha/aidemo"
]
}
}
}Add to `~/.gemini/settings.json`.
{
"mcpServers": {
"aidemo": {
"type": "local",
"command": "npx",
"args": [
"-y",
"@tandryukha/aidemo"
],
"tools": [
"*"
]
}
}
}Add to `~/.copilot/mcp-config.json`, or run `/mcp add` inside the CLI.
{
"context_servers": {
"aidemo": {
"command": {
"path": "npx",
"args": [
"-y",
"@tandryukha/aidemo"
]
}
}
}
}Add to your Zed `settings.json`.
npx -y @tandryukha/aidemoRun `goose configure`, choose **Add Extension โ Command-line Extension**, and paste this command.
Score
39 / 100
Incomplete
- Documentation25/25
- Maintenance19/25
- Trust13/20
- Capability0/15
- Install experience12/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 19 days ago
- Has a release history
- Repository is not archived
- Licensed MIT
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 0 tool(s) documented
- Provides prompt templates
- Provides resources
- 12 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint โ no local install
Version history
| Versions | Published |
|---|---|
| 0.8.0Latest | Jul 15, 2026 |

