Skip to main content
Glama

Edit a video editor project (timeline commands)

vivid_edit_timeline
Destructive

Apply editing commands to a saved VIVID timeline—clips, trims, speed ramps, transitions, text, subtitles, masks, keyframes, and audio—then save it under the same id. Optionally import media first.

Instructions

Apply editing commands to a saved editor project — clips, trims, speed and speed ramps, transitions, canvas preset (16:9 ↔ 9:16), texts (incl. animated gradient fills), word-level subtitles, masks, keyframes, audio — through the same engine as the VIVID web editor, then save it back under the same id. Optionally import media first. Returns applied/errors (plus warnings for things applied but likely not visible, e.g. motion blur on a still clip), the ids created, and the updated timeline. Render the result with vivid_render_project. Commands are the same editing operations as the VIVID editor: [{ "type", "payload" }], one typed payload per type. Timeline: ADD_CLIP {assetId, canvasObject?{x,y,w,h,rotation,opacity,blendMode}} (places the whole asset at the first free gap of a matching track; then trim it with UPDATE_CLIP) · UPDATE_CLIP {id, startMs?, durationMs?, sourceOffsetMs?, playbackRate?, volume?, opacity?} · REMOVE_CLIP {id} · SPLIT_CLIP {clipId, splitAtMs} · DUPLICATE_CLIP {id} · DETACH_AUDIO {clipId} · ADD_TRACK {type:'visual'|'audio'} · CUT_TO_BEAT {audioClipId (an AUDIO clip id in the timeline), beatInterval (1–32: beats or peaks between cuts; 4 = one cut per bar), grid?: 'beats' (constant BPM grid, default) | 'peaks' (detected hits/accents — right for cuts "sui picchi", drops, voice, music without a steady tempo), minStrength? (grid peaks: 0–1, keep only hits ≥ it), mode?: 'redistribute' (default: re-slice all visual clips in order to fill the music) | 'snap' (only nudge existing edges), syncClips?: 'all' | [clipIds]} — the audio is analysed on the server automatically (free); to plan cuts by hand call vivid_analyze_audio and use its beats/peaks (ms) as UPDATE_CLIP boundaries. Look: SET_TRANSITION {clipId, edge:'in'|'out', type:'dissolve'|'fade-black' (visual) | 'crossfade'|'fade-in'|'fade-out' (audio), durationMs} · SET_CLIP_ANIMATION {clipId, phase:'in'|'out', type:'fade'|'slide-up'|'slide-down'|'zoom-in'|'zoom-out'|'zoom-pan'|'spin'|'blur-reveal', durationMs} · SET_CINEMATIC_LOOK {look} · SET_CANVAS_PRESET {id,label,width,height} (crop/reframe: landscape 1280x720, landscape-fhd 1920x1080, portrait 720x1280, portrait-fhd 1080x1920, square 1080x1080, social 864x1080) · UPDATE_CANVAS_OBJECT {id, x?, y?, w?, h?, rotation?, blendMode?}. Text: ADD_TEXT {text, startMs, endMs, x (0-1), y (0-1), fontFamily?, fontSize?, color?, animation?, fill?} · UPDATE_TEXT {id, ...} · REMOVE_TEXT {id}. fill = animated gradient on the glyphs: {type:'gradient', colors:['#ff6ec4','#7873f5','#4ade80','#facc15'], angle: 100, animate:'shift'|'none', speed?: periods/s (0.35)} — presets: iridescent, sunset, ocean, gold, candy (same colors as the in-app Fill picker). Subtitles (CapCut-style word-level captions): SET_SUBTITLES {cues:[{text, startMs, endMs, words?:[{word,startMs,endMs}]}] | null, templateId?:'outline-reveal'|'ugc-pop'|'karaoke-marker'|'cinematic-fade'|'neon-cyberpunk'|'playful-wiggle', position? (0 top – 100 bottom), styleOverrides?:{fontSize,color,highlightColor,…}, layout?:{x,y,scale,maxWidthPct,rotation}}. Get cues from vivid_transcribe (its cues[] carry per-word timing) on the voice/video asset; words are synthesized evenly when omitted. Keyframes & effects (v2): SET_ANIMATIONS {objectId, objectType:'canvas'|'text', animations:{x|y|scale|rotation|opacity|blur|...: {keyframes:[{t (ms), v, easing?}]}}} · SET_OBJECT_ANIMATION · ADD_EFFECT {objectId, objectType, effect:{type:'blur'|'vignette'|'colorGrade'|'grain'|'glitch'|'chromaticAberration'|'pixelate', ...}, replace?} · REMOVE_EFFECT {objectId, objectType, effectType} · SET_EFFECT_KEYFRAMES {objectId, objectType, effectType, param, keyframes:[{t (ms FROM THE CLIP START — not the timeline), v, easing? 'linear'|'easeInCubic'|'easeOutCubic'|'easeInOutCubic' (default)|'easeOutBack'|'easeOutElastic'|'easeOutBounce'|[x1,y1,x2,y2] bezier}] | null} — animates one value of an effect already on the object (ADD_EFFECT first, same batch is fine): cameraShake.intensity|speed, motionBlur.intensity, flash.intensity|decayMs, zoomBlur.amount|centerX|centerY, lightLeak.intensity|speed|hue, blur.amount, vignette.intensity|size, colorGrade.brightness|contrast|saturation|hue, grain/glitch/chromaticAberration/pixelate values. Use it for anything that changes over time (a shake that builds up, a leak that fades in). Motion & light effects (canvas objects only): {type:'motionBlur', intensity 0–1 (shutter = intensity × 2 frames; blurs the clip's OWN movement — keyframes, intro/outro, shake, beat pump — not motion inside the footage, so pair it with SET_ANIMATIONS or SET_CLIP_ANIMATION), samples? 2–32} · {type:'cameraShake', intensity 0–1 (1 = ±3% of the short side, ±2°), speed? Hz 0.5–20 (6), seed?} · {type:'flash', intensity 0–1, color? '#rrggbb' (white), everyBeats? 1–16, bpm? (used only when the project has no analysed music), decayMs? 30–2000 (150)} · {type:'zoomBlur', amount 0–1, centerX? centerY? 0–1} · {type:'lightLeak', intensity 0–1, speed? 0.1–4, hue? 0–360 (25 = warm)}. Effect recipes (one style across the edit, preferred over hand-written effects/keyframes): APPLY_EFFECT_RECIPE {recipe:'beat-flash' (flash pinned to the music's real beats — the audio is analysed on the server automatically, like CUT_TO_BEAT) | 'punch-in' (scale pop + motion blur on every cut) | 'whip' (fast slide-in from alternating sides + motion blur on every cut) | 'handheld' (subtle shake) | 'light-leak' | 'clear' (removes what recipes added), intensity? 0–1 (0.6), clipIds? (default all visual clips), everyBeats? (beat-flash), color? (beat-flash), audioClipId? (beat-flash)} — its keyframes sit on the timeline, so send it AFTER CUT_TO_BEAT or anything that moves clips. · SET_MASK {objectId, mask:{type:'rect'|'circle'|'reveal'|'clipPath'|'none', ...}} · ADD_AUDIO_REACTIVE. Speed: UPDATE_CLIP.playbackRate is constant per clip; SET_SPEED_RAMP {clipId, preset:'speed-up'|'slow-down'|'slow-mo-hit'|'punch-in'|'ease-in-out'|'none'} or {clipId, keyframes:[{t (ms from clip start on the timeline), v (rate 0.1–8)}]} gives a variable speed (linear between keyframes; the clip keeps its timeline duration unless the source runs out, then it is shortened). Ids: read them from vivid_get_editor_project or from "created" in the previous result; a batch is applied one command at a time, so a later command can use a clip created earlier in the same batch.

Input Schema

NameRequiredDescriptionDefault
mediaNoMedia to import into the library before applying the commands.
dryRunNoApply and report, but do not save.
commandsYes
projectAssetIdYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.36.0

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, openWorldHint=true and idempotentHint=false, and the description is consistent with that. It adds real value beyond them: audio is analysed server-side for free, commands execute one at a time so later commands can reference earlier-created clips, speed ramps shorten a clip only when the source runs out, and results include warnings for effects that apply but won't be visible. However it never states transactionality or what happens to already-applied commands when one errors.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded with purpose, return shape and the render follow-up, and uses section labels (Timeline, Look, Text, Subtitles, Keyframes, Speed). But it is extremely dense, run-on and separator-choked, making it hard to scan; a fair amount reads as reference manual rather than tool-selection guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with ~24 command variants, 4 top-level params and no output schema, the description covers most of what an agent needs, including the return payload (applied/errors, warnings, created ids, updated timeline). Remaining holes are undocumented commands and payloads (ADD_AUDIO_REACTIVE, portions of mask/animation payloads).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With only 50% schema coverage, the description carries most of the payload semantics: beatInterval meaning (4 = one per bar), grid 'peaks' vs 'beats', mode redistribute vs snap, keyframe t measured from the clip start rather than the timeline, easing options and default, gradient fill presets, canvas preset dimensions. Gaps remain — ADD_AUDIO_REACTIVE is named with no explanation, and SET_MASK/SET_OBJECT_ANIMATION payload semantics are thin.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names a specific verb and resource — apply editing commands to a saved editor project, then save it back under the same id — and enumerates the domains covered (clips, trims, speed ramps, transitions, canvas preset, texts, subtitles, masks, keyframes, audio). It also distinguishes itself from siblings by routing rendering to vivid_render_project and id lookup to vivid_get_editor_project.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit alternatives and ordering rules are given: use vivid_analyze_audio and its beats/peaks for hand-planned cuts instead of CUT_TO_BEAT, get cues from vivid_transcribe for subtitles, read ids from vivid_get_editor_project or the previous result's "created", and send APPLY_EFFECT_RECIPE after CUT_TO_BEAT. It even states preferences (recipes "preferred over hand-written effects/keyframes") and batch semantics.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.