Describe a video. Watch it render. Ship it — in under 5 minutes.
No motion designer. No video editor. No rendering farm.
Just one sentence — and a production-ready MP4 in your hands.
Video Forger runs entirely in Docker and works three ways:
a web dashboard, a REST API, and a Claude Desktop MCP plugin —
each powered by Remotion + headless Chromium.
→ Get started in 5 minutes · See example videos · API docs
| 🚀 Founders & indie hackers | Ship promo videos without hiring an agency — launch day sorted in an afternoon |
| 📣 Marketers & growth teams | Generate video creatives for every campaign without a production budget |
| 📊 Data teams | Animate charts and reports that actually get watched instead of ignored |
| 🛠️ Developers | Programmatic video via REST API — drop it into your CI/CD, cron job, or script |
| 🎙️ Content creators | AI voice-over + polished visuals in one command, no editing software needed |
| 🎓 Educators & trainers | Turn slides and walkthroughs into narrated explainer videos automatically |
| 📦 Open-source maintainers | Create killer project demos and release announcement videos that get stars |
| 🤖 Claude power users | Tell Claude what you want — it writes the code, renders it, and hands you the link |
- AI Chat in the dashboard — describe a video in plain English; Gemini writes TSX, renders it, iterates with you
- Claude Desktop plugin — full MCP integration; Claude creates, renders, and delivers videos without leaving the chat
- AI voice narration — Google AI Studio TTS generates voice-overs synced to your visuals
- REST API — every action is a clean HTTP call for automation or CI/CD
- Web dashboard — upload compositions, trigger renders, watch videos inline, manage jobs
- Auto port detection — finds a free port automatically if 3000 is taken
- Docker-packaged — one command to start; zero Node.js setup on the host
Make me a 45-second product demo video for a SaaS tool called "Video Forger".
Use a dark theme with indigo, violet, and pink gradient accents throughout.
Show 5 scenes:
Hero — Logo spring-in with the tagline "Turn your words into stunning videos in minutes — not days." Add animated floating color orbs and sparkle particles in the background. Show 3 badges: Docker-packaged, Remotion-powered, Claude Plugin.
Features — Three dark cards with glowing colored borders for: "Describe It" (just tell Claude what you want), "Web Dashboard" (manage and watch renders live), and "Claude Plugin" (one-command setup).
How It Works — Four steps in a row: Describe → Generate → Render → Download, connected by an animated gradient line that draws itself across the screen.
By the Numbers — Four stat cards: < 5 min first video, 1 cmd to start, 0 Node.js required, ∞ videos you can create.
Outro — Pulsing glow background, logo, bold CTA text "Ship your first video in under 5 minutes", and the install command in a terminal-style box. Add AI voice narration (energetic tone, Puck voice) synced to each scene — no overlap between clips. No background music.
product-demo.mp4
Create a 10-second logo reveal animation for "Apex Labs".
Start with particles converging to the center, then the company name
springs in with a bounce effect. Use gold on black.
logo-reveal.mp4
Build a 20-second animated bar chart video showing monthly revenue
growing from $10k in January to $95k in December.
Animate each bar rising one by one as the months progress.
data-viz.mp4
Make a 15-second vertical video (1080×1920) for Instagram Reels
announcing a summer sale: "50% OFF — Ends Sunday".
Bold text, bright orange gradient background, countdown feel.
social-short.mp4
Create a 45-second video that reveals a Python quicksort function
line by line, with syntax highlighting.
Each line appears with a fade-in as if being typed.
code-walkthrough.mp4
presentation.mp4
Build a 60-second presentation video with 4 slides:
1. Title: "Q3 Results"
2. Revenue up 40% — animated bar chart
3. 3 bullet points about new product launches, each appearing with a spring animation
4. "Thank You" outro with company logo
Use a clean white and navy blue color scheme.
- Requirements
- Quick Start
- Claude Desktop Plugin
- Dashboard Usage
- Video Types
- TSX Composition Format
- AI Voice Narration (TTS)
- Environment Variables
- API Reference
- Project Structure
- License
| Dependency | Version | Install |
|---|---|---|
| Docker Desktop | 4.x+ | docker.com/products/docker-desktop |
Node.js is NOT required on the host. The entire runtime (Node.js 20, Remotion, Chromium) runs inside Docker.
| Dependency | Install |
|---|---|
| Claude Desktop | claude.ai/download |
| Dependency | How |
|---|---|
| Google AI Studio API key | aistudio.google.com/apikey — free tier available |
Choose one setup path:
Video Forger is available on PyPI as a thin launcher. Docker must be installed — nothing runs via Python itself.
pip install video-forgermkdir my-videos && cd my-videos
video-forger initvideo-forger init copies the project template (Dockerfile, docker-compose.yml, server.js, .env.example, etc.) into the current directory. Your .env lives here, alongside those files.
cp .env.example .envThen open .env and add your Google AI Studio key:
GOOGLE_AI_STUDIO_API_KEY=your_key_hereGet a free key (no billing required) at aistudio.google.com/apikey.
With this key you get:
- AI Chat — describe videos in plain English, the dashboard writes and renders them for you
- Voice narration — auto-generates narration audio for your videos via Gemini TTS
video-forger startOther commands:
video-forger stop # Stop the running Docker container
video-forger --help # Show all optionsgit clone https://github.com/coderXcode/video-forger
cd video-forgerCopy the example and add your Google AI Studio key to unlock AI Chat and voice narration:
cp .env.example .env # or create .env manually# .env
GOOGLE_AI_STUDIO_API_KEY=your_key_hereGet a free key (no billing required) at aistudio.google.com/apikey.
With this key you get:
- AI Chat — describe videos in plain English, the dashboard writes and renders them for you
- Voice narration — auto-generates narration audio for your videos via Gemini TTS
Without it, Video Forger still works — you just write TSX manually and the Chat panel will say the key is missing.
chmod +x start.sh
./start.shstart.sh will automatically:
- ✅ Verify Docker is running
- ✅ Find a free port (starts at 3000, increments if busy)
- ✅ Build the Docker image (~3 min first run — Chromium is large)
- ✅ Start the container
- ✅ Register the MCP plugin with Claude Desktop (if installed)
- ✅ Open the dashboard in your browser
To stop:
docker compose downOpen http://localhost:3000 (or whichever port was auto-selected) after starting.
| Page | What it does |
|---|---|
| Dashboard | Overview: composition count, video count, active and completed renders |
| AI Chat | Describe a video in plain English — Gemini writes the TSX, renders it, lets you iterate |
| Compositions | Browse, edit source, and delete uploaded TSX files |
| Videos | Watch rendered MP4 files inline with full seek support; download |
| Render Jobs | Live progress bars for all render jobs with logs |
- Open AI Chat and describe the video you want
- Gemini writes the TSX composition and uploads it automatically
- Say "render it" — the chat triggers the render and shows live progress
- Watch the video inline in chat; ask for changes ("make the text bigger", "add a blue background")
- Gemini updates the composition and re-renders on your instruction
- Write a
.tsxfile following the format below - Upload it via Compositions → + New or the API
- Click ▶ Render on the composition card
- Open Videos to watch and download the result
When ./start.sh runs, it automatically registers Video Forger in Claude Desktop's config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
After registration, quit and reopen Claude Desktop. Video Forger appears in the MCP tools panel.
If auto-registration was skipped, add this to your claude_desktop_config.json:
{
"mcpServers": {
"video-forger": {
"command": "docker",
"args": ["exec", "-i", "video-forger", "node", "/app/mcp-server.js"]
}
}
}Requires the video-forger Docker container to be running (./start.sh).
| Tool | What Claude uses it for |
|---|---|
get_video_capabilities |
Learn the TSX format and available video types |
list_compositions |
See uploaded compositions |
create_composition |
Write and upload TSX code |
update_composition |
Edit an existing composition |
generate_narration |
Generate a voice-over audio file from text (Google TTS) |
render_video |
Trigger a render job |
get_render_status |
Poll progress until complete |
list_rendered_videos |
List finished MP4s with direct links |
delete_composition |
Remove a composition |
| Type | Description | Duration | Resolution |
|---|---|---|---|
| Product / Feature Demo | Animated slides with feature callouts and smooth transitions | 30s | Any |
| Explainer / Narrated | Visuals synchronized to AI voice-over | 30–60s | Any |
| Data Visualization | Animated charts and counters | 15–30s | Any |
| Title Card / Logo Reveal | Spring animations, fade-ins, scale effects | 5–15s | Any |
| Code Walkthrough | Syntax-highlighted code revealed line by line | 30–90s | Any |
| Social Short (9:16) | Vertical format for Reels / TikTok / Shorts | 15–30s | Any |
| Presentation Slides | Multi-scene with bullet-reveal animations | 60–120s | Any |
| Countdown Promo | Animated timer with glow/particle effects | 15–30s | Any |
Every composition file must follow this structure:
// @remotion durationInFrames=900 fps=30 width=1920 height=1080
import React from 'react';
import { AbsoluteFill, useCurrentFrame, interpolate, spring, useVideoConfig } from 'remotion';
export default function MyVideo() {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const opacity = interpolate(frame, [0, 30], [0, 1], { extrapolateRight: 'clamp' });
const scale = spring({ frame, fps, config: { stiffness: 80 } });
return (
<AbsoluteFill style={{ background: '#111', justifyContent: 'center', alignItems: 'center' }}>
<div style={{
opacity,
transform: `scale(${scale})`,
color: '#fff',
fontSize: 72,
fontFamily: 'sans-serif',
}}>
Hello, Video Forger!
</div>
</AbsoluteFill>
);
}- Line 1 must be the
// @remotion durationInFrames=... fps=... width=... height=...comment - Must have a default export that is a React function component
- No external npm packages beyond what ships in the image (
remotion,react,react-dom) - For audio in TSX: always use absolute URLs —
http://localhost:3000/api/audio/filename.wav— relative URLs fail during rendering because Remotion resolves them against its internal webpack server
| API | Returns | Description |
|---|---|---|
useCurrentFrame() |
number |
Current frame index (0 → durationInFrames − 1) |
useVideoConfig() |
object |
{ fps, durationInFrames, width, height } |
interpolate(frame, [in0, in1], [out0, out1], opts) |
number |
Map frame range to value range. Use extrapolateRight: 'clamp' |
spring({ frame, fps, config }) |
number |
Physics spring animation (0 → 1). config: { stiffness, damping, mass } |
<AbsoluteFill> |
JSX | Full-bleed positioned container (position: absolute, inset: 0) |
<Sequence from={n} durationInFrames={n}> |
JSX | Render children only during a time window |
<Audio src="url" volume={0.5} /> |
JSX | Audio track. Use absolute URL |
<Img src="url" /> |
JSX | Frame-safe image (waits for asset to load) |
| Duration | Frames (at 30fps) |
|---|---|
| 5s | 150 |
| 10s | 300 |
| 15s | 450 |
| 30s | 900 |
| 60s | 1800 |
| 90s | 2700 (max recommended) |
Video Forger supports Google AI Studio (Gemini) for voice-over generation.
Add to your .env:
GOOGLE_AI_STUDIO_API_KEY=your_key_here
GOOGLE_AI_STUDIO_TTS_MODEL=gemini-2.5-flash-preview-tts
GOOGLE_AI_STUDIO_TTS_VOICE=Kore
GOOGLE_AI_STUDIO_TTS_SPEAKING_RATE=1.0
GOOGLE_AI_STUDIO_TTS_PITCH=0.0Get a free API key at aistudio.google.com.
curl -X POST http://localhost:3000/api/tts/google \
-H 'Content-Type: application/json' \
-d '{
"text": "Welcome to our product. Let'\''s get started.",
"filename": "welcome-narration"
}'Returns { "publicUrl": "/audio/welcome-narration.wav" }.
Use in TSX:
<Audio src="http://localhost:3000/audio/welcome-narration.wav" volume={0.9} />Configure in .env in the project root before running ./start.sh:
# ── Google AI Studio TTS (optional) ──────────────────────────────────────────
GOOGLE_AI_STUDIO_API_KEY= # Your AI Studio API key
GOOGLE_AI_STUDIO_TTS_MODEL=gemini-2.5-flash-preview-tts
GOOGLE_AI_STUDIO_TTS_VOICE=Kore # Voice name
GOOGLE_AI_STUDIO_TTS_SPEAKING_RATE=1.0 # 0.25 – 4.0
GOOGLE_AI_STUDIO_TTS_PITCH=0.0 # -20.0 – 20.0
# ── Advanced (usually leave as defaults) ─────────────────────────────────────
VIDEO_FORGER_ORIGIN=http://localhost:3000 # Base URL for audio assets in TSX renderers
VIDEO_FORGER_CONTAINER=video-forger # Docker container name
NARRATION_COMPOSITIONS=MCPForgerVideoNarrated,MCPForgerVideoStudioNarrated
# Comma-separated composition names that
# trigger automatic TTS pre-generation
# ── Set by start.sh automatically ────────────────────────────────────────────
# STUDIO_PORT=3000 # Set manually to force a specific host portAll endpoints are on the running server (default http://localhost:3000).
| Method | Path | Body / Params | Description |
|---|---|---|---|
GET |
/api/compositions |
— | List all uploaded compositions |
GET |
/api/compositions/:name |
— | Get source code + metadata |
POST |
/api/compositions |
multipart: file=<.tsx> |
Upload a new composition |
PUT |
/api/compositions/:name |
{ "content": "..." } |
Update source code |
DELETE |
/api/compositions/:name |
— | Delete a composition |
| Method | Path | Body | Description |
|---|---|---|---|
POST |
/api/render/:name |
— | Start a render → { "jobId": "..." } |
GET |
/api/jobs |
— | List all render jobs |
GET |
/api/jobs/:id |
— | Job status, progress %, logs, output filename |
| Method | Path | Description |
|---|---|---|
GET |
/api/videos |
List rendered MP4 files |
GET |
/api/videos/stream/:filename |
Stream/download with HTTP range request support |
DELETE |
/api/videos/:filename |
Delete a video file |
| Method | Path | Body | Description |
|---|---|---|---|
POST |
/api/tts/google |
{ text, filename?, voiceName?, speakingRate?, pitch? } |
Generate audio from text |
GET |
/api/audio/:filename |
— | Serve a generated audio file |
| Method | Path | Description |
|---|---|---|
GET |
/api/mcp/capabilities |
Full guide: video types, TSX format, workflow (used by Claude) |
GET |
/api/health |
Health check → { "status": "ok" } |
GET |
/api/stats |
Dashboard stats: composition count, video count, job counts |
video-forger/
├── start.sh # One-command launcher (build → start → register MCP)
├── mcp-docker-bridge.sh # Claude Desktop → Docker stdio bridge
├── mcp-server.js # MCP tool server (stdio, JSON-RPC 2.0, runs in Docker)
├── server.js # Express REST API + render engine
├── index.html # Dashboard UI (vanilla JS, no build step)
├── docker-compose.yml # Service definition
├── Dockerfile # Node 20 + Chromium image
├── package.json
├── remotion.config.ts
├── tsconfig.json
├── index.ts # Remotion entry point
├── src/
│ └── Root.tsx # Auto-generated — lists registered compositions
├── public/
│ └── audio/ # Generated TTS audio cache
├── project_mnts/ # Host-mounted volume (persists across restarts)
│ ├── uploaded_tsx/ # Your TSX composition files
│ └── generated_videos/ # Rendered MP4 output
└── video_forger/ # Python pip package
├── __init__.py
├── cli.py
└── assets/ # Project files bundled with the pip package
Video Forger is released under the Apache 2.0 License.
This project uses Remotion for video rendering. Remotion is free for individuals and teams of 3 or fewer people. For larger teams, a Remotion license is required — see remotion.dev/license. Go play for non commercial purposes, for commercial purposes give right credits (helps the developers!), Have a good time , OK , thanks, bye - Manas Joshi

