kimo
A video editor an AI can drive. MCP-first. Every feature is a tool call. Written in Rust, runs on a 2 GB box. getkimo.tech
What it is
v1.0.0. 255 tools, fuzzed (9359 calls, 0 failures). main is the stable v1; new work lands on feature branches.
kimo is a video editor with no GUI. You talk to it over the Model Context Protocol. Cut, keyframe, grade, track, key, relight, simulate, caption, mix and export are all registered commands, and the MCP server's tool list is generated from that same registry. There is no feature a human can reach that an AI cannot.
The target is the surface of CapCut, After Effects, Premiere and DaVinci Resolve in one engine: editing, motion graphics, VFX, tracking and pro color. It is an early engine with honest tiers. Read FEATURES.md for what is solid, what is beta and what is not built.
- MCP first. Add a tool in the registry and it is in the MCP server, the fuzz test and the schema automatically.
- CPU, small memory. The renderer is CPU only and tuned for a 2 GB machine. GPU code is off by default with a CPU fallback.
- Measured, not claimed. Every "better than X" line in FEATURES.md has a stated baseline and a measured number, including the cases where we lost.
- Few entry points.
tools/listreturns 16 grouped tools (15.7 KB) instead of 255 (176 KB), measured 11.2x smaller (compact JSON, v1.0.0). Every individual tool is still callable by its own name. - Fuzzed. 255 tools, 9359 calls, 0 failures, before anything is published.
Install
Download a binary (Linux x86_64, static, no dependencies except ffmpeg):
Windows x64 also ships a per-user setup installer and portable ZIP, with thesame MCP server and bundled fonts. Download Windows assets fromGitHub Releases, or froma manual release workflow run's artifacts. See theWindows setup guide for FFmpeg installationand MCP configuration. To build locally, runpowershell -ExecutionPolicy Bypass -File packaging/windows/build.ps1with Rust, Python 3, and Inno Setup 6 installed.
curl -LO https://github.com/naman-sharma12345/kimo/releases/download/v1.0.0/kimo-v1.0.0-linux-x86_64.tar.gz
tar xzf kimo-v1.0.0-linux-x86_64.tar.gz
./kimo-v1.0.0-linux-x86_64/kimo-mcp # speaks MCP over stdin/stdout
The binary is about 10 MB and answers its first MCP request in about 2 ms (measured: initialize 2 ms, first tools/list 6 ms). It is statically linked (musl), so it runs on any x86_64 Linux. It needs ffmpeg and ffprobe on PATH for decode and encode.
Windows x64: download the installer (kimo-1.0.0-windows-x86_64-setup.exe) or the portable ZIP from the Windows release. The installer is unsigned, so Windows may show a SmartScreen warning; check the .sha256 file next to it. See the Windows setup guide.
macOS binaries are not shipped yet; build from source there (below).
Build from source (Rust stable):
cargo build --release # target/release/kimo-mcp
python3 examples/demo_grade.py # graded 2-clip sequence with a transition, built only with MCP calls
python3 examples/effects_gallery.py # renders every effect
Setup: add kimo to your AI client
kimo is a local MCP server that speaks over stdin/stdout (the "stdio" transport). There is nothing to start by hand: your client launches kimo-mcp itself. You only need the path to the binary.
1. Get the binary (see Install above) and put it somewhere stable, for example:
mkdir -p ~/.local/bin && cp kimo-v1.0.0-linux-x86_64/kimo-mcp ~/.local/bin/
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | ~/.local/bin/kimo-mcp
The second command should print a JSON reply containing "serverInfo":{"name":"kimo". Install ffmpeg and ffprobe too (sudo apt install ffmpeg, or your package manager).
2. Add it to your client. Replace /home/you/.local/bin/kimo-mcp with your absolute path. Config formats below were checked against each client's public docs on 2026-10-11; client configs change, so if one fails, check the linked page.
Claude Code
(docs)
claude mcp add --transport stdio kimo -- /home/you/.local/bin/kimo-mcp
Add --scope user to make it available in every project, or --scope project to write it to a shared .mcp.json. Check with claude mcp list, or type /mcp inside Claude Code. The same thing as a .mcp.json file in your project:
{ "mcpServers": { "kimo": { "command": "/home/you/.local/bin/kimo-mcp", "args": [] } } }
OpenAI Codex (CLI and IDE extension)
(docs)
codex mcp add kimo -- /home/you/.local/bin/kimo-mcp
Or edit ~/.codex/config.toml (or .codex/config.toml in a trusted project):
[mcp_servers.kimo]
command = "/home/you/.local/bin/kimo-mcp"
Cursor
(docs)
Create ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project):
{ "mcpServers": { "kimo": { "command": "/home/you/.local/bin/kimo-mcp", "args": [] } } }
Then open Cursor's MCP settings and switch the kimo server on.
OpenCode
(docs)
Put this in opencode.json in your project, or in ~/.config/opencode/opencode.json for all projects. Note that OpenCode takes command as a list and uses type: "local":
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"kimo": { "type": "local", "command": ["/home/you/.local/bin/kimo-mcp"], "enabled": true }
}
}
Any other MCP client
kimo is a standard MCP stdio server (protocol 2024-11-05, initialize, tools/list, tools/call). Any client that can register a stdio server by command works: give it the absolute path to kimo-mcp and no arguments. Many clients use the mcpServers JSON shape shown for Cursor; some (for example Zed) use a different key, so check your client's MCP docs for the exact file and format. Only the four clients above were checked against their docs.
Windows: use the path to kimo-mcp.exe (the installer puts it in %LOCALAPPDATA%\\Programs\\kimo\\bin; in JSON write backslashes doubled, see the Windows guide). The configs above are the same except for the path; the Claude Code, Codex, Cursor and OpenCode formats were checked on their docs, not tested on Windows here. macOS: build from source (below) and use the path to target/release/kimo-mcp.
3. Try it. Ask your assistant: "Use kimo to import /path/to/clip.mp4, add a title, and render a frame." Or drive it yourself with the Python client in examples/mcp_client.py.
Grouped or flat tool list
By default the server lists 16 grouped tools (about 15.7 KB) so small context windows are not flooded; call a group with action and args, or use kimo_search to find a tool by intent and kimo_describe to see its arguments. Every one of the 255 tools can still be called by its own name. To list all 255 individually, set KIMO_TOOLS=flat in the server's environment:
claude mcp add --transport stdio --env KIMO_TOOLS=flat kimo -- /home/you/.local/bin/kimo-mcp
[mcp_servers.kimo.env]
KIMO_TOOLS = "flat"
For JSON configs add "env": { "KIMO_TOOLS": "flat" } to the server entry (OpenCode: "environment": { "KIMO_TOOLS": "flat" }).
Troubleshooting
- Server shows as failed: run the
initializeline above by hand; if that works, the path in your config is wrong (use an absolute path). - Tools that read or write video fail:
ffmpegandffprobeare not on the PATH your client launches with. - A long export times out in your client: raise the client's MCP tool timeout;
KIMO_TIMEOUT_Ssets the server-side limit per tool call.
Work made with kimo
These are renders from the engine, driven by tool calls. Some are from the film we are building on it. Where something is still rough, it says so.
Fracture glass
Glass shards with physical motion, refraction, a shutter-correct motion blur and a damped core so the break starts from the point of impact. Shown on a city plate, top row before core damping, bottom row after. The dark hole where the glass breaks can now be filled with hole_fill (default off): a defocused, dimmed copy of the pane (depth behind the glass), or with hole_source=1 the layers below. The fill is a blur, not a rebuilt scene, so it reads as out-of-focus depth only.

Left, default hole. Right, hole_fill=1 (same frame, 1280x720 city plate, t=1.0 s):

Frosted glass (backdrop effect)
frosted_glass turns any layer's alpha into a glass pane: inside it shows the composite below, blurred, tinted and refracted at a bevel, with a rim light. It runs after the layer's own position and scale, so a sliding panel frosts what is really under it. Frame from a 5 s 1280x720 clip (export took 15.0 s on the 2 GB box); the title sits on the pane. magnify turns the pane into a magnifier lens. Limits: not for 3D-tilted layers; the refraction is a bevel offset, not a ray-traced lens; frosting is a 3-pass box blur, not a Gaussian.

Particles that hit things
Emitters take colliders (circle, rect or plane, analytic and deterministic) that sparks bounce off with bounce and friction, plus a vortex swirl force. Left to right: no obstacle, a circle and a floor plane, a vortex with a floor (same seed). Colliders can also be another layer's alpha silhouette (kind: layer, clip_id), so sparks bounce off a title or shape; the silhouette is read at the current frame by default; follow: true on the collider uses the silhouette at each step's own time (0.1 s bins), so an animating title plows particles ahead of it. Limits: particles do not collide with each other; thin rects can be tunnelled by very fast particles (60 integration steps per second).

Particles from a layer
An emitter with shape: layer and emit_clip spawns on that clip's alpha silhouette (emit_edge for the outline only), so embers can rise off a title's letters; sparks can also bounce off it (colliders kind layer). Shown: a 5 s 1280x720 title clip, export 18.8 s. With emit_follow each particle spawns on the silhouette as it was at its own birth time (0.1 s bins), so a moving or animating title leaves a trail of its past positions; without it the silhouette at the current frame is used. Limit: bins are 0.1 s wide, so a very fast layer steps between bins, and each bin costs one clip render.

Motion blur on particles and on 3D scenes
Both take shutter_deg and blur_samples, default off. The scene is sampled at several instants across the shutter and averaged in premultiplied space. 3D scene blur re-poses the whole scene per sample, so object animation, parenting and camera moves all blur. Measured on a 1280x720 scene: 0.19 s per frame off, 0.87 s at 8 samples. At 8 samples a very fast move shows stepped copies, so raise blur_samples.


Tracking and stabilizing
Point, planar and mesh trackers, feature tracking with homography fits, long-gap tracking, and diagnostics that report jitter and residuals. The frames below are a synthetic test plate (top: a label pinned to a moving surface, bottom: the stabilized result), so they show the mechanism, not a real-footage result. A confidence score is not pixel lock, and the validation tools can show a track is unreliable, not that it is true. We say that in every report.
![]()
Why kimo
- Built for an AI, not retrofitted. 255 tools, each one a registered command with a schema. Nothing in the editor is reachable only by mouse.
tools/listis grouped into 16 entries (15.7 KB instead of 176 KB, 11.2x smaller), withkimo_searchto find a tool by intent andkimo_describefor its arguments, so a small context window can still drive all of it. - Tested the way a server should be. A fuzzer calls every tool with generated arguments before anything is published: 255 tools, 9359 calls, 0 failures. Features ship with a proof that can fail, for example frosted glass reduces pane detail from 114444 to 4473 on a test plate, and a moving collider leaves a corridor of 88 pixels behind it where a frozen one leaves 163.
- Physical effects, not presets. Fracture glass with refraction, shutter-correct motion blur and a damped impact core. Frosted glass that frosts what is really under a moving pane, with a magnifier lens. Particles that collide with circles, planes and the moving silhouette of a layer, and that are born on that silhouette.
- Real tracking, honestly reported. Point, planar, mesh and feature tracking, stabilization and camera solve, with diagnostics that say when a track is unreliable instead of a confidence number that looks good.
- Pro colour. ACES and ACEScct, ASC CDL, OCIO, LUTs, HDR, grade node graphs, scopes and film response, in a float pipeline with 16-bit, EXR and TIFF output.
- Small and fast to start. A static 10 MB binary that answers its first MCP request in 2 ms, CPU only, tuned for a 2 GB machine. A 5 s 1280x720 shot with a video plate, a sliding title, collider rain and embers exports in about 40 s on that box.
- Honest about limits. Every feature has a tier in FEATURES.md, with its baseline, its measured number and the cases where it lost.
What is inside
| Area | Tools |
|---|---|
| Timeline and edit | project_set, import_media, add_track, add_clip, move/trim/split/delete, ripple_delete, ripple_trim, roll_edit, slip_clip, slide_clip, markers, multicam, sync_clips, undo/redo, save/load |
| Look and motion | set_property, set_keyframe (any property, with easing and bezier), expressions, motion paths, motion presets, speed ramps, freeze frame, flow blur, camera shake |
| Effects and transitions | add_effect, add_transition, blend modes, effect masks, adjustment layers |
| Masks and roto | bezier masks, mask keyframes, roto propagation, track mattes, refine_matte, chroma_key |
| Text and graphics | add_text with animators and paths, captions, titles, HUD frames, counters, detection boxes, shapes and path shapes with modifiers, layer styles |
| 3D and relight | add_scene3d, camera, lights, materials, relight, shard bursts, fracture glass |
| Particles and physics | add_emitter, add_particles, simulate_physics |
| Tracking and vision | track_point, track_planar, track_mesh, track_features, stabilize, solve_camera, undistort_clip, validation tools |
| Color | primaries, wheels, curves, HSL, LUTs, ACES and ACEScct, ASC CDL, OCIO, HDR, grade node graphs, scopes, film response, match_grade |
| Audio | fades, EQ, denoise, compressor, echo, pitch, pan, loudness, auto_duck, beat detection and binding |
| Output | render_frame, export, export_alpha, export_gif, export_audio, export_preset, high bit depth, float EXR and TIFF |
The full, current tool list is whatever tools/list returns.
How an AI sees the tools
The default tools/list is grouped, so a client does not have to read 255 tool schemas up front.
| Group | What it covers |
|---|---|
| project, timeline, animate, effects | project and media, edits, keyframes and motion, effects and transitions |
| masks, text, graphics, vfx3d | masks and roto, text and captions, shapes and HUD, 3D, particles and fracture |
| tracking, color_grade, color_science, scopes | tracking and camera solve, grading, color management, measurement |
| audio, output | audio, render and export |
| kimo_search, kimo_describe | find an action by keywords (also searches the effect and transition catalogs), get one action's full arguments |
Call a group with {"action": "<tool name>", "args": {...}}, for example {"name": "vfx3d", "action": "add_scene3d", "args": {...}}. Calling a tool by its own name (add_scene3d) still works, and tools/list with {"mode": "flat"} (or KIMO_TOOLS=flat) lists all 255. A new tool is placed in a group by name rules in crates/kimo-core/src/toolgroups.rs, and a unit test fails if one is left unassigned. tests/group_proof.py checks that every tool is in exactly one group and that grouped and direct calls give the same result.
Layout
crates/-kimo-core(model, keyframes, command registry, tool groups, CPU renderer, effects, text, audio, tracking, color) andkimo-mcp(the MCP stdio server)examples/- Python client and demosdocs/- design notes and reviewstests/- the tool fuzz runner
Status: early, CPU renderer. See ROADMAP.md and FEATURES.md.
Contributing and the README rule
The README is updated with every product change. If a change adds, removes or regroups tools, or ships a new proof, the same commit updates this file.
MIT licensed.