Skip to main content
Glama

Set transform

clip.set_transform
Idempotent

Position, scale, rotate, fade, flip, crop or fit a video clip over the tracks below (picture-in-picture, overlays, punch-ins). fit none shows a graphic at its own pixel size, so scale 1 is its real size; the default contain scales it to touch the frame edges. Any number takes a constant or {keyframes: [{frame, value, ease}]} with frames from the clip start; a keyframe's ease shapes the move from it to the next one (sine_in_out, cubic_out, back_out, hold and more). Overlays that must follow a zoom or pan: put the clip and its overlays in a timeline of the same shape, nest it with clip.add {nested_timeline_id} and transform the nested clip, so everything moves together. Omitted fields keep their value; null resets one. To pin an overlay to a moving subject, use media.analyze track boxes as keyframes: for each box, frame = timeline frame of the box time (where the tracked clip plays that media second) minus this clip's start, x = box x + w/2 and y = box y + h/2 (add your offset). That holds when the tracked clip fills the frame as is; if it is scaled, moved or cropped, map the box through its transform first. Skip boxes with found false. The result's placements say where the clip now shows, in sequence pixels: its picture box, the part visible after crop and mask inside the frame, and the source pixels that show there. Returns the edit result (see the server instructions).

Input Schema

NameRequiredDescriptionDefault
xNoCentre x, 0 = left edge, 1 = right edge (default 0.5); -4 to 5
yNoCentre y, 0 = top, 1 = bottom (default 0.5); -4 to 5
fitNo
cropNo
flipNo
scaleNoSize relative to the fit (default 1); 0 to 20
clip_idYes
opacityNoOpacity (default 1); 0 to 1
previewNoinline: image in the result; link: URI that renders on read; nonelink
scale_xNoExtra horizontal stretch (default 1); 0 to 20
scale_yNoExtra vertical stretch (default 1); 0 to 20
rotationNoDegrees clockwise (default 0); -36000 to 36000
timeline_idYesTimeline handle; every edit returns a new one

Output Schema

NameRequiredDescriptionDefault
parentYesTimeline handle; every edit returns a new one
changedYes
clip_idNo
previewYes
clip_idsNo
track_idNo
warningsYes
placementsNoWhere each clip the edit moved, cropped, masked or animated shows, sequence pixels
timeline_idYesTimeline handle; every edit returns a new one

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • changedInput schema / $defs / Animatable / anyOf
      Previous value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "properties": {
      -      "keyframes": {
      -        "description": "frame is relative to the clip start; ease from video://catalog/eases",
      -        "items": {
      -          "properties": {
      -            "ease": {
      -              "type": "string"
      -            },
      -            "frame": {
      -              "maximum": 100000000,
      -              "minimum": -1000000,
      -              "type": "integer"
      -            },
      -            "value": {
      -              "type": "number"
      -            }
      -          },
      -          "required": [
      -            "frame",
      -            "value"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 1000,
      -        "minItems": 1,
      -        "type": "array"
      -      }
      -    },
      -    "required": [
      -      "keyframes"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "type": "number"
      +  },
      +  {
      +    "properties": {
      +      "keyframes": {
      +        "description": "frame is from the clip start; ease shapes the move from this keyframe to the next (default linear; hold waits, then jumps)",
      +        "items": {
      +          "properties": {
      +            "ease": {
      +              "enum": [
      +                "linear",
      +                "hold",
      +                "smooth",
      +                "sine_in",
      +                "sine_out",
      +                "sine_in_out",
      +                "quad_in",
      +                "quad_out",
      +                "quad_in_out",
      +                "cubic_in",
      +                "cubic_out",
      +                "cubic_in_out",
      +                "quart_in",
      +                "quart_out",
      +                "quart_in_out",
      +                "quint_in",
      +                "quint_out",
      +                "quint_in_out",
      +                "expo_in",
      +                "expo_out",
      +                "expo_in_out",
      +                "circ_in",
      +                "circ_out",
      +                "circ_in_out",
      +                "back_in",
      +                "back_out",
      +                "back_in_out",
      +                "elastic_in",
      +                "elastic_out",
      +                "elastic_in_out",
      +                "bounce_in",
      +                "bounce_out",
      +                "bounce_in_out"
      +              ],
      +              "type": "string"
      +            },
      +            "frame": {
      +              "maximum": 100000000,
      +              "minimum": -1000000,
      +              "type": "integer"
      +            },
      +            "value": {
      +              "type": "number"
      +            }
      +          },
      +          "required": [
      +            "frame",
      +            "value"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 1000,
      +        "minItems": 1,
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "keyframes"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / crop / anyOf
      Previous value: -[
      -  {
      -    "description": "Fractions of the picture hidden from each edge; the rest stays where it was",
      -    "properties": {
      -      "bottom": {
      -        "default": 0,
      -        "maximum": 0.99,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "left": {
      -        "default": 0,
      -        "maximum": 0.99,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "right": {
      -        "default": 0,
      -        "maximum": 0.99,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "top": {
      -        "default": 0,
      -        "maximum": 0.99,
      -        "minimum": 0,
      -        "type": "number"
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "description": "Hidden from each edge, in fractions of the clip's fitted frame (the sequence-shaped box with the picture fitted inside, bars included, as for masks); the rest stays where it was",
      +    "properties": {
      +      "bottom": {
      +        "default": 0,
      +        "maximum": 0.99,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "left": {
      +        "default": 0,
      +        "maximum": 0.99,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "right": {
      +        "default": 0,
      +        "maximum": 0.99,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "top": {
      +        "default": 0,
      +        "maximum": 0.99,
      +        "minimum": 0,
      +        "type": "number"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / fit / anyOf
      Previous value: -[
      -  {
      -    "description": "contain: whole picture inside the frame, scaled up or down to touch its edges (default); cover: fill the frame, cropping; fill: stretch; none: its own pixels at sequence size, unscaled (a 300 px logo stays 300 px on a 1920 px sequence), for logos and graphics made to size",
      -    "enum": [
      -      "contain",
      -      "cover",
      -      "fill",
      -      "none"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "description": "contain: whole picture inside the frame, scaled up or down to touch its edges (default); cover: fill the frame, cropping what overflows equally on both sides (move x or y off 0.5 to show another part); fill: stretch; none: its own pixels at sequence size, unscaled (a 300 px logo stays 300 px on a 1920 px sequence), for logos and graphics made to size",
      +    "enum": [
      +      "contain",
      +      "cover",
      +      "fill",
      +      "none"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedOutput schema / properties / placements
      Added value: +{
      +  "description": "Where each clip the edit moved, cropped, masked or animated shows, sequence pixels",
      +  "items": {
      +    "properties": {
      +      "clip_id": {
      +        "type": "string"
      +      },
      +      "complete": {
      +        "description": "true: values move in straight lines between entries; false: evenly sampled",
      +        "type": "boolean"
      +      },
      +      "frames": {
      +        "items": {
      +          "properties": {
      +            "frame": {
      +              "description": "From the clip start",
      +              "type": "number"
      +            },
      +            "opacity": {
      +              "type": "number"
      +            },
      +            "picture": {
      +              "description": "The whole picture, before crop and mask and rotation",
      +              "properties": {
      +                "h": {
      +                  "type": "number"
      +                },
      +                "w": {
      +                  "type": "number"
      +                },
      +                "x": {
      +                  "type": "number"
      +                },
      +                "y": {
      +                  "type": "number"
      +                }
      +              },
      +              "required": [
      +                "x",
      +                "y",
      +                "w",
      +                "h"
      +              ],
      +              "type": "object"
      +            },
      +            "rotation": {
      +              "type": "number"
      +            },
      +            "source": {
      +              "anyOf": [
      +                {
      +                  "properties": {
      +                    "h": {
      +                      "type": "number"
      +                    },
      +                    "w": {
      +                      "type": "number"
      +                    },
      +                    "x": {
      +                      "type": "number"
      +                    },
      +                    "y": {
      +                      "type": "number"
      +                    }
      +                  },
      +                  "required": [
      +                    "x",
      +                    "y",
      +                    "w",
      +                    "h"
      +                  ],
      +                  "type": "object"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ],
      +              "description": "The part of the source that shows, source pixels"
      +            },
      +            "visible": {
      +              "anyOf": [
      +                {
      +                  "properties": {
      +                    "h": {
      +                      "type": "number"
      +                    },
      +                    "w": {
      +                      "type": "number"
      +                    },
      +                    "x": {
      +                      "type": "number"
      +                    },
      +                    "y": {
      +                      "type": "number"
      +                    }
      +                  },
      +                  "required": [
      +                    "x",
      +                    "y",
      +                    "w",
      +                    "h"
      +                  ],
      +                  "type": "object"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ],
      +              "description": "What it shows: crop and mask applied, rotated, inside the frame; null: nothing"
      +            }
      +          },
      +          "required": [
      +            "frame",
      +            "picture",
      +            "rotation",
      +            "opacity",
      +            "visible",
      +            "source"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "clip_id",
      +      "frames",
      +      "complete"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  2. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Beyond annotations, it discloses that omitted fields keep their value, null resets a field, keyframes are relative to clip start, and the result reports placements in sequence pixels including visible picture and source pixels. This is substantial behavioral context for a mutation tool with idempotentHint=true and destructiveHint=false.

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

Conciseness4/5

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

The core transform purpose is front-loaded and the description is information-dense, but it is a long single paragraph mixing core parameters with advanced tracking and nested-timeline workflows. Those details are useful, though the structure could be easier to scan.

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

Completeness5/5

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

For a complex 13-parameter edit tool with an output schema and annotations, the description covers the important non-schema behavior: keyframes, fit semantics, reset behavior, tracking workflow, and placement return information. The output schema handles return details, so no critical agent-facing context is missing.

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?

The description adds useful meaning for the Animatable parameters, keyframe frame/ease semantics, and scale relative to fit. However, with 13 parameters and 69% schema description coverage, some parameters such as flip and clip_id are left to the schema, and several fit/crop explanations partly repeat schema text.

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 description opens with a specific verb set and resource: position, scale, rotate, fade, flip, crop or fit a video clip over lower tracks. That makes the tool's transform scope clear and distinguishes it from adjacent clip tools such as clip.move, clip.trim, clip.set_mask, and clip.set_blend.

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?

It gives explicit usage scenarios: fit none for graphics at native pixel size, contain as default, nested timelines for overlays that must follow zoom/pan, and media.analyze track boxes for pinning overlays to moving subjects. It also explains reset behavior and names complementary tools/approaches rather than leaving the agent to infer them.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.