Skip to main content
Glama

Edit an animation

edit_animation

Change an animation's code: ONE revision, checked and probed in a sandbox. Each direct save returns a contact sheet (preview: false skips; preview: true or {entry, timestamps, filmstrip, ...} looks closer; preview_warnings).

The server holds the files; keep no local copy. Create with each file's full text once, then edit the saved revision: files: [{path, content}] new file or rewrite files: [{path, edits: [{old, new, replace_all?}]}] a change edits: [{op: delete|move, path, to?}] On disk: patch (git diff) · {path, patch} · {path, upload_id} · upload_ids from upload_file. A non-matching edit, or code that fails to parse or build, saves nothing (saved: false; retry from the same base_rev). files_changed has sha256s.

Before writing animation code, read get_design_guide({topic: "animation"}); before writing any helper, search the stdlib with get_design_guide({topic: "stdlib", query}). Hard rules: code never reads voiceover words; one cue per story moment, set from word timings, small things timed from it; render is deterministic (no state between frames, randomness only from the seed).

CREATE IN PLACE: animation:'new' (scope, name, slug) + project_id + place: {clip_index} places it on the first passing save and returns element_id; then edit by element_id + project_id (saves update the editor live). More entries: place: {clip_index, entry}, no changes needed. WHILE DRAFTING, PASS project_id: passing saves move its uses; without it uses_behind names projects that "will see an update available" and the animation.update_uses call. checkpoint: '' keeps a version.

Reply: rev, saved, probe, checks, errors, files_changed, element_id, uses_moved, uses_behind, note; detail: 'full' adds hunks and thumbnails. Imports stay pinned (dependency_updates: animation.bump('', '')); project-scope importers re-pin (dependents_updated).

Refusals: stale_base, target_required ('shared'|'fork'), check_failed. Settings, actions, cues: update_elements({updates:[{element_id, cues:[{op:'set', key, t}]}]}).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameNoOnly with animation 'new': the display name.
slugNoOnly with animation 'new': lowercase letters, digits and dashes; becomes @org/<slug>. Slugs are workspace-wide: one an animation of another project (or the library) holds is saved as the next free <slug>-N (the reply's animation and note say which, nothing to resend); one this project already holds is refused, naming it and a free slug.
editsNoOperations, applied in order before `files`: delete and move (replace and write also work; files is the shorter way).
filesNoPer-file changes, each with exactly one of edits, content, patch or upload_id. Applied in order after `edits` and `patch`, all saved as ONE revision.
patchNoFor a client working from files on disk: a unified diff of any number of files against the saved revision (`git diff`, `diff -u` or `diff -ruN`), run from the folder holding manifest.json. The server holds the base. New files (--- /dev/null), deletes and renames apply too. A hunk whose context no longer matches is refused with the saved lines around it; nothing is saved.
placeNoPut the animation on the canvas on the first passing save, as an animation element on this clip (the add_elements placement), and return its element_id: pass that on every later edit so each passing save updates the editor live. Needs project_id. Placing is per entry and clip: an entry already on that clip is not placed again (its element_id comes back); any other entry, or the same entry on another clip, is, and existing elements keep their own entries. Works for an existing animation too (animation: '@org/<slug>', or element_id + place.entry for another entry of the element's animation), and with no file changes at all it only places the latest revision. A failing save places nothing.
scopeNoOnly with animation 'new': one element, this project (the default with project_id; every scene of the video can import it), or the workspace library, only when the user asks to reuse it in other videos.
detailNosummary (default) returns the outcome and what changed; full adds the diff hunks and every probe thumbnail.
folderNoOnly with animation 'new' and scope 'library' (a save the user asked to keep for the workspace): the library folder, by path, e.g. 'Characters' or 'Characters/Presenters'. Missing folders are created (at most three levels).
targetNoRequired when the animation is used outside this project: 'shared' changes it for everyone who updates, 'fork' copies it for this project first. Official and community animations always fork.
dry_runNoBuild and check the edits without saving. Returns a `preview` token; render it with get_clip(render: {preview}).
previewNoEvery direct save already returns a small contact sheet (four moments). false skips it; true or an object asks for a larger one with your choice of entry, moments, a filmstrip and test settings (parameter_values, where an image setting may be an upload id or a URL; param_tracks, actions, cues). With a project it shows a placed use of the entry with that element's own settings; with dry_run the unsaved code; without project_id a plain background. Nothing about the preview is saved.
base_revNoThe revision you read and expect to edit from. If it has moved, the save is refused with stale_base, the current revision and the files changed since.
animationNoThe animation to edit when there is no element: @org/<slug> or an id. 'new' creates one (then pass scope, name and slug).
checkpointNoA one-line note that saves this revision, when it passes, as a version in the element's history in the editor (the user can preview and restore it there). Set it when you reach a state worth returning to, not on every draft.
element_idNoThe animation element this edit is about. The edit starts from the revision that element shows, and every use in this project moves to the new revision when it passes.
project_idNoProject the element is in. Needed with element_id.
upload_idsNoWhole files sent with upload_file(file_names: [...]) and its one curl: each upload's file name is its path in the animation (e.g. 'entries/city.js'), and its text replaces or adds that file. Applied after files.
update_dependentsNoAfter a passing save, re-pin every animation that imports this one (a kit's scenes) to the new revision in the same call and move this project's uses of them; dependents_updated {report, project_uses_moved, note} says what moved. Left out: on for a project-scoped animation saved with project_id, off otherwise (a library animation's importers span the workspace: pass true).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Added

TDQS

A4.3/5.0
Behavior5/5

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

Annotations are relatively weak here (idempotentHint=false, destructiveHint=false), so the description carries real weight: it discloses sandbox check/probe behavior, that a failing edit or unparseable build saves nothing (saved:false, retry from same base_rev), that preview output is never persisted, that the server holds the files, and that passing saves move uses live and can re-pin dependents. Nothing contradicts destructiveHint=false, since every change lands as a recoverable revision.

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 and organized into labelled blocks (CREATE IN PLACE, WHILE DRAFTING, Reply, Refusals), which helps. But it is a very long wall of compressed fragments using '·' separators and telegraphic phrases ('On disk: patch (git diff) · {path, patch} · ...'), which costs readability for a tool that already has a fully-documented schema.

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?

With no output schema, the description compensates by enumerating the reply fields (rev, saved, probe, checks, errors, files_changed, element_id, uses_moved, uses_behind, note) and detailing the refusals and the checkpoint/version behavior. Combined with placement, scope, target and dry_run guidance, an agent has everything needed to invoke a 19-parameter nested tool correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all 19 parameters in detail; the description's shorthand ('files: [{path, content}] new file or rewrite', 'edits: [{op: delete|move, path, to?}]') largely restates it. It adds a little workflow semantics (edits applied before files, upload_ids from upload_file, preview:false skips the contact sheet), but the baseline of 3 is right when the schema does the heavy lifting.

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

Purpose4/5

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

The opening sentence gives a specific verb and resource ('Change an animation's code'), plus a distinctive scope ('ONE revision, checked and probed in a sandbox') that separates it from read_animation and update_elements. It also implicitly contrasts with add_elements by noting placement is 'the add_elements placement'. It stops short of naming the sibling it supersedes for read-only work, but the scope statement is enough for an agent to choose correctly.

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 when-to-use: create with full file text once, then edit the saved revision; read get_design_guide({topic:'animation'}) before writing animation code and search stdlib before writing helpers; pass project_id while drafting; use target 'shared' vs 'fork' by whether the animation is used outside the project; set checkpoint only for states worth returning to. It also names the failure modes (stale_base, target_required, check_failed) and what to do about each.

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.