Everything else
Discovery and the tools that fit no single step. 28 tools.
On the main list
The tools a client sees when it connects.
tools
Find a tool
Every Typecut tool is callable here by name, listed or not. {step} lists the unlisted ones for a step, one line each; {q} finds tools by words; {name} returns one tool's full definition; {can: "picture"} lists what you can do with an image. No arguments: the steps. Free.
| Input | Type | Description |
|---|---|---|
step | "orient" | "plan" | "sound" | "bible" | "media" | "build" | "look" | "deliver" | "talk" | "account" | "more" | A step of the loop. |
q | string | Words to find, e.g. "cutout" or "beat grid". |
name | string | One tool's name: its arguments. |
can | "picture" | What can I do with a picture? Every image ability, the tool for each and the chain. |
invoke_tool
Call a house tool by name
Call any Typecut tool by name, listed here or not. Its own arguments go INSIDE arguments, never beside name: {name:"get_bible", arguments:{project_id:"…"}}.
| Input | Type | Description |
|---|---|---|
name required | string | Tool name. |
arguments | object | |
describe | boolean | Return its schema, call nothing. |
Callable by name
Not listed on connect, to keep the list short. Call them directly by name, or find them with tools.
ask
Ask the person to choose, on the canvas
ADMIN ONLY, experimental. Ask the person to choose, as a question bubble on the project bar: a question and 2-8 options (label, picture, what it points at). The person clicks one (or several with multi) and may add a note; read it back with ask_answers. Use it instead of a long text question when the choice is visual (designs, takes, crops, colours). Anchor it with scene_id (+ t_start) so it shows over that moment. The answer also arrives as a reply in the comment thread. Free.
| Input | Type | Description |
|---|---|---|
project_id required | string | Project. |
question required | string | The question, one line ("Which tab icon should we ship?"). |
options required | array | 2-8 options: {id?, label, image_url? (https), detail? (one line), ref? (a tc: handle or scene id)}. Ids default to a, b, c. |
multi | boolean | Allow several picks. Default false. |
scene_id | string | Show it over this scene. |
t_start | number | Scene seconds it points at. |
anchors | array | Several places at once, as add_comment takes them. |
ask_answers
Read the answers to your choice cards
ADMIN ONLY, experimental. The choice cards on a project and what the person picked: status waiting | answered | all (default answered), or ids for the cards you asked. Each answer lists the picked options in full and the note. Free.
| Input | Type | Description |
|---|---|---|
project_id required | string | Project. |
status | "waiting" | "answered" | "all" | Default answered. |
ids | array | Only these cards (comment ids from ask). |
scene_id | string | Only cards on this scene. |
bake_layer
Bake a scene to a cached layer
Render a scene at a low rate (at most 24 frames, 12 fps, so a long scene gets a lower rate) and stitch the frames into ONE sheet a parent composition draws by timeline time, so the slow or static part of a design (a blurred gradient, an ambient loop) is painted once instead of every frame. Answers the layer manifest (sheet_url, cols, rows, n, duration, size) and its handle tc:layer/\<scene id\>. Draw it in a scene with the lib:layer module: <script data-tc-module="lib:layer@1"></script> then LAYER.sheet(tl, root, {src: sheet_url, cols, n, dur, mode: "blend"}) (seek-pure: frame = f(t)). The scene may live in ANOTHER project of the account. Re-bake when the source scene changes. Free: it uses the preview renderer (quick:true, the warm CPU pass, by default; quick:false is the GPU renderer, identical to the MP4, slower).
| Input | Type | Description |
|---|---|---|
scene_id required | string | The scene to bake. |
fps | number | Frames per second to bake (default and cap 12; at most 24 frames in all). |
cols | number | Columns in the sheet. Default fits the frame count. |
cell_width | number | Width of one frame in the sheet (default 640; height follows the canvas). |
quick | boolean | Default true: warm CPU renderer. false: GPU renderer. |
compose_dialogue
Compose a conversation into a scene, in one call
A SCRIPT in, a finished dialogue scene out: every line voiced (cached lines are free), laid out on one clock with real overlaps, and landed with kit:dialogue's visual (speaker cards, voice meter, word-by-word captions) and the speech clips placed. One call replaces speak per line + hand-computed timings + put_scene_composition. SPENDS CREDITS at the voice-over rate for new lines. Create the scene first (create_scene), then pass its scene_id.
cast: [{name, voice_id | clone_id, color?, img?, actor?}] — actor ("dee"|"gus") hosts a 3D character on the card (also pass modules: the Cast3D set the project uses, e.g. ["kit:cast3d@2", …]). script, one line each (# comments ok): Dee: So I tried putting my phone away. a turn; it starts ~60 ms before the line before ends ~Vic@phone: Mm-hm. a backchannel, quiet, under the word "phone" (or @3 = word index) Vic<-: And? Did it work? a cut-in over the last 280 ms of the line before Dee: [laugh] No. {gap=250 tone=angry gain=-3} options: gap (ms, negative = overlap), overlap (ms, cut-in), gain (dB), tone (a Fish tag put in front) ALL(Dee,Vic): [shout] No! unison: every voice at once, ±40 ms spread, small pitch differences ALL(Dee,Vic,Nell) {mode=stagger}: Yes. Yes. Yes. stagger: call and response; {mode=murmur}: low, filtered crowd under the scene
Returns { scene_id, duration_sec, credits_used, lines:[{n, who, kind, t0, t1, overlaps:[line numbers sounding with it], text, asset_id, audio_sec}], clips, voiced, kit }; asset_id is the line's voiced take (one speaker), e.g. talking_head {audio_asset_id} in a chain. Change it with edit_dialogue (by line number) instead of re-sending the script. A scene carries at most 24 speech clips (one per speaker per line, a unison counts each voice); 1920×1080. style: podcast (default) | cards | caption | drama | interview. dry_run:true lays the plan out (real timings for lines already voiced, a pace estimate for new ones, estimated:true) and speaks nothing.
| Input | Type | Description |
|---|---|---|
scene_id required | string | The scene to land the dialogue in (create_scene). |
cast | array | Speakers, 1–8. name is what the script uses before the colon. |
script | string | The dialogue, one line per turn (see above). |
style | "podcast" | "cards" | "caption" | "drama" | "interview" | Default podcast. |
label | string | Small corner label. |
accent | string | Accent colour of the meter and captions. |
modules | array | Extra module refs to pin in the scene, e.g. the Cast3D set ["kit3d@11", "kit:cast3d@2"]. |
dry_run | boolean | Parse and report; speak and land nothing. |
html | string | YOUR OWN composition, with the dialogue written inside it as <script type="application/tc-dialogue">{"cast":[…],"script":"…"}</script> above your timeline script. It lands as written with the speech placed, and window.__tcDialogue = {duration, lines:[{n, who, t0, t1, words:[{w,t,e}]}]} (scene seconds) is set right after the block, so your motion reads the real times. Re-land after an edit: only changed lines are voiced. cast/script then come from the block. |
src_url | string | Same as html, by a create_upload url (prefer it for anything over a few KB). |
check | boolean | Listen back: a speech recogniser hears every take and reports per line what was heard, match (0-1 of the words), loudness, any [tag] read aloud, the loudness spread between speakers, and a warning per line to redo. Free; adds a few seconds. |
declare_agent
Say who you are
Declare yourself ONCE, early, so the project shows a named agent and not a new anonymous one. Your edits, comments and claims are then attributed to "<name> (agent) on behalf of <the person>" in History, the contributor list and comment threads. key is your stable identity: reuse the same key whenever you reconnect or start a new chat for the same job, and you stay ONE agent (default: a slug of name). Name the job, not the model ("Roman scene writer"). If another agent started you, pass its key as parent_key. Calling again renames or re-points this connection. run_chain steps are attributed to you automatically. Not declaring is fine: you show up as one "Unnamed agent" per connection. Free.
| Input | Type | Description |
|---|---|---|
name required | string | What people should see, e.g. "Roman scene writer". 1-80 chars. |
key | string | Stable identity you reuse on every reconnect: lowercase letters, digits, . _ - (max 64). Default: a slug of name. |
role | string | One line on what you are for (optional). |
parent_key | string | The key of the agent that spawned you (optional). |
edit_dialogue
Edit lines of a composed dialogue
Change a dialogue compose_dialogue landed, by line number (as its result listed them), and re-land it. Only edited text is voiced again (every other line is cached, so it costs nothing); timings, overlaps and the visual are recomputed. SPENDS CREDITS only for new text. ops (applied against the numbering you see): {line:4, text:"No. Not even a little."} rewrite a line {line:4, tone:"angry"} / {line:4, tone:null} set or clear the expression tag {line:5, gap_ms:-300} start 300 ms earlier (more overlap); null = default {line:5, overlap_ms:450, gain_db:-3} a cut-in's overlap / any line's level {line:6, at_word:"phone"} move a backchannel under another word {line:6, remove:true} {insert_after:3, script:"~Vic: Right."} new lines, script syntax; insert_after:0 = at the start Returns the same compact result as compose_dialogue. dry_run:true checks the edit without voicing or landing.
| Input | Type | Description |
|---|---|---|
scene_id required | string | The dialogue scene. |
ops required | array | Edits: {line, text?, tone?, gap_ms?, overlap_ms?, gain_db?, at_word?, remove?} or {insert_after, script}. |
style | "podcast" | "cards" | "caption" | "drama" | "interview" | Change the look. |
label | string | Change the corner label. |
dry_run | boolean | Check the edit; voice and land nothing. |
export_formats
List export formats
Every export Typecut can make: scope (scene / project), file type, alpha, cost, options and status (live, flag = some accounts, coming = planned). Free.
| Input | Type | Description |
|---|---|---|
scope | "scene" | "project" | Only formats for this scope. |
export_web_block
Export a scene as an embeddable web block
Publish a finished scene you authored (plain DOM + GSAP, resolved, seekable) as a block any web page can embed and drive: returns a hosted embed_url and a two-line snippet (a div with data-typecut-block + the loader script). You declare the contract in manifest: {v:1, initial, inputs:{name:{type:number|boolean|trigger, min,max,default, states:[whenTrue,whenFalse] (boolean), go (trigger)}}, states:{name:{range:[t0,t1] seconds, drive:<number input>, mode:play|loop, next, at, poster}}, events:{name:{on:<css selector>, dom:<event>}}, slots:{name:{type:text|color, selector, var}}, audio:{tracks:[{src:<https url>, start:<scene seconds where the file begins>, volume, role}]} (plays in sync with the timeline after the visitor's first tap; block.sound(true) from a click handler)}. The page then calls block.set(input, value), block.on(event, fn), block.slot(name, value). A validation gate refuses a scene that is not portable (WebGL/video/audio elements, unresolved data-tc markers, network access, no registered timeline) or a manifest that does not match it (ranges past the end, unknown drive/next/go, selectors matching nothing); every error says what to change. dry_run runs the gate and publishes nothing. re-exporting a scene keeps its embed_url and bumps the version. Free. CHAPTER: pass chapter_id instead of scene_id (manifest optional) to publish a whole chapter as ONE sequence embed: its scenes play back to back on one clock, mounted a window at a time (WebGL, Pixi, three.js and project modules are fine), with the chapter's voice and the project's music carried across scene boundaries (with_scene_audio, default on for chapters). Every scene must be HTML you authored; manifest.sequence {loop, autoplay, controls}; the page gets block.play/pause/seek(sec). embed_url opens a play page in a browser.
| Input | Type | Description |
|---|---|---|
scene_id | string | The scene to export (or chapter_id). |
chapter_id | string | Export this whole chapter as one sequence (instead of scene_id). |
manifest | object | The block contract (see description); optional for a chapter. |
name | string | Optional label for the block. |
dry_run | boolean | Run the validation gate only; publish nothing. |
with_scene_audio | boolean | Add the scene's own voice and music as audio tracks (when the manifest has none). |
feedback_digest
Read the collected platform feedback
ADMIN ONLY. The platform feedback agents filed or the server captured (failed calls, oversized results), clustered by tool and kind and ranked by how many separate sessions hit it. days defaults to 14. Facts first: weigh a cluster by sessions, not count, and treat suggestions as ideas. Free.
| Input | Type | Description |
|---|---|---|
days | number | Look back this many days (1-90, default 14). |
generate_3d
Make a 3D model from a picture
Reconstruct ONE picture as a 3D model (.glb with textures): a library image (image_asset_id) or a public https image url (image_url). Name the model explicitly: microsoft:trellis-2@4b or meta:sam@3d; there is no default yet because neither licence is cleared for shipping. SPENDS CREDITS (dry_run:true quotes). The model is filed in the library with its licence note and optimised, and comes back as result {assetId, url, model}; place it in a scene with build_terrain-style loading (models: [{ src: "tc-asset:<assetId>" }]). Takes about a minute: this waits ~50 s, then answers status "generating"; poll get_generation with the generation_id.
| Input | Type | Description |
|---|---|---|
project_id required | string | Project whose library receives the model. |
image_asset_id | string | The picture: a library image id. Or image_url. |
image_url | string | The picture: a public https image url. |
model required | string | microsoft:trellis-2@4b or meta:sam@3d. Required. |
prompt | string | Optional steering text, up to 1000 chars. |
seed | number | Provider seed for a repeatable take. |
dry_run | boolean | Quote only: returns {credits, available} and charges nothing. |
get_frames
See the source at any time
Frames of a source video cut at the times you name: JPEGs hosted by content (a repeat of the same time, width and crop costs nothing). Pass analysis_id (the video analysis) OR project_id (its recorded reference). times: seconds, up to 12 per call. width: pixels (default 640). crop: [x, y, w, h] as fractions of the frame, to zoom on a region. Returns {frames: [{t, url, width}]} — open the urls to look.
Cut the replica with the same times and crop to compare the two pictures side by side.
| Input | Type | Description |
|---|---|---|
analysis_id | string | The video analysis to cut frames from. |
project_id | string | Instead of analysis_id: the project whose recorded reference to cut frames from. |
times required | array | Seconds into the video, e.g. [4.5, 12, 47.3]. |
width | number | Frame width in pixels (default 640). |
crop | array | Region as fractions of the frame [x, y, w, h], e.g. [0.25, 0.25, 0.5, 0.5]. |
get_inventory
Composition inventory
A project's composition INVENTORY: every scene with its gen:html compositions summarised as a gist (layout family, visible text, palette, unit keys, cast subjects) at ~60 tokens each — plan across chapters without inspecting compositions one by one. Optional where narrows it; the same selector drives batch_add_elements. First call computes gists (seconds); later calls are cached. Free.
| Input | Type | Description |
|---|---|---|
project_id required | string | Project id. |
where | object | Scene selector: scene_ids[], chapter_ids[], family (title-card|stat|list|diagram|illustration|caption|media|engine|mixed, or an array), text_contains, title_contains, state (resolved|prompted|placeholder|generating|error), position (first-in-chapter|last-in-chapter), has_composition, cast. |
cached_only | boolean | Skip blob fetches; uncached scenes show gist: null. |
get_overlays
What a project shows over its film
The overlay rules a project shows: its own list (source "project"), or, when it has none, its workspace's brand kit (source "workspace"). Free, reads only.
| Input | Type | Description |
|---|---|---|
project_id required | string | Project id. |
get_revisions
Edit history (restore points)
A project's edit-history ledger, newest first: every row is the PRIOR state of a scene or chapter captured just before an update or delete, whoever made it (you, the editor, the Director). Covers element patches, composition-unit edits and llm_edit rewrites, which list_changes does not. Use to answer "what changed?", to find a restore point for undo_scene_edit, or to link a fix to a comment (resolve_comment revision_id). Scope to one scene with scene_id. Free.
| Input | Type | Description |
|---|---|---|
project_id required | string | Project id. |
scene_id | string | Only this scene's history. |
limit | number | Max rows (default 20, max 200). |
get_sources
Read what the project was grounded in
What this project was grounded in and WHAT WAS SAID in it. Free.
READ THIS AFTER transcribe_media rather than guessing: each source reports its state and, when something went wrong, the REASON in words. A transcription that failed is a fact to relay, not a silence to explain away.
The transcript comes back as timed SEGMENTS — \{index, startSec, endSec, text\} — not as words. That shape is the point: a quote and a clip window are the same object. When you pick a moment, quote its segment back to the user AND use the same numbers as the shot's in-point and length. Never paraphrase a passage you are about to show; quote it.
from_sec/to_sec read one passage instead of the whole talk. timed: false means the recording has text but no word timings (it was ingested before timings were kept) — read that as NOT TIMED, never as "nothing was said".
| Input | Type | Description |
|---|---|---|
project_id required | string | The project whose sources to read. |
source_id | string | One source, instead of all of them. |
from_sec | number | Read from this second of the recording. |
to_sec | number | Read up to this second. |
limit | number | Max segments per source (default 200, max 500). |
include_text | boolean | Also return the raw transcript text. Off by default — the segments are usually what you want. |
instrument_loop
Add, change, vary or list instrument loop clips (synth loops people play and modulate live)
Our own instrument, as a LOOP CLIP on a track of its own, named after the instrument (like a pattern region in a DAW): a synth whose loop is 8 lead rows by 16 steps a bar plus a bass row, through cutoff, reso, decay, echo and level knobs and a lead envelope. The editor plays it live from its notes; a recorded copy, made on the server with the same renderer, is what the share link and the export play, so all sound the same. A person selects the clip in /studio and plays, edits and modulates it in the Sound tab. list: true returns the project's loop clips, each with its whole loop. Send any part of loop; the rest comes from the clip (a change, a variation) or the default (the NexusUI demo pattern at the film's tempo). loop: {name, bars: 1|2|4|8, bpm, rows: 8 midi pitches top first, lead: per step (bars×16) the row indexes 0-7 that sound, bass: per step a midi note or 0, knobs: {cut, res, dec, dly, level} each 0..1, env: [{x,y}] 0..1, auto: automation lines {loops: how many repeats of the loop the lines span (1-64), lanes: {cut|res|dec|level: [{x: 0..1 through the span, v: 0..1}]}}: each note takes the line's value where it starts, e.g. a filter sweep over 4 loops; the clip repeats the span}. Add: chapter_id + start (chapter seconds) + repeats (default 4). Change: clip_id + the parts of loop to change. VARIATION: from_clip_id + the parts to change (and/or vary: a seed for a new lead line over the same bass) makes a new clip, by default right after the original. The answer carries the whole loop. Free. Check it in the mix with listen.
| Input | Type | Description |
|---|---|---|
project_id required | string | Project id. |
chapter_id | string | Chapter to add the loop clip to. |
clip_id | string | A loop clip to change instead. |
from_clip_id | string | Make a variation of this loop clip: a new clip from its loop. |
vary | number | A seed: a new lead line over the same bass (with clip_id or from_clip_id). |
list | boolean | List the project's loop clips with their loops; nothing changes. |
start | number | Seconds on the chapter clock (default 0). |
repeats | number | How many times the loop plays (default 4). |
duration | number | Or the clip length in seconds. |
loop | object | {name?, bars?, bpm?, rows?, lead?, bass?, knobs?, env?, auto?}; missing parts come from the clip or the default. |
issues
Work the issue inbox
ADMIN ONLY. The issue inbox: agents' reports (and, with origin "system" or "all", the server's captured failures) as issues. op list: open ones by default (status, origin, issue_kind, days, limit). op update: move several at once: claimed with board_task (the board task or PR that now owns them), fixed or wont_fix with resolution (one line). Merge duplicates by updating them together. Free.
| Input | Type | Description |
|---|---|---|
op | "list" | "update" | list (default) or update. |
status | string | list: open (default), claimed, fixed, wont_fix or all. update: the new status. |
origin | "agent" | "system" | "all" | list: agent reports (default), system captures, or all. |
issue_kind | "gap" | "bug" | "slow" | "missing_tool" | "docs" | list: only this kind. |
days | number | list: look back this many days (default 30). |
limit | number | list: at most this many (default 50, max 200). |
ids | array | update: the issue ids (up to 50). |
board_task | string | update to claimed: the board task id or PR url that owns them. |
resolution | string | update to fixed / wont_fix: what was done, or why not. |
list_observations
What is known about an artifact
Everything the system has DETERMINED about one artifact — the caption written when a picture was ingested, plus any later analysis of it — with its provenance. Use before building around an asset you have not seen. Each entry says WHO produced it and how sure they were: a user_assertion or correction OUTRANKS anything the system inferred, and an entry flagged superseded is history — read it to understand a past decision, never to act on. This never replaces the artifact itself; it tells you what is already known about it. Free.
| Input | Type | Description |
|---|---|---|
subject_type required | string | What kind of thing you are asking about — usually 'media_asset' (also: scene, project, chapter, generation). |
subject_id required | string | The artifact id (e.g. an asset id from list_media). |
kind | string | Restrict to one analysis kind (e.g. 'caption'). |
limit | number | Max entries (default 20, max 100). |
list_overlay_blocks
The blocks the overlay layer can show
The OVERLAY LAYER puts channel things on top of a film, switched on by rules: an animated logo, a lower third, a subscribe button, an end card. This lists the house starter kit: each block with its url (kit:<id>@<n>), size and length, its fill-in fields (vars) and where and when it usually goes (suggested). Copy a block and its suggested when/place into a rule for set_overlays or set_brand_kit. Free, reads only.
No inputs.
pin_reply
Pin your answer to the project as a report
Send the answer you already wrote (markdown, as you would write it in chat) and it is pinned to the project and shown as ONE animated report scene, with no HTML and no spec to write. Rules turn its shape into beats: # Title; the opening paragraph is the verdict (signed from); each ## heading starts a section; a paragraph is a note; a bullet list is a list (✓ ⚠ ✗ ○ at the start set each line's mark), or counters when every line is "label: number"; a short numbered list is a row of steps; a table is a table; a picture  is a picture, two side by side are a compare. The scene goes at the end of the project's "Updates" chapter (made on first use); the full text is kept as its comment, so people answer it in place. Returns {scene_id, share_url, comment_id, beats, duration_sec}. dry_run:true lists the beats and writes nothing. Free; a few seconds. For a custom look, use put_report with your own spec.
| Input | Type | Description |
|---|---|---|
project_id required | string | The project the answer belongs to. |
text required | string | Your answer as written (markdown), up to 5000 characters. |
from | string | Who is answering, e.g. "Claude (media chains)". |
title | string | Title, when the text has no "# Title" line. |
chapter | string | Chapter to add it to (default "Updates", made on first use). |
look | "doodle" | Hand-drawn look. |
light | boolean | Light background. |
dry_run | boolean | Show the beats only; writes nothing. |
play_clip
Answer as a short animated clip
Show the user a SHORT animated clip instead of (or beside) text: 1-8 beats on one clock, each with an optional spoken line. Free, stores nothing. Use it when the answer is numbers, a comparison or a short sequence the user would rather watch than read; for plain prose just write prose. It plays in the conversation where the host renders MCP Apps views, with a Play button (sound starts on the first press); elsewhere the user gets the text summary, so keep the same facts in your reply.
clip = {"beats":[BEAT,...], "title"?, "voice"?:false to start muted, "aspect"?:"16:9"|"4:3"|"1:1"|"9:16"}. Write "say" (one sentence, <=160 chars) FIRST in each beat. BEAT kinds, k: note text, who? kpi items:[[label,value,delta?,tone?]] (<=4; numbers count up; tone ok|warn|bad) bars items:[[label,number]], u? (<=6) list items:[[text,status,detail?]] status ok|warn|bad|todo (<=5) steps items:[[label,done|now|next]] (<=5) table cols:[str], rows:[[cell,...]] (<=4 rows) spark items:[numbers], v:"headline", label An item beat (kpi, bars, list, steps, spark) may add swap:[{at:seconds, items:[...]}] (up to 6, at 0.5-30 s) to replace its items at those offsets inside the same view. Beat 1 is the answer. 3-5 beats, short labels, numbers as numbers (take them from tool results, never memory). A bad spec is rejected with the reason.
| Input | Type | Description |
|---|---|---|
clip required | object |
resolve_handles
Resolve tc: handles
Turn tc:\<kind\>/\<id\>[@from-to] handles into what a player needs: title, poster, duration, project, where to play it. Batched (up to 50, comma-separated), free, read-only. Kinds: scene (any scene you can read, in any of your projects; clip_url when it has a render), asset, project, layer (a scene baked by bake_layer: the sheet and how to draw it). A handle that does not resolve answers {ok:false, error} for itself only. Citing costs about 10 tokens a handle instead of pasting the thing.
| Input | Type | Description |
|---|---|---|
handles required | array | Handles such as tc:scene/<id>@0-4.8 or tc:layer/<scene id>. |
set_overlays
Show blocks over a film, by rules
Set a project's overlay rules (the WHOLE list; it replaces the previous one). A rule is {id, block, when, place, vars?, hold?, giveWay?, off?, label?}. block: copy it from list_overlay_blocks ({url, width, height, duration, loop?}). when: {kind:"always"} | {kind:"at", t} (film seconds) | {kind:"start"|"end", of:"film"|"chapter"|"scene", index? (1-based, -1 = the last; omit = every one), offset?} | {kind:"every", seconds, first?, until?} (counts FILM time, across cuts) | {kind:"word", word:"subscrib*", every?} (when the voice says it; * matches the start of a word; first time only unless every) | {kind:"cue", name}. place: {anchor: top-left|top|top-right|left|center|right|bottom-left|bottom|bottom-right, size (share of the frame width, 0.02–1), margin?, dx?, dy?}. vars: the block's fill-in fields (its words, colours, picture). hold: seconds it stays up (default the block's length). giveWay: rule ids this one hides behind (a logo stepping aside for the end card). inherit:true instead drops the project's list so it shows its workspace's brand kit again; rules:[] shows nothing. Blocks ride in the scene documents that already render: no extra render pass, and the editor, the share page and the export agree. Free; re-render a scene to see it in its MP4.
| Input | Type | Description |
|---|---|---|
project_id required | string | Project id. |
rules | array | The whole list of rules (see the description). |
inherit | boolean | Drop the project's own list: it shows its workspace's brand kit again. |
expected_version | integer | The project's edit_version (from get_project or the last project-level write's response). Optional: when sent, the write is refused with a conflict (current_version, last_writer) if anyone changed the project settings since — nothing is written. Omit to write unconditionally. |
stop_sharing
Switch a share link off
Switch the project's public share link off: every link minted for it stops working. Use it to undo a public link the user did not ask for, or when the user asks to unpublish. Free.
| Input | Type | Description |
|---|---|---|
project_id required | string | Project id. |
youtube_channel
Study a YouTube channel
ADMIN-ONLY. A YouTube channel's latest and most popular long-form videos with their numbers: title, exact views, duration, publish date, keywords, description, and outlier = views ÷ the median views of its latest uploads (2.0 = twice its usual). Plus the channel itself (subscribers, video count, description). Free, a few seconds.
Use it to see what a channel makes and what performs before writing in its style; then youtube_transcripts for what the videos SAY. channel takes a channel URL, a @handle, a channel id (UC…), or any one of its video URLs. include adds videos you name (the one you are replicating).
| Input | Type | Description |
|---|---|---|
channel required | string | Channel URL, @handle, channel id (UC…), or a URL of one of its videos. |
latest | number | How many of its latest uploads (default 20, max 60). |
popular | number | How many of its most viewed videos (default 10, max 30). |
include | array | Video URLs or ids to add to the list. |
details | boolean | false = the tab's rounded numbers only, no per-video read (faster). |
youtube_transcripts
Read what YouTube videos say
ADMIN-ONLY. Timed transcripts of public YouTube videos: the narration one sentence per line with its [m:ss] start, plus a visual log (one line per shot: setting, characters, on-screen text, charts, camera, transition). Each comes with words and words-per-minute. Gemini watches each video from its URL (YouTube captions cannot be read from our servers); a video is transcribed ONCE and kept, so reading it again is instant and free. Free to you (~$0.03 per 15 min of video on us).
ASYNCHRONOUS: the first call starts the missing ones and returns their status (pending / ready / failed with the reason); call again with the same ids to poll — a 15-minute video takes about a minute, two run at a time. Up to 50 ids per call. include_text: true returns the transcript and visual log, for at most 5 ids per call. retry_failed: true re-runs failed ones.
| Input | Type | Description |
|---|---|---|
video_ids required | array | YouTube video ids (11 characters), e.g. from youtube_channel. |
include_text | boolean | Return the transcript and visual log (max 5 ids per call). |
start | boolean | false = only report, start nothing. |
retry_failed | boolean | Re-run videos that failed before. |