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.3.tar.gz (2.6 MB 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.3-py3-none-any.whl (2.4 MB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: openvideokit-0.1.3.tar.gz
  • Upload date:
  • Size: 2.6 MB
  • 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.3.tar.gz
Algorithm Hash digest
SHA256 5592a17a82cfbe5036d78662f2b15f727a0caea96390d8a4a9015c037b06f491
MD5 6a436986c5f7b6abf75ae599f78a2f07
BLAKE2b-256 4b71d0cabe28060f823a462d606361d8429920a6bba360d68f139c867c633277

See more details on using hashes here.

File details

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

File metadata

  • Download URL: openvideokit-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 2.4 MB
  • 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ce9a8d8d7e4dc841bdc7904307f15ec9682dfda66189fad19e64d4dfcdccbf61
MD5 b8ce1c1e0333ef51ca209c5b66993180
BLAKE2b-256 3c0a093777f7e7fdbcda286569975f0b9c4303c4772f0fa1c5753e65af77fd9d

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