Create long-form YouTube videos end to end: script, storyboard, voiceover, final MP4.
Inferred from the transports this listing declares (streamable-http). A client not listed here hasn’t been ruled out — it just isn’t something Forge can confirm.
Verification confirms publisher identity (repo ownership), not code safety. The security scan covers known CVEs and suspicious install scripts.
Read from a real MCP initialize → tools/list handshake against the declared endpoint. No tool was ever invoked — tools/list is the read-only introspection call the protocol defines for this. It reflects what the server advertised at that moment; a hosted endpoint is not pinned to any version and can change without notice.
https://api.framesail.com/mcp72 tools · 299mslist_channelsList your channels. Every project lives in a channel, which owns the
reusable styles (art/narrative/director) that drive generation.List your channels. Every project lives in a channel, which owns the reusable styles (art/narrative/director) that drive generation.
No input schema was published for this tool.
create_channelCreate a new channel — the container for projects and their reusable
styles. Use when the user wants a fresh creative identity rather than
adding to an existing channel.Create a new channel — the container for projects and their reusable styles. Use when the user wants a fresh creative identity rather than adding to an existing channel.
| Parameter | Type | Description |
|---|---|---|
| name* | string | Display name for the new channel |
| description | string | Optional free-text description of the channel's content focus |
list_projectsList projects in a channel.List projects in a channel.
| Parameter | Type | Description |
|---|---|---|
| channel_id* | string | ID of the channel whose projects to list, from list_channels or create_channel |
create_projectCreate a project. The description (the video concept/topic) seeds script
generation, so write a meaningful one. Pass video_format='portrait' for a
vertical video — every shot, overlay, and the export are then composed for
a 9:16 frame. The response's web_url is the project's page in the web app…Create a project. The description (the video concept/topic) seeds script generation, so write a meaningful one. Pass video_format='portrait' for a vertical video — every shot, overlay, and the export are then composed for a 9:16 frame. The response's web_url is the project's page in the web app…
| Parameter | Type | Description |
|---|---|---|
| channel_id* | string | ID of the channel to create the project in, from list_channels or create_channel |
| title* | string | Project title shown in the app |
| description | string | The video concept/topic; seeds script generation, so make it specific and meaningful |
| video_format | string | Output frame shape: 'landscape' (16:9, the default — YouTube and long-form) or 'portrait' (9:16 — Shorts, Reels, TikTok). Fixed once the storyboard is generate… |
get_projectFetch a project row — settings, voice config, default style, export URL.Fetch a project row — settings, voice config, default style, export URL.
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
update_projectPatch project fields. Updatable: title, description,
sfx_level, video_concept, voice_mix, voice_tts_provider,
script_target_minutes, narrator_speed, video_format. (The narrator's TTS
voice is NOT here — use set_narrator_voice.)
narrator_speed is the narration rate (0.5-2.0, default 1.0; clampe…Patch project fields. Updatable: title, description, sfx_level, video_concept, voice_mix, voice_tts_provider, script_target_minutes, narrator_speed, video_format. (The narrator's TTS voice is NOT here — use set_narrator_voice.) narrator_speed is the narration rate (0.5-2.0, default 1.0; clampe…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| fields* | object | Partial dict of fields to patch; allowed keys: title, description, sfx_level ('none'|'minimal'|'frequent'), video_concept, voice_mix ('narrator_only'|'narrator… |
delete_projectprivilegedPermanently delete a project and everything in it (script versions,
assets, voiceover, segments, renders). Irreversible — confirm with your
user first.Permanently delete a project and everything in it (script versions, assets, voiceover, segments, renders). Irreversible — confirm with your user first.
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | ID of the project to permanently delete, from list_projects |
set_project_styleSet the project's default style — the style whose art/narrative/director
fields drive its generations. Use after create_style to put a new visual
identity into effect, or to switch a project between channel styles.Set the project's default style — the style whose art/narrative/director fields drive its generations. Use after create_style to put a new visual identity into effect, or to switch a project between channel styles.
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| style_id* | string | ID of the style to make the project's default, from create_style or list_styles |
update_caption_configMerge a patch into the project's burned-in caption config (keys like
enabled, plus styling). Read the current value from get_project
(caption_config). Applies at the next export — no rebuild needed.Merge a patch into the project's burned-in caption config (keys like enabled, plus styling). Read the current value from get_project (caption_config). Applies at the next export — no rebuild needed.
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| caption_config* | object | Partial caption config to merge (keys like enabled, plus styling); read the current value from get_project's caption_config |
get_pipeline_progressTHE resume/orientation tool: one call returns every pipeline step's
state (script -> scan -> reference_images -> voices -> voiceover ->
style_templates -> storyboard -> segment_assets -> scenes -> export), any
running jobs, and a next_action telling you exactly what to do next. Call
this when p…THE resume/orientation tool: one call returns every pipeline step's state (script -> scan -> reference_images -> voices -> voiceover -> style_templates -> storyboard -> segment_assets -> scenes -> export), any running jobs, and a next_action telling you exactly what to do next. Call this when p…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
get_workflow_statusPoll this between steps: returns active + recently-finished AI jobs
(scope by project_id, or style_id for style analysis), plus per-segment-
asset render statuses for projects. A step is done when its jobs reach
status=complete (or error, with a user-readable message). NOTE: finished
jobs drop…Poll this between steps: returns active + recently-finished AI jobs (scope by project_id, or style_id for style analysis), plus per-segment- asset render statuses for projects. A step is done when its jobs reach status=complete (or error, with a user-readable message). NOTE: finished jobs drop…
| Parameter | Type | Description |
|---|---|---|
| project_id | string | Project ID to scope jobs to; pass exactly one of project_id or style_id |
| style_id | string | Style ID to scope jobs to (style analysis); pass exactly one of project_id or style_id |
await_jobsBlock (server-side) until the scope has no pending/running jobs, or the
timeout passes — use this instead of polling get_workflow_status yourself.
Returns {done, jobs}. If done=false the work is still running: just call
await_jobs again (a 3-5 minute storyboard takes a few consecutive calls).
K…Block (server-side) until the scope has no pending/running jobs, or the timeout passes — use this instead of polling get_workflow_status yourself. Returns {done, jobs}. If done=false the work is still running: just call await_jobs again (a 3-5 minute storyboard takes a few consecutive calls). K…
| Parameter | Type | Description |
|---|---|---|
| project_id | string | Project ID whose jobs to wait for; pass exactly one of project_id or style_id |
| style_id | string | Style ID whose analysis/template jobs to wait for; pass exactly one of project_id or style_id |
| timeout_seconds | integer | Max seconds to block server-side before returning done=false; keep <= 50 so the client doesn't time out the tool call |
get_section_templateInspect the prompt sections a generation job exposes for per-call
override via editable_sections (jobs: script, script_scan, storyboard,
segment_image, segment_video, voice_block, ...). Sections marked locked
cannot be overridden.Inspect the prompt sections a generation job exposes for per-call override via editable_sections (jobs: script, script_scan, storyboard, segment_image, segment_video, voice_block, ...). Sections marked locked cannot be overridden.
| Parameter | Type | Description |
|---|---|---|
| job* | string | Generation job name, e.g. "script", "script_scan", "storyboard", "segment_image", "segment_video", "voice_block" |
list_modelsList the models allowed for a generation job, with display names, credit
estimates, and each model's settings_schema — the valid keys for that
tool's `settings` param (e.g. image quality/orientation, video duration).
When model is omitted the server picks: the account's saved expert-drawer
choi…List the models allowed for a generation job, with display names, credit estimates, and each model's settings_schema — the valid keys for that tool's `settings` param (e.g. image quality/orientation, video duration). When model is omitted the server picks: the account's saved expert-drawer choi…
ovider` field — a voice_block model must match the
project's voice| Parameter | Type | Description |
|---|---|---|
| job* | string | Generation job whose allowed models to list, e.g. "script", "storyboard", "segment_image", "segment_video", "voice_block" |
generate_scriptGenerate the project's script from its description/concept and the
channel's narrative style. Async — returns {job_id}; poll get_workflow_status.Generate the project's script from its description/concept and the channel's narrative style. Async — returns {job_id}; poll get_workflow_status.
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| model | string | Model ID to generate with; empty uses the default (see list_models("script")) |
| editable_sections | — | Per-call prompt section overrides, keyed by section name; see get_section_template("script") for the sections this job exposes |
| settings | — | Model-specific settings; valid keys come from the model's settings_schema in list_models("script") |
get_scriptRead the active script's full text + the version list. Use this to show
the script to your user for review/feedback before scan_script — the
review-edit-resave loop (get_script -> discuss -> save_script) is the
expected workflow when the user wants input.Read the active script's full text + the version list. Use this to show the script to your user for review/feedback before scan_script — the review-edit-resave loop (get_script -> discuss -> save_script) is the expected workflow when the user wants input.
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
save_scriptSave script text (your own draft, or an edited version of the generated
one). Saving UPDATES the active version in place — the previous text is
not kept, so show the user the current script (get_script) before
overwriting it. New versions are created by generate_script runs, and
activate_script…Save script text (your own draft, or an edited version of the generated one). Saving UPDATES the active version in place — the previous text is not kept, so show the user the current script (get_script) before overwriting it. New versions are created by generate_script runs, and activate_script…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| content* | string | Full script text to save as a new version; plain prose narration, optionally with `[SCENE: ...]` direction paragraphs, `<break time="0.5s" />` pauses, and `Nam… |
revise_scriptAI-rewrite a passage of the active script in the project's narrative
voice (the same in-editor revise the UI offers). selected_text must appear
verbatim in the script; omit it to revise the whole script. `[SCENE: ...]`
directions in range are preserved exactly, in place, unless the
instruction…AI-rewrite a passage of the active script in the project's narrative voice (the same in-editor revise the UI offers). selected_text must appear verbatim in the script; omit it to revise the whole script. `[SCENE: ...]` directions in range are preserved exactly, in place, unless the instruction…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| instruction* | string | Natural-language edit instruction, e.g. "make the intro punchier" |
| selected_text | string | Exact passage to rewrite; must appear verbatim in the active script. Omit to revise the whole script |
activate_script_versionSwitch the project's active script to another saved version (ids come
from get_script's version list — each generate_script run creates one;
save_script edits the active version in place). Re-run scan_script /
rescan_voice_blocks afterwards if the text differs, since downstream
artifacts follow…Switch the project's active script to another saved version (ids come from get_script's version list — each generate_script run creates one; save_script edits the active version in place). Re-run scan_script / rescan_voice_blocks afterwards if the text differs, since downstream artifacts follow…
| Parameter | Type | Description |
|---|---|---|
| script_id* | string | ID of the script version to activate, from get_script's version list |
scan_scriptAnalyze the active script: extracts character/environment/object assets
and splits narration into voice blocks. DESTRUCTIVE on re-run (assets are
recreated, not merged — curated descriptions, reference images, and voices
are lost; prefer rescan_voice_blocks after script edits).
Extraction read…Analyze the active script: extracts character/environment/object assets and splits narration into voice blocks. DESTRUCTIVE on re-run (assets are recreated, not merged — curated descriptions, reference images, and voices are lost; prefer rescan_voice_blocks after script edits). Extraction read…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| model | string | Model ID to scan with; empty uses the default (see list_models("script_scan")) |
| editable_sections | — | Per-call prompt section overrides, keyed by section name; see get_section_template("script_scan") |
list_assetsList the project's assets extracted by scan_script — characters,
environments, objects. Each has a description (the spec every shot uses to
render it — surfaced top-level here; the raw row nests it at
ai_output.description), an optional reference image (file_path is a public
URL — view_image it…List the project's assets extracted by scan_script — characters, environments, objects. Each has a description (the spec every shot uses to render it — surfaced top-level here; the raw row nests it at ai_output.description), an optional reference image (file_path is a public URL — view_image it…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| asset_type | string | Optional filter: "character", "environment", or "object"; empty lists all asset types |
create_assetManually add a character/environment/object the scan missed.
asset_type: "character" | "environment" | "object". The description is the
generation-facing spec of its look — be specific.
The scan reads narration and `[SCENE: ...]` directions, so the common
miss is anyone NEITHER ever names — a…Manually add a character/environment/object the scan missed. asset_type: "character" | "environment" | "object". The description is the generation-facing spec of its look — be specific. The scan reads narration and `[SCENE: ...]` directions, so the common miss is anyone NEITHER ever names — a…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| asset_type* | string | Kind of asset: "character", "environment", or "object" |
| name* | string | Asset name as the script refers to it (e.g. the character's name) |
| description | string | Generation-facing spec of the asset's look; every shot renders from it, so be specific |
update_assetRename an asset and/or rewrite its description. If the look changed,
regenerate its reference image afterwards so renders match.Rename an asset and/or rewrite its description. If the look changed, regenerate its reference image afterwards so renders match.
| Parameter | Type | Description |
|---|---|---|
| asset_id* | string | Asset ID, as returned by list_assets or create_asset |
| name | string | New asset name; empty leaves the name unchanged |
| description | string | New generation-facing look description; empty leaves it unchanged |
delete_assetprivilegedDelete a project asset (e.g. one the scan over-extracted).Delete a project asset (e.g. one the scan over-extracted).
| Parameter | Type | Description |
|---|---|---|
| asset_id* | string | ID of the asset to delete, from list_assets |
generate_asset_referenceRender an asset's reference image in the channel's art style — the
visual anchor that keeps a character/environment looking identical across
every shot. EVERY character, environment, and object asset needs one before
generate_voiceover (the server enforces this; fire the jobs for all assets,
th…Render an asset's reference image in the channel's art style — the visual anchor that keeps a character/environment looking identical across every shot. EVERY character, environment, and object asset needs one before generate_voiceover (the server enforces this; fire the jobs for all assets, th…
| Parameter | Type | Description |
|---|---|---|
| asset_id* | string | ID of the asset to render a reference image for, from list_assets |
| model | string | Image model ID; empty uses the server default for reference images |
| editable_sections | — | Per-call prompt section overrides, keyed by section name; see get_section_template for the reference-image job |
| settings | — | Model-specific settings (e.g. image quality/orientation); valid keys come from the model's settings_schema in list_models |
set_character_voiceBind a TTS voice to a character asset — required before generate_voiceover
for every character with dialogue (the narrator's voice is separate:
set_narrator_voice). Browse ids with list_voices.Bind a TTS voice to a character asset — required before generate_voiceover for every character with dialogue (the narrator's voice is separate: set_narrator_voice). Browse ids with list_voices.
| Parameter | Type | Description |
|---|---|---|
| asset_id* | string | Character asset ID, from list_assets |
| voice_id* | string | TTS voice ID, from list_voices (use the provider matching the project's voice_tts_provider) |
list_voicesList available TTS voices (id, label, preview audio URL) for a provider:
"minimax" (default engine) or "elevenlabs". Match the project's
voice_tts_provider (see get_project) so picked ids work with its engine.
Returns {groups: {name: count}, voices}; the ElevenLabs catalogue is
150+ voices, so…List available TTS voices (id, label, preview audio URL) for a provider: "minimax" (default engine) or "elevenlabs". Match the project's voice_tts_provider (see get_project) so picked ids work with its engine. Returns {groups: {name: count}, voices}; the ElevenLabs catalogue is 150+ voices, so…
| Parameter | Type | Description |
|---|---|---|
| provider | string | TTS engine to list voices for: "minimax" (default engine) or "elevenlabs"; match the project's voice_tts_provider |
| group | string | Return only this catalogue group (case-insensitive; e.g. "Narration", "Characters"). Empty returns every group — the ElevenLabs catalogue is 150+ voices, so fi… |
set_narrator_voiceSet the project's narrator TTS voice — required before generate_voiceover
whenever the script has narration. Browse ids with list_voices. (Character
dialogue voices are separate: set_character_voice.)Set the project's narrator TTS voice — required before generate_voiceover whenever the script has narration. Browse ids with list_voices. (Character dialogue voices are separate: set_character_voice.)
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| voice_id* | string | TTS voice ID for the narrator, from list_voices (use the provider matching the project's voice_tts_provider) |
list_voice_blocksList the project's voice blocks (per-speaker narration chunks) with
their audio status and assigned voices. A block's `scene_direction` is the
script's `[SCENE: ...]` direction governing it (never spoken; null when
the span carries none). Word-level subtitle timings are stripped unless
include_…List the project's voice blocks (per-speaker narration chunks) with their audio status and assigned voices. A block's `scene_direction` is the script's `[SCENE: ...]` direction governing it (never spoken; null when the span carries none). Word-level subtitle timings are stripped unless include_…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| include_subtitle_data | boolean | Include each block's word-level subtitle timings — bulky and rarely needed; omitted by default (subtitle_data reports "omitted" when present but stripped) |
update_voice_blockOverride one voice block's voice or playback volume (block ids from
list_voice_blocks). Re-run generate_voiceover for the block afterwards if
you changed its voice — existing audio is not regenerated automatically.Override one voice block's voice or playback volume (block ids from list_voice_blocks). Re-run generate_voiceover for the block afterwards if you changed its voice — existing audio is not regenerated automatically.
| Parameter | Type | Description |
|---|---|---|
| voice_block_id* | string | Voice block ID, from list_voice_blocks |
| voice_id | string | New TTS voice ID for this block, from list_voices; empty leaves the voice unchanged |
| volume | — | Playback volume for this block, 0-1; omit to leave unchanged |
rescan_voice_blocksRe-extract voice blocks from the active script WITHOUT touching assets
or their reference images — the non-destructive alternative to scan_script
after a script edit. Blocks whose spoken text is unchanged keep their
audio; only edited blocks come back empty, so a follow-up
generate_voiceover fi…Re-extract voice blocks from the active script WITHOUT touching assets or their reference images — the non-destructive alternative to scan_script after a script edit. Blocks whose spoken text is unchanged keep their audio; only edited blocks come back empty, so a follow-up generate_voiceover fi…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
generate_voiceoverGenerate TTS audio for the project's voice blocks. Without
voice_block_ids it fills gaps: only blocks with no audio yet run, so
re-calling it is always safe (already-generated and currently-generating
blocks are skipped, never re-billed). Pass voice_block_ids to explicitly
REgenerate those bloc…Generate TTS audio for the project's voice blocks. Without voice_block_ids it fills gaps: only blocks with no audio yet run, so re-calling it is always safe (already-generated and currently-generating blocks are skipped, never re-billed). Pass voice_block_ids to explicitly REgenerate those bloc…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| model | string | TTS model ID; empty uses the default for the project's TTS provider. If set, it must belong to that provider — see list_models("voice_block") for each model's… |
| voice_block_ids | — | Block IDs (from list_voice_blocks) to explicitly REgenerate; omit to fill gaps — only blocks with no audio yet run |
| editable_sections | — | Per-call prompt section overrides applied to every selected block; see get_section_template("voice_block") |
| settings | — | Model-specific TTS settings applied to every selected block; valid keys come from the model's settings_schema in list_models("voice_block") |
generate_storyboardPlan the full visual storyboard: segments, shot pacing, image/video
prompts, overlays, continuation chains — driven by the channel's director
and art styles. Requires voiceover to exist (timing comes from it).
Plans generated stills + real media only (real media requires the style's
@real-media…Plan the full visual storyboard: segments, shot pacing, image/video prompts, overlays, continuation chains — driven by the channel's director and art styles. Requires voiceover to exist (timing comes from it). Plans generated stills + real media only (real media requires the style's @real-media…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| model | string | Model ID to plan with; empty uses the default (see list_models("storyboard")) |
| editable_sections | — | Per-call prompt section overrides, keyed by section name; see get_section_template("storyboard") |
| settings | — | Model-specific settings; valid keys come from the model's settings_schema in list_models("storyboard") |
get_segmentsList the storyboard's segments (narration span, type, duration, creative
direction). The 1-based segment_number is the handle every segment tool takes
(update/split/combine/continuation/regenerate) — you never need a UUID.
Returns {total, offset, returned, segments}; on big projects page through…List the storyboard's segments (narration span, type, duration, creative direction). The 1-based segment_number is the handle every segment tool takes (update/split/combine/continuation/regenerate) — you never need a UUID. Returns {total, offset, returned, segments}; on big projects page through…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| offset | integer | 0-based index of the first segment to return (pagination) |
| limit | integer | Maximum segments to return; 0 returns all. Long-form projects can hold 100+ segments — page with offset/limit instead of pulling everything at once. |
get_segment_assetsList one segment's assets (images/video/overlays) including their
status, config (prompts, model), and public URLs of rendered files —
pass an image's public_url to view_image to actually look at it.List one segment's assets (images/video/overlays) including their status, config (prompts, model), and public URLs of rendered files — pass an image's public_url to view_image to actually look at it.
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| segment_number* | integer | 1-based segment number, as reported by get_segments |
regenerate_segment_assetRegenerate a segment's primary image or video with optional overrides —
the API equivalent of the editor's expert drawer. asset_type: "image" |
"video" (for a video segment, "image" targets its start frame). Use a
different model, override prompt sections (see
get_section_template("segment_imag…Regenerate a segment's primary image or video with optional overrides — the API equivalent of the editor's expert drawer. asset_type: "image" | "video" (for a video segment, "image" targets its start frame). Use a different model, override prompt sections (see get_section_template("segment_imag…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| segment_number* | integer | 1-based segment number, as reported by get_segments |
| asset_type* | string | "image" or "video"; for a video segment, "image" targets its start frame |
| model | string | Model ID to render with; empty uses the job's default (see list_models("segment_image") / list_models("segment_video")) |
| editable_sections | — | Per-call prompt section overrides, keyed by section name; see get_section_template("segment_image") or ("segment_video") |
| settings | — | Model-specific settings (e.g. image quality, video duration); valid keys come from the model's settings_schema in list_models |
rollback_segment_assetRestore a previously rendered version of a segment's image or video —
every regeneration archives the render it replaces (last 5), so a regen
that came out worse is reversible for free. The current render is archived
in its place, making the rollback itself reversible. The frame/clip pair
resta…Restore a previously rendered version of a segment's image or video — every regeneration archives the render it replaces (last 5), so a regen that came out worse is reversible for free. The current render is archived in its place, making the rollback itself reversible. The frame/clip pair resta…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| segment_number* | integer | 1-based segment number, as reported by get_segments |
| asset_type* | string | "image" or "video" — which primary to restore; for a video segment, "image" targets its start frame |
| index | integer | Which archived render to restore, 0 = the most recent (each asset's config.history in get_segment_assets lists them) |
change_segment_typeChange what a segment's base visual IS: a generated still ("image"),
fetched real media (media_source="real" — a real photo for "image", stock
b-roll footage for "video"), or an overlay scene. Generated video is NOT
set here — it's the state a rendered still reaches through animate_segment
(voi…Change what a segment's base visual IS: a generated still ("image"), fetched real media (media_source="real" — a real photo for "image", stock b-roll footage for "video"), or an overlay scene. Generated video is NOT set here — it's the state a rendered still reaches through animate_segment (voi…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| segment_number* | integer | 1-based segment number, as reported by get_segments |
| segment_type* | string | New visual type: "image", "video" (fetched b-roll only — requires media_source "real"), or "overlay_scene" |
| carry_frame | boolean | True reuses the already-rendered frame as the new type's starting visual instead of recreating it from scratch |
| media_source | string | "" keeps the segment's current source; "real" makes the visual fetched stock footage / a real photo (b-roll) instead of a generated one; "generated" switches b… |
| dry_run | boolean | True previews the consequences (assets kept / staled / recreated / deleted, rendered assets lost) without changing anything |
animate_segmentAnimate one segment in a single call: flip it to a generated video shot
(keeping its rendered image as the clip's first frame) and START the clip
render immediately. BILLS video credits on this call — the segment's image
must already be rendered (400 otherwise). A refused generation (out of
cre…Animate one segment in a single call: flip it to a generated video shot (keeping its rendered image as the clip's first frame) and START the clip render immediately. BILLS video credits on this call — the segment's image must already be rendered (400 otherwise). A refused generation (out of cre…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| segment_number* | integer | 1-based segment number, as reported by get_segments |
| voice | boolean | True lip-syncs the on-frame speaker to the voiceover (lip-sync model family — bills the exact segment length, so long segments cost proportionally more); False… |
update_segment_contentRewrite one segment's creative direction from feedback ("make this shot
a close-up", "show the machine from above") — an LLM rewrites the shot's
prompts; continuation links, SFX, and overlays are preserved. The visual
assets reset to not_started: re-render them afterwards (generate_segments
or…Rewrite one segment's creative direction from feedback ("make this shot a close-up", "show the machine from above") — an LLM rewrites the shot's prompts; continuation links, SFX, and overlays are preserved. The visual assets reset to not_started: re-render them afterwards (generate_segments or…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| segment_number* | integer | 1-based segment number, as reported by get_segments |
| user_input* | string | Natural-language feedback describing the change to this shot, e.g. "make this a close-up" or "show the machine from above" |
| dry_run | boolean | True previews the consequences (assets recreated, rendered assets lost) without changing anything |
update_segment_promptsSet one segment's final prompts VERBATIM — no LLM rewrite. The direct
counterpart to update_segment_content: your text is written as-is to the
segment's creative direction and to the matching asset configs the
renderer reads. Asset statuses are untouched: an already-rendered asset
stays complet…Set one segment's final prompts VERBATIM — no LLM rewrite. The direct counterpart to update_segment_content: your text is written as-is to the segment's creative direction and to the matching asset configs the renderer reads. Asset statuses are untouched: an already-rendered asset stays complet…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| segment_number* | integer | 1-based segment number, as reported by get_segments |
| image_prompt | string | New scene-image prompt (image segments; also the retrieval-miss fallback on real-photo segments). Empty leaves it unchanged. |
| start_frame_prompt | string | New start-frame prompt (generated video segments). Empty leaves it unchanged. |
| video_prompt | string | New motion/video prompt (video segments; also the retrieval-miss fallback on real b-roll). Empty leaves it unchanged. |
| media_queries | — | New stock-search queries for a fetched-media segment (real b-roll / real photo). Replaces the search text verbatim; re-fetch an already-fetched clip with regen… |
split_segmentSplit a segment at the given time offsets (ms, 1-3 cuts → 2-4 parts).
inherit_index picks which resulting part keeps the original creative data —
that part keeps its rendered assets, SFX, overlays and continuation links
(a rendered clip goes stale; re-render it). The other parts start fresh.
La…Split a segment at the given time offsets (ms, 1-3 cuts → 2-4 parts). inherit_index picks which resulting part keeps the original creative data — that part keeps its rendered assets, SFX, overlays and continuation links (a rendered clip goes stale; re-render it). The other parts start fresh. La…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| segment_number* | integer | 1-based number of the segment to split, as reported by get_segments |
| offsets_ms* | array | Cut points as millisecond offsets from the segment start, ascending; 1-3 cuts producing 2-4 parts |
| inherit_index | integer | 0-based index of the resulting part that keeps the original creative data (default: the first part) |
| dry_run | boolean | True previews the consequences without changing anything |
combine_segmentsMerge a segment with an adjacent one (segment numbers must be
neighbors). keep: "this" | "other" — whose creative data survives: its
assets are kept (rendered frame/clip marked stale against the combined
narration and its prompts re-derived); the other segment's assets are
deleted. Later segmen…Merge a segment with an adjacent one (segment numbers must be neighbors). keep: "this" | "other" — whose creative data survives: its assets are kept (rendered frame/clip marked stale against the combined narration and its prompts re-derived); the other segment's assets are deleted. Later segmen…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| segment_number* | integer | 1-based segment number, as reported by get_segments |
| with_segment_number* | integer | 1-based number of the adjacent segment to merge with (must neighbor segment_number) |
| keep | string | Whose creative data survives the merge: "this" (segment_number) or "other" (with_segment_number) |
| dry_run | boolean | True previews the consequences without changing anything |
set_segment_continuationMake a segment's image render as a continuation of an EARLIER segment's
frame (same composition evolving — the storyboard's continues_from_segment,
settable after the fact). continues_from is that earlier segment's number;
pass 0 to clear the link. Regenerate the segment's image afterwards — the…Make a segment's image render as a continuation of an EARLIER segment's frame (same composition evolving — the storyboard's continues_from_segment, settable after the fact). continues_from is that earlier segment's number; pass 0 to clear the link. Regenerate the segment's image afterwards — the…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| segment_number* | integer | 1-based number of the segment whose image should continue an earlier frame, as reported by get_segments |
| continues_from | integer | 1-based number of the EARLIER segment whose frame this one continues; pass 0 to clear the link |
add_segment_sfxAttach a sound effect from the audio library to a segment (find track
ids via browse_audio_library with category="sfx"). Re-run build_scenes to
get it onto the timeline.Attach a sound effect from the audio library to a segment (find track ids via browse_audio_library with category="sfx"). Re-run build_scenes to get it onto the timeline.
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| segment_number* | integer | 1-based segment number, as reported by get_segments |
| library_track_id* | string | Audio library track ID, from browse_audio_library(category="sfx") |
remove_segment_sfxprivilegedRemove a sound effect from a segment. With one SFX attached, no name
needed; with several, pass sfx_name (the asset name shown by
get_segment_assets).Remove a sound effect from a segment. With one SFX attached, no name needed; with several, pass sfx_name (the asset name shown by get_segment_assets).
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| segment_number* | integer | 1-based segment number, as reported by get_segments |
| sfx_name | string | Name of the SFX asset to remove, as shown by get_segment_assets; needed only when the segment has several SFX attached |
generate_segmentsRender every actionable segment asset (images, video clips, overlays)
across the project, in dependency order. THE most expensive call in the
pipeline: ALWAYS dry_run=true first, show your user the estimate next to
get_credit_balance, and wait for a fresh yes before the real run — prior
blanket…Render every actionable segment asset (images, video clips, overlays) across the project, in dependency order. THE most expensive call in the pipeline: ALWAYS dry_run=true first, show your user the estimate next to get_credit_balance, and wait for a fresh yes before the real run — prior blanket…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| dry_run | boolean | True returns the credit-cost estimate without rendering anything; ALWAYS run true first and get user approval before the real run |
| segment_numbers | — | 1-based segment numbers (from get_segments) to render only a subset; omit to render every actionable asset in the project |
| asset_scope | string | "" renders everything actionable; "no_clips" is the cheap base pass (images, overlays, fetched b-roll — no generated video clips); "clips_only" renders just th… |
build_scenesCompile segments + assets + voiceover into the editor/render timeline
(scenes). Run after segment assets are complete, before export.
Returns a receipt — {scene_count, scenes: [{scene_id, segment_number,
duration_frames, status, layer_count}]}; composition detail via
list_scenes.Compile segments + assets + voiceover into the editor/render timeline (scenes). Run after segment assets are complete, before export. Returns a receipt — {scene_count, scenes: [{scene_id, segment_number, duration_frames, status, layer_count}]}; composition detail via list_scenes.
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
list_scenesList the project's scenes in timeline order. Default rows are light
summaries ({scene_id, segment_number, duration_frames, status,
layer_count}) — enough to address a scene by number or id;
include_composition=True returns the full layer/layout JSON (bulky —
page with offset/limit on long proje…List the project's scenes in timeline order. Default rows are light summaries ({scene_id, segment_number, duration_frames, status, layer_count}) — enough to address a scene by number or id; include_composition=True returns the full layer/layout JSON (bulky — page with offset/limit on long proje…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| include_composition | boolean | Include each scene's full composition JSON (layers, layout) — kilobytes per scene, so page with offset/limit when True; the default summary rows are enough for… |
| offset | integer | 0-based index of the first scene to return (pagination) |
| limit | integer | Maximum scenes to return; 0 returns all |
director_noteEdit ONE scene with a natural-language note (the same director chat the
editor UI uses): move/restyle/add/remove layers and overlays, retime, etc.
Synchronous — returns the applied mutations + updated scene. Address the
scene by project_id + segment_number (preferred — always resolves to the
cu…Edit ONE scene with a natural-language note (the same director chat the editor UI uses): move/restyle/add/remove layers and overlays, retime, etc. Synchronous — returns the applied mutations + updated scene. Address the scene by project_id + segment_number (preferred — always resolves to the cu…
| Parameter | Type | Description |
|---|---|---|
| message* | string | Natural-language edit note for this scene, e.g. "move the caption to the top" or "remove the overlay" |
| project_id | — | Project ID; required (with segment_number) when not passing scene_id |
| segment_number | — | 1-based segment number of the scene to edit (from list_scenes or get_segments) — preferred over scene_id because it is resolved to the current scene at call ti… |
| scene_id | — | ID of the scene to edit, from a FRESH list_scenes call — scene ids change whenever segments are edited (split/combine/update-content), so never reuse ids saved… |
| conversation_history | — | Prior chat turns as [{"role": ..., "content": ...}] to continue an editing conversation on this scene; omit to start fresh |
project_director_noteApply a project-WIDE director note ("make the intro punchier", "all
captions bigger", "tighten pacing in the back half"). A routing pass picks
only the scenes the note applies to and edits each one. Synchronous — a
few seconds per affected scene. Returns the per-scene results; re-run
export_vid…Apply a project-WIDE director note ("make the intro punchier", "all captions bigger", "tighten pacing in the back half"). A routing pass picks only the scenes the note applies to and edits each one. Synchronous — a few seconds per affected scene. Returns the per-scene results; re-run export_vid…
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| message* | string | Project-wide director note in natural language, e.g. "make the intro punchier" or "all captions bigger" |
export_videoRender the final MP4 (Remotion). Fetches the current timeline and queues
the render. Async — poll get_workflow_status for the video_export job, then
call get_video_url.Render the final MP4 (Remotion). Fetches the current timeline and queues the render. Async — poll get_workflow_status for the video_export job, then call get_video_url.
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
get_video_urlDownload URL for the most recent completed export.Download URL for the most recent completed export.
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
list_stylesList the channel's style rows (variable groups). Styles hold the
art_style / narrative_style / director_style / script_prompt fields that
drive every generation step, plus any custom @variables.List the channel's style rows (variable groups). Styles hold the art_style / narrative_style / director_style / script_prompt fields that drive every generation step, plus any custom @variables.
| Parameter | Type | Description |
|---|---|---|
| channel_id* | string | ID of the channel that owns the styles, from list_channels |
get_styleFetch one style row — its inputs (reference material), analyzed fields
(art_style, narrative_style, director_style, script_prompt, ...), and
`templates`: {"character": url|null, "environment": url|null}, the two
template images. A null there means that template is genuinely missing and
needs ge…Fetch one style row — its inputs (reference material), analyzed fields (art_style, narrative_style, director_style, script_prompt, ...), and `templates`: {"character": url|null, "environment": url|null}, the two template images. A null there means that template is genuinely missing and needs ge…
| Parameter | Type | Description |
|---|---|---|
| style_id* | string | Style ID, as returned by create_style or list_styles |
update_style_fieldsinjection riskHand-edit a style's analyzed fields after reviewing them — e.g. tighten
the art_style wording or adjust the director_style pacing rules.
`fields` is a PATCH, merged over what the style already has: send only the
keys you are changing and leave the rest out — there is no need to read
the whole…Hand-edit a style's analyzed fields after reviewing them — e.g. tighten the art_style wording or adjust the director_style pacing rules. `fields` is a PATCH, merged over what the style already has: send only the keys you are changing and leave the rest out — there is no need to read the whole…
fields: Exfiltration-shaped instruction str, "applies_to": [...]}} — send ONLY the keys you are changing; unlisted keys keep their current value| Parameter | Type | Description |
|---|---|---|
| style_id* | string | Style ID, as returned by create_style or list_styles |
| fields* | object | Sparse patch of style fields, shaped {key: {"value": str, "applies_to": [...]}} — send ONLY the keys you are changing; unlisted keys keep their current value |
update_style_referencesReplace a style's reference set — add or remove references without
touching the analyzed fields.
FULL REPLACE: read the current list with get_style first and send every
entry you're keeping plus the changes. New entries are youtube (video
link, or a channel link/@handle) or text; new image/vid…Replace a style's reference set — add or remove references without touching the analyzed fields. FULL REPLACE: read the current list with get_style first and send every entry you're keeping plus the changes. New entries are youtube (video link, or a channel link/@handle) or text; new image/vid…
| Parameter | Type | Description |
|---|---|---|
| style_id* | string | Style ID, as returned by create_style or list_styles |
| inputs* | array | The COMPLETE reference list the style should have after this call, in display order: [{"input_type": "youtube" | "text" | "image" | "video", "value": "<url or… |
list_style_presetsThe curated preset catalog for the no-AI style creation path, grouped
by axis (art_style / narrative_style / director_style). Show the user the
labels + descriptions and let THEM pick one per axis — don't choose
silently. Art presets include preview image URLs (view_image works on
them). Create…The curated preset catalog for the no-AI style creation path, grouped by axis (art_style / narrative_style / director_style). Show the user the labels + descriptions and let THEM pick one per axis — don't choose silently. Art presets include preview image URLs (view_image works on them). Create…
No input schema was published for this tool.
create_styleCreate a style. Two mutually exclusive paths:
References (best): inputs=[{"input_type": "youtube" | "text", "value":
"<url or description>"}] — YouTube videos are watched (a channel link or
@handle resolves to that channel's newest usable upload) and text
directions read; async analysis writes…Create a style. Two mutually exclusive paths: References (best): inputs=[{"input_type": "youtube" | "text", "value": "<url or description>"}] — YouTube videos are watched (a channel link or @handle resolves to that channel's newest usable upload) and text directions read; async analysis writes…
| Parameter | Type | Description |
|---|---|---|
| channel_id* | string | ID of the channel to create the style in, from list_channels |
| name* | string | Display name for the style |
| inputs | — | Reference material to analyze, [{"input_type": "youtube" | "text", "value": "<url or description>"}]; a youtube value can be a video link or a channel link/@ha… |
| presets | — | Preset IDs per axis, {"art_style": id, "narrative_style": id, "director_style": id}, from list_style_presets; instant, no analysis. Mutually exclusive with inp… |
analyze_styleRe-run style analysis (after changing a style's inputs). Async —
await_jobs(style_id=...) until the style_analysis job completes.Re-run style analysis (after changing a style's inputs). Async — await_jobs(style_id=...) until the style_analysis job completes.
| Parameter | Type | Description |
|---|---|---|
| style_id* | string | ID of the style to re-analyze, from create_style or list_styles |
generate_style_templateRender one of a style's two template images — a REAL step of style
setup, not an optional extra: a style isn't finished until both its
character and environment templates are rendered (the app shows them on
the style card). Asset reference images render against them (characters →
character temp…Render one of a style's two template images — a REAL step of style setup, not an optional extra: a style isn't finished until both its character and environment templates are rendered (the app shows them on the style card). Asset reference images render against them (characters → character temp…
| Parameter | Type | Description |
|---|---|---|
| style_id* | string | Style ID, as returned by create_style or list_styles |
| template_type* | string | Which of the style's two template images to render: "character" or "environment" — run once for each |
| replace | boolean | Set True ONLY to deliberately overwrite an existing template of this type — the user must have asked for a new one. Leave False and the call refuses rather tha… |
| model | string | Image model ID; empty uses the template job's default (see list_models) |
| editable_sections | — | Per-call prompt section overrides, keyed by section name; see get_section_template for the template job |
delete_styleprivilegedDelete a style (e.g. a failed analysis experiment). Don't delete a
style that projects still use as their default — rebind them first with
set_project_style.Delete a style (e.g. a failed analysis experiment). Don't delete a style that projects still use as their default — rebind them first with set_project_style.
| Parameter | Type | Description |
|---|---|---|
| style_id* | string | ID of the style to delete, from list_styles |
set_provider_keyRegister a BYOK provider API key (encrypted at rest, BYOK plan only).
Jobs whose model belongs to this provider then run on YOUR key and charge
0 credits. Providers: openai, gemini, anthropic, fal, elevenlabs, minimax.Register a BYOK provider API key (encrypted at rest, BYOK plan only). Jobs whose model belongs to this provider then run on YOUR key and charge 0 credits. Providers: openai, gemini, anthropic, fal, elevenlabs, minimax.
| Parameter | Type | Description |
|---|---|---|
| provider* | string | Provider the key belongs to: "openai", "gemini", "anthropic", "fal", "elevenlabs", or "minimax" |
| key* | string | The provider API key to register; stored encrypted at rest |
list_provider_keysList registered BYOK providers (masked — only the last 4 characters).
Returns {keys: [...]}; an empty list means no keys are registered (every
job bills platform credits).List registered BYOK providers (masked — only the last 4 characters). Returns {keys: [...]}; an empty list means no keys are registered (every job bills platform credits).
No input schema was published for this tool.
whoamiVerify the connection: the account email and plan behind the current
credential. Call once after connecting — before creating anything — to
confirm you're on the right account; costs nothing.Verify the connection: the account email and plan behind the current credential. Call once after connecting — before creating anything — to confirm you're on the right account; costs nothing.
No input schema was published for this tool.
get_credit_balanceCurrent credit balance + plan info. Check before expensive steps (a
full segment render can cost hundreds of credits — generate_segments
dry_run gives the estimate). Jobs covered by a BYOK provider key bill 0.Current credit balance + plan info. Check before expensive steps (a full segment render can cost hundreds of credits — generate_segments dry_run gives the estimate). Jobs covered by a BYOK provider key bill 0.
No input schema was published for this tool.
browse_audio_libraryBrowse the audio library for background music and sound effects.
category: "music" | "sfx". Returns {tracks} — track ids feed
add_music_track / add_segment_sfx. Zero matches also returns the mood and
genre tags the library actually carries, so retry with one of those
rather than guessing new fi…Browse the audio library for background music and sound effects. category: "music" | "sfx". Returns {tracks} — track ids feed add_music_track / add_segment_sfx. Zero matches also returns the mood and genre tags the library actually carries, so retry with one of those rather than guessing new fi…
| Parameter | Type | Description |
|---|---|---|
| category | string | Track kind: "music" (background tracks) or "sfx" (sound effects); empty returns both |
| search | string | Free-text search over track names/descriptions; empty for no filter |
| mood | string | Filter by the track's mood tag; empty for no filter |
| genre | string | Filter by the track's genre tag; empty for no filter |
list_music_tracksList the project's background music tracks (volume, loop, timing).List the project's background music tracks (volume, loop, timing).
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
add_music_trackAdd background music to the project from the audio library (find track
ids with browse_audio_library, category="music"). Defaults loop the track
under the whole video at bed level (volume 0.12 ≈ -18.4 dB under narration —
don't raise it without being asked); re-run export_video to hear it.Add background music to the project from the audio library (find track ids with browse_audio_library, category="music"). Defaults loop the track under the whole video at bed level (volume 0.12 ≈ -18.4 dB under narration — don't raise it without being asked); re-run export_video to hear it.
| Parameter | Type | Description |
|---|---|---|
| project_id* | string | Project ID, as returned by create_project or list_projects |
| library_track_id* | string | Audio library track ID, from browse_audio_library(category="music") |
| name | string | Display name for the track on the project's timeline |
| volume | number | Playback volume 0-1; the 0.12 default sits at bed level under narration — don't raise it unless asked |
| loop | boolean | True loops the track under the whole video; false plays it once |
| start_frame | integer | Timeline frame at which the track starts (0 = start of the video) |
update_music_trackTweak a music track. fields keys: name, volume (0-1), loop, start_frame,
duration_frames, position, trim_start_frame, trim_end_frame.Tweak a music track. fields keys: name, volume (0-1), loop, start_frame, duration_frames, position, trim_start_frame, trim_end_frame.
| Parameter | Type | Description |
|---|---|---|
| track_id* | string | Music track ID, from list_music_tracks or add_music_track |
| fields* | object | Partial dict of track fields to patch; allowed keys: name, volume (0-1), loop, start_frame, duration_frames, position, trim_start_frame, trim_end_frame |
remove_music_trackprivilegedRemove a music track from the project.Remove a music track from the project.
| Parameter | Type | Description |
|---|---|---|
| track_id* | string | ID of the music track to remove, from list_music_tracks |
view_imageFetch a rendered Framesail image so you (and your user) can SEE it —
pass a URL from get_segment_assets, get_style, or asset endpoints. Returns
the image inline. Only Framesail media URLs are allowed.Fetch a rendered Framesail image so you (and your user) can SEE it — pass a URL from get_segment_assets, get_style, or asset endpoints. Returns the image inline. Only Framesail media URLs are allowed.
| Parameter | Type | Description |
|---|---|---|
| url* | string | Public Framesail media URL to fetch — a public_url from get_segment_assets, a file_path from list_assets, or a template/preset image URL from get_style / list_… |
72 of 72 tools published a description.
Tool names and descriptions are written by the publisher and shown verbatim as inert text. They are the strings an MCP client passes to a model, so Forge scans them for prompt-injection patterns — any finding appears with the security scan above. “Privileged” is a keyword match on the tool name, not an audit of what the tool does: a benign-sounding name can still do anything.
Create long-form YouTube videos end to end: script, storyboard, voiceover, final MP4.
+ 32 more observed on this entry.
Linked names open Forge’s index of every entry observed exposing that tool. Browse all indexed tools.
This entry publishes no npm package, so Forge has no dependency tree for it. That is a gap in coverage — not a statement that it has no dependencies.