{"authentication":{"alsoAccepts":"bearer token minted at https://valmera.io/mcp/connect","dynamicClientRegistration":true,"metadata":"https://valmera.io/.well-known/oauth-authorization-server","pkce":"S256","required":true,"schemes":["oauth2"],"type":"oauth2"},"description":"Edit real video from inside an AI conversation. Upload footage, describe the edit in plain English, and the connected model cuts silences and filler words, adds word-timed captions, reframes to 9:16, mixes music, grades the picture, renders a preview, and looks at the frames it produced. When the user approves, export_final renders the full-quality MP4 from the ORIGINAL file (Studio export works too). It edits footage you already have \u2014 it is not a text-to-video generator.","documentationUrl":"https://valmera.io/mcp","iconUrl":"https://valmera.io/icon-512.png","name":"io.valmera/video-editor","notSupported":["delegating edits to Valmera's in-house agent","text-to-video generation of a whole video","SRT/VTT import or export (captions are burned in)","team seats or collaboration","direct publishing to YouTube or TikTok","custom font uploads","true crossfade/dissolve transitions","motion-tracked overlays or stickers","denoise / studio sound","AI music generation"],"notes":["Slow work (renders and pixel repainting) returns a job id and a wait_for_job tool rather than a fabricated completion.","Tools edit a versioned edit decision list. The uploaded file is never modified and any cut can be restored.","Direct editing tools use the same live registry and implementations as Valmera's own agent; agent-delegation tools are intentionally excluded from MCP.","A tool whose backing service is unconfigured is hidden from tools/list rather than exposed and failing at call time.","Editing one project from the web studio and over MCP at the same time is refused in both directions."],"pricing":{"free":"Account creation and upload are free; editing requires a subscription","paidFrom":"USD 25/month","url":"https://valmera.io/subscribe"},"prompts":[],"remotes":[{"type":"streamable-http","url":"https://valmera.io/mcp/server"}],"resources":[],"serverInfo":{"name":"valmera","title":"Valmera Video Editor","version":"0.1.0"},"sessionTools":["apply_short_edit_batches","create_project","download_url","export_final","index_status","list_projects","open_project","open_short","project_state","shorts_status","upload_finish","upload_start","wait_for_job","watch_video"],"title":"Valmera \u2014 agentic AI video editor","toolCount":143,"toolGroups":{"audio":["add_music","add_sfx","add_voiceover","add_web_sfx","audit_audio_mix","audition_sfx_candidates","beat_align_cuts","extract_audio","fetch_sfx","move_sfx","remove_music","remove_sfx","remove_voiceover","review_audio","separate_music","set_audio_gain","set_master_loudness","set_music_fit","set_volume","swap_music"],"captions and on-screen text":["add_captions","add_kinetic_text","add_text","add_text_behind","add_title_card","audit_captions","erase_burned_text","remove_text","set_caption_fixes","set_caption_mutes","set_caption_style","set_text_motion"],"colour and finishing":["add_stylize","apply_look","enhance_video","remove_stylize","set_color_grade","set_fades","set_grade_custom","set_transitions"],"cutting":["cut_output_range","cut_range","cut_silences","keep_segments","remove_filler_words","restore_range"],"editing":["add_custom_filter","add_vector_graphic","apply_edit_batch","ask_user","bind_motion_motif","compare_uploaded_media","compose_panels","expand_toolset","justify_verification_findings","make_shorts","open_visual_page","punch_in_on_emphasis","remove_custom_filter","remove_editorial_graphic","remove_picture_card","remove_stem_mix","remove_typography_scene","remove_vector_graphic","render_preview","research_broll","reset_edit","set_editorial_graphic","set_picture_card","set_typography_scene","set_vector_graphic","start_media_sequence","suggest_emphasis"],"framing and motion":["add_aspect_shift","add_freeze_frame","add_screen_takeover","add_zoom","add_zoom_path","auto_reframe","enhance_cursor","remove_aspect_shift","remove_cursor_enhance","remove_screen_frame","remove_screen_takeover","remove_speed","remove_zoom","remove_zoom_path","set_frame","set_screen_frame","set_speed"],"media, generation and screen capture":["add_overlay","add_stock_media","fetch_url","insert_media","move_insert","move_overlay","record_website","record_website_demo","remove_insert","remove_overlay","set_insert_window","set_overlay_motion","showcase_demo"],"reading the footage":["find_burned_text","find_footage","find_silences","find_song","find_visual_moments","get_audio_analysis","get_editorial_map","get_edl","get_kept_transcript","get_shots","get_transcript","get_video_info","get_words","list_assets","look_at","look_at_asset","read_skill","search_sfx","search_stock","search_transcript"],"repair and censoring":["add_color_screen","add_corrupt_screen","blur_region","erase_region","remove_blur","remove_erase"]},"toolReferenceUrl":"https://valmera.io/mcp/tools","tools":[{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"Export a reviewed edit as a full-resolution MP4 when the user asks for the finished video. Pass the explicit project_id and reviewed edl_version. Uses the same ownership, upload, timeline, quality and watermark checks as Studio. Repeated requests reuse an existing current export or its running job. A queued job is NOT a finished video: call wait_for_job, then download_url(kind='final', edl_version=...) to deliver the file. Never claim delivery until a download link is returned.","inputSchema":{"properties":{"edl_version":{"minimum":1,"type":"integer"},"project_id":{"minimum":1,"type":"integer"}},"required":["project_id","edl_version"],"type":"object"},"name":"export_final","title":"Export the finished video"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"Save caller-authored edits for up to 30 shorts in one request, without running another model or rendering. project_id is the parent; every child must belong to it. Each batch uses apply_edit_batch's operations and current base_version, and has its own unique retry operation_id. Each child is atomic; results explicitly report partial failures. All times describe that child's resulting timeline. Read and inspect each short first. Saved edits still require changed-moment and final quality review. This tool never exports finals.","inputSchema":{"properties":{"batches":{"items":{"properties":{"base_version":{"type":"integer"},"operation_id":{"type":"string"},"operations":{"items":{"properties":{"action":{"enum":["set","upsert","remove","reorder"],"type":"string"},"id":{"type":"string"},"layer":{"type":"string"},"value":{}},"required":["action","layer"],"type":"object"},"maxItems":64,"minItems":1,"type":"array"},"project_id":{"type":"integer"}},"required":["project_id","base_version","operation_id","operations"],"type":"object"},"maxItems":30,"minItems":1,"type":"array"},"project_id":{"type":"integer"}},"required":["project_id","batches"],"type":"object"},"name":"apply_short_edit_batches","title":"Apply edits to selected shorts"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"List this account's video projects, newest first, with whether each has a video, its project kind, its podcast-shorts status, and which parent generated a short. The navigation-pointer label is informational only; every project-targeting call still requires project_id. Start here.","inputSchema":{"properties":{},"type":"object"},"name":"list_projects","title":"List this account's projects"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Open a project for navigation and return its full state: the video, its transcript and shots, the current EDL and what is available to place. Copy this project_id into every later project-scoped call; no edit or review tool guesses from the active pointer.","inputSchema":{"properties":{"project_id":{"type":"integer"}},"required":["project_id"],"type":"object"},"name":"open_project","title":"Open a project for navigation"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true},"description":"Open one generated short for DIRECT editing by this MCP caller. Select it by its 1-based board card number or child project ID; copy the returned child project ID into every normal editor tool for exactly the same capabilities as Valmera's own agent. This does NOT call or delegate to Valmera's agent. Use this, then watch_video and the normal editing tools, when the user says YOU should edit a short. card requires parent_project_id; a direct child_project_id resolves its own parent and never trusts the active-project pointer.","inputSchema":{"properties":{"card":{"description":"1-based card number from shorts_status.","minimum":1,"type":"integer"},"child_project_id":{"description":"Generated child project ID.","type":"integer"},"parent_project_id":{"description":"Shorts board project; required when selecting by card.","type":"integer"}},"type":"object"},"name":"open_short","title":"Open a short for direct editing"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"Create an empty project and select it for navigation. Copy the returned project_id into every later call. Upload a video into it with upload_start, or build a canvas program from generated/uploaded assets. kind='shorts' creates a Podcast to Shorts intake project. After its main video finishes analyzing, read the podcast and call make_shorts with your explicit story arcs; selection does not start automatically.","inputSchema":{"properties":{"kind":{"description":"Default 'edit'. Use 'shorts' for a long podcast/video that should fan out into multiple generated short projects.","enum":["edit","shorts"],"type":"string"},"title":{"type":"string"}},"type":"object"},"name":"create_project","title":"Create a project"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"Re-read one explicit project's state (video, transcript, shots, current EDL, assets). Cheap \u2014 call it whenever you are unsure what the edit currently looks like.","inputSchema":{"properties":{"project_id":{"type":"integer"}},"required":["project_id"],"type":"object"},"name":"project_state","title":"Read an explicit project's state"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"Begin uploading a LOCAL file into an explicit project. Returns presigned URL(s) you upload the bytes to yourself (curl), then call upload_finish. kind: 'original' the main video, 'clip' b-roll, 'music' audio, 'image' a still. A clip may instead be marked role='shorts_reference' for reference-only Shorts style analysis.","inputSchema":{"properties":{"duration_s":{"description":"Optional locally probed media duration in seconds; repeated in the returned upload_finish contract.","exclusiveMinimum":0,"type":"number"},"filename":{"description":"Name with extension, e.g. talk.mp4","type":"string"},"kind":{"enum":["original","clip","music","image"],"type":"string"},"project_id":{"type":"integer"},"role":{"description":"Optional and valid only with kind='clip'. Makes the upload reference-only Shorts style input, not placeable media.","enum":["shorts_reference"],"type":"string"},"size_bytes":{"description":"Exact size of the local file","type":"integer"}},"required":["project_id","filename","size_bytes"],"type":"object"},"name":"upload_start","title":"Start uploading a local file"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"Finish an upload once every byte is in storage. For a main video this starts the analysis (transcript, shots, silences) \u2014 poll index_status until it is done.","inputSchema":{"properties":{"duration_s":{"description":"Optional locally probed media duration in seconds.","exclusiveMinimum":0,"type":"number"},"filename":{"type":"string"},"kind":{"enum":["original","clip","music","image"],"type":"string"},"parts":{"description":"Multipart uploads only: [{part_number, etag}] in order","items":{"properties":{"etag":{"type":"string"},"part_number":{"type":"integer"}},"type":"object"},"type":"array"},"project_id":{"type":"integer"},"role":{"description":"Optional and valid only with kind='clip'. Marks a reference-only Shorts style clip.","enum":["shorts_reference"],"type":"string"},"storage_key":{"type":"string"},"upload_id":{"description":"Multipart uploads only","type":"string"}},"required":["project_id","storage_key"],"type":"object"},"name":"upload_finish","title":"Finish an upload"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"Progress of an explicit project's video analysis. The editing tools cannot read a transcript, shots or silences until this reaches 'done'.","inputSchema":{"properties":{"project_id":{"type":"integer"}},"required":["project_id"],"type":"object"},"name":"index_status","title":"Check video analysis progress"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"Read an explicit project's Podcast to Shorts progress, planner job, generated child project IDs, edit versions, and final-render states. Safe to poll while clips are being built. If project_id names a generated short, this reports its parent run and preserves that explicit child identity in the answer.","inputSchema":{"properties":{"project_id":{"type":"integer"}},"required":["project_id"],"type":"object"},"name":"shorts_status","title":"Check podcast shorts progress"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"Wait for a background job (a render, or a tool call that outran its reply) and return its result. Safe to call repeatedly \u2014 each call waits a bounded time and tells you whether it is still running.","inputSchema":{"properties":{"job_id":{"type":"integer"}},"required":["job_id"],"type":"object"},"name":"wait_for_job","title":"Wait for a running job"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"A temporary URL for watching or downloading a render of an explicit project, with a durable receipt. asset_id recovers a historical render. kind 'preview' (complete draft/approval), 'preview_check' (changed sections), or 'final' (a completed export). This tool cannot create a final export.","inputSchema":{"properties":{"asset_id":{"type":"integer"},"edl_version":{"type":"integer"},"kind":{"enum":["preview","preview_check","final"],"type":"string"},"project_id":{"type":"integer"}},"required":["project_id"],"type":"object"},"name":"download_url","title":"Get a download link for a render"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"WATCH THE VIDEO YOURSELF \u2014 the real file, pixels and audio, not a description of it. Use this instead of look_at whenever your own model can take video input: look_at sends frames to Valmera's vision model and hands you back a PARAGRAPH, while this hands you the footage. kind 'timeline' (default) is the assembled program as the viewer sees it \u2014 it renders the current edit first if it has not been rendered; 'source' is the raw uploaded footage; 'asset' is one uploaded clip (pass asset_key). start/end watch a window rather than the whole thing. It comes back as a direct download link \u2014 a plain MP4 you fetch and watch. Cheap: normally it hands over a file that already exists, untouched.","inputSchema":{"properties":{"asset_key":{"description":"kind='asset' only: the storage_key list_assets prints.","type":"string"},"delivery":{"description":"A download link either way. Embedding the file in the reply is off on this deployment.","enum":["auto","url"],"type":"string"},"end":{"description":"Watch up to this second.","type":"number"},"frames":{"description":"Default true. False returns only the video file/link and suppresses sampled frame sheets plus their attached audio; use false for clean external ASR retrieval.","type":"boolean"},"kind":{"description":"Default 'timeline' \u2014 the current edit.","enum":["timeline","source","asset"],"type":"string"},"max_height":{"description":"Cap the picture height (e.g. 360). Never up-scales.","type":"integer"},"max_mb":{"description":"Shrink to about this many megabytes. Use when your model has a file-size limit.","type":"number"},"project_id":{"description":"Required immutable project scope.","type":"integer"},"render":{"description":"kind='timeline': false watches the last render that exists instead of rendering the current edit, and says how stale it is. Default true.","type":"boolean"},"start":{"description":"Watch from this second. OUTPUT seconds for 'timeline', source seconds otherwise.","type":"number"}},"required":["project_id"],"type":"object"},"name":"watch_video","title":"Watch the video itself"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Apply a complete group of ordinary edits atomically, with no render wait. Read get_edl first; base_version must be current. operation_id is a unique 16-80 character retry id (letters/digits/hyphens/underscores); reuse it on transport retry. Each operation is {action,layer,value?,id?}. set replaces one complete layer; upsert patches or adds a named item; remove deletes a named item; reorder accepts all insert ids for a canvas sequence. Layers: keep,speed,inserts,frame,captions,caption_mutes,texts,vectors,music,sfx,voiceover,volume,master,effects,overlays,canvas. Use existing EDL field shapes and project media keys. All times describe the RESULTING timeline: include dependent caption/music/text timing changes in the same batch. Unknown fields or invalid media reject the whole batch. This saves an edit; it does not certify picture/audio quality. Review changed moments, then the finished edit.","inputSchema":{"properties":{"base_version":{"type":"integer"},"operation_id":{"type":"string"},"operations":{"items":{"properties":{"action":{"enum":["set","upsert","remove","reorder"],"type":"string"},"id":{"description":"Existing item id for upsert/remove; omit for whole-layer set.","type":"string"},"layer":{"enum":["keep","speed","inserts","frame","captions","caption_mutes","texts","vectors","music","sfx","voiceover","volume","master","effects","overlays","canvas"],"type":"string"},"value":{"description":"set: complete layer value (array for texts/inserts/music). upsert: one item object merged by id. reorder: all insert ids. Read get_edl for exact shapes."}},"required":["action","layer"],"type":"object"},"maxItems":64,"minItems":1,"type":"array"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["base_version","operations","operation_id","project_id"],"type":"object"},"name":"apply_edit_batch","title":"Apply edit batch"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Video metadata plus index and EDL summary. Use only when the supplied project state does not already answer the metadata question.","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"get_video_info","title":"Get video info"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Sentence-level SOURCE transcript with timestamps for a time range (source seconds). For word-exact timing use get_words; for what the current EDIT keeps, use get_kept_transcript. Pass asset_key to read an UPLOADED clip's or song's own transcript instead (clip seconds).","inputSchema":{"properties":{"asset_key":{"type":"string"},"end":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"start":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"get_transcript","title":"Get transcript"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. The transcript the CURRENT edit actually keeps, in program time with matching source spans, plus automatic repeated-phrase detection. ALWAYS call this after cutting repetitions or tightening \u2014 it is how you verify nothing repeated survived.","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"get_kept_transcript","title":"Get kept transcript"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Word-level timestamps [{t0-t1 word}] for any source-time range (the response caps at 400 words and says how to page for the rest). THE source of truth for cut points inside a sentence \u2014 never estimate word timing from sentence ranges.","inputSchema":{"properties":{"end":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"start":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"get_words","title":"Get words"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Find where something is said (substring + fuzzy over sentences).","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"query":{"type":"string"}},"required":["query","project_id"],"type":"object"},"name":"search_transcript","title":"Search transcript"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Shot boundaries (scene changes \u2014 where transitions may land) for a time range. The PICTURE itself is in your filmstrips and look_at.","inputSchema":{"properties":{"end":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"start":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"get_shots","title":"Get shots"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. READ: compact cross-modal SOURCE timeline joining each sentence (or shot when there is no speech) to overlapping shot changes, relative energy/trend, beats, vocal stress, pauses and measured face/source-text/dense-UI evidence. Use this instead of separately re-reading transcript + shots + audio analysis when directing a substantial reel, podcast, montage or B-roll/SFX/motion treatment. It aligns evidence but does not recognize the full picture or prescribe effects: inspect filmstrips/look_at before visual choices. Pass asset_key for an indexed uploaded clip. focus can be all, story, visual, energy, faces, ui, quiet or peaks.","inputSchema":{"properties":{"asset_key":{"type":"string"},"end":{"type":"number"},"focus":{"enum":["all","energy","faces","peaks","quiet","story","ui","visual"],"type":"string"},"limit":{"maximum":80,"minimum":1,"type":"integer"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"start":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"get_editorial_map","title":"Get editorial map"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. READ: focused semantic search across the COMPLETE indexed main-video filmstrip. Use once for a long source when requested highlights are visual rather than transcript-searchable (gameplay saves/fails, a gesture, a product appearing, action moments). query names one concrete visible event. It returns coarse SOURCE timestamps after scanning all tiles in parallel; verify useful candidates with ONE batched look_at call, then WRITE. Never replace it with serial whole-video look_at probing.","inputSchema":{"properties":{"end":{"type":"number"},"max_results":{"maximum":20,"minimum":1,"type":"integer"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"query":{"type":"string"},"start":{"type":"number"}},"required":["query","project_id"],"type":"object"},"name":"find_visual_moments","title":"Find visual moments"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Load a focused editing playbook (captions, zooms, audio, transitions, ...) into this turn. The SKILLS list in your instructions names them. Read the matching skill before your first edit of that kind \u2014 batch it with your other reading calls. Pass section to retrieve only the decision, evidence, pattern, failure, verification, or repair material needed now.","inputSchema":{"properties":{"name":{"enum":["audio","beats-emphasis","broll-inserts","captions","cutting","effects-grades","formats","generate-fetch","hooks-retention","music","premium-composition","reframe-aspect","review","screen-takeover","short-form-direction","text-graphics","transitions","zooms"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"section":{"enum":["editorial decision principles","evidence to inspect","strong treatment patterns","common failure modes","verification procedure","repair ladder"],"type":"string"}},"required":["name","project_id"],"type":"object"},"name":"read_skill","title":"Read an editing skill"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Load additional tool schemas for the NEXT reasoning step when the compact catalog does not expose a capability you need. This changes no media or EDL and is not a tool limit: request any relevant domains, then continue immediately.","inputSchema":{"properties":{"domains":{"items":{"enum":["story","captions","graphics","audio","sfx","media","acquisition","motion","looks","screen","shorts"],"type":"string"},"type":"array"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["domains","project_id"],"type":"object"},"name":"expand_toolset","title":"Expand toolset"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Silences of at least min_seconds, with midpoints and surrounding words \u2014 cut points should snap to these midpoints or word boundaries.","inputSchema":{"properties":{"min_seconds":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"find_silences","title":"Find silences"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Every file in this project \u2014 used on the timeline AND unused uploads sitting in the library. kind='music' lists audio (use its storage_key with add_music or add_voiceover); 'clip' lists uploaded video clips and 'image' reference images (use with insert_media); 'render' past renders; 'all' everything. UNUSED files are marked AVAILABLE and can be placed without asking the user to re-upload.","inputSchema":{"properties":{"kind":{"enum":["music","image","clip","render","all"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"list_assets","title":"List assets"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. YOUR OWN EYES on SEVERAL uploaded clips/images in ONE story-wide comparison. Pass every relevant exact storage_key together; each candidate is represented on dynamically built labeled pages, with representative real frames, CLIP seconds and exact sentence/shot IDs. Use this instead of serial look_at_asset calls when choosing/order-casting a reel, montage, B-roll library or multi-clip story. It does not rank by upload order, does not silently shortlist, and explicitly allows leaving a weak/redundant asset unused. Then use source_asset_key + the returned evidence_ids in sequence_map.","inputSchema":{"properties":{"asset_keys":{"items":{"type":"string"},"type":"array"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"question":{"type":"string"},"samples_per_asset":{"maximum":12,"minimum":1,"type":"integer"}},"required":["asset_keys","project_id"],"type":"object"},"name":"compare_uploaded_media","title":"Compare uploaded media"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Open one or more labeled pages from the main footage's persisted hierarchical visual storyboard. The full text inventory names every cluster; use this whenever you need the actual pixels for an evidence_id not present in the initial orientation page. Pages are transport batches, not an editorial allowance: call repeatedly and open as many as the edit requires. With pages omitted, opens every page not yet delivered in this logical turn.","inputSchema":{"properties":{"pages":{"items":{"minimum":1,"type":"integer"},"type":"array"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"open_visual_page","title":"Open visual page"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. YOUR OWN EYES on the footage. Pass times=[...] (1-8 exact source seconds of the MAIN video) and the frames at those moments come back as ONE timestamp-labeled picture in your own context \u2014 you see the footage yourself and judge it directly (composition, where the subject is, clear space for text, what a moment looks like). Every frame carries a faint tenths grid ((0,0) = top-left): READ aim points, cx/cy and rects off its labels instead of estimating. start/end still work as a range sampled evenly. OR pass output_times=[...] to see the ASSEMBLED PROGRAM instead: output seconds of the current edit, resolved through the EDL \u2014 kept footage AND spliced inserts both sample correctly, each tile labeled with its scene number, in TRUE output geometry (canvas fit and any active zoom applied \u2014 so you can SEE an aimed zoom's framing before rendering) \u2014 THE way to check what the viewer sees at a moment of the EDITED video ('the second scene') without rendering. Look as often as you need \u2014 there is no cap on looking; before aiming anything and before disputing what a user saw, look. Batch the moments you need into ONE call with several times rather than a string of separate calls. The filmstrips already gave you the whole video at a glance \u2014 use look_at for the CLOSER look: exact framing, small text, a precise instant. The transcript is ASR and can be wrong; inspect confidence and sentence context using get_words / the transcript \u2014 never look to lip-read or guess a word. IMPORTANT: the assembled geometry view omits burn-ins. Set rendered=true after render_preview to inspect the CURRENT preview's real pixels\u2014including captions, text, overlays and grade. In rendered mode output_times (or times) are output seconds and any useful set can be batched for caption QA.","inputSchema":{"properties":{"end":{"type":"number"},"native_resolution":{"description":"With rendered=true, preserve image width up to 1920px; request one time for full-detail approval pixels without another encode.","type":"boolean"},"output_times":{"items":{"type":"number"},"type":"array"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"question":{"type":"string"},"rendered":{"type":"boolean"},"start":{"type":"number"},"times":{"items":{"type":"number"},"type":"array"}},"required":["project_id"],"type":"object"},"name":"look_at","title":"Look at frames of the video"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. YOUR OWN EYES on an UPLOADED clip or image, or a finished RENDER (storage_key from list_assets; kind='render' lists past previews/finals). Same contract as look_at: pass times=[...] (seconds into the clip) and the frames arrive as one labeled picture you read yourself, with the same tenths grid for reading positions. THE way to choose which moment of a long clip to splice in \u2014 one call over the whole clip, then insert_media with clip_start_s at the moment you saw. On a RENDER it is how you CHECK YOUR OWN WORK at exact moments \u2014 narrow times sample frame-accurately, so use it to verify a transition junction or an effect the user questions before claiming it is fine. For video clips it also returns a cached, measured temporal profile (static/frozen share, motion intensity and abrupt changes). This is sparse measurement\u2014not continuous playback\u2014and remains available on later turns.","inputSchema":{"properties":{"asset_key":{"type":"string"},"end":{"type":"number"},"native_resolution":{"description":"Preserve image width up to 1920px; one requested time avoids contact-sheet downscaling.","type":"boolean"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"question":{"type":"string"},"start":{"type":"number"},"times":{"items":{"type":"number"},"type":"array"}},"required":["asset_key","project_id"],"type":"object"},"name":"look_at_asset","title":"Look at frames of an uploaded asset"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. REPLACE the whole keep list: the parts of the SOURCE video that survive, [[start,end],...] in seconds. Everything else is cut. Use only for wholesale restructuring, always after get_edl \u2014 for local fixes prefer cut_range/restore_range. snap_to_words:true moves boundaries outward to word edges so no word is clipped.","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"segments":{"items":{"items":{"type":"number"},"maxItems":2,"minItems":2,"type":"array"},"type":"array"},"snap_to_words":{"type":"boolean"}},"required":["segments","project_id"],"type":"object"},"name":"keep_segments","title":"Keep segments"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove ONE source-time range from the current keep set (a local edit \u2014 the rest of the edit is untouched). Creates a new EDL version. snap_to_words:true keeps neighbouring words whole. SOURCE seconds of the main video ONLY \u2014 when the user gives times of the EDITED video ('cut 12-15 of the video'), or the span sits inside an inserted clip, use cut_output_range.","inputSchema":{"properties":{"end":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"snap_to_words":{"type":"boolean"},"start":{"type":"number"}},"required":["start","end","project_id"],"type":"object"},"name":"cut_range","title":"Cut range"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Cut a span of the ASSEMBLED program \u2014 OUTPUT seconds, the clock the viewer and the scene map use \u2014 no matter what plays there. Kept footage under the span is cut in source time; an inserted clip it crosses is SPLIT around it (or removed when fully covered); one version write, everything re-anchored. THE tool for 'cut 12-15 of the video' / 'cut that part of the second scene' \u2014 never answer that cutting inside an insert is impossible, and never fake it with set_insert_window (that changes WHICH part plays, it cannot remove a middle). One range per call; batch several calls for several ranges.","inputSchema":{"properties":{"end":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"start":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"cut_output_range","title":"Cut a range of the finished edit"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Add a previously-cut source-time range back into the keep set (undo one cut without touching the rest). Creates a new EDL version.","inputSchema":{"properties":{"end":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"snap_to_words":{"type":"boolean"},"start":{"type":"number"}},"required":["start","end","project_id"],"type":"object"},"name":"restore_range","title":"Restore range"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. ONE-CALL silence trim \u2014 THE tool for 'cut the silences' / 'tighten this up' / 'remove the dead air'. Cuts every detected pause at least min_silence_s long (default 0.5s), keeping padding_s (default 0.12s) of breathing room around speech and snapping to word edges so no word is clipped. Do this in one call instead of many cut_range calls; then get_kept_transcript to verify. If at least half of the gaps contain audible material and the pass would remove 25%+ of the program, it refuses without changing the EDL. Set allow_nonquiet=true ONLY when the user explicitly permits discarding those non-speaking music/game/room-performance moments.","inputSchema":{"properties":{"allow_nonquiet":{"type":"boolean"},"min_silence_s":{"type":"number"},"padding_s":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"cut_silences","title":"Cut silences"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. ONE-CALL filler removal \u2014 THE tool for 'remove the ums' / 'cut the uhs' / 'take out the filler words'. Cuts every um, uh, er, hmm, etc. using the exact word timestamps (deterministic, never estimated). Pass a custom `words` list to target different tokens (e.g. [\"like\",\"you know\"]) \u2014 the default set is only the safe non-word hesitations.","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"words":{"items":{"type":"string"},"type":"array"}},"required":["project_id"],"type":"object"},"name":"remove_filler_words","title":"Remove filler words"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Burned captions. mode='from_transcript' (word-timed from the real transcript, recommended) or mode='off', or items=[{text,start,end,style?}] (source seconds) for text the user dictates. PREMIUM PRESETS (style.preset) are professionally designed looks with real fonts. SAFE DEFAULTS: 'clean' (white Plus Jakarta Sans, complete short phrases, size-only hierarchy), 'documentary' (restrained subtitles on a translucent contrast panel), and 'broadcast' (left-aligned news/explainer lower third). SOCIAL/CREATIVE: 'reels' (FLAGSHIP short-form system: tight two-line hierarchy, warm hero word and multi-stage elastic word landings), 'podcast' (bold white words land on screen as spoken, keywords light up in the accent color, get a highlight box or serif italics, numbers render HUGE), 'beast' (loud MrBeast-style: ALL-CAPS impact font, centered, the spoken word pops in the accent color), 'karaoke' (an accent box follows each spoken word), 'spotlight' (ONE glowing word at a time, centred, uppercase \u2014 the modern single-word look for hype/motivation/fast talking; the ONLY preset that belongs mid-frame), 'elegant' (calm lower-third, serif-italic accents \u2014 interviews/luxury), 'lyric' (phrase-led music/quote typography), plus stacked/iridescent/chrome/editorial/fashion/luxe/impact/retro/neon composed looks; 'classic' is the plain legacy look. If style is omitted, the tool chooses a coherent preset deterministically from the measured format, speech pace and brief \u2014 it does not make every project wear the same caption skin. PLACEMENT: multi-word presets default to the BOTTOM, clear of the face \u2014 do not move them to 'middle'; only a single-word-at-a-time look may sit centred. With a preset, sparse emphasis is AUTO-SELECTED from the KEPT transcript when emphasis_words is omitted; measured vocal stress leads on short-form/cached audio, with numbers and semantic outcome words as fallback. pass a verbatim list only when specific words are required, or [] to explicitly disable hierarchy. highlight_color sets the accent (default warm yellow); uppercase overrides the preset's casing; position bottom/top/middle overrides its placement and LOCKS that band for the whole video (no shot-by-shot position changes); anchor_y similarly locks an exact vertical frame fraction. Omit both to let collision-aware placement adapt by shot. Other style fields: color '#RRGGBB', size s|m|l|xl (presets are already big at 'm'), size_scale 0.5-3.0, dynamic:true (legacy karaoke, no preset), animation fade|pop|slide_up|punch|blur_in|whip|flash|rise|drop|elastic|bounce|swing|zoom_blur, or 'none' to turn a preset's animation OFF (instant words), single_line:true to guarantee one rendered row per transcript-caption state regardless of the preset's normal flow/stack layout, max_words_per_caption 1-16. Default modern look is 1-2 words at a time, stacked levels, fade in (preset 'stacked', max_words_per_caption 2) \u2014 not a sentence subtitle. Example \u2014 modern reel captions: {mode:'from_transcript', style:{preset:'stacked', animation:'fade'}, max_words_per_caption:2}. Example \u2014 dictated title card: {items:[{text:'CHAPTER ONE', start:0, end:2.5, style:{preset:'beast'}}]}. Stack presets (stacked/iridescent/chrome/fashion/luxe/editorial/impact) compose 1-2 words across lines of very different SIZES; font picks a bundled family, emphasis 'big' enlarges keywords WITHOUT recolouring them, leading below 1.0 overlaps the lines so a smaller word fades in behind the hero. Production controls include outline_color/outline_width, shadow, background_color/background_opacity, tracking and text_align.","inputSchema":{"properties":{"emphasis_words":{"items":{"type":"string"},"type":"array"},"items":{"items":{"type":"object"},"type":"array"},"max_words_per_caption":{"type":"integer"},"min_words_per_caption":{"description":"Preferred minimum for static phrase presets such as clean; QA flags unavoidable fragments.","type":"integer"},"mode":{"type":"string"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"style":{"properties":{"anchor_y":{"maximum":0.95,"minimum":0.05,"type":"number"},"animation":{"enum":["none","fade","pop","slide_up","punch","blur_in","whip","flash","rise","drop","elastic","bounce","swing","zoom_blur"],"type":"string"},"background_color":{"type":"string"},"background_opacity":{"type":"number"},"color":{"type":"string"},"dynamic":{"type":"boolean"},"effect":{"enum":["chroma","chrome","glow"],"type":"string"},"emphasis":{"enum":["big","huge","accent","pop","box","serif","script","chrome","glow","chroma","none"],"type":"string"},"emphasis_scale":{"type":"number"},"font":{"enum":["Inter Display Black","Inter Display ExtraBold","Inter Display Bold","Anton","Bebas Neue","Archivo Black","Poppins Black","Syne ExtraBold","Playfair Display Black","Instrument Serif","DM Serif Display","Montserrat","Plus Jakarta Sans"],"type":"string"},"highlight_color":{"type":"string"},"layout":{"enum":["stack","flow"],"type":"string"},"leading":{"type":"number"},"outline_color":{"type":"string"},"outline_width":{"type":"number"},"position":{"enum":["bottom","top","middle"],"type":"string"},"preset":{"enum":["composed","clean","documentary","broadcast","retro","neon","podcast","reels","beast","karaoke","elegant","spotlight","stacked","iridescent","chrome","editorial","fashion","luxe","impact","lyric","classic"],"type":"string"},"shadow":{"type":"number"},"single_line":{"type":"boolean"},"size":{"enum":["s","m","l","xl"],"type":"string"},"size_scale":{"type":"number"},"text_align":{"enum":["left","center","right"],"type":"string"},"tracking":{"type":"number"},"uppercase":{"type":"boolean"}},"type":"object"}},"required":["project_id"],"type":"object"},"name":"add_captions","title":"Add captions"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Find web links for a SPECIFIC song the user NAMED ('add Blinding Lights by The Weeknd') \u2014 the case a generic catalog cannot serve, because named commercial tracks need exact discovery. Returns candidate links best-guess first; pick the real thing (artist's own/'- Topic' channel or 'Official Audio'; no lyric/sped-up/loop/cover versions unless asked; never a full album/mix \u2014 one track only), then fetch_url(url, as_kind='music') downloads the pick. Always tell the user which version you grabbed. Search can verify the likely recording, NOT a usage license; a public/downloadable upload does not grant republication rights, so disclose that. For a genre/vibe request ask for a user-supplied file or link; a trending platform sound can only be provided by the user.","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"query":{"type":"string"}},"required":["query","project_id"],"type":"object"},"name":"find_song","title":"Find song"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Mix music into the edit. The defaults are CONTEXT-AWARE: under speech the track sits low as a bed (-18dB, ducked); when NO speech survives under the window the music is the LEAD audio (-4dB, no ducking) so the user actually hears it. Pass gain_db/duck only to override that. storage_key is an exact key from list_assets(kind='music') \u2014 the user's own uploads or a track fetch_url just downloaded \u2014 never invent one. Choose from the user's direction, metadata, context and measured get_audio_analysis evidence. start/end are OUTPUT-timeline seconds and DEFAULT TO THE WHOLE VIDEO, so omit them for 'add some music'. Fades in/out by default. loop=true (the default) repeats a short track to fill the span; offset_s starts partway into the track, e.g. to skip a slow intro. Ducking is SMOOTH by default (a sidechain dip that follows the voice; set_music_fit(duck_mode='step') restores the legacy hard -12dB duck).","inputSchema":{"properties":{"duck":{"type":"boolean"},"end":{"type":"number"},"fade_in_s":{"type":"number"},"fade_out_s":{"type":"number"},"gain_db":{"type":"number"},"loop":{"type":"boolean"},"offset_s":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"purpose":{"description":"Why this music belongs in this program/window, including the story turn or energy role it supports.","type":"string"},"start":{"type":"number"},"storage_key":{"type":"string"}},"required":["storage_key","project_id"],"type":"object"},"name":"add_music","title":"Add music"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Take ONLY the sound out of an uploaded VIDEO and save it as an audio file \u2014 THE answer to 'use the song from this clip', 'put this video's audio on my video', 'I want the sound but not the picture'. Users hand you songs as videos because a TikTok or Reel download is the only file they have; that is normal and it works. The clip's picture is never shown. asset_key is a [video_clip] storage_key from list_assets. Returns a new storage_key for add_music / add_sfx / add_voiceover \u2014 nothing is in the edit until you place it. Passing a clip's key DIRECTLY to those tools does the same thing in one step; call this when you want the file first (e.g. to get_audio_analysis its beats). If the clip is silent it says so \u2014 never claim a sound was added.","inputSchema":{"properties":{"asset_key":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["asset_key","project_id"],"type":"object"},"name":"extract_audio","title":"Extract audio"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Find REAL footage of a NAMED topic on the web \u2014 the b-roll move: the speaker mentions Elon Musk, the cut shows his rocket. Query the concrete THING ('spacex starship launch', 'tesla factory'), not a mood \u2014 search_stock covers generic visuals ('busy city'), THIS covers named people, companies, products, events. Returns candidate links best-guess first; pick real footage of the subject (short clips), then fetch_url(url, as_kind='clip'), look_at_asset for the right seconds, and a cutaway or insert at the mention. Tell the user what footage you used (title + channel).","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"query":{"type":"string"}},"required":["query","project_id"],"type":"object"},"name":"find_footage","title":"Find footage"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Search the web for a REAL recorded sound effect \u2014 the editor's whoosh, camera shutter, UI click, pop, riser. Query by the sound's PHYSICAL name ('whoosh', 'camera shutter', 'keyboard click'), not a mood. Results carry duration and license terms (public domain, credit, or NON-COMMERCIAL-ONLY) \u2014 relay the terms. max_seconds caps length (default 15s; one-shots are seconds long).","inputSchema":{"properties":{"max_seconds":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"query":{"type":"string"}},"required":["query","project_id"],"type":"object"},"name":"search_sfx","title":"Search sfx"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Compare multiple search_sfx candidates using their ACTUAL waveform before choosing. Measures attack, peak position, tail, crest, spectral balance, bass and whether the file contains one clean event or several. Ranks those facts against a named physical/editorial purpose. The language model does not hear the recordings; use this evidence together with title/license, then fetch and place the winner exactly on the visible event.","inputSchema":{"properties":{"ids":{"items":{"type":"string"},"type":"array"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"purpose":{"type":"string"}},"required":["ids","purpose","project_id"],"type":"object"},"name":"audition_sfx_candidates","title":"Audition sfx candidates"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Download ONE search_sfx result (by its id) into the project \u2014 returns the storage_key for add_sfx. Repeat the license line to the user when it carries an obligation.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"fetch_sfx","title":"Fetch sfx"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. ONE-CALL on-demand sound design: search real Openverse/Freesound recordings, rank clean physical one-shots above loops/music/ambience, DOWNLOAD and acoustically compare the candidates. By default an actual-audio reviewer may choose KEEP THIS MOMENT DRY when every sound weakens it; pass allow_none=false only when the user explicitly requires an effect. Otherwise the tool fetches the best measured/listened match and places it at an exact OUTPUT-timeline second. Use for 'add a cinematic whoosh at 3.2s', 'put a shutter on this cut', or any specific requested sound. The result reports the real source and license. gain_db defaults -6; max_seconds defaults 15.","inputSchema":{"properties":{"allow_none":{"type":"boolean"},"at":{"type":"number"},"gain_db":{"type":"number"},"max_seconds":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"query":{"type":"string"}},"required":["query","at","project_id"],"type":"object"},"name":"add_web_sfx","title":"Add web sfx"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Punctuate a MOMENT with a one-shot sound effect \u2014 a whoosh on a cut, a click on a beat, an impact on a reveal. Choose it when the brief, format, timing, or your editorial judgment says sound design improves the cut. Analysis, metadata, and deterministic preview AUDIO CHECK are useful evidence; uncertainty is something to judge rather than a reason the tool becomes unavailable. storage_key is an exact key from fetch_sfx or list_assets(kind='music') \u2014 never invent one. `at` is an OUTPUT-timeline second (the edited program, not source time). This is NOT background music: it plays once, for as long as the sound is, and never ducks. offset_s starts inside source audio \u2014 use it when an extracted clip contains the requested hit late in a long track. purpose records the nameable visible/editorial event for later final-mix review; do not add anonymous decorative sounds. Default -6dB.","inputSchema":{"properties":{"at":{"type":"number"},"gain_db":{"type":"number"},"offset_s":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"purpose":{"type":"string"},"storage_key":{"type":"string"}},"required":["storage_key","at","project_id"],"type":"object"},"name":"add_sfx","title":"Add sfx"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Retime an existing sound effect \u2014 'the whoosh is too early'. Keeps which sound and how loud. id from get_edl.","inputSchema":{"properties":{"at":{"type":"number"},"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","at","project_id"],"type":"object"},"name":"move_sfx","title":"Move sfx"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Delete a sound effect by id (from get_edl).","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_sfx","title":"Remove sfx"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Replace the TRACK of an existing music item while keeping its position, level and fit \u2014 THE tool for 'use a different song' / 'try something more upbeat'. id from get_edl; storage_key as for add_music.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"storage_key":{"type":"string"}},"required":["id","storage_key","project_id"],"type":"object"},"name":"swap_music","title":"Swap music"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Retime or refit EXISTING music in place \u2014 'start the music later', 'let it run to the end', 'fade it out', 'loop it', 'stop it ducking'. Anything you omit is left alone. duck_mode: 'smooth' = a sidechain dip that follows the voice and swells back in the gaps; 'step' = the legacy hard -12dB duck. Use this instead of remove+re-add, which loses the other settings. For loudness use set_audio_gain.","inputSchema":{"properties":{"duck":{"type":"boolean"},"duck_mode":{"enum":["smooth","step"],"type":"string"},"end":{"type":"number"},"fade_in_s":{"type":"number"},"fade_out_s":{"type":"number"},"id":{"type":"string"},"loop":{"type":"boolean"},"offset_s":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"start":{"type":"number"}},"required":["id","project_id"],"type":"object"},"name":"set_music_fit","title":"Set music fit"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one background-music item by its id (see get_edl). Use this to cut the music entirely or before re-adding it with a different range.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_music","title":"Remove music"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Change the loudness of an EXISTING music, sound-effect or voiceover item without re-adding it \u2014 THE tool for 'lower the music' / 'make the narration quieter' / 'that whoosh is too loud'. kind: 'music', 'sfx' or 'voiceover'; id from get_edl; gain_db e.g. -12.","inputSchema":{"properties":{"gain_db":{"type":"number"},"id":{"type":"string"},"kind":{"enum":["music","sfx","voiceover"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["kind","id","gain_db","project_id"],"type":"object"},"name":"set_audio_gain","title":"Set audio gain"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Change how existing captions LOOK without touching their text or timing. Pass only the fields to change: 'make the captions premium/viral' -> {\"style\":{\"preset\":\"clean\"}} (see add_captions for the preset menu: clean/documentary/broadcast/podcast/beast/karaoke/spotlight/elegant/stacked/.../classic), 'make it red' -> {\"style\":{\"color\":\"#FF0000\"}}, 'center the captions' -> {\"style\":{\"position\":\"middle\"}}, 'bigger / more dynamic captions' -> {\"style\":{\"size\":\"xl\",\"dynamic\":true}} (dynamic = legacy karaoke without a preset; presets animate on their own). highlight_color changes the accent of emphasized/spoken words; uppercase forces casing; emphasis_words (top-level arg, with a preset) replaces the emphasized keyword list. An explicit position or anchor_y locks captions there for the whole video and removes any old shot-aware placement track \u2014 use this when the user says captions must stop moving. For fine size control that the s|m|l|xl buckets can't hit pass size_scale (0.5-3.0; 1.5 = 50% bigger). Outline, shadow, backing panel, tracking and text alignment are independently editable. For transcript captions, single_line:true overrides any preset stack and guarantees one rendered row per state. Works for from_transcript and manual captions; errors helpfully if no captions exist yet.","inputSchema":{"properties":{"emphasis_words":{"items":{"type":"string"},"type":"array"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"style":{"properties":{"anchor_y":{"maximum":0.95,"minimum":0.05,"type":"number"},"animation":{"enum":["none","fade","pop","slide_up","punch","blur_in","whip","flash","rise","drop","elastic","bounce","swing","zoom_blur"],"type":"string"},"background_color":{"type":"string"},"background_opacity":{"type":"number"},"color":{"type":"string"},"dynamic":{"type":"boolean"},"effect":{"enum":["chroma","chrome","glow"],"type":"string"},"emphasis":{"enum":["big","huge","accent","pop","box","serif","script","chrome","glow","chroma","none"],"type":"string"},"emphasis_scale":{"type":"number"},"font":{"enum":["Inter Display Black","Inter Display ExtraBold","Inter Display Bold","Anton","Bebas Neue","Archivo Black","Poppins Black","Syne ExtraBold","Playfair Display Black","Instrument Serif","DM Serif Display","Montserrat","Plus Jakarta Sans"],"type":"string"},"highlight_color":{"type":"string"},"layout":{"enum":["stack","flow"],"type":"string"},"leading":{"type":"number"},"outline_color":{"type":"string"},"outline_width":{"type":"number"},"position":{"enum":["bottom","top","middle"],"type":"string"},"preset":{"enum":["composed","clean","documentary","broadcast","retro","neon","podcast","reels","beast","karaoke","elegant","spotlight","stacked","iridescent","chrome","editorial","fashion","luxe","impact","lyric","classic"],"type":"string"},"shadow":{"type":"number"},"single_line":{"type":"boolean"},"size":{"enum":["s","m","l","xl"],"type":"string"},"size_scale":{"type":"number"},"text_align":{"enum":["left","center","right"],"type":"string"},"tracking":{"type":"number"},"uppercase":{"type":"boolean"}},"type":"object"}},"required":["project_id"],"type":"object"},"name":"set_caption_style","title":"Set caption style"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Volume automation on the ORIGINAL footage's audio (the speaker) over a SOURCE-time span. NOT for music or voiceover loudness \u2014 use set_audio_gain for those.","inputSchema":{"properties":{"end":{"type":"number"},"gain_db":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"start":{"type":"number"}},"required":["start","end","gain_db","project_id"],"type":"object"},"name":"set_volume","title":"Set volume"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Set the output aspect ratio for every render. ratio: source, 16:9, 9:16, 1:1 or 4:5; mode: crop (default), pad (black bars) or pad_blur (blurred backdrop). focus_x/focus_y aim the CROP at the subject (fractions of the source frame, (0,0) = top-left) \u2014 without them the crop is the dead-center window, which chops an off-center speaker. For 'make it 9:16' on real footage PREFER auto_reframe, which measures the subject and sets the focus for you. Finals compose on an HD canvas so new captions and branding stay sharp even on archival footage; this does not restore missing source detail. focus_track replaces the complete per-shot track: [{t0,t1,x,y,mode}] in SOURCE seconds. Read get_edl(frame) first; change only the desired spans. Tracks survive trims and speed changes. picture=[left,top,right,bottom] optionally places the main picture and inserts inside a normalized output rectangle on black. Crop/fit and focus apply inside it, preserving native audio/transcript timing. For a 4:3 picture on 9:16: picture=[0,0.2890625,1,0.7109375]. Captions, headlines and branding stay at the full delivery resolution.","inputSchema":{"properties":{"focus_track":{"items":{"properties":{"mode":{"enum":["crop","pad","pad_blur"],"type":"string"},"t0":{"type":"number"},"t1":{"type":"number"},"x":{"type":"number"},"y":{"type":"number"}},"required":["t0","t1"],"type":"object"},"type":"array"},"focus_x":{"type":"number"},"focus_y":{"type":"number"},"mode":{"enum":["crop","pad","pad_blur"],"type":"string"},"picture":{"items":{"type":"number"},"maxItems":4,"minItems":4,"type":"array"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"ratio":{"enum":["source","16:9","9:16","1:1","4:5"],"type":"string"}},"required":["ratio","project_id"],"type":"object"},"name":"set_frame","title":"Set frame"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. THE tool for 'make it 9:16 / vertical / for TikTok'. It samples frames across the kept footage and MEASURES two things before writing the frame: where the subject is (faces found in the pixels; vision or a detail-energy estimate only when there is no face), and whether a crop is the right operation at all \u2014 how much of the picture's detail would survive the crop window. With mode='auto' (default) footage with a subject gets a crop aimed at it, and footage whose content runs to the edges (gameplay, screen recordings, wide scenes) is FITTED into the new frame over a blurred backdrop so nothing is cut off \u2014 cropping those is the 'it just truncated my video instead of adjusting it' complaint. Pass mode explicitly to force one. Read what it reports and repeat THAT.","inputSchema":{"properties":{"mode":{"enum":["auto","crop","pad","pad_blur"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"ratio":{"enum":["9:16","1:1","4:5","16:9","source"],"type":"string"}},"required":["ratio","project_id"],"type":"object"},"name":"auto_reframe","title":"Reframe for a vertical or square platform"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Start a NEW media-only sequence from one uploaded video clip or image, replacing the current programme in ONE valid append-only EDL write. Use this when the requested story should be assembled from uploaded assets instead of the project's main video. This is the safe first operation in an atomic recipe: it never creates an invalid empty timeline. Add later scenes with insert_media. Every earlier EDL version remains recoverable. duration_s and clip_start_s select a video window; motion/fit match insert_media.","inputSchema":{"properties":{"asset_key":{"type":"string"},"clip_start_s":{"type":"number"},"duration_s":{"type":"number"},"fit":{"enum":["auto","crop","pad","pad_blur"],"type":"string"},"motion":{"enum":["zoom_in","zoom_out","pan_left","pan_right"],"type":"string"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["asset_key","project_id"],"type":"object"},"name":"start_media_sequence","title":"Start media sequence"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Splice an uploaded video clip or image INTO the edit at ANY position in the FINAL edited video \u2014 mid-take positions split the take cleanly at a word edge, so 'in the middle of the talk' works exactly. NEVER splice a clip the user sent as a STYLE REFERENCE ('watch this', 'make it like this', 'use this as reference', 'recreate this', a YouTube they asked you to study) \u2014 look_at_asset it, extract_audio / add_music if they want THAT song, and rebuild the look from the MAIN gameplay/footage. If the studio already placed a reference on the timeline, remove_insert it. Call list_assets(kind='clip') or kind='image' first and pass the exact storage_key. duration_s: how long the insert plays (image default 3.0s; a video defaults to its available length). clip_start_s: where in the source clip the window starts \u2014 use look_at_asset to pick the right moment. motion: 'zoom_in', 'zoom_out', 'pan_left' or 'pan_right' gives either a still or a video insert its own slow local camera move without changing timing or audio. Use it deliberately to direct attention, not on every shot. Inserted media is NOT transcribed \u2014 captions cover the main footage only. fit defaults to 'auto': the WHOLE asset is preserved (black bars when the program frame is already pad; a blurred extension otherwise) so a portrait card cannot be center-cropped into an empty middle band. Pass fit='pad' for solid black; never use blur when the user asked for black. fit='crop' fills edge-to-edge. Assets may be reused whenever the edit benefits from repetition or a different source window.","inputSchema":{"properties":{"asset_key":{"type":"string"},"at_output_s":{"type":"number"},"clip_start_s":{"type":"number"},"duration_s":{"type":"number"},"fit":{"enum":["auto","crop","pad","pad_blur"],"type":"string"},"motion":{"enum":["zoom_in","zoom_out","pan_left","pan_right"],"type":"string"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["asset_key","at_output_s","project_id"],"type":"object"},"name":"insert_media","title":"Insert media"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. PROJECT-SCOPED: build ONE 16:9 clip that shows 2 or 3 independent videos side-by-side on a solid BLACK canvas \u2014 the signature multi-panel athlete/action wall. Do NOT fake this with pad_blur inserts plus small PIP overlays. columns is either a list of 2\u20133 asset_keys or a list of columns, each a list of {asset_key, start, duration} clips that play in that column (when one clip ends the next one in that column starts). duration_s caps the result (1\u201320s, default 8). The file is saved as a video_clip and is NOT in the program until insert_media (use fit='pad'). Audio is omitted \u2014 add_music for the bed.","inputSchema":{"properties":{"columns":{"type":"array"},"duration_s":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["columns","project_id"],"type":"object"},"name":"compose_panels","title":"Compose panels"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Change which part of an already-spliced clip plays, IN PLACE \u2014 duration_s for how long it runs, clip_start_s for where in the clip it starts, rate for how FAST it plays. USE THIS instead of remove_insert + insert_media to trim or re-window a clip that is already on the timeline: removing and re-adding costs two edit versions and two renders, and the user watches their clip disappear and come back. rate (0.25-4, round 76) is THE tool for 'speed up that scene instead of cutting it': rate alone keeps the clip window and shortens the block (a 10s screen recording at rate 2 becomes a 5s scene with nothing lost, audio pitch-corrected); with duration_s the block is duration_s long and consumes duration_s*rate of clip. TO SPLIT a spliced clip in two: shorten it here to the first part, then insert_media the same asset_key at the SAME at_output_s with clip_start_s set to where the first part ended \u2014 the two halves play in the order you created them. crop=[x0,y0,x1,y1] (round 77) shows ONE REGION of the clip as the whole scene, letterboxed (black bars) \u2014 THE tool for 'show the full timeline strip/panel, nothing else, static': a zoom's 16:9 window can never hold a wide UI strip without also holding what sits above it, so crop the insert instead and leave the zoom wide over it. Fractions of the CLIP's frame, read off a look_at_asset grid; pass 'full' to clear. mute=true (round 78) silences the scene's OWN audio \u2014 THE answer to 'mute that clip' / 'mute all scenes' (set_volume only reaches the main footage; muting every scene = set_volume on the kept spans + mute on each video insert). mute=false brings it back. fit (round 79) sets how THIS scene maps onto the canvas: 'pad' shows the WHOLE picture letterboxed on black \u2014 THE fix for a portrait image or clip that the default cover-crop beheads ('the image looks corrupted / cut off') \u2014 'pad_blur' fits it over a blurred backdrop, 'crop' forces the cover-crop, 'auto' clears the override. rotation repairs THIS scene clockwise by 0/90/180/270 degrees \u2014 use it for one sideways phone clip instead of a whole-program custom filter. motion=none removes local zoom/pan, which otherwise still crops the picture AFTER pad/pad_blur fitting.","inputSchema":{"properties":{"clip_start_s":{"type":"number"},"crop":{"items":{"type":"number"},"type":"array"},"duration_s":{"type":"number"},"fit":{"enum":["pad","pad_blur","crop","auto"],"type":"string"},"id":{"type":"string"},"motion":{"enum":["none","zoom_in","zoom_out","pan_left","pan_right"],"type":"string"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"mute":{"type":"boolean"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"rate":{"type":"number"},"rotation":{"type":["integer","string"]}},"required":["id","project_id"],"type":"object"},"name":"set_insert_window","title":"Set insert window"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. MOVE A SPLICED SCENE \u2014 reorder an inserted clip between any other scenes, in place. after_id is the insert it should play right AFTER (the scene map in get_edl names each scene's insert id); omit it to play FIRST at its boundary. THE tool for 'move this clip between those two scenes' / 'put the uploaded video after the intro' \u2014 never remove + re-insert, which costs two versions and the user watches the clip vanish. Everything anchored to the moved scenes (zooms, takeovers, texts) re-anchors and follows.","inputSchema":{"properties":{"after_id":{"type":"string"},"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"move_insert","title":"Move insert"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one spliced insert by its id (see get_edl) \u2014 the surrounding timing is restored exactly. If an insert landed wrong, remove it BEFORE re-inserting, or the old one stays in the video.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_insert","title":"Remove insert"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":true,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Download media from a LINK the user gave you and save it as a project asset \u2014 a video, a song, or an image. Works with direct file links (Dropbox, Drive, a CDN, a stock library) and with page links (YouTube, TikTok, Vimeo, SoundCloud). Use this whenever the user pastes a URL for something they want in the edit; never tell them to upload a file you could have fetched. The file type is detected automatically \u2014 pass as_kind only to force audio-only from a video page ('music'). The result is saved to the project but is NOT in the video until you add it with insert_media (clip/image) or add_music (audio). Fetching verifies neither ownership nor license: the returned RIGHTS CHECK must be relayed; a downloadable file is not permission to republish.","inputSchema":{"properties":{"as_kind":{"enum":["clip","music","image"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"url":{"type":"string"}},"required":["url","project_id"],"type":"object"},"name":"fetch_url","title":"Fetch url"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":true,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. SEARCH for b-roll images/clips the user does not have. Two kinds of query work: generic visuals ('a busy city', 'ocean waves') AND \u2014 with kind='photo' \u2014 REAL topical subjects ('Elon Musk', 'SpaceX Starship', a company, a product) from Wikimedia/Flickr's photo record; relay each photo's license line when it carries an obligation. For real topical VIDEO use find_footage instead. Returns a VISUALLY REVIEWABLE, provider-diverse grid (Pexels/Pixabay/Openverse when configured), not a homogeneous first-provider dump. Candidates ONLY: nothing is downloaded and nothing enters the video. kind 'video' (default) or 'photo'. orientation defaults to the project's output frame, so a 9:16 edit gets vertical footage. Then call add_stock_media with the best id.","inputSchema":{"properties":{"count":{"type":"integer"},"kind":{"enum":["video","photo"],"type":"string"},"orientation":{"enum":["landscape","portrait","square"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"query":{"type":"string"}},"required":["query","project_id"],"type":"object"},"name":"search_stock","title":"Search stock"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Research B-roll as a COHERENT STORY SEQUENCE, not one isolated keyword at a time. Pass every meaningful cutaway moment with a concrete visual query, its editorial purpose, intended output time and approximate duration. For an important beat, query_variants can name distinct truthful visual routes (exact subject, observable action, environment/detail) so the choice is not trapped inside one keyword's near-duplicates. The tool searches moments concurrently, adapts candidate depth to the size of the story, returns candidates grouped by purpose, and attaches one balanced visual board spanning the whole edit. For the in-house editor, one independent sequence cast compares visible specificity, authenticity, composition, color and diversity and may choose KEEP BASE PICTURE / NO B-ROLL for any weak moment. This is selection evidence, not a placement quota. Nothing enters the project until add_stock_media; the actual downloaded clip is then visually reviewed before placement. Use kind='photo' for real people/products/places when topical video is unavailable.","inputSchema":{"properties":{"moments":{"items":{"properties":{"at":{"type":"number"},"duration_s":{"type":"number"},"id":{"type":"string"},"kind":{"enum":["video","photo"],"type":"string"},"purpose":{"type":"string"},"query":{"type":"string"},"query_variants":{"items":{"type":"string"},"type":"array"}},"required":["query","purpose"],"type":"object"},"maxItems":128,"type":"array"},"orientation":{"enum":["landscape","portrait","square"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["moments","project_id"],"type":"object"},"name":"research_broll","title":"Research broll"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":true,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. DOWNLOAD one saved search_stock or research_broll result and save it as a project asset. `id` must exactly match a result returned for THIS PROJECT; handles survive later turns and MCP worker processes. The clip is SILENT and is NOT in the video yet \u2014 place it with add_overlay(fit='cover') for a cutaway that keeps the speech running, or insert_media to splice it in. Representative frames from the ACTUAL downloaded rendition are automatically attached; inspect them before placement. Always tell the user which shot you used.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"add_stock_media","title":"Add stock media"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":true,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. RECORD A LIVE WEB PAGE as video: a headless browser opens the URL at the project's aspect, holds the top, smooth-scrolls to the bottom and holds \u2014 the classic product-demo pan \u2014 and the capture becomes a project video asset. THE tool for 'show my website / landing page / this product page in the edit'. duration_s 4-30 (default 12). orientation defaults to the project's output frame. scroll=false just holds the top of the page. The capture is SILENT and shows the PUBLIC page (no logins, no clicks); place it with insert_media or add_overlay(fit='cover').","inputSchema":{"properties":{"duration_s":{"type":"number"},"orientation":{"enum":["landscape","portrait","square"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"scroll":{"type":"boolean"},"url":{"type":"string"}},"required":["url","project_id"],"type":"object"},"name":"record_website","title":"Record website"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":true,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. RECORD THE BROWSER USING A SITE \u2014 the showcase capture. A headless browser opens the URL with a VISIBLE cursor drawn on screen and works through `steps` you write: it glides the pointer to a button, clicks it, waits for the page to react, types into fields at human speed, scrolls between sections. THE tool for 'record yourself using my product', a launch/demo video, or 'show how it works', where record_website only pans down a static page. Steps are objects: {do:'click', text:'Start free trial'} (text = the VISIBLE label; or selector: a CSS selector), {do:'type', selector:'input[type=email]', text:'you@example.com'}, {do:'scroll', to:'Pricing'} or {do:'scroll', by:800}, {do:'hover', text:'Plans'}, {do:'press', key:'Enter'}, {do:'wait', seconds:1.5}, {do:'goto', url:'\u2026'}. Add `seconds` to any step to hold longer after it. It returns an EVENT TRACK \u2014 every click, scroll and keystroke timestamped with its position in the frame \u2014 then place it with showcase_demo, which uses that track. It records the PUBLIC site as a visitor sees it and will not type into password or payment fields. Write 4-10 steps that tell one story; a demo that clicks everything shows nothing.","inputSchema":{"properties":{"orientation":{"enum":["landscape","portrait","square"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"steps":{"items":{"type":"object"},"type":"array"},"url":{"type":"string"}},"required":["url","steps","project_id"],"type":"object"},"name":"record_website_demo","title":"Record website demo"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":true,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. PLACE A SCREEN RECORDING AND CUT IT LIKE A PRODUCT VIDEO \u2014 one call. Splices the clip into the edit, then puts a zoom on each run of POSITIONED clicks. Click sounds are optional; choose them when they serve the edit. Works on ANY video clip, not just a record_website_demo capture. On a capture I made, the event track is exact: the frame pushes in and TRAVELS between the buttons, with a soft pop on each page change and a swipe under each scroll. On a recording the USER made, pass click_times=[...] (seconds into the clip) to supply timing. Clicks cannot be located from timing alone, so no zoom is invented without a position. With neither, it still places the clip and tells you plainly that nothing was synced. at_output_s defaults to the END of the current edit; zoom_strength 0.05-4.5 (0.4 default \u2014 screen text needs a real push to read); set zooms=false to place it plainly; click_sounds=true is opt-in. Follow up with add_zoom_path to make the frame travel on a user recording, and enhance_cursor if the pointer is too small to follow.","inputSchema":{"properties":{"asset_key":{"type":"string"},"at_output_s":{"type":"number"},"click_sounds":{"type":"boolean"},"click_times":{"items":{"type":"number"},"type":"array"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"zoom_strength":{"type":"number"},"zooms":{"type":"boolean"}},"required":["asset_key","project_id"],"type":"object"},"name":"showcase_demo","title":"Showcase demo"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Apply a color-grade preset to the whole video (captions stay unstyled): vibrant, warm, cool, bw, vintage, cinematic \u2014 or 'none' to clear. THE tool when the user asks for a filter / look / mood.","inputSchema":{"properties":{"preset":{"enum":["vibrant","warm","cool","bw","vintage","cinematic","none"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["preset","project_id"],"type":"object"},"name":"set_color_grade","title":"Set color grade"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Zoom on a time range of the FINAL edited video (output seconds) only when a named event needs the camera to move: a reveal, a UI target, a punchline, an explicit user beat. A talking-head already in frame does NOT need a punch-in. strength 0.05-4.5 (default 0.15; above 1.0 is a dramatic 2x+ punch). mode: 'ease' (default, smooth ramp \u2014 use this), 'push_in' / 'pull_out' (continuous Ken Burns drift), 'punch' (instant snap \u2014 ONLY the single biggest peak or an explicit punch-in request, never every few seconds). TWO ways to aim, and they answer different requests: rect=[x0,y0,x1,y1] (fractions of the output frame, read off look_at's grid) FRAMES A REGION \u2014 the tool solves strength and centre so that box fills the frame with margin, THE way to 'zoom into the message / that button / this panel', and its result reports where the region lands on screen. cx/cy instead PIN A POINT: that point keeps its exact screen position while everything magnifies around it \u2014 right for emphasis on a subject that is already well-composed, and wrong for framing a thing near an edge (an edge point stays at the edge at any strength \u2014 it never slides to centre). Pass rect OR cx/cy, not both; if both arrive the rect wins (it already determines the centre) and the call still succeeds. Omitting all targets uses the frame center and returns a quality advisory. Coordinates may come from look_at, the filmstrip, user direction, or the editor's own judgment; no prior evidence call is required. Zero zooms is often correct. Do not sprinkle punches on 'important sentences'. punch_in_on_emphasis is only for an explicit punch-in-on-stressed-words request. If the zoom should MOVE while pushed in \u2014 'then move it to X', 'keep it and go to the next message', 'follow the cursor' \u2014 that is ONE add_zoom_path (its keyframes take rect too), never a chain of static zooms.","inputSchema":{"properties":{"cx":{"type":"number"},"cy":{"type":"number"},"end":{"type":"number"},"mode":{"enum":["punch","ease","push_in","pull_out"],"type":"string"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"purpose":{"description":"The nameable narrative or visible reason for this zoom.","type":"string"},"rect":{"items":{"type":"number"},"type":"array"},"start":{"type":"number"},"strength":{"type":"number"},"target_evidence_ids":{"items":{"type":"string"},"type":"array"}},"required":["start","end","project_id"],"type":"object"},"name":"add_zoom","title":"Add zoom"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one zoom by its id (see get_edl).","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_zoom","title":"Remove zoom"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. A ZOOM THAT MOVES \u2014 THE tool for 'make the zoom follow the cursor' / 'move the zoom between buttons' / 'stay zoomed and then move to the next thing' on ANY footage, including a screen recording the user made themselves. Any request where ONE zoom should hold, travel, or visit several subjects in sequence is THIS tool \u2014 never a chain of static add_zoom calls, which cut out and back instead of moving. keyframes is a list of at least two points, each {t, rect, strength} or {t, cx, cy, strength}: t is OUTPUT-timeline seconds; rect=[x0,y0,x1,y1] FRAMES the thing to look at there (fractions of the frame from look_at's grid \u2014 the same solver as add_zoom rect, so edge subjects come out framed, and omitting strength on a rect keyframe picks the strength that fits it); cx/cy instead PIN a point ((0,0) = top-left). strength 0-4.5 interpolates between keyframes, so the frame can push in as it arrives and ease out as it leaves; to HOLD on a subject, repeat its keyframe at the hold's start and end times. The window runs from the first t to the last. NO ramp is added at the edges: give the first and last keyframe strength 0 for a seamless entry and exit (a strength-0 rect keyframe still aims where the move is going). ease: 'cubic_in_out' (default \u2014 settles at each keyframe, the right answer for stopping at buttons) or 'linear' (constant speed, for a steady scan across a wide screenshot). It re-anchors across later cuts exactly like add_zoom, so cutting elsewhere never strands it. Remove the whole move with remove_zoom_path.","inputSchema":{"properties":{"ease":{"enum":["cubic_in_out","linear"],"type":"string"},"keyframes":{"items":{"type":"object"},"type":"array"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"purpose":{"type":"string"},"target_evidence_ids":{"items":{"type":"string"},"type":"array"}},"required":["keyframes","project_id"],"type":"object"},"name":"add_zoom_path","title":"Add zoom path"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one keyframed travelling zoom by its id (see get_edl). Use remove_zoom for ordinary punch/ease zooms.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_zoom_path","title":"Remove zoom path"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. MAKE THE MOUSE POINTER BIGGER AND STEADIER \u2014 THE tool for 'the cursor is too small' / 'too jittery' on a screen recording. It finds the pointer in the source frames, repaints the original out, and redraws it at `scale`x (1-4; 2 is the usual answer) along a path filtered to remove hand tremor \u2014 `smoothing` 0-1, where fast deliberate moves stay sharp at any setting. click_times is a list of SOURCE-video seconds that get an expanding ripple: I CANNOT see clicks in the pixels (nothing distinguishes a press from a hover), so either pass the times record_website_demo reported, or ask the user when the clicks were \u2014 never guess them. Set click_highlight=false to skip the ripples. This bakes into the source copy the render reads, so every cut keeps it and no timestamp moves; it reports what fraction of frames the pointer was actually found in and refuses outright on footage that has no visible cursor. Undo with remove_cursor_enhance.","inputSchema":{"properties":{"click_highlight":{"type":"boolean"},"click_times":{"items":{"type":"number"},"type":"array"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"scale":{"type":"number"},"smoothing":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"enhance_cursor","title":"Enhance cursor"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Put the original mouse pointer back (re-derives from the untouched source).","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"remove_cursor_enhance","title":"Remove cursor enhance"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Compose FOOTAGE ONLY as a rounded picture card during start/end program seconds. Captions, designed type and branding stay independent and sharp. Stable id replaces the card. box=[left,top,right,bottom] on the output canvas; radius 0-.25 of card short side; border 0-.015 of canvas short side. entrance/exit none, fade, lift (restrained settle), or reveal (picture opens/closes inside its rounded window). duration_s .12-1.2. Source is frame.picture if present, otherwise the whole composed program. Set frame.picture first to preserve a wide original inside portrait; this cannot recover pixels already cropped away. Use fit=pad to retain that whole source, crop to fill. Windows must not overlap. Inspect entry, settle, exit and the speaker framing. Rounded cards are one purposeful format, not a quota.","inputSchema":{"properties":{"background":{"type":"string"},"border":{"type":"number"},"border_color":{"type":"string"},"box":{"items":{"type":"number"},"maxItems":4,"minItems":4,"type":"array"},"duration_s":{"type":"number"},"end":{"type":"number"},"entrance":{"enum":["none","fade","lift","reveal"],"type":"string"},"exit":{"enum":["none","fade","lift","reveal"],"type":"string"},"fit":{"enum":["crop","pad"],"type":"string"},"id":{"type":"string"},"motion_motif":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"radius":{"type":"number"},"shadow":{"type":"number"},"start":{"type":"number"}},"required":["id","start","end","project_id"],"type":"object"},"name":"set_picture_card","title":"Set picture card"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove a footage card by id.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_picture_card","title":"Remove picture card"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Author a measured, restrained editorial composition as editable native text/vector layers in ONE revision. Stable id replaces its whole group. kind: statement, comparison (text vs secondary), metric (text is the real value, secondary its meaning), quote, chapter, label, headline. headline requires the verified speaker name in speaker and a faithful claim in text: it prefixes the name inline, wraps at readable font_size (default .052), and holds still without a panel or caption suppression. Max three lines; shorten excess copy. Place its box above the actual picture; never infer identity from a reference. Pass exact supported claims; never invent statistics. Optional eyebrow is short context, not filler. palette ink/paper/slate; motion settle/none; box=[left,top,right,bottom] chooses its region. treatment=panel draws a backdrop; type removes the box for integrated editorial typography. Dialogue captions remain by default. Set mute_captions=true ONLY when this graphic replaces the spoken text; its own live window then owns the suppression and removal restores captions. Reading-time and type-size checks reject overcrowding rather than silently shrinking it. Place in deliberate clear space or use as a meaningful cutaway; inspect the rendered composition.","inputSchema":{"properties":{"box":{"items":{"type":"number"},"maxItems":4,"minItems":4,"type":"array"},"end":{"type":"number"},"eyebrow":{"type":"string"},"font_size":{"type":"number"},"id":{"type":"string"},"kind":{"enum":["statement","comparison","metric","quote","chapter","label","headline"],"type":"string"},"motion":{"enum":["settle","none"],"type":"string"},"motion_motif":{"type":"string"},"mute_captions":{"type":"boolean"},"palette":{"enum":["ink","paper","slate"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"secondary":{"type":"string"},"speaker":{"type":"string"},"start":{"type":"number"},"text":{"type":"string"},"treatment":{"enum":["panel","type"],"type":"string"}},"required":["id","kind","text","start","end","project_id"],"type":"object"},"name":"set_editorial_graphic","title":"Set editorial graphic"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove an editorial group and its caption suppression.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_editorial_graphic","title":"Remove editorial graphic"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Compose a speech-cued mixed-font phrase in ONE revision, as editable native text. All words reserve their final positions: earlier words never jump or replay their entrance. Stable id replaces its group. lines is 1-6 rows, each {runs:[{text,at,font,italic,scale,color}],size?}. at is the REAL PROGRAM cue in seconds (not source or relative time); default=start. Runs stay until the shared end. Use build to accumulate at spoken cues; still displays everything. Pair Inter Display Bold with sparse Instrument Serif italic for meaningful contrast, not every word. A line's size and run scale multiply font_size (fraction of canvas short edge). box=[left,top,right,bottom] is a measured region; align left/center/right; motion settle/none. Oversized/overcrowded lines are rejected instead of silently shrinking or reflowing. mute_captions=true replaces dialogue ONLY in these actual live windows; false for independent labels. Use real words and cue times from get_kept_transcript. Inspect the opening, build, settled phrase and face clearance. This is designed typography, not a substitute for selecting a good story.","inputSchema":{"properties":{"align":{"enum":["left","center","right"],"type":"string"},"box":{"items":{"type":"number"},"maxItems":4,"minItems":4,"type":"array"},"color":{"type":"string"},"end":{"type":"number"},"font_size":{"type":"number"},"id":{"type":"string"},"leading":{"type":"number"},"lines":{"items":{"properties":{"runs":{"items":{"properties":{"at":{"type":"number"},"color":{"type":"string"},"font":{"enum":["Inter Display Black","Inter Display ExtraBold","Inter Display Bold","Anton","Bebas Neue","Archivo Black","Poppins Black","Syne ExtraBold","Playfair Display Black","Instrument Serif","DM Serif Display","Montserrat","Plus Jakarta Sans ExtraBold"],"type":"string"},"italic":{"type":"boolean"},"scale":{"type":"number"},"text":{"type":"string"}},"required":["text"],"type":"object"},"type":"array"},"size":{"type":"number"}},"required":["runs"],"type":"object"},"maxItems":6,"minItems":1,"type":"array"},"motion":{"enum":["settle","none"],"type":"string"},"mute_captions":{"type":"boolean"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"reveal":{"enum":["build","still"],"type":"string"},"start":{"type":"number"}},"required":["id","start","end","lines","project_id"],"type":"object"},"name":"set_typography_scene","title":"Set typography scene"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove a native typography scene and its owned caption suppression.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_typography_scene","title":"Remove typography scene"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. THE tool for 'that floating rounded window on a gradient' look \u2014 the standard treatment for a screen recording or app demo. The finished picture is inset, its corners rounded, a soft shadow dropped under it, and it floats on a solid colour or a two-colour gradient. inset 0.02-0.35 (0.08 default \u2014 how much room the backdrop gets); radius 0-0.25 as a fraction of the picture's short side; shadow 0-1; background/background2 are #RRGGBB (pass background2 for a gradient, or 'none' to go flat) with direction vertical/horizontal/diagonal/radial \u2014 the same gradient renderer add_color_screen uses, so a backdrop can match an interstitial exactly. Calling it again edits the settings rather than stacking. It applies to the WHOLE finished picture (captions and overlays scale with it, because they are inside the window) and changes no timing at all. Remove with remove_screen_frame.","inputSchema":{"properties":{"background":{"type":"string"},"background2":{"type":"string"},"direction":{"enum":["vertical","horizontal","diagonal","radial"],"type":"string"},"inset":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"radius":{"type":"number"},"shadow":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"set_screen_frame","title":"Set screen frame"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove the floating rounded window \u2014 the picture goes back to full-bleed.","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"remove_screen_frame","title":"Remove screen frame"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. CHANGE THE ASPECT RATIO MID-VIDEO, SMOOTHLY \u2014 THE tool for 'go vertical for this bit' / 'squeeze to square here and back'. At at_output_s the visible frame MORPHS to `ratio` over duration_s (0.1-4s, 0.8 default) with an eased close-in, and stays there until the next shift; add another with ratio='source' to open back out. The rendered file keeps ONE resolution \u2014 it has to, that is what a video file is \u2014 so the change is the frame itself closing in, which is exactly what a smooth aspect change looks like and is why it cannot desync audio or move a caption. zoom=true (default) pushes the picture in as the frame narrows so the subject holds its size. color is the bars' colour. For changing the aspect of the WHOLE video use set_frame or auto_reframe instead. Remove one with remove_aspect_shift.","inputSchema":{"properties":{"at_output_s":{"type":"number"},"color":{"type":"string"},"duration_s":{"type":"number"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"ratio":{"enum":["source","16:9","9:16","1:1","4:5","4:3"],"type":"string"},"zoom":{"type":"boolean"}},"required":["at_output_s","ratio","project_id"],"type":"object"},"name":"add_aspect_shift","title":"Change aspect ratio mid-video"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one mid-video aspect change by its id (see get_edl).","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_aspect_shift","title":"Remove aspect shift"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Fade from black at the start and/or to black at the end (video + audio). Seconds; 0 clears. Example: set_fades(fade_in_s=0.5, fade_out_s=0.8).","inputSchema":{"properties":{"fade_in_s":{"type":"number"},"fade_out_s":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"set_fades","title":"Set fades"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Transitions at SCENE CHANGES \u2014 junctions where the footage actually changes shot, or where an insert (b-roll, title card, generated clip) splices in. All duration-preserving junction effects (footage never overlaps, timing never changes). IMPORTANT \u2014 after cut_silences a talking-head video has one junction per removed pause, and nearly all of them are JUMP CUTS inside one continuous shot: same framing, same subject, the speaker's head half a word further along. A jump cut works by being invisible. Putting a whip or a dip on each one fires a full-screen effect every couple of seconds through footage that never changed scene, and it reads as broken \u2014 a real user shipped 45 whips through one continuous shot and said so. scope defaults to 'scene' and handles this for you; the result tells you how many junctions it actually landed on and how many it skipped, so report THAT number, not the cut count. Pass scope='every_cut' whenever that stronger treatment serves the edit. Styles: 'dip_black' = quick dip through black (calm, universal); 'dip_white' = soft white fade-through; 'whip_left'/'whip_right' = fast directional slide with motion blur (energetic vlogs/reels); 'zoom_punch' = accelerating push through the cut (hype, sports); 'glitch' = RGB-split/noise burst (tech, gaming); 'flash' = additive white pop peaking ON the cut (beat-synced edits). duration_s 0.1-1.5 (default 0.3; keep whip/flash short, 0.15-0.4). 'none' removes them (hard cuts again). True crossfades (overlapping footage) are NOT supported \u2014 offer one of these instead and say so.","inputSchema":{"properties":{"duration_s":{"type":"number"},"max_transitions":{"description":"Optional cap for a restrained treatment. The tool distributes the effect across at most this many eligible scene changes; use 2-4 when the user asks for subtle or not excessive transitions.","minimum":1,"type":"integer"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"scope":{"description":"'scene' (default) = only where the footage changes shot or an insert splices in. 'every_cut' = every junction including silence-removal jump cuts; use it whenever that is the intended treatment.","enum":["scene","every_cut"],"type":"string"},"style":{"enum":["dip_black","dip_white","whip_left","whip_right","zoom_punch","glitch","flash","none"],"type":"string"}},"required":["style","project_id"],"type":"object"},"name":"set_transitions","title":"Set transitions"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Put a VISIBLE censor over a fixed RECTANGLE of the original footage \u2014 blur, mosaic or a black bar. Use it when the user WANTS the covering to show: a face, a document, a phone number, a plate. To make something GO AWAY instead \u2014 burned-in captions, a watermark, a username, an object \u2014 use erase_region / erase_burned_text, which repaint the pixels and rebuild the picture behind them; a blur where the user asked for removal reads as a workaround. x,y = TOP-LEFT corner and w,h = size, all as FRACTIONS (0-1) of the SOURCE frame \u2014 exactly the frames look_at shows you; a 9:16 or other output reframe moves the censored footage with it automatically, and spliced-in clips/images are never censored. Example \u2014 a username in the top-right corner: x=0.6, y=0.02, w=0.38, h=0.1. FIRST look_at the video asking exactly where the text sits (corner? edge? how big?), then blur_region, then render_preview and CHECK the sheet \u2014 if text still shows, remove_blur and place a bigger region. start/end (output seconds) optionally limit when it applies; omit both for the whole video. mode: 'blur' (soft, default), 'pixelate' (mosaic), 'black' (solid bar). The rectangle does NOT track motion \u2014 text that moves with the camera may leave it; verify and tell the user honestly.","inputSchema":{"properties":{"end":{"type":"number"},"h":{"type":"number"},"mode":{"enum":["blur","pixelate","black"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"start":{"type":"number"},"w":{"type":"number"},"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y","w","h","project_id"],"type":"object"},"name":"blur_region","title":"Blur region"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one censor region by its id (see get_edl), or ALL censor regions when id is omitted.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"remove_blur","title":"Remove blur"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. MEASURE where text is burned into the footage \u2014 subtitle bands, watermarks, handles, on-screen labels. Reads the actual frames and returns EXACT rectangles as frame fractions, plus when each is visible. Use this INSTEAD of estimating a rectangle from look_at: an estimated box is what puts a bar next to the text instead of over it. Read-only. scope: 'captions' (wide subtitle lines whose words change), 'watermark' (a small mark identical in every frame), 'text', or 'all' (default). start/end limit the scan to a source-time window.","inputSchema":{"properties":{"end":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"scope":{"enum":["all","captions","watermark","text"],"type":"string"},"start":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"find_burned_text","title":"Find burned text"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. TRULY REMOVE burned-in captions (or watermarks) \u2014 one call: it measures every matching region and REPAINTS THE PIXELS, reconstructing the picture that was behind the text. This is real removal, not a blur or a bar: say 'removed'. Use it for 'remove the captions' / 'take the subtitles off' / 'get rid of the watermark' on footage that arrived with text burned in, and BEFORE add_captions when the user wants a different caption font or style \u2014 with the old text gone, new captions cannot stack on it. Cuts, timings, transcript and captions are unaffected; the video is unchanged except that the text is gone. scope defaults to 'captions'.","inputSchema":{"properties":{"end":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"scope":{"enum":["all","captions","watermark","text"],"type":"string"},"start":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"erase_burned_text","title":"Erase burned-in text from the picture"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. TRULY REMOVE whatever is inside a rectangle \u2014 repaints those pixels and reconstructs the background, so the thing is GONE, not covered. Use it for a word, a sign, a sticker, a logo, a person's name on screen, or any object the user wants taken out. SEVERAL marks (a watermark AND a handle AND a caption bar) go in ONE call as regions=[{x,y,w,h,fill?,start?,end?}, ...]. The repaint costs time proportional to the WINDOW you erase, not the video \u2014 so pass start/end around when the mark is actually visible and the erase lands in seconds; earlier erases are never redone. x,y = TOP-LEFT corner, w,h = size, all FRACTIONS (0-1) of the SOURCE frame \u2014 get them from find_burned_text rather than estimating. fill: 'text' (default \u2014 repaints only the letter strokes and keeps the picture behind them; best for captions/handles) or 'box' (repaints the whole rectangle; use for an OBJECT or a solid graphic). start/end (SOURCE seconds) limit it to a window; omit both for the whole video. Reconstruction is excellent for thin text and for anything on a steady shot; a large object on a moving, detailed background can leave a soft patch \u2014 the result is measured and reported back to you, so check it before you promise anything.","inputSchema":{"properties":{"end":{"type":"number"},"fill":{"enum":["text","box"],"type":"string"},"h":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"regions":{"items":{"properties":{"end":{"type":"number"},"fill":{"enum":["text","box"],"type":"string"},"h":{"type":"number"},"start":{"type":"number"},"w":{"type":"number"},"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y","w","h"],"type":"object"},"type":"array"},"start":{"type":"number"},"w":{"type":"number"},"x":{"type":"number"},"y":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"erase_region","title":"Erase region"},{"annotations":{"destructiveHint":true,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Start again from the full untouched source video whenever that is the best route for the brief or current edit. The tool creates a new version, so every prior cut remains recoverable in version history. It drops every current cut, caption, track and effect; state honestly when you chose to rebuild from source.","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"reset_edit","title":"Discard the edit and start from the source"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Undo an erase: put the original pixels back for one erased region by its id (see get_edl), or for ALL of them when id is omitted. Instant for window-patch erases; legacy whole-file erases rebuild from the untouched original.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"remove_erase","title":"Remove erase"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Lay an uploaded audio file OVER the whole program from start_output_s (a position in the FINAL edited video, default 0). duck_others (default true) lowers all other audio 12dB while it plays. source_offset_s seeks into the file in place (use it to start a narration/song excerpt at the right moment; never create an externally trimmed workaround). duration_s ends the excerpt after exactly that many seconds. To reuse dialogue from the MAIN source over an inserted/second scene, pass asset_key='main', its SOURCE start as source_offset_s, the sentence length as duration_s, and the destination scene's OUTPUT time as start_output_s. Otherwise use a storage_key from list_assets(kind='music').","inputSchema":{"properties":{"asset_key":{"type":"string"},"duck_others":{"type":"boolean"},"duration_s":{"type":"number"},"gain_db":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"source_offset_s":{"type":"number"},"start_output_s":{"type":"number"}},"required":["asset_key","project_id"],"type":"object"},"name":"add_voiceover","title":"Add voiceover"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one voiceover by its id (see get_edl).","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_voiceover","title":"Remove voiceover"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Speed up or slow down a SOURCE-time range of the main video (like set_volume, start/end are SOURCE seconds \u2014 the ramp stays on its footage through later cuts, and music/overlays/zooms/sfx are re-anchored automatically). factor 0.25-4.0: 2.0 = double speed, 0.5 = half; audio keeps its pitch. Slow motion below 0.6x visibly steps (frames are duplicated, not synthesized) \u2014 the tool warns; prefer 0.6-0.8x. A span that overlaps an existing one REPLACES it (disclosed). THE tool for 'speed up the boring part' / 'slow-mo that moment'.","inputSchema":{"properties":{"end":{"type":"number"},"factor":{"type":"number"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"start":{"type":"number"}},"required":["start","end","factor","project_id"],"type":"object"},"name":"set_speed","title":"Set speed"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one speed span by its id (see get_edl) \u2014 that footage returns to normal speed and program-time items re-anchor automatically.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_speed","title":"Remove speed"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Draw an image or video clip OVER the program picture for a window of PROGRAM time \u2014 picture-in-picture, a corner logo, or fit='cover' for a FULL-FRAME B-ROLL CUTAWAY. fit='picture' fills only frame.picture, preserving portrait bars and headline space. The picture switches to the asset while the program's audio (the speaker, the music) keeps playing \u2014 THE way to show what the speaker is talking about without touching the timing. asset_key from list_assets (kind='clip'/'image') or a generated/fetched/recorded asset. duration_s defaults: image 4s, video the clip's length (bounded by the program end); b-roll reads best at 2-6s. x/y = the overlay's CENTER as fractions of the frame (ignored with fit='cover') \u2014 pass a keyframe list [{t,v}] (t = seconds from the overlay's own start) for a slow drift/slide. scale = overlay width as a fraction of the frame width (0.05-1.0, default 0.4; ignored with fit='cover'). opacity 0.05-1.0 (omit = opaque). entrance/exit: fade, slide_left, slide_right, slide_up. source_start_s seeks into a video overlay. HONEST LIMITS: a video overlay's audio does NOT play (silent), overlays render above footage but BELOW captions (captions stay visible over b-roll), and they do NOT track objects in the footage. insert_media PAUSES the talk and adds time; fit='cover' does not \u2014 pick by whether the speech should continue. Assets may be reused whenever the edit benefits from repetition or a different source window.","inputSchema":{"properties":{"asset_key":{"type":"string"},"duration_s":{"type":"number"},"entrance":{"enum":["fade","slide_left","slide_right","slide_up"],"type":"string"},"exit":{"enum":["fade","slide_left","slide_right","slide_up"],"type":"string"},"fit":{"enum":["cover","picture"],"type":"string"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"opacity":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"scale":{"type":"number"},"source_start_s":{"type":"number"},"start":{"type":"number"},"x":{"type":["number","array"]},"y":{"type":["number","array"]}},"required":["asset_key","start","project_id"],"type":"object"},"name":"add_overlay","title":"Add overlay"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Reposition/retime/resize an EXISTING overlay \u2014 'move the logo to the other corner', 'make the PIP smaller'. Only the fields you pass change. id from get_edl.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"scale":{"type":"number"},"start":{"type":"number"},"x":{"type":["number","array"]},"y":{"type":["number","array"]}},"required":["id","project_id"],"type":"object"},"name":"move_overlay","title":"Move overlay"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Author or replace x/y/scale/rotation/opacity on an EXISTING visual overlay using scalars or element-local keyframes. This is the general motion-graphics primitive for logos, images and PIP clips: one coherent move can drift, push, overshoot, rotate and fade without stacking named presets. Keyframe t=0 is the overlay's own start, not program time. A scalar makes that property static. Full-frame B-roll covers ignore x/y/scale; screen takeovers own their tracked camera geometry and reject ordinary curves.","inputSchema":{"properties":{"id":{"type":"string"},"motion":{"additionalProperties":false,"description":"Element-local visual-overlay curves. t is seconds from the overlay's own start; x/y and scale are frame fractions, rotation is degrees, opacity is 0..1.","properties":{"opacity":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"rotation":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"scale":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"x":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"y":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]}},"type":"object"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","motion","project_id"],"type":"object"},"name":"set_overlay_motion","title":"Set overlay motion"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one overlay by its id (see get_edl).","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_overlay","title":"Remove overlay"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. PUSH INTO A SCREEN IN THE SHOT AND LET WHAT IS ON IT BECOME THE WHOLE VIDEO \u2014 THE tool for 'zoom into the laptop and continue with the other scene', 'make it go into the phone screen', 'transition into the monitor smoothly', and every request that describes the camera travelling INTO a device and the content taking over. It is ONE continuous move, not a zoom plus a cut: the asset is corner-pinned onto the glass so it plays ON the screen inside the shot, the camera pushes in, the picture flattens out of the screen into the full frame, and the clip cuts in on the SAME frame the push ends on \u2014 which is why the join cannot be seen. Do NOT build this out of add_zoom + insert_media: an overlay is drawn ABOVE the zoom, so the content sits flat and still while the shot pushes past it, and the cut lands as a jump. at_output_s is where in the FINAL video the takeover FINISHES and the asset is full screen (the push happens in the duration_s before it). The device shot may be the MAIN footage or a SPLICED-IN video clip: point at_output_s inside an inserted clip that shows the device and the push rides that clip's tail, arriving exactly where it ends (I snap there and say so). duration_s 0.4-5, default 1.2 \u2014 1.0-1.5 is the move people mean. I find the corners THREE ways, in order of trust: first I MATCH the content's own pixels against the filmed glass (the laptop was almost always filmed displaying that very recording \u2014 a feature homography gives exact corners INCLUDING rotation and keystone, and the pinned clip then grows out of the very pixels it was filmed playing on, living on the glass from the window's start); else I MEASURE a screen-shaped region from the pixels; else I READ the corners with the vision model. When the corners are matched the content is on the glass the whole window; when they are only measured or read, the glass shows what was FILMED until the push is ~half done and the content dissolves on late (a scene switch visible in a wide shot of the room is the #1 thing users call 'not smooth'), fully there before the picture lands. Momentum carries through the cut either way (a brief settle past full frame); ease='accelerate' dives with speed peaking at the cut. Pass `corners` only to override all of that (8 numbers x0,y0,x1,y1,x2,y2,x3,y3 as FRACTIONS of the frame in the order top-left, top-right, BOTTOM-LEFT, bottom-right \u2014 or a {x,y,w,h} rectangle). clip_start_s picks where in the asset the takeover starts playing; hold_s is how long the asset stays full screen afterwards (default: the rest of it). push 0-1 is how far the camera travels (1 = all the way, the default \u2014 there is no further zoom past 1; a push that feels weak is usually a short duration_s, so lengthen the move instead). ease: 'smooth' (default), 'accelerate', 'linear'. settle:false turns OFF the through-cut momentum (the brief zoom past full frame after the handoff that settles back) \u2014 use it when the user says the video 'keeps zooming after the transition' or 'zooms then returns', or asks for a dead-flat landing. It REFUSES rather than guessing when it cannot measure the screen, and refuses when the screen is under 8% of the frame (the push would be a >12x blowup). TO CHANGE AN EXISTING TAKEOVER (flat landing, different ease/length), call this again at the SAME arrival: it REPLACES that takeover in one write \u2014 parameters you omit are inherited, and its accepted pin corners are reused instead of re-measured (pass corners to force a re-measure). remove_screen_takeover is only for taking the transition OUT.","inputSchema":{"properties":{"asset_key":{"type":"string"},"at_output_s":{"type":"number"},"clip_start_s":{"type":"number"},"corners":{"items":{"type":"number"},"type":"array"},"duration_s":{"type":"number"},"ease":{"enum":["smooth","accelerate","linear"],"type":"string"},"hold_s":{"type":"number"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"push":{"type":"number"},"settle":{"type":"boolean"}},"required":["asset_key","at_output_s","project_id"],"type":"object"},"name":"add_screen_takeover","title":"Add screen takeover"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Undo a screen takeover by its id (see get_edl): the corner pin, the camera push and the clip it handed off to all go together. Pass keep_clip=true to leave the clip spliced in as a plain cut.","inputSchema":{"properties":{"id":{"type":"string"},"keep_clip":{"type":"boolean"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_screen_takeover","title":"Remove screen takeover"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Burn a designed motion-graphics TEXT template over a PROGRAM-time window \u2014 separate from captions (spoken words) and overlays (media). Templates: 'title' (big centered opening card), 'subtitle' (support line under a title), 'lower_third' (name/context bar, interviews), 'callout' (short pointed label), 'big_number' (a huge stat \u2014 '10x', '$40K'), 'quote' (a quoted line), 'chapter' (section marker). x/y override the template's position (fractions of the frame); size_scale 0.4-3.0; color/accent_color '#RRGGBB'; font size can instead use font_size .012-.3 of the canvas short side, with max_width .1-.96 for its text column; font from the bundled families (exact name, e.g. 'Anton'); outline_width/shadow 0-12 override template edges (0 for clean flat type on a graphic panel); entrance/exit: 'none' (INSTANT \u2014 the text is simply there at frame one and simply gone at the end, no animation at all; use when the user wants no effect), fade, pop, slide_up, blur_in, whip, rise, drop, plus 'typewriter' (entrance only); uppercase forces casing; box adds a backing panel. motion is the general primitive for authored x/y/scale/rotation/opacity curves in LOCAL seconds: it can express a coherent drift, arc, settle, punch, spin or fade instead of choosing a named preset. When motion is present, omit entrance/exit. Use for text the user dictates \u2014 titles, labels, stats; spoken-word captions stay with add_captions. This text item owns caption suppression for its live window, so enabling captions before or after cannot stack two word layers and removing the text restores those captions automatically. Pass mute_captions=false for an independent headline or label in a separate visual area so dialogue captions remain visible. Inspect their geometry together.","inputSchema":{"properties":{"accent_color":{"type":"string"},"box":{"type":"boolean"},"color":{"type":"string"},"end":{"type":"number"},"entrance":{"enum":["none","fade","pop","slide_up","blur_in","whip","rise","drop","elastic","bounce","swing","zoom_blur","typewriter"],"type":"string"},"exit":{"enum":["none","fade","pop","slide_up","blur_in","whip","rise","drop","elastic","bounce","swing","zoom_blur"],"type":"string"},"font":{"enum":["Inter Display Black","Inter Display ExtraBold","Inter Display Bold","Anton","Bebas Neue","Archivo Black","Poppins Black","Syne ExtraBold","Playfair Display Black","Instrument Serif","DM Serif Display","Montserrat","Plus Jakarta Sans ExtraBold"],"type":"string"},"font_size":{"maximum":0.3,"minimum":0.012,"type":"number"},"max_width":{"maximum":0.96,"minimum":0.1,"type":"number"},"motion":{"additionalProperties":false,"description":"Element-local motion curves. t is seconds from this text's own start; x/y are frame fractions, scale is relative, rotation is degrees, opacity is 0..1.","properties":{"opacity":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"rotation":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"scale":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"x":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"y":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]}},"type":"object"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"mute_captions":{"type":"boolean"},"outline_width":{"maximum":12,"minimum":0,"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"shadow":{"maximum":12,"minimum":0,"type":"number"},"size_scale":{"type":"number"},"start":{"type":"number"},"template":{"enum":["title","subtitle","lower_third","callout","big_number","quote","chapter"],"type":"string"},"text":{"type":"string"},"uppercase":{"type":"boolean"},"x":{"type":"number"},"y":{"type":"number"}},"required":["text","start","end","project_id"],"type":"object"},"name":"add_text","title":"Add text"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Add a renderer-native VECTOR graphic over a PROGRAM-time window. Kinds: rectangle (panel/highlight), ellipse, line (underline or connector), arrow, ring (point at a real visible subject/UI target), progress (a truthful completion indicator). x/y are frame-fraction centres; width/height are frame fractions. color/stroke_color/background_color are #RRGGBB; stroke_width is a fraction of the short frame edge; rounding is 0-0.5 of the shape's short side; progress value is 0-1. motion uses the same LOCAL x/y/scale/rotation/opacity keyframes as designed text. These are compositional primitives, not decoration quotas: use a panel to support hierarchy, a line to connect, and arrows/rings only when the frame contains the thing they identify. Preview the whole path before accepting it.","inputSchema":{"properties":{"background_color":{"type":"string"},"color":{"type":"string"},"end":{"type":"number"},"height":{"type":"number"},"kind":{"enum":["rectangle","ellipse","line","arrow","ring","progress"],"type":"string"},"motion":{"additionalProperties":false,"description":"Element-local motion curves. t is seconds from this text's own start; x/y are frame fractions, scale is relative, rotation is degrees, opacity is 0..1.","properties":{"opacity":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"rotation":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"scale":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"x":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"y":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]}},"type":"object"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"opacity":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"rounding":{"type":"number"},"start":{"type":"number"},"stroke_color":{"type":"string"},"stroke_width":{"type":"number"},"value":{"type":"number"},"width":{"type":"number"},"x":{"type":"number"},"y":{"type":"number"}},"required":["kind","start","end","project_id"],"type":"object"},"name":"add_vector_graphic","title":"Add vector graphic"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Patch an existing vector graphic by id: its kind, program window, geometry, palette, progress value, or general motion. Pass motion={} to clear keyframes. This modifies the existing layer instead of stacking a duplicate.","inputSchema":{"properties":{"background_color":{"type":"string"},"color":{"type":"string"},"end":{"type":"number"},"height":{"type":"number"},"id":{"type":"string"},"kind":{"enum":["rectangle","ellipse","line","arrow","ring","progress"],"type":"string"},"motion":{"additionalProperties":false,"description":"Element-local motion curves. t is seconds from this text's own start; x/y are frame fractions, scale is relative, rotation is degrees, opacity is 0..1.","properties":{"opacity":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"rotation":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"scale":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"x":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"y":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]}},"type":"object"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"opacity":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"rounding":{"type":"number"},"start":{"type":"number"},"stroke_color":{"type":"string"},"stroke_width":{"type":"number"},"value":{"type":"number"},"width":{"type":"number"},"x":{"type":"number"},"y":{"type":"number"}},"required":["id","project_id"],"type":"object"},"name":"set_vector_graphic","title":"Set vector graphic"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one renderer-native vector graphic by id.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_vector_graphic","title":"Remove vector graphic"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. CHOREOGRAPH THE SPOKEN WORDS onto the screen in ONE pass \u2014 the signature move of top creator reels: each phrase of the transcript appears AT the instant it is spoken, placed in the empty space around the speaker, alternating sides, animated, and holding until the next phrase replaces it. Use it for 'edit this' talking-head footage, promo/educator reels, and whenever the house style calls for speech-carried typography \u2014 instead of dozens of add_text calls. start/end (PROGRAM seconds) scope it; default whole program. emphasis_words get the accent color, a size bump and a pop. zone: 'upper' (beside/above the head \u2014 default), 'lower', 'sides'. Mutes bottom captions over its window so words never print twice. Each phrase is a normal text item \u2014 inspect with get_edl, remove_text by id, or remove and re-run to restyle. AFTER rendering, LOOK at the frames: wrong zone for this framing -> re-run with another zone. motion_style='composed' (default) uses one restrained settle language across the pass and a controlled overshoot only for semantic emphasis; 'preset' restores the legacy named entrances; 'still' removes phrase animation.","inputSchema":{"properties":{"accent_color":{"type":"string"},"color":{"type":"string"},"emphasis_words":{"items":{"type":"string"},"type":"array"},"end":{"type":"number"},"font":{"enum":["Inter Display Black","Inter Display ExtraBold","Inter Display Bold","Anton","Bebas Neue","Archivo Black","Poppins Black","Syne ExtraBold","Playfair Display Black","Instrument Serif","DM Serif Display","Montserrat","Plus Jakarta Sans ExtraBold"],"type":"string"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"motion_style":{"enum":["composed","preset","still"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"size_scale":{"type":"number"},"start":{"type":"number"},"zone":{"enum":["upper","lower","sides"],"type":"string"}},"required":["project_id"],"type":"object"},"name":"add_kinetic_text","title":"Add kinetic text"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Put words BEHIND the moving subject \u2014 the person walks IN FRONT of the letters, the way a title painted on the street or the wall behind them would. This is the 'text behind me walking' / 'name behind the subject' move, and it is a REAL depth composite, not a fade: a person-matting model that carries temporal state between frames cuts the subject out of every frame \u2014 dark clothes on a dark wall, handheld wobble and a moving camera are all fine, and the mask holds steady instead of flickering \u2014 and the renderer lays them back over the words. PEOPLE occlude the words (with whatever they carry); static objects \u2014 furniture, walls \u2014 do NOT: over those the words read as an ordinary title, which is what keeps the occlusion steady. Say so if the user asks about an object. Same styling arguments as add_text (template/x/y/size_scale/color/font/entrance/exit); at_output_s + duration_s are where in the EDITED video the words appear. REQUIREMENTS I check and refuse on, so read the reply: a PERSON must be visible in the window (nothing to go behind otherwise \u2014 I say so and you offer add_text instead), they must not fill most of the frame (the words would never be visible), the window must be inside ONE take with no cut in it, and no speed ramp over that footage. I also report how much of the text the subject actually crosses \u2014 if that is near zero the user will see a plain title, so move the text or the window. BIG TYPE IS THE LOOK: the subject should cross the MIDDLE of tall glyphs with their tops and bottoms staying readable \u2014 that is what reads as depth. A small line sits entirely inside the body and whole words vanish, so titles default to size_scale 2.4 here; NEVER shrink the text to 'fix' hidden letters \u2014 enlarge it or shorten the phrase. Do NOT put a zoom or a stabilize pass over the window. Remove it with remove_text like any other text.","inputSchema":{"properties":{"accent_color":{"type":"string"},"at_output_s":{"type":"number"},"box":{"type":"boolean"},"color":{"type":"string"},"duration_s":{"type":"number"},"entrance":{"enum":["none","fade","pop","slide_up","blur_in","whip","rise","drop","elastic","bounce","swing","zoom_blur","typewriter"],"type":"string"},"exit":{"enum":["none","fade","pop","slide_up","blur_in","whip","rise","drop","elastic","bounce","swing","zoom_blur"],"type":"string"},"font":{"enum":["Inter Display Black","Inter Display ExtraBold","Inter Display Bold","Anton","Bebas Neue","Archivo Black","Poppins Black","Syne ExtraBold","Playfair Display Black","Instrument Serif","DM Serif Display","Montserrat","Plus Jakarta Sans ExtraBold"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"size_scale":{"type":"number"},"template":{"enum":["title","subtitle","lower_third","callout","big_number","quote","chapter"],"type":"string"},"text":{"type":"string"},"uppercase":{"type":"boolean"},"x":{"type":"number"},"y":{"type":"number"}},"required":["text","at_output_s","project_id"],"type":"object"},"name":"add_text_behind","title":"Put text behind the subject"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one text element by its id (see get_edl) \u2014 including one placed behind the subject.","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_text","title":"Remove text"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Set or replace coherent x/y/scale/rotation/opacity keyframes on an EXISTING ordinary text item. Curves use LOCAL seconds from that text's start, so moving the text window keeps its choreography. This replaces named entrance/exit animation with one authored motion system. Pass motion={} (or omit it) to clear the explicit curve and leave the text static. Subject-matted text cannot move.","inputSchema":{"properties":{"id":{"type":"string"},"motion":{"additionalProperties":false,"description":"Element-local motion curves. t is seconds from this text's own start; x/y are frame fractions, scale is relative, rotation is degrees, opacity is 0..1.","properties":{"opacity":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"rotation":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"scale":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"x":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]},"y":{"anyOf":[{"type":"number"},{"items":{"properties":{"ease":{"enum":["linear","in","out","in_out","hold"],"type":"string"},"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"],"type":"object"},"minItems":1,"type":"array"}]}},"type":"object"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"set_text_motion","title":"Set text motion"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Cut to a STANDALONE full-frame card showing only this text, then return to the footage \u2014 the 'show the term on a blank screen' move. One call does all of it: builds the solid-colour card, splices it into the program at at_output_s, and centres the text on it. Because the card is a real cut (not an overlay), spoken-word captions never appear on it, so nothing overlaps. at_output_s is PROGRAM seconds and everything after it shifts later by duration_s (2-3s reads well). bg_color is the card colour ('#000000' default); subtitle adds a smaller second line under the title. Use add_text instead when the text should sit OVER the footage rather than replace it.","inputSchema":{"properties":{"accent_color":{"type":"string"},"at_output_s":{"type":"number"},"bg_color":{"type":"string"},"color":{"type":"string"},"duration_s":{"type":"number"},"entrance":{"enum":["none","fade","pop","slide_up","blur_in","whip","rise","drop","elastic","bounce","swing","zoom_blur","typewriter"],"type":"string"},"exit":{"enum":["none","fade","pop","slide_up","blur_in","whip","rise","drop","elastic","bounce","swing","zoom_blur"],"type":"string"},"font":{"enum":["Inter Display Black","Inter Display ExtraBold","Inter Display Bold","Anton","Bebas Neue","Archivo Black","Poppins Black","Syne ExtraBold","Playfair Display Black","Instrument Serif","DM Serif Display","Montserrat","Plus Jakarta Sans ExtraBold"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"size_scale":{"type":"number"},"subtitle":{"type":"string"},"template":{"enum":["title","subtitle","lower_third","callout","big_number","quote","chapter"],"type":"string"},"text":{"type":"string"}},"required":["text","at_output_s","project_id"],"type":"object"},"name":"add_title_card","title":"Add title card"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Cut to a full-frame SOLID or GRADIENT colour screen for a moment, then return to the footage \u2014 NO text, NO image generation, built instantly. Use for a plain white/black flash, a coloured interstitial, or a gradient backdrop. color is '#RRGGBB' (default black; '#FFFFFF' is white); pass color2 for a two-colour gradient with direction vertical/horizontal/diagonal/radial. at_output_s is PROGRAM seconds; everything after it shifts later by duration_s. motion adds a slow Ken Burns push on the screen. For a card WITH a word on it use add_title_card; to put text over this screen afterwards, add_text at the same window.","inputSchema":{"properties":{"at_output_s":{"type":"number"},"color":{"type":"string"},"color2":{"type":"string"},"direction":{"enum":["vertical","horizontal","diagonal","radial"],"type":"string"},"duration_s":{"type":"number"},"motion":{"enum":["zoom_in","zoom_out","pan_left","pan_right"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["at_output_s","project_id"],"type":"object"},"name":"add_color_screen","title":"Add color screen"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Cut to a full-frame CORRUPT / glitch screen for a beat, then return to the footage \u2014 a datamosh-style transition BETWEEN sections (e.g. podcast -> CORRUPT -> the next scene). Synthesized locally like the colour cards: NO image or video generation, always available, costs no generation credits. style: 'digital' (vivid datamosh macroblocks + horizontal tearing, the default), 'vhs' (tracking band + scanlines + chroma bleed), or 'static' (TV snow / no-signal). at_output_s is PROGRAM seconds; everything after shifts later by duration_s. Keep it SHORT (0.3-1s reads as a hit; longer feels genuinely broken). intensity 0-1 = how harsh (default 0.7). sound (default true) plays a matching static/hiss burst over the glitch; set false for a silent flicker. No captions ever land on it (inserted media).","inputSchema":{"properties":{"at_output_s":{"type":"number"},"duration_s":{"type":"number"},"intensity":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"sound":{"type":"boolean"},"style":{"enum":["digital","vhs","static"],"type":"string"}},"required":["at_output_s","project_id"],"type":"object"},"name":"add_corrupt_screen","title":"Add corrupt screen"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Hide the burned spoken-word captions over specific PROGRAM-time windows, leaving them on everywhere else \u2014 for when a full-frame effect, a graphic or a text treatment would otherwise have captions burned across it. spans is the COMPLETE list of muted windows as [[start, end], ...] in program seconds; it REPLACES the existing list, and spans=[] turns every caption back on. The audio and the cut are untouched \u2014 only the burned text is hidden. Not needed for inserted media or title cards (they are never captioned to begin with).","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"spans":{"items":{"items":{"type":"number"},"type":"array"},"type":"array"}},"required":["spans","project_id"],"type":"object"},"name":"set_caption_mutes","title":"Set caption mutes"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Edit displayed captions. Default operation=replace replaces the COMPLETE active set. append upserts by matching text and scope; clear removes all; list returns active fixes and compiled caption preview. replacements accepts [from,to] pairs or objects with from,to and optional start,end in OUTPUT seconds to target one occurrence. Word-count changes, punctuation and capitalization are supported; replacement text is exact. Audio/cuts remain unchanged. A preview is returned without video encoding.","inputSchema":{"properties":{"clear":{"type":"boolean"},"operation":{"enum":["replace","append","clear","list"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"replacements":{"items":{"anyOf":[{"items":{"type":"string"},"maxItems":2,"minItems":2,"type":"array"},{"properties":{"end":{"type":"number"},"from":{"type":"string"},"start":{"type":"number"},"to":{"type":"string"}},"required":["from","to"],"type":"object"}]},"type":"array"}},"required":["project_id"],"type":"object"},"name":"set_caption_fixes","title":"Set caption fixes"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. FREEZE the picture on a moment and hold it, optionally with a line of text over the held frame \u2014 the 'pearl' / power-phrase move: the frame stops, blurs and darkens behind big centred words, then the video continues. at_output_s is the moment in the EDITED video to freeze; duration_s 2-4s reads well; blur 0-1 and darken 0-0.85 treat the still (0.45/0.35 is the classic look, 0/0 keeps it clean); motion zoom_in/zoom_out/pan_left/pan_right gives the still a slow drift so it does not sit dead; text + subtitle are burned centred and BOUND to the frozen frame. audio_mode='pause' (default) is a real cut: the program pauses and everything after shifts. audio_mode='continue' freezes ONLY the picture as a full-frame cover while the original speech, music and timeline continue \u2014 use it when a visual must hold over an ongoing phrase without stretching or desynchronizing the audio.","inputSchema":{"properties":{"accent_color":{"type":"string"},"at_output_s":{"type":"number"},"audio_mode":{"enum":["pause","continue"],"type":"string"},"blur":{"type":"number"},"color":{"type":"string"},"darken":{"type":"number"},"duration_s":{"type":"number"},"font":{"enum":["Inter Display Black","Inter Display ExtraBold","Inter Display Bold","Anton","Bebas Neue","Archivo Black","Poppins Black","Syne ExtraBold","Playfair Display Black","Instrument Serif","DM Serif Display","Montserrat","Plus Jakarta Sans ExtraBold"],"type":"string"},"motion":{"enum":["zoom_in","zoom_out","pan_left","pan_right"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"subtitle":{"type":"string"},"template":{"enum":["title","subtitle","lower_third","callout","big_number","quote","chapter"],"type":"string"},"text":{"type":"string"}},"required":["at_output_s","project_id"],"type":"object"},"name":"add_freeze_frame","title":"Add freeze frame"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Layer a windowed finishing effect on the program picture: 'grain' (film grain), 'vignette' (darkened corners), 'glow' (soft bloom), 'halation' (warm red-orange highlight bloom like exposed film), 'chromatic' (RGB fringe), 'dream_blur' (soft dreamy diffusion), 'vhs' (tape look), 'flash' (strobe pop), 'shake' (adds camera shake), 'sharpen' / 'denoise' (picture quality \u2014 prefer enhance_video, which orders them correctly), 'motion_blur' (real frame blending; only reads on movement, does nothing on a static shot), 'stabilize' (smooths modest HANDHELD wobble via deshake; mirrored edges may soften and it cannot fix a whip, a walk or rolling shutter; say that rather than promising stabilization). Stabilize is whole-video only. For other kinds start/end are PROGRAM seconds \u2014 omit both for the whole video. intensity 0.05-1.0 (default 0.5). Content-anchored: a stylized moment follows its footage through later cuts. One or two layered effects read as a look; five read as a broken TV.","inputSchema":{"properties":{"end":{"type":"number"},"intensity":{"type":"number"},"kind":{"enum":["grain","vignette","glow","halation","chromatic","dream_blur","vhs","flash","shake","sharpen","denoise","motion_blur","stabilize"],"type":"string"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"start":{"type":"number"}},"required":["kind","project_id"],"type":"object"},"name":"add_stylize","title":"Add stylize"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. PICTURE QUALITY, not a look \u2014 the right answer to 'make it clearer / sharper / better quality / HD / enhance this'. sharpen 0-1 (default 0.5) recovers detail the camera's encoder smeared; denoise 0-1 (default 0) cleans grainy low-light footage and should be raised BEFORE sharpening noisy video. start/end are PROGRAM seconds; omit both for the whole video. It cannot add resolution \u2014 say that plainly instead of promising HD from a small source. Never answer a clarity request with a colour grade.","inputSchema":{"properties":{"denoise":{"type":"number"},"end":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"sharpen":{"type":"number"},"start":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"enhance_video","title":"Enhance video"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one stylize effect by its id (see get_edl).","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_stylize","title":"Remove stylize"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. WRITE YOUR OWN ffmpeg video filter chain and apply it to the program picture \u2014 for the look no preset makes. Presets FIRST: apply_look / add_stylize / set_color_grade / enhance_video cover the common asks; reach here when the user wants something none of them says (a CRT phosphor look, posterize, a slow hue drift, selective channel work). Rules: ONE chain on the single video stream \u2014 filters separated by commas, NO ';' or '[labels]', no file access \u2014 and it must keep the frame's size and rate. The chain is DRY-RUN on the real footage before it stores: a broken chain returns ffmpeg's own error (fix it, never retry the identical string); an over-heavy one returns its measured cost. start/end are PROGRAM seconds (omit both = whole video; windowed moments follow their footage through later cuts). label = short human name for the look ('CRT green') shown in diffs. Example chain: \"hue=s=0.3,curves=green='0/0 0.5/0.6 1/1',noise=alls=8:allf=t\". After it lands, LOOK at the window on the next preview \u2014 a chain that parses can still look wrong.","inputSchema":{"properties":{"chain":{"type":"string"},"end":{"type":"number"},"label":{"type":"string"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"start":{"type":"number"}},"required":["chain","project_id"],"type":"object"},"name":"add_custom_filter","title":"Add custom filter"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Remove one custom filter chain by its id (see get_edl).","inputSchema":{"properties":{"id":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["id","project_id"],"type":"object"},"name":"remove_custom_filter","title":"Remove custom filter"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Bind an EXISTING renderer-visible movement to the exact motif id it was designed to execute in the active Blueprint v3 motion language. This records causal provenance; it does not create an effect or require a count. target_type: zoom, text, vector, overlay, insert, speed, aspect_shift, stylize, custom, transition or captions. Pass id for item targets; transition/captions are track-level. Pass motion_motif='clear' to remove a binding. Static targets and the reserved stillness decision 'hold' are rejected.","inputSchema":{"properties":{"id":{"type":"string"},"motion_motif":{"description":"Active Blueprint motion motif id this event executes; never 'hold'.","type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"target_type":{"enum":["zoom","text","vector","overlay","insert","speed","aspect_shift","stylize","custom","transition","captions"],"type":"string"}},"required":["target_type","motion_motif","project_id"],"type":"object"},"name":"bind_motion_motif","title":"Bind motion motif"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Continuous color controls on all footage, applied AFTER the preset grade (the two compose \u2014 'cinematic but warmer' = preset cinematic + temperature 0.2): exposure -1..1, contrast and saturation accept either a SMALL SIGNED DELTA around neutral (preferred: +0.08 is a restrained lift, -0.08 a reduction, 0 clears) or an explicit final multiplier >=0.5 (1.0 is neutral; contrast max 1.6, saturation max 2.0). Never pass 0.06 intending 6% color: it is treated as +6% and stored as 1.06x. Use the explicit 'bw' preset for monochrome. Temperature -1 (cool)..1 (warm), tint -1 (green)..1 (magenta), shadows -1..1 (positive LIFTS the dark regions \u2014 the answer to 'brighten the shadows / too dark in the corners'), highlights -1..1 (negative RECOVERS bright areas). 'More light' = exposure up; 'remove/soften the shadows' = shadows up. Pass ONLY the axes to change; an axis's neutral value clears it; all axes neutral clears the whole custom grade. Captions and graphics are never graded.","inputSchema":{"properties":{"contrast":{"type":"number"},"exposure":{"type":"number"},"highlights":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"saturation":{"type":"number"},"shadows":{"type":"number"},"temperature":{"type":"number"},"tint":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"set_grade_custom","title":"Set grade custom"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Rebalance the ORIGINAL footage's music vs its speech \u2014 the answer to 'remove the background music but keep the talking', 'the song is too loud under his voice', 'keep only the music'. The soundtrack is separated into speech/vocals + everything-else (once per video, then cached) and each side plays at its own gain: music_gain_db=-60 mutes the music, voice_gain_db=-60 mutes the speech, -12 ducks, 0 leaves untouched (range -60..+6). This changes ONLY the original footage's own audio \u2014 added music tracks are add_music/remove_music, NOT this. Not surgical on dense mixes \u2014 check the preview before promising total silence.","inputSchema":{"properties":{"music_gain_db":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"voice_gain_db":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"separate_music","title":"Separate music"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Restore the original mixed soundtrack (undo separate_music).","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"remove_stem_mix","title":"Remove stem mix"},{"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. enabled=true normalizes the FINAL MIX to -14 LUFS with a codec-safe -2 dBTP target plus a latency-compensated hard ceiling on preview AND export \u2014 the fix for 'the export sounds quiet on TikTok/YouTube'. It changes loudness, not the voice/music/sfx balance. false removes mastering.","inputSchema":{"properties":{"enabled":{"type":"boolean"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["enabled","project_id"],"type":"object"},"name":"set_master_loudness","title":"Master the mix to a loudness target"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. READ: measured musical/energy analysis of the source audio (cached after the first call): tempo (BPM + confidence \u2014 below 0.5 the pulse is unreliable and beat_align_cuts refuses), beat count plus the first up-to-eight detected beat timestamps, where the loudest/quietest sections and the biggest energy rise sit, and the most vocally STRESSED words with timestamps. Times are SOURCE seconds. Call before beat_align_cuts / punch_in_on_emphasis, or to answer 'what's the tempo'. Pass asset_key (an uploaded or fetched music file) to analyze that instead \u2014 e.g. to find the drop for add_music offset_s.","inputSchema":{"properties":{"asset_key":{"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"get_audio_analysis","title":"Get audio analysis"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Listen to bounded REAL audio through the audio-review lane and return its professional assessment. Pass asset_key for an uploaded/fetched song, audio-only file, clip or render; pass times for seconds within that asset. With no asset_key, times reviews SOURCE sound. output_times reviews the CURRENT rendered program and therefore requires render_preview first. Use this for vibe, recording quality, intelligibility, masking and mix judgment; get_audio_analysis remains the authority for BPM/beats/energy and audit_audio_mix for authored roles. Advisory only\u2014never refuse a valid user choice because the listener is unavailable.","inputSchema":{"properties":{"asset_key":{"type":"string"},"output_times":{"items":{"type":"number"},"type":"array"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"question":{"type":"string"},"span_s":{"type":"number"},"times":{"items":{"type":"number"},"type":"array"}},"required":["project_id"],"type":"object"},"name":"review_audio","title":"Review audio"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Deterministic audit of the CURRENT EDL's authored music, voiceover and SFX roles, files, program windows, source offsets, gains, ducking and mastering. Each music item includes its persisted raw provider provenance, rights-capability signals and downloaded SHA-256, with explicit null/unknown values. Detects the same asset playing twice or a likely song misfiled as voiceover. This state is ground truth; deterministic preview AUDIO CHECK can measure the rendered mix without relabeling roles.","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"audit_audio_mix","title":"Audit audio mix"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. ONLY when the user explicitly asked for punch-ins on stressed / important spoken words. Not a default pass, not 'make it high-retention', not a talking-head finish. Writes a sparse, timeline-distributed motion pass on vocally STRESSED words that survive the current cut (stress from the audio, times from real word timestamps). Prefer zero or one hard punch over a sprinkle. Omit count to keep density sparse; omit strength to keep magnitude small. Face targets are used when detected. If you cannot name why a word deserves a camera bump, do not call this \u2014 hold the frame or use one add_zoom(mode='ease') on the actual turn.","inputSchema":{"properties":{"count":{"type":"integer"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"strength":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"punch_in_on_emphasis","title":"Punch in on emphasized words"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. THE tool for 'cut to the beat'. Slides each INTERNAL cut (never the program's first start / last end) onto the nearest beat within tolerance_s (default 0.35s), skipping any move that would land inside a word. WHICH beat: when the edit has music it uses the SONG the viewer hears, in program time \u2014 that is what 'the beat' means; source='video' forces the footage's own audio instead. If the USER tells you the tempo ('there's a beat every second', 'it's 120 BPM'), pass every_s=1 or bpm=120 \u2014 their tempo is data and skips the confidence gate. With no music, no stated tempo and no clear pulse in the footage it refuses honestly rather than 'syncing' to noise \u2014 never invent a tempo yourself. Cuts must already exist: this MOVES boundaries, it does not create them (to cut ON every beat, build the spans with keep_segments from the beat times get_audio_analysis reports, then call this to tighten them). One EDL version; reports moved/skipped counts.","inputSchema":{"properties":{"bpm":{"type":"number"},"every_s":{"type":"number"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"source":{"enum":["music","video"],"type":"string"},"tolerance_s":{"type":"number"}},"required":["project_id"],"type":"object"},"name":"beat_align_cuts","title":"Snap cuts to the musical beat"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. READ: candidate emphasis words from the REAL transcript \u2014 the most vocally stressed words (measured), words with digits, and rare/distinctive words \u2014 as a verbatim list to pass to add_captions / set_caption_style emphasis_words.","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"suggest_emphasis","title":"Suggest emphasis"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. ONE-CALL aesthetic: composes caption preset + grade + custom grade + transitions + fades + stylize in a single EDL version and reports every component it set. Looks: 'hype' (beast xl captions, vibrant grade, zoom_punch cuts, closing fade), 'clean' (clean white size-led captions, ungraded, gentle fades), 'cinematic' (elegant captions, cinematic grade + slight warmth, 1s fades, dip_black), 'luxury' (luxe captions, warm grade + temperature lift, long fades), 'meme' (impact xl captions, flash cuts, grain). Preserves existing emphasis_words, else picks them from the transcript. Never touches cuts, music or sfx \u2014 place accents with add_sfx. Every component can be adjusted afterwards with its own tool.","inputSchema":{"properties":{"name":{"enum":["cinematic","clean","hype","luxury","meme"],"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["name","project_id"],"type":"object"},"name":"apply_look","title":"Apply look"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":true},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Current EDL JSON and version. Large timelines return a compact index instead of invalid truncated JSON. Request top-level sections such as ['captions','overlays'] and paginate list sections with offset/limit. Natural aliases are accepted without a retry: cuts/segments -> keep, text -> texts, zooms/transitions/grades/fades -> effects, audio -> all audio sections, and program/overview/summary -> the compact program overview. compact=true always returns counts, caption state and duplicate assets.","inputSchema":{"properties":{"compact":{"type":"boolean"},"limit":{"type":"integer"},"offset":{"type":"integer"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"sections":{"description":"Use exact top-level fields: keep, split_keep_boundaries, canvas, captions, music, sfx, volume, frame, inserts, voiceover, effects, overlays, texts, vectors, speed, master, stem_mix, caption_mutes, source_clean, patches; or overview. Feature/tool names are not sections. Read the creative plan with get_edit_plan.","items":{"type":"string"},"type":["array","string"]}},"required":["project_id"],"type":"object"},"name":"get_edl","title":"Read the edit decision list"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Mechanically compile and audit the CURRENT caption track using the exact ASS artifact ffmpeg burns. Reports first-caption lateness, missing spoken-word coverage, true distinct-state overlaps, max_words_seen, max_lines_seen, declared-density and single-line wrap violations, exact event pages and up to 16 high-information output times for rendered pixel QA. Call after adding or restyling captions and after render_preview; this is stronger timing evidence than a visual critic.","inputSchema":{"properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["project_id"],"type":"object"},"name":"audit_captions","title":"Audit captions"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Render evidence for the current immutable EDL. complete=false makes changed-section proof only; this does not create a watchable complete preview. complete=true creates the complete stored video, even on the first call. quality=approval implies complete=true and renders from the original at up to 720x1280 portrait using the final composition and typography path; draft is the inexpensive 480px preview. The Studio attaches the complete preview. wait_for_job observes pending work; call render_preview again to review its existing result. MCP clients can retrieve it with watch_video or download_url.","inputSchema":{"properties":{"complete":{"type":"boolean"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"quality":{"enum":["draft","approval"],"type":"string"}},"required":["project_id"],"type":"object"},"name":"render_preview","title":"Render preview"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Resolve a genuine verification false positive only after direct pixel/audio evidence proves it. The finding and justification stay in the immutable EDL version's durable record. Missing previews, caption proof, corrupt glyphs and invalid music timing require repair and cannot be justified.","inputSchema":{"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_ids":{"items":{"type":"string"},"minItems":1,"type":"array"},"justification":{"minLength":20,"type":"string"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"}},"required":["finding_ids","justification","project_id"],"type":"object"},"name":"justify_verification_findings","title":"Justify verification findings"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Ask the user a specific question and wait for their reply (ends this turn). Use whenever a material choice genuinely belongs to the user.","inputSchema":{"properties":{"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"question":{"type":"string"}},"required":["question","project_id"],"type":"object"},"name":"ask_user","title":"Ask user"},{"annotations":{"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"readOnlyHint":false},"description":"PROJECT-SCOPED: this call acts only on the explicit project_id and returns the project identity with its result. Scout this LONG podcast/video for multiple complete story arcs and create LOCKED child projects. Valmera's internal agent may let the background scout choose the arcs. MCP callers MUST do the editorial selection themselves: read the full transcript, then pass clips with explicit source ranges and useful story context. The pipeline only seeds the selected source windows; it does not choose captions, framing, B-roll, music, effects or render a creative edit. Studio users explicitly press Edit on a card to boot a fresh editor. MCP callers open each child and perform the edits directly. It returns the scouting job ID; poll with wait_for_job or shorts_status. count bounds only Valmera's legacy one-call auto-scout. An explicit clips array keeps every valid non-overlapping story arc; total creation is naturally bounded by source duration, not an editorial quota. style_note is reference context for the eventual child editor, not a hard-coded recipe.","inputSchema":{"properties":{"clips":{"description":"Caller-authored story arcs. Required over MCP so the connected model chooses the shorts itself.","items":{"properties":{"end":{"description":"Source seconds; end after the payoff resolves.","type":"number"},"hook":{"description":"Preserved verbatim as caller-authored story context.","type":"string"},"score":{"maximum":100,"minimum":0,"type":"integer"},"start":{"description":"Source seconds; start on a complete setup/question boundary.","type":"number"},"story":{"properties":{"development":{"type":"string"},"payoff":{"type":"string"},"setup":{"type":"string"}},"type":"object"},"title":{"description":"Preserved verbatim as the child project/card title.","type":"string"}},"required":["start","end","title"],"type":"object"},"type":"array"},"count":{"type":"integer"},"project_id":{"description":"Required immutable scope for this call. Copy the id from list_projects/open_project/project_state; the active-project pointer is never used to guess.","type":"integer"},"style_note":{"description":"Optional audience or reference context to preserve for the eventual editor.","type":"string"}},"required":["clips","project_id"],"type":"object"},"name":"make_shorts","title":"Build podcast shorts from explicit story arcs"}],"version":"0.1.0","websiteUrl":"https://valmera.io"}
