# timeline_edit MCP tool

Edit the timeline.

{/* Generated by landing/scripts/generate-mcp-docs.ts. Do not edit. */}

MCP name `timeline_edit` dispatches to renderer `timelineEdit`.

Does not use hosted quota. Local editor operation.

Edit the timeline. Set action to addClip, updateClip, deleteClip, splitClip, deleteLayer, removeTimeRanges, removeSilences, addTransition, addFade, or removeTransition. Call timeline_get_state before using clip or layer ids. Never use type=text; use component clips for typography. After creating a component, place it with addClip type=component and that assetId. Omit layerId unless targeting an existing layer; addClip creates a matching layer when none exists. Pass newLayer true only when the user wants a separate layer of the same type. To shorten the timeline to N seconds: action removeTimeRanges with ranges [{from: N, to: currentEnd}]. To shorten one clip from its in-point: action updateClip with clipId and duration N. removeSilences takes only an assetId. addFade is the fade between two adjacent clips. addClip ripples later clips by default. Pass the child fields for that action. Editor must be open. Does not use hosted quota. Local editor operation.

## Advertised MCP input

This tool is registered with **passthrough**. The fields below are what `listTools` advertises. The renderer still validates the child fields for the chosen action or kind. Extra advertised-only values are documented under Reachable behavior.

| Field | Type | Required | Constraints | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `action` | enum("addClip", "updateClip", "deleteClip", "splitClip", "deleteLayer", "removeTimeRanges", "removeSilences", "addTransition", "addFade", "removeTransition") | yes | — | — | action for timeline_edit |
| `clipId` | string | no | minLength 1 | — | Required for updateClip and splitClip. Clip id from timeline_get_state. |
| `clipIds` | string[] | no | minItems 1 | — | Required for deleteClip. One or more clip ids from timeline_get_state. |
| `layerId` | string | no | minLength 1 | — | Optional target layer id for addClip or updateClip. |
| `layerIds` | string[] | no | minItems 1 | — | Required for deleteLayer. |
| `assetId` | string | no | minLength 1 | — | Required for removeSilences. Also used by addClip for media clips. |
| `type` | string | no | — | — | Clip type for addClip, or transition type for addTransition. |
| `name` | string | no | — | — | Optional clip name for addClip or updateClip. |
| `start` | number | no | min 0 | — | Timeline start in seconds for addClip or updateClip. |
| `duration` | number | no | exclusiveMin 0 | — | Clip duration in seconds for addClip, updateClip, addFade, or addTransition. |
| `offset` | number | no | min 0 | — | Source in-point in seconds for addClip or updateClip. |
| `time` | number | no | min 0 | — | Required for splitClip. Timeline time in seconds. 0 is valid. |
| `speed` | number | no | exclusiveMin 0 | — | Playback speed for addClip or updateClip. |
| `newLayer` | boolean | no | — | — | addClip: place on a new layer of the same type. |
| `ripple` | boolean | no | — | — | addClip: ripple later clips. Default true. |
| `snapTo` | enum("beat", "downbeat") | no | — | — | Optional beat snap for addClip, updateClip, or splitClip. |
| `ranges` | object[] | no | minItems 1 | — | Required for removeTimeRanges. Ripple-delete these timeline ranges. |
| `ranges[].from` | number | yes | min 0 | — | Range start in timeline seconds. |
| `ranges[].to` | number | yes | min 0 | — | Range end in timeline seconds. |
| `fromClipId` | string | no | minLength 1 | — | Required for addFade, addTransition, and removeTransition. |
| `toClipId` | string | no | minLength 1 | — | Required for addFade, addTransition, and removeTransition. |
| `resultStart` | integer | no | min 0; max 9007199254740991 | 0 | First character offset to return. Use 0 for the first call. |
| `resultEnd` | integer | no | min 1; max 9007199254740991 | 8000 | Exclusive end offset. resultEnd - resultStart must be at most 8000. Increment resultStart by 8000 to page through large results. |

## Reachable behavior

Advertised action values match the renderer children: `addClip`, `updateClip`, `deleteClip`, `splitClip`, `deleteLayer`, `removeTimeRanges`, `removeSilences`, `addTransition`, `addFade`, `removeTransition`.

## Renderer child fields

These are the authoritative fields for each `action`. Send them on the same MCP call. Grouped MCP tools use passthrough, so these fields are not all listed in the advertised schema.

### `action=addClip`

Renderer tool: `timelineAddClip`.

Insert a new clip on the timeline. Never use type='text'; for titles, captions, labels, callouts, lower thirds, or any typography, create a custom component asset and add it with type='component'. For media clips (video/audio/image/model3d), provide type and assetId only—do not pass src (playback URL is resolved from assetId). For component clips, provide type='component' and assetId—componentName and inputDefs are resolved from the asset automatically. For 3D model clips, use type='model3d' with a GLB or glTF asset. For screen recordings, use type='vidova' with assetId—cursor data, face camera, and auto-zoom are resolved automatically. Use type='camera' for project-level whole-composition camera moves; these go on the singleton camera track, not a visual layer. Omit layerId unless targeting an existing layer; a matching layer is created when none exists. Pass newLayer true to put the clip on a new top layer of the same type. Optionally pass componentInputs to override default input values; for component asset inputs, pass asset IDs and Vidova resolves them to playback URLs at preview/render time. Use enterTransition and exitTransition for fade, slide, zoom, blur, RGB split, fisheye, swoosh, whip pan, radial blur, glitch, pixel burst, light leak, liquid warp, prism split, bounce pop, spin zoom, shake pop, flash bang, or vortex twist effects (type, duration 0.1-5s).

| Field | Type | Required | Constraints | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `layerId` | string | no | — | — | — |
| `newLayer` | boolean | no | — | — | When true, place the clip on a new top layer instead of the existing matching-type layer. Use only when the user wants a separate layer. Omit layerId in that case. |
| `name` | string | no | minLength 1; maxLength 180 | — | — |
| `start` | number | no | min 0 | 0 | — |
| `duration` | number | no | exclusiveMin 0 | — | — |
| `offset` | number | no | min 0 | — | — |
| `speed` | number | no | max 8; exclusiveMin 0 | — | — |
| `position` | object | no | — | — | — |
| `position.x` | number | yes | — | — | — |
| `position.y` | number | yes | — | — | — |
| `scale` | object | no | — | — | — |
| `scale.x` | number | yes | — | — | — |
| `scale.y` | number | yes | — | — | — |
| `assetId` | string | no | — | — | — |
| `ripple` | boolean | no | — | — | Ripple insert (default). Every clip already at or after 'start' on the same layer shifts right by the new clip's duration, so the insert makes room instead of covering existing content. Pass false to drop the clip in place, which fails if it would overlap a neighbour. |
| `snapTo` | enum("beat", "downbeat") | no | — | — | Snap start to the nearest beat or downbeat of this clip's asset. Requires a completed detectBeatGrid result for that asset. |
| `type` | enum("video", "audio", "image", "text", "component", "model3d", "blur", "vidova", "camera") | no | — | — | — |
| `width` | number | no | exclusiveMin 0 | — | — |
| `height` | number | no | exclusiveMin 0 | — | — |
| `sourceDuration` | number | no | exclusiveMin 0 | — | — |
| `focus` | object | no | — | — | — |
| `focus.x` | number | yes | min 0; max 1 | — | — |
| `focus.y` | number | yes | min 0; max 1 | — | — |
| `focus.zoom` | number | yes | min 1 | — | — |
| `objectFit` | enum("contain", "cover", "fill") | no | — | — | — |
| `audioVolume` | number | no | min 0; max 1 | — | — |
| `volume` | number | no | min 0; max 1 | — | — |
| `text` | string | no | — | — | — |
| `fontSize` | number | no | exclusiveMin 0 | — | — |
| `fill` | string | no | — | — | — |
| `opacity` | number | no | min 0; max 1 | — | — |
| `template` | enum("text", "title-card", "lower-third", "caption-style") | no | — | — | — |
| `subtitle` | string | no | — | — | — |
| `backgroundColor` | string | no | — | — | — |
| `enterTransition` | object | no | — | — | — |
| `enterTransition.type` | enum("none", "fade", "slide-left", "slide-right", "slide-up", "slide-down", "cross-dissolve", "zoom", "blur", "dip-to-black", "rgb-split-in", "rgb-split-out", "fisheye-in", "fisheye-out", "swoosh-left", "swoosh-right", "swoosh-up", "swoosh-down", "radial-blur-burst", "glitch-pop-in", "glitch-pop-out", "whip-pan-left", "whip-pan-right", "pixel-burst", "light-leak", "liquid-warp", "prism-split", "bounce-pop", "spin-zoom", "shake-pop", "flash-bang", "vortex-twist", "depth-swoop", "depth-rush", "depth-swing") | yes | — | — | — |
| `enterTransition.duration` | number | yes | min 0.1; max 5 | — | — |
| `exitTransition` | object | no | — | — | — |
| `exitTransition.type` | enum("none", "fade", "slide-left", "slide-right", "slide-up", "slide-down", "cross-dissolve", "zoom", "blur", "dip-to-black", "rgb-split-in", "rgb-split-out", "fisheye-in", "fisheye-out", "swoosh-left", "swoosh-right", "swoosh-up", "swoosh-down", "radial-blur-burst", "glitch-pop-in", "glitch-pop-out", "whip-pan-left", "whip-pan-right", "pixel-burst", "light-leak", "liquid-warp", "prism-split", "bounce-pop", "spin-zoom", "shake-pop", "flash-bang", "vortex-twist", "depth-swoop", "depth-rush", "depth-swing") | yes | — | — | — |
| `exitTransition.duration` | number | yes | min 0.1; max 5 | — | — |
| `componentInputs` | object | no | — | — | For component clips: input values keyed by input name. For asset inputs, pass the source asset ID; preview/render resolves it to a playback URL. |
| `blurStrength` | number | no | min 0; max 100 | — | — |
| `blurQuality` | number | no | min 1; max 32 | — | — |
| `roundedness` | number | no | min 0 | — | — |
| `cameraSettings` | object | no | — | — | For camera clips: whole-composition pan/zoom/rotation settings. |
| `cameraSettings.position` | object | no | — | — | — |
| `cameraSettings.position.x` | number | yes | — | — | — |
| `cameraSettings.position.y` | number | yes | — | — | — |
| `cameraSettings.zoom` | number | no | min 0.05 | — | — |
| `cameraSettings.rotation` | number | no | — | — | — |

### `action=updateClip`

Renderer tool: `timelineUpdateClip`.

Adjust clip timing, target layer, static opacity, and type-specific settings. For text clips, use textSettings with typography, effects, template, subtitle, and backgroundColor. For component clips, use componentInputs to update input values; for asset inputs, pass asset IDs and Vidova resolves them to playback URLs at preview/render time. For video, image, component, and Vidova clips, use perspectiveSettings to set the exact ClipPerspectiveSurface object: enabled, rotateX, rotateY, rotateZ, perspective, depthShading, rim, sheen, depthBlur, shadow, debugGrid. For Vidova screen-recording clips, use vidovaSettings to edit layout, cursor/spotlight, click effects, motion/tracking, facecam/camera overlay, appearance/quality, captions, audio, and keyboard shortcut UI controls. For camera clips, use cameraSettings and camera.* keyframe paths for whole-composition pan/zoom/rotation on the singleton camera track. Vidova zoom clips remain screen-recording zooms only; clip animation is per-clip attention motion only. Use enterTransition and exitTransition to set fade, slide, zoom, blur, RGB split, fisheye, swoosh, whip pan, radial blur, glitch, pixel burst, light leak, liquid warp, prism split, bounce pop, spin zoom, shake pop, flash bang, or vortex twist effects (type, duration 0.1-5s). Use animation (none|hover|pulse|float|glow|zoom-in|zoom-out) and animationIntensity (0-5x) for idle animations on visual layer clips. Use keyframeActions to set/remove/clear keyframes on position.x/y, scale.x/y, focus.x/y/zoom, modelPosition.x/y/z, modelRotation.x/y/z, camera.position.x/y, camera.zoom, camera.rotation, faceCamera.position.x/y, perspective.rotateX/Y/Z, perspective.depth, perspective.depthShading, perspective.rim, perspective.sheen, perspective.depthBlur, and perspective.shadow using clip-local display seconds. COLOR GRADING: contrast, saturation, temperature, tint, highlights, shadows use range -100 to 100 (NOT 0–1). Use 20–50 for visible effect—values like 0.1 or 0.2 are too small. exposure is -2 to 2.

| Field | Type | Required | Constraints | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `clipId` | string | yes | minLength 1 | — | — |
| `name` | string | no | minLength 1; maxLength 180 | — | — |
| `start` | number | no | min 0 | — | — |
| `snapTo` | enum("beat", "downbeat") | no | — | — | Snap start to the nearest beat or downbeat of this clip asset. Requires a completed detectBeatGrid result. Ignored unless start is provided. |
| `duration` | number | no | min 0.1 | — | — |
| `offset` | number | no | min 0 | — | — |
| `speed` | number | no | max 8; exclusiveMin 0 | — | — |
| `layerId` | string | no | minLength 1 | — | — |
| `position` | object | no | — | — | — |
| `position.x` | number | yes | — | — | — |
| `position.y` | number | yes | — | — | — |
| `scale` | object | no | — | — | — |
| `scale.x` | number | yes | — | — | — |
| `scale.y` | number | yes | — | — | — |
| `opacity` | number | no | min 0; max 1 | — | — |
| `assetId` | string | no | — | — | — |
| `videoSettings` | object | no | — | — | — |
| `videoSettings.width` | number | no | exclusiveMin 0 | — | — |
| `videoSettings.height` | number | no | exclusiveMin 0 | — | — |
| `videoSettings.objectFit` | enum("contain", "cover", "fill") | no | — | — | — |
| `videoSettings.focus` | object | no | — | — | — |
| `videoSettings.focus.x` | number | yes | min 0; max 1 | — | — |
| `videoSettings.focus.y` | number | yes | min 0; max 1 | — | — |
| `videoSettings.focus.zoom` | number | yes | min 1 | — | — |
| `videoSettings.colorGrading` | object | no | — | — | Exposure: -2 to 2. All others: -100 to 100. Use 20-50 for visible change—never 0.1 or 0.2. |
| `videoSettings.colorGrading.exposure` | number | no | min -2; max 2 | — | Range -2 to 2 only |
| `videoSettings.colorGrading.contrast` | number | no | min -100; max 100 | — | Range -100 to 100. Use 15-50 for visible effect (not 0.1). |
| `videoSettings.colorGrading.saturation` | number | no | min -100; max 100 | — | Range -100 to 100. Use 15-50 for visible effect (not 0.15). |
| `videoSettings.colorGrading.temperature` | number | no | min -100; max 100 | — | Range -100 to 100 (cool to warm). Use 15-50 for visible effect (not 0.2). |
| `videoSettings.colorGrading.tint` | number | no | min -100; max 100 | — | Range -100 to 100 (green to magenta). Use 15-50 for visible effect. |
| `videoSettings.colorGrading.highlights` | number | no | min -100; max 100 | — | Range -100 to 100. Use 15-50 for visible effect. |
| `videoSettings.colorGrading.shadows` | number | no | min -100; max 100 | — | Range -100 to 100. Use 15-50 for visible effect. |
| `videoSettings.chromaKey` | object | no | — | — | — |
| `videoSettings.chromaKey.color` | string | yes | pattern `^#[0-9a-fA-F]{3,6}$` | — | — |
| `videoSettings.chromaKey.threshold` | number | yes | min 0; max 1 | — | — |
| `videoSettings.chromaKey.smoothness` | number | no | min 0; max 1 | — | — |
| `videoSettings.audioVolume` | number | no | min 0; max 1 | — | — |
| `audioSettings` | object | no | — | — | For audio and video clips: playback volume from 0 to 1. Use volume 0 to mute a clip. On a video clip this sets the same value as videoSettings.audioVolume. |
| `audioSettings.volume` | number | no | min 0; max 1 | — | — |
| `imageSettings` | object | no | — | — | — |
| `imageSettings.width` | number | no | exclusiveMin 0 | — | — |
| `imageSettings.height` | number | no | exclusiveMin 0 | — | — |
| `imageSettings.colorGrading` | object | no | — | — | Exposure: -2 to 2. All others: -100 to 100. Use 20-50 for visible change—never 0.1 or 0.2. |
| `imageSettings.colorGrading.exposure` | number | no | min -2; max 2 | — | Range -2 to 2 only |
| `imageSettings.colorGrading.contrast` | number | no | min -100; max 100 | — | Range -100 to 100. Use 15-50 for visible effect (not 0.1). |
| `imageSettings.colorGrading.saturation` | number | no | min -100; max 100 | — | Range -100 to 100. Use 15-50 for visible effect (not 0.15). |
| `imageSettings.colorGrading.temperature` | number | no | min -100; max 100 | — | Range -100 to 100 (cool to warm). Use 15-50 for visible effect (not 0.2). |
| `imageSettings.colorGrading.tint` | number | no | min -100; max 100 | — | Range -100 to 100 (green to magenta). Use 15-50 for visible effect. |
| `imageSettings.colorGrading.highlights` | number | no | min -100; max 100 | — | Range -100 to 100. Use 15-50 for visible effect. |
| `imageSettings.colorGrading.shadows` | number | no | min -100; max 100 | — | Range -100 to 100. Use 15-50 for visible effect. |
| `textSettings` | object | no | — | — | — |
| `textSettings.text` | string | no | minLength 1 | — | — |
| `textSettings.fontSize` | number | no | exclusiveMin 0 | — | — |
| `textSettings.fontFamily` | string | no | minLength 1 | — | — |
| `textSettings.fontWeight` | number | no | min 1; max 1000 | — | — |
| `textSettings.fill` | string | no | — | — | — |
| `textSettings.opacity` | number | no | min 0; max 1 | — | — |
| `textSettings.effect` | enum("none", "glitch", "ripple", "vhs", "pixelate", "chromatic", "fisheye") | no | — | — | — |
| `textSettings.effectIntensity` | number | no | min 0; max 1 | — | — |
| `textSettings.template` | enum("text", "title-card", "lower-third", "caption-style") | no | — | — | — |
| `textSettings.subtitle` | string | no | — | — | — |
| `textSettings.backgroundColor` | string | no | — | — | — |
| `enterTransition` | object \\| null | no | — | — | — |
| `exitTransition` | object \\| null | no | — | — | — |
| `animation` | enum("none", "hover", "pulse", "float", "glow", "zoom-in", "zoom-out") \\| null | no | — | — | — |
| `animationIntensity` | number | no | min 0; max 5 | — | — |
| `componentInputs` | object | no | — | — | For component clips: input values keyed by input name. For asset inputs, pass the source asset ID; preview/render resolves it to a playback URL. |
| `perspectiveSettings` | object | no | strict | — | For video, image, component, and Vidova clips: exact ClipPerspectiveSurface object. Required fields: enabled, rotateX, rotateY, rotateZ, perspective, depthShading, rim, sheen, depthBlur, shadow, debugGrid. |
| `perspectiveSettings.enabled` | boolean | yes | — | — | — |
| `perspectiveSettings.rotateX` | number | yes | min -1.2; max 1.2 | — | — |
| `perspectiveSettings.rotateY` | number | yes | min -1.2; max 1.2 | — | — |
| `perspectiveSettings.rotateZ` | number | yes | min -3.14; max 3.14 | — | — |
| `perspectiveSettings.perspective` | number | yes | min 0.1; max 4 | — | — |
| `perspectiveSettings.depthShading` | number | yes | min 0; max 0.6 | — | — |
| `perspectiveSettings.rim` | number | yes | min 0; max 1 | — | — |
| `perspectiveSettings.sheen` | number | yes | min 0; max 1 | — | — |
| `perspectiveSettings.depthBlur` | number | yes | min 0; max 10 | — | — |
| `perspectiveSettings.shadow` | number | yes | min 0; max 0.6 | — | — |
| `perspectiveSettings.debugGrid` | boolean | yes | — | — | — |
| `vidovaSettings` | object | no | — | — | — |
| `vidovaSettings.layout` | enum("screen-and-cam", "screen-only", "cam-only", "half-half") | no | — | — | — |
| `vidovaSettings.crop` | object | no | — | — | Normalized crop edges for the screen recording: Left/Top/Right/Bottom in the 0..1 range. |
| `vidovaSettings.crop.Top` | number | no | min 0; max 1 | — | — |
| `vidovaSettings.crop.Bottom` | number | no | min 0; max 1 | — | — |
| `vidovaSettings.crop.Left` | number | no | min 0; max 1 | — | — |
| `vidovaSettings.crop.Right` | number | no | min 0; max 1 | — | — |
| `vidovaSettings.zoomLayerId` | string | no | — | — | Use a zoom layer ID from timeline_get_state. Pass an empty string to clear. |
| `vidovaSettings.blurLayerId` | string | no | — | — | Use an overlay/blur layer ID from timeline_get_state. Pass an empty string to clear. |
| `vidovaSettings.roundedness` | number | no | min 0; max 50 | — | — |
| `vidovaSettings.padding` | number | no | min 0; max 100 | — | — |
| `vidovaSettings.screenAudioVolume` | number | no | min 0; max 1 | — | — |
| `vidovaSettings.cameraAudioVolume` | number | no | min 0; max 1 | — | — |
| `vidovaSettings.muteScreenAudio` | boolean | no | — | — | — |
| `vidovaSettings.muteCameraAudio` | boolean | no | — | — | — |
| `vidovaSettings.zoomAnimationStyle` | enum("soft-spring", "snappy-spring", "soft-landing", "fast-settle", "gentle-curve") | no | — | — | Zoom feel: soft-spring (default), snappy-spring, soft-landing, fast-settle, gentle-curve. |
| `vidovaSettings.panAnimationStyle` | enum("heavy-camera", "quick-follow", "soft-lag") | no | — | — | Pan feel: heavy-camera (default), quick-follow, soft-lag. |
| `vidovaSettings.linkedZoomTransitionDuration` | number | no | min 0; max 2 | — | — |
| `vidovaSettings.useAutoLinkedZoomTransitionDuration` | boolean | no | — | — | Set true to clear the manual linked zoom handoff duration. |
| `vidovaSettings.trackingIntensity` | integer | no | min 0; max 5 | — | — |
| `vidovaSettings.trackingStyle` | enum("steadicam", "director", "anchor", "momentum") | no | — | — | Camera-path solver for cursor-following zooms: steadicam, director, anchor, or momentum. |
| `vidovaSettings.clickFollow` | object | no | strict | — | Keep out-of-view clicks in frame and near centre. Clicks already in view stay put. enabled (default true), tight 0.05-0.45 (default 0.35), zoom 1-6 (steadicam click-punch cap, default 3.5), window 0.2-1.6s (default 0.8), lead 0-0.8s (default 0.38), margin 0.35-1 (steadicam hold slack, default 0.85). Partial objects merge with the clip current values. |
| `vidovaSettings.clickFollow.enabled` | boolean | no | — | — | — |
| `vidovaSettings.clickFollow.tight` | number | no | min 0.05; max 0.45 | — | — |
| `vidovaSettings.clickFollow.window` | number | no | min 0.2; max 1.6 | — | — |
| `vidovaSettings.clickFollow.lead` | number | no | min 0; max 0.8 | — | — |
| `vidovaSettings.clickFollow.zoom` | number | no | min 1; max 6 | — | — |
| `vidovaSettings.clickFollow.margin` | number | no | min 0.35; max 1 | — | — |
| `vidovaSettings.motionBlurStrength` | number | no | min 0; max 2 | — | — |
| `vidovaSettings.cursorHidden` | boolean | no | — | — | False shows the cursor. |
| `vidovaSettings.cursorStyle` | enum("default", "cartoon", "modern", "original", "banana", "capitaine-dark", "capitaine-light", "touch", "tahoe", "whitesur", "bibata", "bibata-original") | no | — | — | — |
| `vidovaSettings.cursorSize` | number | no | min 16; max 256 | — | — |
| `vidovaSettings.smoothCursorChanges` | boolean | no | — | — | — |
| `vidovaSettings.hideCursorWhenStill` | boolean | no | — | — | — |
| `vidovaSettings.enableCursorMotionBlur` | boolean | no | — | — | — |
| `vidovaSettings.cursorMotionBlurStrength` | number | no | min 0; max 2 | — | — |
| `vidovaSettings.enableCursorTilting` | boolean | no | — | — | — |
| `vidovaSettings.returnToOriginalPosition` | boolean | no | — | — | — |
| `vidovaSettings.cursorSmoothingStyle` | enum("original", "steady", "soft", "fluid", "glide") | no | — | — | Cursor path: original, steady (default), soft, fluid, glide. |
| `vidovaSettings.pinCursorToClicks` | boolean | no | — | — | Pin the path through each click so the cursor lands on the button. |
| `vidovaSettings.cursorClickPinWindow` | number | no | min 0.04; max 0.4 | — | How long the cursor holds on each click, in seconds. Default 0.12. |
| `vidovaSettings.cursorSmoothingTime` | number | no | min 0.01; max 0.12 | — | Steady and Soft smoothness in seconds. Default 0.045. |
| `vidovaSettings.cursorSmoothingSpace` | number | no | min 4; max 80 | — | Steady: how strongly fast flicks are kept, in pixels. Default 18. |
| `vidovaSettings.cursorSmoothingTension` | number | no | min 40; max 400 | — | Fluid spring weight. Default 170. |
| `vidovaSettings.cursorSmoothingFriction` | number | no | min 4; max 40 | — | Fluid spring damping. Default 20. |
| `vidovaSettings.cursorSmoothingSimplify` | number | no | min 2; max 40 | — | Glide: how much jitter to drop before the curve. Default 8. |
| `vidovaSettings.clickEffectStyle` | enum("none", "default", "effect-1", "effect-2", "effect-3", "effect-4", "effect-5", "effect-6") | no | — | — | — |
| `vidovaSettings.clickEffectSize` | number | no | min 16; max 256 | — | — |
| `vidovaSettings.cursorSpotlight` | object | no | strict | — | — |
| `vidovaSettings.cursorSpotlight.enabled` | boolean | no | — | — | — |
| `vidovaSettings.cursorSpotlight.radius` | number | no | — | — | — |
| `vidovaSettings.cursorSpotlight.softness` | number | no | — | — | — |
| `vidovaSettings.cursorSpotlight.dimOpacity` | number | no | — | — | — |
| `vidovaSettings.cursorSpotlight.onlyOnClick` | boolean | no | — | — | — |
| `vidovaSettings.cursorSpotlight.clickWindow` | number | no | min 0.05; max 4 | — | — |
| `vidovaSettings.camera` | object | no | — | — | — |
| `vidovaSettings.camera.size` | number | no | min 5; max 70 | — | — |
| `vidovaSettings.camera.sizeDuringZoom` | number | no | min 5; max 100 | — | — |
| `vidovaSettings.camera.roundedness` | number | no | min 0; max 100 | — | — |
| `vidovaSettings.camera.shape` | enum("default", "squircle", "circle") | no | — | — | — |
| `vidovaSettings.camera.hideCamera` | boolean | no | — | — | False shows the camera overlay. |
| `vidovaSettings.camera.mirrorCamera` | boolean | no | — | — | — |
| `vidovaSettings.camera.removeBackground` | boolean | no | — | — | True composites the baked person mask. The mask must already exist on the camera asset. |
| `vidovaSettings.camera.position` | object | no | — | — | Camera anchor grid position. Use -1, 0, or 1 for x/y. |
| `vidovaSettings.camera.position.x` | number | yes | min -1; max 1 | — | — |
| `vidovaSettings.camera.position.y` | number | yes | min -1; max 1 | — | — |
| `vidovaSettings.camera.alignment` | object | no | — | — | Crop alignment inside squircle/circle camera shapes. |
| `vidovaSettings.camera.alignment.x` | number | yes | min -1; max 1 | — | — |
| `vidovaSettings.camera.alignment.y` | number | yes | min -1; max 1 | — | — |
| `vidovaSettings.camera.differentSizeDuringZoom` | boolean | no | — | — | — |
| `vidovaSettings.camera.verticalPadding` | number | no | min 0; max 100 | — | — |
| `vidovaSettings.camera.globalPosition` | boolean | no | — | — | True anchors the camera to the scene instead of the clip. |
| `vidovaSettings.mouseIndicator` | object | no | — | — | — |
| `vidovaSettings.mouseIndicator.enabled` | boolean | no | — | — | — |
| `vidovaSettings.mouseIndicator.position` | object | no | — | — | Mouse indicator anchor grid position. Use -1, 0, or 1 for x/y. |
| `vidovaSettings.mouseIndicator.position.x` | number | yes | min -1; max 1 | — | — |
| `vidovaSettings.mouseIndicator.position.y` | number | yes | min -1; max 1 | — | — |
| `vidovaSettings.mouseIndicator.size` | number | no | min 40; max 180 | — | Mouse indicator size in px. |
| `vidovaSettings.mouseIndicator.opacity` | number | no | min 0; max 1 | — | — |
| `vidovaSettings.mouseIndicator.style` | enum("minimal", "dark", "light", "colored") | no | — | — | — |
| `vidovaSettings.mouseIndicator.highlightColor` | string | no | pattern `^#[0-9a-fA-F]{6}$` | — | — |
| `vidovaSettings.mouseIndicator.minActiveDuration` | number | no | min 0.02; max 0.5 | — | Minimum button/wheel highlight duration in seconds. |
| `vidovaSettings.mouseIndicator.globalPosition` | boolean | no | — | — | True anchors the mouse indicator to the scene instead of the clip. |
| `vidovaSettings.quality` | number | no | min 0 | — | Motion-blur shader sample quality. 0 disables sampled motion blur. |
| `vidovaSettings.sharpenFactor` | number | no | min 0; max 5 | — | — |
| `vidovaSettings.shadowStrength` | number | no | min 0; max 100 | — | — |
| `vidovaSettings.inset` | number | no | min 0; max 50 | — | — |
| `vidovaSettings.isVertical` | boolean | no | — | — | — |
| `vidovaSettings.showShortcuts` | boolean | no | — | — | — |
| `vidovaSettings.shortcutsSize` | number | no | min 1; max 300 | — | — |
| `vidovaSettings.shortcutsDuration` | number | no | min 0.5; max 5 | — | — |
| `vidovaSettings.captionSettings` | object | no | strict | — | — |
| `vidovaSettings.captionSettings.enabled` | boolean | no | — | — | — |
| `vidovaSettings.captionSettings.fontFamily` | string | no | — | — | — |
| `vidovaSettings.captionSettings.fontWeight` | 400 \\| 500 \\| 700 | no | — | — | — |
| `vidovaSettings.captionSettings.fontSize` | number | no | — | — | — |
| `vidovaSettings.captionSettings.distanceFromBottom` | number | no | — | — | — |
| `vidovaSettings.captionSettings.style` | enum("pill", "karaoke-lime", "karaoke-magenta", "karaoke-cyan", "outlined", "bold-outline", "minimal", "word-highlight", "pink-pill", "dark-pill-lime", "cloud-blob", "amber-tape", "studio") | no | — | — | — |
| `vidovaSettings.captionSettings.textColor` | string | no | — | — | — |
| `vidovaSettings.captionSettings.highlightColor` | string | no | — | — | — |
| `vidovaSettings.captionSettings.backgroundColor` | string | no | — | — | — |
| `vidovaSettings.captionSettings.shadowColor` | string | no | — | — | — |
| `vidovaSettings.captionSettings.shadowBlur` | number | no | — | — | — |
| `vidovaSettings.captionSettings.maxCharsPerLine` | number | no | — | — | — |
| `cameraSettings` | object | no | — | — | For camera clips only: project-level whole-composition pan/zoom/rotation. |
| `cameraSettings.position` | object | no | — | — | Whole-composition pan in scene pixels. |
| `cameraSettings.position.x` | number | yes | — | — | — |
| `cameraSettings.position.y` | number | yes | — | — | — |
| `cameraSettings.zoom` | number | no | min 0.05 | — | Whole-composition camera zoom. 1 = default, 2 = 2x. |
| `cameraSettings.rotation` | number | no | — | — | Whole-composition camera rotation in degrees. |
| `keyframeActions` | object \\| object \\| object[] | no | minItems 1 | — | Optional keyframe edits using clip-local display seconds. Supported propertyPath values: position.x, position.y, scale.x, scale.y, focus.x, focus.y, focus.zoom, modelPosition.x, modelPosition.y, modelPosition.z, modelRotation.x, modelRotation.y, modelRotation.z, camera.position.x, camera.position.y, camera.zoom, camera.rotation, faceCamera.position.x, faceCamera.position.y, perspective.rotateX, perspective.rotateY, perspective.rotateZ, perspective.depth, perspective.depthShading, perspective.rim, perspective.sheen, perspective.depthBlur, perspective.shadow. Use op=set with time/value, op=remove with time, or op=clear to remove all keys for a property. |

### `action=deleteClip`

Renderer tool: `timelineDeleteClip`.

Remove one or more clips from the timeline by their IDs. Deletion is a ripple delete: each clip's time range is cut from every layer and all later content shifts left to close the gap, so the edit never leaves a hole. To cut a range without naming clips, use timelineRemoveTimeRanges instead.

| Field | Type | Required | Constraints | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `clipIds` | string[] | yes | minItems 1 | — | List of clip IDs to delete from the timeline |

### `action=splitClip`

Renderer tool: `timelineSplitClip`.

Split a single clip at a specific timestamp. For removing multiple silence segments or time ranges at once, prefer timelineRemoveTimeRanges instead.

| Field | Type | Required | Constraints | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `clipId` | string | yes | minLength 1 | — | — |
| `time` | number | yes | min 0 | — | Timeline timestamp in seconds |
| `snapTo` | enum("beat", "downbeat") | no | — | — | Snap the split time to the nearest beat or downbeat of this clip's asset. Requires a completed detectBeatGrid result. |

### `action=deleteLayer`

Renderer tool: `timelineDeleteLayer`.

Remove one or more timeline layers by their IDs. All clips on those layers are removed.

| Field | Type | Required | Constraints | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `layerIds` | string[] | yes | minItems 1 | — | List of layer IDs to delete from the timeline |

### `action=removeTimeRanges`

Renderer tool: `timelineRemoveTimeRanges`.

Remove multiple time ranges from the timeline in a single operation. Each range is deleted with ripple: all content after the removed interval shifts left to close the gap. Use this for bulk silence removal or any scenario where multiple segments need to be cut at once.

| Field | Type | Required | Constraints | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `ranges` | object[] | yes | minItems 1 | — | List of timeline time ranges (in seconds) to remove with ripple. All clips after each removed range will shift left automatically. Overlapping or adjacent ranges are merged before applying. |
| `ranges[].from` | number | yes | min 0 | — | Start of the range to remove, in timeline seconds |
| `ranges[].to` | number | yes | min 0 | — | End of the range to remove, in timeline seconds |

### `action=removeSilences`

Renderer tool: `removeSilencesFromAsset`.

Remove the dead air from a transcribed recording. Vidova computes the silence ranges from the transcript word timings itself and ripple-deletes them, so no timestamps are needed and no speech is cut. Use this instead of working out silence ranges and calling timelineRemoveTimeRanges by hand. Requires a completed transcription and exactly one recording clip for the asset on the timeline.

| Field | Type | Required | Constraints | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `assetId` | string | yes | minLength 1 | — | Asset id of the transcribed recording to tighten. |

### `action=addTransition`

Renderer tool: `timelineAddTransition`.

Add a named transition between two adjacent video clips on the same layer. Prefer timelineAddFade when the user asks for a fade — do not use cross-dissolve as a substitute for fade. Supports fade, slide, zoom, blur, RGB split, fisheye, swoosh, whip pan, radial blur, glitch, pixel burst, light leak, liquid warp, prism split, bounce pop, spin zoom, shake pop, flash bang, and vortex twist transitions.

| Field | Type | Required | Constraints | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `fromClipId` | string | yes | minLength 1 | — | — |
| `toClipId` | string | yes | minLength 1 | — | — |
| `type` | enum("fade", "slide-left", "slide-right", "slide-up", "slide-down", "cross-dissolve", "zoom", "blur", "dip-to-black", "rgb-split-in", "rgb-split-out", "fisheye-in", "fisheye-out", "swoosh-left", "swoosh-right", "swoosh-up", "swoosh-down", "radial-blur-burst", "glitch-pop-in", "glitch-pop-out", "whip-pan-left", "whip-pan-right", "pixel-burst", "light-leak", "liquid-warp", "prism-split", "bounce-pop", "spin-zoom", "shake-pop", "flash-bang", "vortex-twist", "depth-swoop", "depth-rush", "depth-swing") | no | — | "fade" | Transition effect type |
| `duration` | number | no | max 5; exclusiveMin 0 | 0.5 | Transition duration in seconds |

### `action=addFade`

Renderer tool: `timelineAddFade`.

Add a fade between two adjacent video clips on the same layer. Use this whenever the user asks for a fade or soft dissolve — always applies type fade (never cross-dissolve). Prefer this over timelineAddTransition for fade requests.

| Field | Type | Required | Constraints | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `fromClipId` | string | yes | minLength 1 | — | — |
| `toClipId` | string | yes | minLength 1 | — | — |
| `duration` | number | no | max 5; exclusiveMin 0 | 0.5 | Fade duration in seconds |

### `action=removeTransition`

Renderer tool: `timelineRemoveTransition`.

Remove an existing transition between two clips.

| Field | Type | Required | Constraints | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `fromClipId` | string | yes | minLength 1 | — | — |
| `toClipId` | string | yes | minLength 1 | — | — |

## Result window

Every local MCP tool accepts `resultStart` and `resultEnd` so large payloads can be paged.

- `resultStart` — first character offset. Default `0`.
- `resultEnd` — exclusive end offset. Default `8000`.
- `resultEnd - resultStart` must be at most **8000** characters.
- Increment `resultStart` by 8000 to read the next window.

## Nested objects

Cursor, camera overlay, layout, and captions live on `vidovaSettings` during `updateClip`. See [vidovaSettings](/docs/mcp/schemas/vidova-settings).

Do not call a retired `vidova_set_cursor` tool. It is not in MCP.
