Skip to main content

A scene-based, AI-first video editor. A built-in copilot proposes edits you accept or reject, and any MCP agent can drive it.

Project description

OpenVideoKit

A scene-based, AI-first video editor. A built-in copilot proposes edits you accept or reject, and any MCP agent can drive it.

Website · Get Started · Template Gallery · PyPI · Docs

Demo

🎬 Template Showcase

OpenVideoKit demo video

Watch on YouTube

🖼️ Editor Screenshot

Editor screenshot with the prompt that generated the demo video

The editor showing the AI prompt that generated the demo video on the left.

🌍 Text-to-Speech Engine Showcase — 7 Languages in 44 Seconds

Global Voices demo — edge-tts voiceover across 7 languages

Watch on YouTube

edge-tts voiceover showcase: 🇺🇸 Ava Multilingual → 🇫🇷 Vivienne → 🇩🇪 Florian → 🇯🇵 Nanami → 🇻🇳 Hoài My → 🇨🇳 Xiaoxiao → 🇧🇷 Thalita → 🇺🇸 Ava Multilingual.


OpenVideoKit is a video templating pipeline: edit slides in a web UI → Python SSR stamps values into self-contained GSAP compositions → <hyperframes-player> renders them live → edge-tts generates voiceover audio → export to MP4 via HyperFrames. A LangGraph AI agent proposes edits (the same EditOps a human dispatches) that the user accepts or rejects — undo/redo works uniformly.

Slides pick a layout from a curated template catalog (templates/slides/<author>/<name>/) and their media (image/video/audio) are URL strings stored in slide fields — uploaded to a content-addressed backend store or any remote URL (picsum, S3).

┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│  ovk-web     │    │  Python API  │    │  Disk        │
│  (React SPA) │    │  (FastAPI)   │    │  (per-slide) │
│  :3000       │←──→│  :8000       │←──→│  data/       │
│              │    │              │    │              │
│ <hf-player>  │    │ Stamp HTML   │    │ project.json │
│ EditBus      │    │ PUT/SSE/rev  │    │ audio-{hash} │
│ Playhead     │    │ edge-tts     │    │ assets/      │
│ Captions     │    │ Render MP4   │    │ jobs/        │
│ AIDock       │    │ LangGraph AI │    │ jobs.json    │
│ Properties   │    │ Templates    │    │              │
│  +Media      │    │  +Assets     │    │              │
└──────────────┘    │  /mcp (MCP)  │    └──────────────┘
                     │   29 tools   │
                     └──────┬───────┘
                            │
              ┌─────────────┼─────────────┐
              │             │             │
         ┌────┴────┐  ┌─────┴───┐  ┌──────┴──┐
         │Claude   │  │Cursor   │  │Gemini CLI│
         │Code     │  │         │  │Goose    │
         │(MCP)    │  │(MCP)    │  │(MCP)    │
         └─────────┘  └─────────┘  └─────────┘
              external AI agents edit via MCP tools (→ Python API, not disk)

Quickstart

Option 1 — Install from PyPI (recommended for users)

python3 -m venv .venv
source .venv/bin/activate           # Windows: .venv\Scripts\activate
pip install openvideokit
ovk serve                           # http://0.0.0.0:8000

On first ovk serve, OpenVideoKit writes a documented config file to ~/.openvideokit/config.toml (chmod 600 — secrets safe). To enable AI, edit it and restart:

ovk config edit                 # opens $EDITOR; set [ai].openai_api_key
ovk serve                       # restart to apply

That's it. The bundled SPA, all 25 slide templates, edge-tts voiceover, MP4 export, the LangGraph AI co-pilot, and the MCP server for external agents are all included in the wheel.

  • Editorhttp://localhost:8000
  • AI connection testovk llm test
  • Browse free modelsovk llm free (lists free OpenRouter models with context, reasoning, tools, uptime)
  • Settings pagehttp://localhost:8000/settings (read-only runtime config + edit guidance)
  • MCP endpointhttp://localhost:8000/mcp/

See docs/config.md for the full priority chain (env vars > .env > config.toml > defaults), workflow walkthroughs, and the ovk config init|get|set|edit CLI reference.

Option 2 — Dev checkout (recommended for contributors)

git clone <this-repo>
cd openvideokit
uv sync --extra dev              # install Python deps
cp .env.example .env             # then edit .env (set OPENAI_API_KEY for AI)
cd ovk-web && pnpm install && cd ..  # install frontend deps

Run the dev stack — two terminals (recommended)

scripts/dev.sh backgrounds both servers with nohup, so import errors, port clashes, and missing-env failures are hidden in /tmp/*.log and the script reports success even when a server has died. Run each server in its own foreground terminal instead — you get live logs and Ctrl-C stops cleanly.

Terminal 1 — Python API (port 8000):

uv run ovk serve --reload

Terminal 2 — Vite dev (port 3000, proxies /api → `:8000):

cd ovk-web && pnpm dev -- --port 3000 --host

Then open http://localhost:3000.

  • Python APIhttp://localhost:8000
  • Vite devhttp://localhost:3000 (proxies /api:8000)
  • AI connection testuv run ovk llm test
  • Browse free modelsuv run ovk llm free (lists free OpenRouter models with context, reasoning, tools, uptime)

Alternative: scripts/dev.sh (both servers in background)

If you prefer one command and don't need live logs:

./scripts/dev.sh                 # start both servers (background)
./scripts/dev.sh --stop          # stop both
tail -f /tmp/ovk-server.log      # API log
tail -f /tmp/ovk-vite.log        # Vite log

Note: the script returns immediately and servers keep running detached — check the logs above if anything looks wrong.

Connect AI agents via MCP

The MCP server is enabled by default on port 8000 at /mcp/. Any MCP-compatible client can connect and edit projects through the same toolset the in-app AI uses — without touching files directly.

Claude Code

Create .claude/mcp.json (or ~/.config/claude-code/mcp.json):

{
  "mcpServers": {
    "openvideokit": {
      "url": "http://localhost:8000/mcp/"
    }
  }
}

Then ask Claude Code: "Create a 3-slide product video and set the title on each slide." It will call create_project_tool, set_field, add_slide, etc. — each mutation persists to disk immediately.

Cursor / Gemini CLI / Goose

{
  "mcpServers": {
    "openvideokit": {
      "transport": { "type": "streamable_http", "url": "http://localhost:8000/mcp/" }
    }
  }
}

Verify

uv run python scripts/test-mcp.py --no-tts   # 32 checks, all 29 tools

See docs/mcp.md for the full design (execute-on-call semantics, path-safety contract, voiceover TTS loop, undo trade-off).

Commands

User-facing (work for both pip install openvideokit and dev checkout):

Task Command
Run server ovk serve (dev: uv run ovk serve --reload)
Edit config ovk config edit (opens $EDITOR on ~/.openvideokit/config.toml)
AI connection test ovk llm test
Browse free models ovk llm free

Dev checkout only:

Task Command
Start dev stack ./scripts/dev.sh
Stop ./scripts/dev.sh --stop
MCP e2e test uv run --extra dev python scripts/test-mcp.py --no-tts
Python lint uv run ruff check src scripts tests
Python unit tests (fast) uv run pytest tests/
Python unit tests (incl. render) uv run pytest tests/ --run-slow
Python AI tests uv run pytest tests/ai/
Python MCP tests uv run pytest tests/mcp/
Python E2E test uv run --extra dev python scripts/test-e2e.py
Frontend dev cd ovk-web && pnpm dev
Frontend test cd ovk-web && pnpm test
Frontend lint cd ovk-web && pnpm exec biome check src/
Install web browsers uv run playwright install chromium

Architecture

  • Python SSR (src/openvideokit/): FastAPI serves stamped HF compositions, project JSON, TTS, SSE, and MP4 export. Disk-backed store with per-slide folders, fcntl.flock, and a watchdog file watcher.
  • Frontend (ovk-web/): React 19 SPA with <hyperframes-player>, EditBus for mutations, Zustand playhead, TanStack Query + optimistic locking (content-hash rev).
  • AI (src/openvideokit/ai/): a LangGraph agent that explores the project with read-only tools and proposes edits as EditOp lists over SSE. The frontend AIDock dispatches each op through the same EditBus a human edit uses on Accept — so undo/redo, lint gates, and SSE sync are preserved (AI flow == human flow). Default model gpt-5.4-nano; any OpenAI-compatible endpoint via OPENAI_BASE_URL (OpenAI / OpenRouter / Ollama / vLLM / LM Studio). Always-registered web_search (DuckDuckGo) + web_fetch (crawl4ai) tools give the agent live web access — gated at runtime by OVK_ENABLE_WEB. Accepting a proposal auto-continues the agent with a tagged receipt ([AI PROPOSED] / [USER ACCEPTED]) carrying the created slide ids and field values (VITE_AI_AUTOCONTINUE, default on). See docs/ai.md.
  • TTS: edge-tts generates content-addressed audio-{hash}.mp3 per slide. Manual Generate button (no auto-fire). Voiceover data lives in audio.json, separate from index.json.
  • Export: npx hyperframes render subprocess on a bounded ThreadPoolExecutor (OVK_MAX_CONCURRENT_RENDERS). Voiceover audio is concatenated from per-slide TTS into a single track. Job metadata persists to {project_id}/jobs.json. See docs/web/export.md.
  • Captions: Word-level karaoke captions baked into the composition HTML (captions.py). Both preview and render share the same GSAP timeline — no separate overlay system. Settings persist in root.captions via EditBus.
  • Templates: a curated, read-only catalog of slide-layout archetypes under templates/slides/<author>/<name>/ (16 ovk layouts ship). Each is a bare <template> using the __OVK_*__ field vocabulary; backgrounds are user-themeable via the bg_color field. REST: GET /api/projects/{id}/templates
    • GET /api/projects/{id}/templates/{author}/{name}. AI tools: list_templates, read_templates, apply_template; add_slide/add_many_slides take a template_id directly. See docs/templates.md.
  • Media assets: image/video/audio live in slide.fields as URL strings set via set_field (no client blob store). Uploads POST /api/projects/{id}/assets → backend content-addressed store (key = sha256(project_id + bytes), so each project's assets are isolated), served at GET /api/assets/{key} (with a cosmetic .ext). OVK_ASSETS_BASE_URL is the S3/CDN seam. See docs/assets.md.
  • MCP server (src/openvideokit/mcp/): exposes all 26 editing tools + 2 project-management tools (28 total) to any MCP-compatible AI agent via the Model Context Protocol at POST /mcp/ (Streamable HTTP). Claude Code, Cursor, Gemini CLI, Goose connect directly — mutations execute on call (persist to disk via the same store.update_project the web uses). Enabled by default (OVK_MCP_ENABLED=true). See docs/mcp.md.

See docs/web/ for detailed architecture, API reference, export pipeline, and concurrency model, and docs/ai.md for the AI implementation contract.

Debugging AI

Every AI turn can dump its full LLM context (system prompt + tools + messages

  • project snapshot) plus a live execution trace (every tool call with input, output, and duration) to a per-run Markdown file. Default-on during initial development; flip with OVK_AI_MONITORING=false in .env.
# traces land here (one .md per run_agent invocation, UTC timestamp):
data/{project_id}/monitor/
├── 20260703-102345Z.md           the trace (header  context  events  summary)
├── latest.md                     symlink  newest (open once, reload after each turn)
└── index.md                      regenerated table, newest first

# live-tail a run in progress:
tail -f data/proj-1/monitor/latest.md

# diff two runs to see what changed:
diff data/proj-1/monitor/20260703-102345Z.md data/proj-1/monitor/20260703-102400Z.md

The trace records exactly what the model was given and exactly what it did, so when the agent misbehaves you can pinpoint whether the issue is the prompt, the tool wiring, the message history, or the model itself. For real token usage and dashboards, see the LangSmith alternative in docs/ai-monitoring.md.

Project structure

openvideokit/
├── src/openvideokit/       # Python SSR server
│   ├── app.py              # FastAPI + lifespan (store, executor, watcher, MCP mount)
│   ├── routes.py           # /api endpoints (projects, TTS, export, SSE, AI chat, chats, templates, assets)
│   ├── store.py            # Disk-backed store + rev + flock
│   ├── validation.py       # Identifier regex gates (path-safety, enforced in path helpers)
│   ├── gsap_validator.py   # GSAP <script> body validator (reserved — see docs/animation.md)
│   ├── composition.py      # Self-contained GSAP composition builder
│   ├── captions.py         # Caption layer: timing + HTML + GSAP + CSS
│   ├── rendering.py        # Export pipeline: executor, jobs, voiceover concat
│   ├── voiceover.py        # edge-tts pipeline + content-addressed cache
│   ├── config.py           # Env vars + .env auto-load (python-dotenv)
│   ├── events.py           # SSE pub/sub (thread-safe)
│   ├── watcher.py          # watchdog file watcher
│   ├── stamp.py            # __OVK_*__ token stamping
│   ├── templates.py        # Slide-template catalog reader (lint-gated)
│   ├── assets.py           # Media asset store (content-addressed, project-isolated)
│   ├── seed.py             # Fixture project
│   ├── chats.py            # JSONL chat persistence (see docs/chat.md)
│   ├── cli.py              # `ovk serve` + `ovk llm test` + `ovk llm free` (Typer)
│   ├── mcp/                # MCP server for external AI agents (see docs/mcp.md)
│   │   ├── apply_op.py     # Pure EditOp reducer (port of ovk-web applyOp.ts)
│   │   ├── persist.py      # Execute-on-call: fold ops + store.update_project + TTS
│   │   └── server.py       # FastMCP server wrapping 29 tools at /mcp/
│   └── ai/                 # LangGraph agent (see docs/ai.md)
│       ├── config.py       # OPENAI_BASE_URL / OPENAI_API_KEY / OVK_AI_MODEL
│       ├── ops.py          # EditOp mirror of ovk-web ops.ts
│       ├── graph.py        # create_agent ReAct loop
│       ├── server.py       # run_agent → SSE stream
│       ├── prompts/        # modular .py prompt sections (assembled in fixed order)
│       ├── tools/          # read-only + OVK EditOp-emitter tools (see src/openvideokit/ai/tools/)
│       └── monitor/        # AI observability — file-based per-run trace dumps (see docs/ai-monitoring.md)
├── ovk-web/                # React SPA
├── templates/slides/ovk/   # Curated slide-layout templates (25 across ovk/ovk-data/ovk-type/ovk-draw) — see docs/templates.md
├── tests/                  # Python unit tests (pytest) — including tests/security/
├── scripts/                # dev.sh, test-e2e.py, test-mcp.py, migrate_assets.py, gc_assets.py
├── docs/                   # mcp.md + ai.md + assets.md + templates.md + animation.md + security/ + web/ + rfc/
└── legacy/                 # Frozen MVP (not imported)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openvideokit-0.1.2.tar.gz (966.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openvideokit-0.1.2-py3-none-any.whl (825.6 kB view details)

Uploaded Python 3

File details

Details for the file openvideokit-0.1.2.tar.gz.

File metadata

  • Download URL: openvideokit-0.1.2.tar.gz
  • Upload date:
  • Size: 966.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for openvideokit-0.1.2.tar.gz
Algorithm Hash digest
SHA256 c2a36b0b9230ba3737961a92f0535f858803071b9b4c1a2f55137e90ced9e666
MD5 d5fb9f53ed01ef3bcccc5928cd2d477f
BLAKE2b-256 4d947fcd2cdb0d965dab81089ff3896406c14126ffec3e9cbf24d6a0add918e1

See more details on using hashes here.

File details

Details for the file openvideokit-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: openvideokit-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 825.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for openvideokit-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 884faf89e324248865cd6f454e5ea6edfc26ce8dcce73c12570fddc1cd2aba0b
MD5 8bc3276b9fefe2307511c4c28e4702c2
BLAKE2b-256 615c0d61b2b624f457705e9a4431cad33419989150d38aac010d44f7fde18ebe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page