MCP Tool Reference

Complete reference for the tools exposed by the Nodaro MCP server.

Scopes

Each tool requires one or more OAuth scopes. Grant the relevant scopes when authorizing the connector; missing scopes cause tools to be omitted entirely (they never appear in the tool list).

Scope Controls
workflows:read list_projects, get_project, list_workflows, get_workflow, get_workflow_json, export_workflow, list_components, get_component_inputs, get_recast_status, validate_studio_plan, list_studio_productions, get_studio_production, plan_studio_export
workflows:write create_workflow, delete_workflow, update_workflow_json, import_workflow, import_recast_script, create_studio_production, import_studio_production, edit_studio_production, share_studio_production, clone_studio_production
workflows:execute run_workflow, all generation verbs (image/video/audio/Suno/character/location/object), run_component, run_app, delete_app_run, analyze_prompt, generate_prompt, enhance_prompt, reduce, forced_alignment, video_analysis, video_audit, silence_detect, apply_edl, resolve_shot_sequence, render_shot_sequence, create_explainer, create_launch_video, start_recast, resolve_recast_gate; with workflows:write also describe_studio_production, generate_studio_still, generate_studio_keyframe, generate_studio_clip, new_studio_shot_from_frame, voice_studio_shot, revoice_studio_clip, score_studio_production
jobs:read list_jobs, get_job, diagnose_run
assets:read browse_gallery, browse_uploads, list_favorites, get_asset, display_asset, get_app_run, list_characters, get_character, list_locations, get_location, list_objects, get_object, list_creatures, get_creature
assets:write favorite_asset, create_character, update_character, approve_portrait, recaption_character, create_location, update_location, approve_main_image, recaption_location, approve_object_main_image, recaption_object, upload_image_widget, upload_audio_widget, upload_video_widget, request_image_upload, request_audio_upload, request_video_upload, prepare_image_upload, prepare_audio_upload, prepare_video_upload
credits:read check_balance, credit_transactions
apps:read list_apps, get_app_inputs
pipelines:read get_pipeline_stage_chat, get_pipeline_status, pipeline_pending_approvals
pipelines:execute branch_pipeline, start_pipeline
pipelines:approve chat_pipeline_stage, apply_chat_proposal
presets:read list_node_presets, get_node_preset
workspaces:read list_workspaces
workspaces:write select_workspace

Ungated (always visible): ping, list_models, start_film_director, start_video_director, start_workflow_editor, get_node_skill, get_picker_catalog, list_shot_shapes, get_shot_shape, list_brand_presets, get_recipe, get_studio_production_skill

The workspace scopes are deliberately not granted to tokens issued before organizations existed: consenting to an app back then could not have meant agreeing to let it choose where your work lands. Re-authorize to grant them.


Workspace tools

Only on instances with organizations. Everywhere else these tools are absent rather than present-and-empty, so a client discovers there is no such concept here instead of finding a switch that does nothing.

A browser picks a workspace from a switcher and every request carries the choice. An MCP client has neither a switcher nor a header it controls, so the same two questions become tools.

list_workspaces

The organizations and workspaces this account belongs to, and which workspace the session is working in.

Scope: workspaces:read Input: none

An empty result means the account belongs to no organization — normal, not an error.

Response shape:

{
  "workspaces": [
    { "id": "uuid", "orgId": "uuid", "name": "Class 1", "slug": "class-1", "role": "member", "memberStatus": "active", "archived": false }
  ],
  "organizations": [
    { "id": "uuid", "slug": "kent-high", "name": "Kent High", "kind": "school", "status": "active", "role": "owner" }
  ],
  "selectedWorkspaceId": "uuid"
}

select_workspace

Work in a workspace for the rest of the session, and remember it for the next one. Pass workspace_id: null to go back to the personal space.

Scope: workspaces:write Input: workspace_id (uuid or null)

The tool does not decide whether a workspace is selectable — it proposes one and the server either resolves it or refuses. Only what actually resolved is remembered: a preference that was never valid costs every later session a lookup.

The stored selection is re-validated at every session, never trusted. A preference is written once and read for months, and membership can end in between; a client that kept working inside a workspace it had been removed from is the one failure the tenancy axis exists to prevent, and unlike a browser there is nobody watching a switcher who would notice. A selection that no longer resolves is cleared and the session continues in the personal space, rather than refusing every tool to someone whose only mistake was being removed from a class.

Selecting records where the session’s work belongs. It grants nothing and moves nothing, so selecting the wrong one wastes a step rather than exposing anything.


Job cards

Generation tools render an inline tool card in MCP-Apps hosts (claude.ai): live progress, then the finished result. Media tools (generate_image, generate_video, generate_music, …) have media-specific cards. All remaining job tools — entity motion clips (generate_*_motion), render_shot_sequence, create_explainer, create_launch_video, run_component, and the text-output tools (image_to_text, generate_script, transcribe, suno_lyrics, suno_style_boost, forced_alignment, video_analysis, video_audit) — share the universal job card, which auto-detects the output: video/image/audio players, inline text with a Copy button (scripts, lyrics, transcripts, alignment JSON), or a component’s stacked outputs.

Result-text contract: job tools respond with "<label> started (id <jobId>)" plus card-first guidance. Clients without card support poll get_job with the job id (run_app returns an execution id — poll get_app_run instead). The result is always also saved to your Nodaro library.


The “mcp” project

In the app’s dashboard these workflows are listed under their own MCP Workflows tab (next to My Workflows / My Projects / Studio Workflows), so flows an MCP client creates never crowd your hand-made list. From that tab you can open, move to another project, or delete them like any other workflow.

All workflow tools that create or modify workflows operate inside a single project named “mcp”. This project is created automatically on first use — agents do not need to set it up.

Scope of the boundary:

Tool Scope
list_projects, get_project Sees all of your projects (read-only discovery)
list_workflows, get_workflow, get_workflow_json Only sees workflows in the mcp project
create_workflow, delete_workflow, update_workflow_json, import_workflow Only touches the mcp project
export_workflow Can read any of your workflows (use it to pull work from a personal project into the mcp project via export → import)
run_workflow Only runs workflows in the mcp project

This isolation keeps agent-managed workflows out of your personal projects.


Project tools

list_projects

Returns all projects in your account, ordered by name.

Scope: workflows:read
Input: none

Response shape:

{
  "data": [
    {
      "id": "uuid",
      "name": "mcp",
      "description": "Workflows managed via MCP",
      "workflowCount": 3,
      "createdAt": "2026-01-15T10:00:00.000Z"
    }
  ]
}

get_project

Returns a single project by UUID or by name (case-sensitive exact match).

Scope: workflows:read

Input:

Field Type Notes
project_id string A project UUID or a project name

Example: { "project_id": "My Feature Film" } resolves by name.
Example: { "project_id": "550e8400-e29b-41d4-a716-446655440000" } resolves by UUID.

Response shape:

{
  "data": {
    "id": "uuid",
    "name": "My Feature Film",
    "description": null,
    "workflowCount": 12,
    "createdAt": "2026-03-01T09:00:00.000Z"
  }
}

Workflow tools

list_workflows

Lists workflows in the mcp project, newest first.

Scope: workflows:read

Input:

Field Type Notes
limit integer (1–100) Default 20
cursor string ISO created_at from a prior response’s next_cursor; use for pagination
include_sub_workflows boolean Default false. When false, hides workflows with parent_workflow_id (child sub-workflows owned by another container). Pass true to surface them.

By default, list_workflows returns only top-level workflows — child sub-workflows (those owned by a parent container via parent_workflow_id) are hidden so the list reflects what you would see in the editor’s project view. Set include_sub_workflows: true if you need to enumerate every workflow in the mcp project regardless of nesting.

Response shape:

{
  "data": [
    {
      "id": "uuid",
      "project_id": "uuid",
      "name": "My Workflow",
      "description": null,
      "version": 1,
      "thumbnail_url": null,
      "created_at": "2026-05-01T12:00:00.000Z",
      "updated_at": "2026-05-01T12:00:00.000Z"
    }
  ],
  "next_cursor": "2026-04-30T08:00:00.000Z"
}

Pass next_cursor as cursor in the next call to get the next page. When next_cursor is null, you’ve reached the last page.


get_workflow

Returns metadata for a single workflow in the mcp project.

Scope: workflows:read

Input:

Field Type Notes
workflow_id UUID string Must be in the mcp project

create_workflow

Creates a new workflow in the mcp project. You can seed it with an initial node graph or leave it empty.

Scope: workflows:write

Input:

Field Type Notes
name string (1–200) Required
description string (max 2000) Optional
nodes array of objects Optional; React Flow node objects
edges array of objects Optional; React Flow edge objects
settings object Optional; workflow-level settings

Response: Returns the new workflow’s id and name in structured content.


delete_workflow

Deletes a workflow from the mcp project. This is permanent.

Scope: workflows:write

Input:

Field Type Notes
workflow_id UUID string Must be in the mcp project

Returns an error if the workflow doesn’t exist in the mcp project.


get_workflow_json

Returns the full React Flow graph for a workflow in the mcp project: nodes, edges, settings, name, and updated_at.

Scope: workflows:read

Input:

Field Type Notes
workflow_id UUID string Must be in the mcp project

Response shape:

{
  "name": "My Workflow",
  "nodes": [ ... ],
  "edges": [ ... ],
  "settings": {},
  "updated_at": "2026-05-10T15:30:00.000Z"
}

Save updated_at and pass it as expected_updated_at to update_workflow_json to enable optimistic concurrency control.


update_workflow_json

Updates a workflow in the mcp project: its node graph (nodes + edges), its settings, and/or its thumbnail_url. All content fields are optional — pass only thumbnail_url, for example, to set the preview image without re-sending the graph.

Any AI prompt node’s data may carry promptPrefix / promptSuffix — pre/post text wrapped around that node’s prompt at run time (settings-only; see Prompt pre & post text).

Scope: workflows:write

Input:

Field Type Notes
workflow_id UUID string Must be in the mcp project
nodes array of objects Optional; replaces the current nodes. Must be sent together with edges.
edges array of objects Optional; replaces the current edges. Must be sent together with nodes.
settings object Optional; if provided, replaces current settings
thumbnail_url string (URL) or null Optional; sets the workflow’s thumbnail image, or null to clear it. Must be an already-hosted image URL.
expected_updated_at string (ISO 8601) Optional; enables optimistic concurrency
expected_version integer Optional; integer CAS from get_workflow_json (preferred over expected_updated_at)
delta object Optional; id-keyed partial update applied atomically against delta.base_version (from get_workflow_json): upsert_nodes, delete_node_ids, upsert_edges, delete_edge_ids, set: { name?, settings? }. Mutually exclusive with every other content field. Prefer it over re-sending the graph.

Studio productions: a workflow whose stored settings.studio exists is a Studio production (its shots, results and plan live there). A settings replace — full-body or delta.set.settings — that changes or drops settings.studio is refused; echo it back unchanged (copy it from get_workflow_json) or leave settings out.

Optimistic concurrency: Pass the updated_at value from a prior get_workflow_json call as expected_updated_at. If the workflow has been modified since you read it, the call returns a conflict error:

“Workflow was modified since you last read it. Fetch the latest JSON with get_workflow_json and retry.”

This prevents accidental overwrites when two agents or sessions edit the same workflow concurrently. Omit expected_updated_at to skip the check and overwrite unconditionally.

Model parameters are corrected, not rejected. Image nodes (generate-image, image-to-image) carry model-specific levers — aspectRatio, resolution, quality — and the allowed values differ sharply per provider. GPT Image 1.5 (gpt-image) renders 1:1 / 3:2 / 2:3 and has no resolution setting at all, while gpt-image-2 accepts auto / 1:1 / 16:9 / 9:16 / 4:3 / 3:4 at 1K–4K. Rather than failing the write, a value the selected model does not accept is snapped to a valid one (or dropped, when the model has no such lever), and the response tells you exactly what changed:

Updated workflow 4f0c… (12 nodes).

Adjusted 2 parameter(s) the selected model does not accept:
  - node_8 (gpt-image): aspectRatio "16:9" → "1:1" — GPT Image 1.5 does not
    support aspect_ratio "16:9". Supported: 1:1, 3:2, 2:3.
  - node_8 (gpt-image): resolution "2K" → removed — GPT Image 1.5 has no
    resolution setting.

The structured payload carries the same information under adjustments. Read it: the stored value is not what you sent, and re-sending the original pair on the next turn just repeats the correction. Use list_models to see each model’s supported values up front, or pick the sibling model that supports what you want. The same correction applies to create_workflow and import_workflow.

Nodes configured with multiple providers at once are left untouched — the valid set there is the intersection across every selected provider, and no single replacement is correct for all of them.


export_workflow

Exports a workflow as a portable JSON bundle. Unlike other workflow tools, export_workflow is not restricted to the mcp project — it can read any of your workflows. Use it to pull an existing personal workflow into the mcp project via export → import.

Scope: workflows:read

Input:

Field Type Notes
workflow_id UUID string Any of your workflows
with_assets boolean Default false. When true, bundles character, object, and location entity data alongside the node graph

Two export modes:

Response: A JSON string in the WorkflowExport format (version 1). Pass the full string directly to import_workflow.

Portability note. When nodes reference media another instance cannot fetch — a self-hosted install’s own storage on localhost, a LAN address, an .internal name — the bundle carries portability.unreachableMedia ({ nodeId, nodeLabel, field, url } per reference). Such a bundle still imports, but those nodes will not run elsewhere until the media is re-uploaded there. Absent when every media URL is publicly reachable.


import_workflow

Imports a workflow from a JSON bundle produced by export_workflow. Always imports into the mcp project. If the bundle includes asset data (with_assets: true), new character, object, and location records are created under your account with fresh IDs; node references are remapped automatically.

Media the bundle references on other hosts is copied onto this instance’s storage where reachable (up to 25 distinct files for the graph’s media and 25 more for the bundled entities’ — separate budgets, so neither starves the other; images up to 20 MB, video/audio up to 50 MB), so the workflow runs from local copies.

Scope: workflows:write

Input:

Field Type Notes
workflow_json string The full JSON string from export_workflow

Response: Returns the new workflow’s id and name in structured content, plus importReport{ rehosted, unreachable[], skipped[], assetIdMap?, assetsSkipped? } — saying which media was copied, which points at a private host this instance cannot reach (left as-is), and which was skipped with the reason. The text reply repeats the same, naming the affected nodes.

Bundled entities (characters, objects, creatures, locations) are re-created under the caller, and both the entity nodes and every @-chip — in the graph or in the workflow’s freeform settings — are re-pointed at the new rows. URLs in settings follow the copies the graph and the entities paid for, but never trigger a copy of their own. An entity’s images are copied into the caller’s own storage even when they already sit on this instance — they are the exporter’s bytes — so the copies count against the caller’s quota; assetIdMap maps each bundled entity id to the row created for it, and assetsSkipped names any entity the quota left uncreated (the workflow still lands).


run_workflow

Runs a saved workflow from the mcp project. Returns an execution_id and registers an async task for progress tracking.

Scope: workflows:execute

Input:

Field Type Notes
workflow_id UUID string Must be in the mcp project
client_request_id string Optional retry token (8–128 chars of letters, digits, _ - . :). Reuse the same value when retrying after a timeout or dropped connection so the run is not started or charged twice; use a fresh value for a new run
inputs object Optional; per-node input overrides keyed by node id

Response: { executionId: "...", name: "..." } — use executionId with the jobs/executions tools or the SDK to poll for completion. MCP clients that support the tasks/* API and widget rendering will show live progress inline.


Prompt tools

AI assistance for writing prompts for generation nodes. All three delegate to POST /v1/prompt-helper/wizard (the same endpoint as the SDK client.promptHelper and the CLI nodaro prompt commands) and reserve credits per call.

Scope (all three): workflows:execute

analyze_prompt

Turns a rough idea into guided questions with options for a target node type (e.g. generate-image, image-to-video, generate-music). Pair with generate_prompt.

Input:

Field Type Notes
nodeType string Required. Target node type.
prompt string (max 5000) Optional. The rough idea. Omit to build from scratch.
provider / style / aspectRatio / duration / llmModel Optional.
advanced_mode / temperature / max_tokens Optional. Gemini models only — runs on the provider’s own API so the sampling levers and the full reasoning range actually apply. Bills one credit tier up; another model returns 400 advanced_mode_unsupported.

Response: { jobId, questions } — each question is { category, label, options[], selected, allowCustom, multi? }.

generate_prompt

Builds a single optimized prompt from analyze_prompt selections.

Input:

Field Type Notes
nodeType string Required.
selections array Required. One { category, value, isCustom } per answered question.
originalPrompt string (max 5000) Optional. Woven into the result.
provider / style / aspectRatio / duration / llmModel Optional.
advanced_mode / temperature / max_tokens Optional. Gemini models only — runs on the provider’s own API so the sampling levers and the full reasoning range actually apply. Bills one credit tier up; another model returns 400 advanced_mode_unsupported.

Response: { jobId, prompt, recommendedModel? }.

enhance_prompt

One-shot “improve this prompt” — rewrites a rough idea into one optimized prompt with no questions round-trip.

Input:

Field Type Notes
nodeType string Required.
prompt string (max 5000) Optional. The rough idea to improve.
provider / style / aspectRatio / duration / llmModel Optional.
advanced_mode / temperature / max_tokens Optional. Gemini models only — runs on the provider’s own API so the sampling levers and the full reasoning range actually apply. Bills one credit tier up; another model returns 400 advanced_mode_unsupported.

Response: { jobId, prompt, recommendedModel? }.


Image generation tools

Scope (all): workflows:execute

Tool Description
generate_image Text-to-image generation. Accepts prompt, model, aspect_ratio, resolution, quality, negative_prompt, reference_image_urls (up to 14 URLs or asset ids for identity/style/composition guidance — the response text confirms how many were attached), and optional structured fields. Advanced callers can also pass connected_references (the editor’s structured wired-reference shape) + reference_order — labeled/ordered references the route assembles into @image_N directives and {image:N} token resolution — and described_references (up to 10 {name, description} entries for a subject you can name but have no picture for: no url, nothing attached, each rendered as a <Name> — <description>. line so a name in your prompt reaches the model as a described subject). Also accepts presetId (from list_node_presets) to apply a built-in or saved preset’s config server-side; any explicit field above overrides the preset, and prompt may be omitted when the preset supplies one. A preset’s promptPrefix / promptSuffix wrap your prompt.
modify_image Image-to-image transformation — apply a style, change colors, swap backgrounds. Accepts image_url, prompt, and strength controls.
image_to_image Structural image-to-image (i2i) using a dedicated i2i model. Distinct from modify_image in that it uses models optimized for structural transfer. Supports multi-reference composition via reference_image_urls (up to 13).
edit_image Targeted edits: remove background, upscale, inpaint (nano-banana-edit), or Grok task-chained ops — free segment maps (grok-2-segment) and region-targeted edits (grok-2-edit) of a prior grok-2 generation.
generate_mask Generate or refine a segmentation mask for inpainting workflows.
image_collage Composite 2–30 images into one 2K/4K image with a smart (justified) or grid layout — no image is ever cropped (smart floats the output height; grid letterboxes). Accepts images[] (url or asset_id, each with an optional size hint: 0 auto / 1 big / 2 medium / 3 small — relative sizing for the smart layout), layout, resolution (default 4K), aspect_ratio (any W:H, default 4:3), gap, background_color. For storyboards it also accepts a per-image label (caption shown after the number, ≤ 80 chars) top-level numbered (stamp 1-based sequence numbers at each image’s corner in images order) and badge_position (top-left, the default, or top-right).
image_overlay Place 1–12 layers on a base image, pixel-exactly — local, deterministic, no AI. Base as image_url or image_asset_id; each layers[] item has a kind (imageurl or asset_id; text — a text object: content, fontId, fontWeight, fontSize as % of base height, colour, align, outline, background box; qr — a qr object; shape — a shape object: rect / rounded / pill / circle / ribbon / triangle / diamond / hexagon / star / burst / arrow) plus anchor (9 positions, default center), x / y (offset in % of the base width / height; negative on a right / bottom anchor moves inward), width (% of base width, default 25; height follows the layer’s aspect unless height is set), opacity, rotation (degrees), blend (over / multiply / screen), fit, shadow, rounded_corners, z_index (stacking order; default = array order). Optional canvas (width, height, background_color) + base_fit change the output size; variants renders extra platform sizes (any of the 12 platform ids, all at once if you like; 2 credits each on top of the 10-credit base) and the job’s output carries them as variants[] ({ id, label, width, height, url }); qr_text fills every QR layer with qr.fromInput: true (the node’s QR link handle — a List column gives one code per row); mask_mode (around default / layers / outside / none) + mask_spread shape the mask the job also emits as maskUrl (white = may change — the ring an AI finish repaints); the output also carries width / height; output_format png (default) / jpg / webp. SVG logos are rasterised crisp at the target size.
suggest_overlay_placement Ask a vision model WHERE one overlay layer should sit on a base image (image_url or image_asset_id): it reads the picture and keeps the element off the faces, the subject and the busiest texture. Answers anchor, x / y and width in image_overlay’s own percent units plus a one-sentence reason — apply it by passing those values on a layer to image_overlay; nothing is composited here. Optional intent (what the element is, in words), layer_aspect (its width / height, 1 = square) and safe_area (x, y, w, h as fractions of the canvas — a platform preset’s always-visible region, which the placement is kept inside). Billed as one image-to-text call.
image_to_text Extract a text description (caption/transcription) from an image using a vision model. Accepts llmModel, reasoning_effort, and the Advanced-mode trio (advanced_mode / temperature / max_tokens) — Advanced mode is Gemini-only and bills one credit tier up.
generate_script Generate a short video script from a prompt (LLM-backed; outputs scene-by-scene copy).
save_image_defaults Persist preferred model, aspect_ratio, and quality values so they become the defaults for subsequent generate_image calls in the same session.

Video generation tools

Scope (all): workflows:execute

Tool Description
generate_video Text-to-video generation. Accepts prompt, model, duration, aspect_ratio, resolution, sound, negative_prompt, seed, and optional structured fields. Advanced callers can also pass connected_references + reference_order (structured wired-reference shape) for labeled/ordered references on reference-capable models (Seedance 2, Gemini Omni, VEO 3.1 Fast / Lite, Kling 3 Omni, Grok i2v, HappyHorse Ref2V — not VEO 3.1 Quality, which has no reference-to-video mode), and described_references (up to 10 {name, description} entries for a subject you can name but have no picture for — no url, nothing attached, rendered as a <Name> — <description>. line). reference_video_captions describes the clips you attached: one caption per reference_video_urls entry in the same order, rendered into the prompt as @video_N: <caption>. — the seat to say what a reference clip is FOR and what to ignore (a Scene3D clay render needs exactly that; see 3D scenes). Captions past the last attached clip are dropped rather than binding a seat the model never receives. Also accepts presetId (from list_node_presets { nodeType: "generate-video" }) to apply a built-in or saved preset’s config server-side; any explicit field above overrides the preset, and prompt may be omitted when the preset supplies one. To animate from a still or use start/end frames, use animate_image. A preset’s promptPrefix / promptSuffix wrap your prompt.
animate_image Image-to-video animation — bring a still image to life. Accepts image_url / image_asset_id, optional prompt, model, duration, aspect_ratio, sound, and end_frame_url (start/end-frame animation). Advanced callers can also pass connected_references + reference_order for labeled/ordered identity references, and described_references for a named subject with no picture (rendered as a <Name> — <description>. line, nothing attached).
extend_video Extend an existing video clip forward in time. Accepts video_url, prompt, model, duration, and (seedance-2-extend only) reference_image_urls — up to 8 reference images, mentioned as @image_1…@image_N in the prompt; one Seedance reference seat is reserved for the continuation anchor.
loop_video Create a seamless looping clip from a short video segment. Accepts video_url and optional loop-trim parameters.
modify_video Video-to-video transformation — apply a style or prompt transformation to an existing clip. Accepts video_url/video_asset_id, prompt, model, resolution, seed plus per-model levers (duration, aspect_ratio, audio, multi_shots, reference_image_url). seedance-2-5 is a whole-clip EDIT: your prompt is sent as edit @video_1 as follows: …, the result keeps the source clip’s length and aspect ratio (clip must be 4–30 s), and reference_image_urls (up to 30) attaches images you cite positionally as {image:1}, {image:2} in the prompt. It is billed like a Generate Video Seedance 2.5 reference-video run — input + output seconds on the -ref ladder, reserved for the longest clip and settled to the delivered length (see Video to Video).
relight_video Relight & switch/composite a clip from its own pixels (Beeble SwitchX). Accepts video_url/video_asset_id + prompt and/or reference_image_url, alpha_mode (auto/fill/select/custom), mask_url, alpha_keyframe_index, max_resolution (720/1080), seed.
trim_video Trim a video to a start/end timestamp. Accepts video_url, start, end.
combine_videos Concatenate multiple video clips with optional transitions. Accepts video_urls[], transition, transition_duration.
assemble_narrated_video Fit N ordered (clip, voice) blocks into one narrated MP4 — a shorter voice is centered over its clip with silence padding, a longer voice slows the clip to fit (capped, holding the last frame beyond the cap); audio is never cropped. Accepts blocks[] (1–60, each video_url/video_asset_id + optional audio_url/audio_asset_id), voice_volume (default 100), clip_audio_volume (default 40), max_slowdown (default 1.5), trim_start_frames, trim_end_frames.
merge_video_audio Merge a video track and an audio track into a single output file.
still_to_video One still image + one audio track → MP4 (local FFmpeg, zero credits). The output length is the audio’s length — no duration parameter. Optional motion (zoom / pan / ken-burns) + intensity, resolution, aspect_ratio, fps, fit/pad_color.
gif_to_video Animated GIF → H.264 MP4 (local FFmpeg, zero credits). Bridges a GIF into the video pipeline as a motion reference for models that reject GIF input (e.g. Seedance). Accepts gif_url/gif_asset_id; optional loop_to_minimum + target_duration (seam-aware looping), interpolate, alpha_background.
slideshow 2–100 images + one optional audio track → MP4 slideshow (local FFmpeg, zero credits). Audio-anchored timing (equal split / image_durations pins with disclosed proportional scaling); silent without audio. transition + transition_duration, motion incl. alternate, resolution/aspect/fps/fit levers.
add_captions Burn subtitles/captions onto a video. Accepts video_url and caption style options. Kinetic styles (word-highlight, karaoke, tiktok-words, word-pop, bouncy) take a look preset — outline (Montserrat 900, UPPERCASE, black outline, yellow spoken word — the TikTok read) or clean — where on the kinetic styles an UNSET look renders as outline. The styling levers font_family, font_weight, stroke_color/stroke_width, uppercase, position_y and look now also apply to the static subtitle style (a styled subtitle renders via Remotion and bills at the kinetic price; a bare plain-text subtitle stays on the cheap FFmpeg path). Only highlight_color (the spoken-word colour) and animate stay kinetic-only and are rejected on subtitle. animate (default true): set false to freeze the per-word motion while keeping grouping, line-holding and the highlight colour (set highlight_color=color too for a fully static line). segments[] applies different treatments to non-overlapping time ranges in one call (a segment that names its own look does not inherit the top-level explicit levers).
extract_frame Extract a single frame from a video at a given timestamp. Returns an image URL.
lip_sync Drive lip-sync on a video or portrait image from an audio track. Accepts video_url / image_url + audio_url, plus model (kling-avatar, kling-avatar-pro, infinitalk, omnihuman-1-5, seedance-2(-fast), minimax-h3, latentsync, wav2lip, video-retalking, sadtalker), prompt, resolution, and (omnihuman-1-5) seed / fast_mode.
speech_to_video Generate a talking-head video from a portrait + speech audio.
motion_transfer Transfer the motion pattern from one video onto a target image or video.
face_swap Swap a face in a source image/video with a reference face.
video_upscale AI upscale a video to a higher resolution (powered by Topaz via KIE).
stop_video_pro Gracefully stop a RUNNING generate-video-pro job (the segmented long-video engine): the in-flight segment is abandoned (still billed), the rest are skipped, everything completed is stitched into the job’s final video, and the untouched reserve refunds. A not-yet-started job is cancelled with a full refund. Accepts job_id.
continue_video_pro Continue a stopped / failed / completed generate-video-pro run as a NEW job — delivered segments below from_segment (1-based; default = first missing) are reused, the rest regenerate; billed only for the regenerated part. Accepts job_id, from_segment?. Returns the new job id.
video_analysis Scene-by-scene analysis of a video for AI re-creation — ≤8s scenes with prompt-ready visualResolved descriptions, layered audio, and castable entity slots. Exactly one source: video_asset_id / video_url / youtube_url (max 10 minutes, no live streams). See video_analysis below.
video_audit Re-watch a video against its analysis and fix what’s wrong — a fix-and-disclose pass: corrections are applied under guards and every one is reported, nothing is silently rewritten. Pass analysis from a prior video_analysis/video_audit call to re-verify it, or omit it to auto-run a fast analysis first. See video_audit below.
silence_detect Detect the silent ranges in a recording — one ffmpeg pass over the source’s audio, no transcript and no pixels. audio_url accepts an audio OR a video source. Tune threshold_db (dBFS, at or below 0), min_silence_ms, pad_ms. Returns a job id — the silence result is the job’s output_data.json ({ ranges, durationMs }); pass THAT object (not the whole output_data) as plan_edit’s silence, or read ranges for a hand-cut EDL.
apply_edl Render an edit-decision list (EDL) into a finished cut. Pass edl (object or JSON string) — the plan from a plan_edit step, or hand-written to the @nodaro/shared Edl contract (integer-ms segments on a master clock, each naming a sources[].id; a video render needs a video source on every segment). Media resolves from each source’s url; sources optionally overrides those URLs positionally. output: video (default) or audio; optional transcript is remapped through the cut. A malformed EDL is rejected up front naming the offending segment and rule. Returns a job id — the rendered file is the job result. Priced per rendered minute.
plan_edit (Cloud only) Turn a timed transcript into an edit-decision-list (EDL) plan for a recording — mode: tighten (clean up the whole recording), clips (find N short clips), or chapters (mark chapters with titles). Reads the transcript, never pixels; pass 1–6 media sources. Returns a job id — the EDL plan is in the job’s output_data, ready to feed an Apply EDL render.
get_recast_authoring_skill (Cloud only) The authoring guide for writing a movie as JSON — the preferred lane for end-to-end “make me a video of X” requests. Generated from the platform’s own planner doctrine. Ungated. See Recast authoring.
validate_recast_script (Cloud only) FREE validation of an authored script; returns { valid, errors (path+hint), warnings } for the repair loop. Ungated, never charges.
import_recast_script (Cloud only) Turn a validated script into a real recast project (visible at recast.nodaro.ai). Free. Requires rights_attested: true, which must reflect the user’s own confirmation of ownership — authored recasts render Faithful, exactly as written. workflows:write.
start_recast (Cloud only) Quote (no confirm) then render (confirm: true after the user accepts the credits) an imported recast; called again it advances a planned or interactive run. Pass interactive: true to choose the cast at pick-1-of-3 gates (priced surcharge — it rides the quote). Optional anchor_mode picks the keyframes anchor discipline — "progressive" (each part’s start still chains off the previous render) or "none" (no frame conditioning; the quote drops the anchor-still surcharge); omitted, the server default applies. workflows:execute.
resolve_recast_gate (Cloud only) Record the user’s pick at an interactive gate (cast / identity sheet / scene stills / music) and advance the run — the pick is free, pure state. picks serves the two pick-1-of-3 gates: bare it answers the CAST gate; with gate: "sheet" it answers the identity-sheet gate (person slots only, opens after the cast pick — the face panel is identical across the 3 sheets, so the pick chooses body & wardrobe). finish_auto: true resolves every remaining gate with the critic’s top candidate. workflows:execute.
get_recast_status (Cloud only) Progress of a recast run — planning / planned / generating (segments, live preview) / completed (result URL) — plus the recast.nodaro.ai deep link. workflows:read.
get_studio_production_skill (Cloud only) How to author and operate a Nodaro Studio production — the lane for “make me a film/short/ad of X” when the user wants scenes they can keep editing at studio.nodaro.ai. part: operating (the tool map, the loop and the edit vocabulary — the default), authoring (the plan format), catalog (every picker/model/enum), schema (the JSON Schema). Ungated, free.
validate_studio_plan (Cloud only) FREE validation of an authored nodaro-studio-production plan; returns { valid, errors (path+message), warnings, summary }, where the summary says how many cast names bound to a row in the user’s own library. Never charges, persists nothing. workflows:read — it resolves every cast name against the caller’s own characters, locations, objects and creatures, exactly as its route does.
list_studio_productions (Cloud only) The user’s studio productions, newest first — id, name, version, thumbnail, shared flag and scene count. Archived rows are hidden, as on the dashboard. Pages with cursor. workflows:read.
get_studio_production (Cloud only) One production: film look, cast, folders, cuts, bin, what is running, and its scenes in timeline order. The keys are the document’s, the user’s words are not: a shots[] entry is a scene to them, its still the scene’s frame, its clip its motion, and the shots they talk about are the beats[] inside a motion — see the two vocabularies. detail: "summary" (default) is counts + each scene’s current frame; "full" adds every past result with its restore context. shot_id narrows to one scene. Address a result by its key (job id, or url when no job made it) — never by position. THIS READ IS ALSO THE WRITE: with workflows:write it first lands whatever has finished since the last read, and it is the only step that does — get_job / wait_for_job report a job’s status and land nothing, so a job that says completed is not in the film until you read it here. workflows:read.
plan_studio_export (Cloud only) What exporting a production would run, and what it would cost — the ordered steps plus a credit estimate. Starts nothing and charges nothing: the quote to show the user first. upscale: true adds the 4K pass. workflows:read.
create_studio_production (Cloud only) Create a production in the user’s own Studio project — visible at studio.nodaro.ai immediately. With a plan, every scene, cast binding and film look lands with it; without one, an empty production. Free: it writes a document, it generates nothing. workflows:write.
import_studio_production (Cloud only) Add a validated plan’s scenes to a production that already exists — the “Add scenes” lane. Appending adds scenes and enrolls whoever is new in the cast; it never renames, re-briefs or re-looks the production. Takes plan, or plan_job_id of a FINISHED llm-structured run whose schema is studio_production (a running one is refused with not_finished). Free. If the user has the production open in the studio editor, that tab writes the whole document back on a debounce and overwrites an append — ask them to reload the editor before the import and again after. workflows:write.
edit_studio_production (Cloud only) Change a production by sending a batch of 1–100 operations — rename a scene (rename_shot: operation names are the document’s), reorder the timeline, select a take, set the shots inside a scene’s motion (set_beats), enroll a cast member, empty the bin. The operation vocabulary and its argument shapes live in get_studio_production_skill (part: "operating"). Applied atomically under a compare-and-swap: a refused operation is answered with its index and nothing is written, and a batch composed against a slightly older version still applies (rebased: true says it did). expected_version + strict: true refuses instead of rebasing. Free. workflows:write.
share_studio_production (Cloud only) Publish a production to a share link, or take it back private (shared: false). Publishing makes it readable by anyone holding the link, so ask the user first — the tool is marked as a publish action. Reversible, and the only way sharing changes: no edit operation can touch it. Free. workflows:write.
clone_studio_production (Cloud only) Copy a production — the user’s own, or one shared with them — into their Studio project. The copy starts private and un-archived and carries the graph and every landed result. Free. workflows:write.
describe_studio_production (Cloud only) Hand a brief to the Director and let it write scenes, cast and looks into an existing production. Costs an LLM run, not a render; returns a job id and marks the production; the draft is written into the document by your next get_studio_production and by nothing else (get_job / wait_for_job land nothing). mode: append (default) or replace. Needs both workflows:write and workflows:execute.
generate_studio_still (Cloud only) Generate a scene’s frame (the document’s still): count candidate images from what the scene already says, plus per-call overrides. Spends credits per candidate — dry_run: true prices it and starts nothing. Returns job ids; a finished image joins the scene’s takes only on your next get_studio_production (get_job / wait_for_job report status and land nothing). Generating again ADDS takes, it never replaces one. Needs both workflows:write and workflows:execute.
generate_studio_keyframe (Cloud only; requires a backend with dependent-frame support) Generate one candidate for a planned frame (a keyframe, keyframe_id — not a scene’s frame, which is generate_studio_still) at expected_revision. A derived frame requires an accepted parent. Description-only cast works without portraits; generating a portrait later does not change that choice. Spends credits; quoting is unavailable and dry_run: true is rejected before submission. The candidate reaches the frame only on your next get_studio_production (get_job / wait_for_job land nothing), and landing it neither accepts it nor starts another frame. Accept explicitly through edit_studio_production after review. Needs both workflows:write and workflows:execute.
generate_studio_clip (Cloud only) Generate a scene’s motion (the document’s clip) from its frame, start/end frames and direction; the lane is chosen from the inputs unless mode forces one. Spends credits — dry_run: true prices it and starts nothing. Returns a job id and marks the scene as rendering; the finished take reaches the scene only on your next get_studio_production (get_job / wait_for_job land nothing). Framing and directing can be in flight at once. Needs both workflows:write and workflows:execute.
new_studio_shot_from_frame (Cloud only) Grab a frame out of a scene’s current motion and put it to work — target: "new-shot" (default) opens the next scene on it, "start-frame" / "end-frame" pin it as this scene’s endpoint, "still" adds it as a take of its frame. mode: first / last / timestamp (with timestamp in seconds). Costs a frame extraction; the route waits and answers with the updated production. Needs both workflows:write and workflows:execute.
voice_studio_shot (Cloud only) Speak a line over a scene — the voiceover lane. Give the text; pick a voice_id from list_voices or let the scene’s own voice settings stand. Costs a text-to-speech run; the route waits and answers with the updated production. Needs both workflows:write and workflows:execute.
revoice_studio_clip (Cloud only) Replace the voices inside a scene’s current motion — the dialogue is re-performed and mixed back over the same picture. Takes a plan naming which speaker gets which voice (see the operating skill). Spends credits and returns a job id; the new mix reaches the scene only on your next get_studio_production (get_job / wait_for_job land nothing). Needs both workflows:write and workflows:execute.
score_studio_production (Cloud only) Write the film a soundtrack from a prompt describing the music — one track for the whole production, not per scene. Spends credits and returns a job id; the track reaches the production only on your next get_studio_production (get_job / wait_for_job land nothing). Needs both workflows:write and workflows:execute.

Seedance 2 (model: "seedance-2") accepts resolution: "4k" and aspect_ratio: "adaptive" (plus "21:9") on generate_video / animate_image — both fields are free strings, forwarded to the route unaltered. The other variants are resolution-capped: seedance-2-fast and seedance-2-mini are 480p / 720p only (no 1080p, no 4K), while seedance-2-5 spans 480p / 720p / 1080p (no 4K; 1080p added 2026-08-17). seedance-2-5 also trades 4K for length — up to 30s in one call vs 15s — and accepts 30 image / 10 video / 10 audio references. Frame inputs and references coexist — when any reference (image / video / audio) is wired alongside image_url / end_frame_url, the frames become prompt-directed Image N references rather than pinned endpoints; the resolver decides the mode, so there is no toggle. Reference videos are billed unit × (input + output) duration — the per-second -ref rate (see the Generate Video node pricing) is scaled by the probed input-video duration plus the output duration, so longer source clips reserve more.

MiniMax Hailuo 3 (model: "minimax-h3") takes the same reference_image_urls / reference_video_urls / reference_audio_urls fields on generate_video / animate_image with the same 9 / 3 / 3 caps, through the same frames-fold-into-references resolver. Output is resolution: "2K" (default) or "768P" (the cheaper per-second rate) — any other resolution value renders and bills as 2K — and audio is always on. aspect_ratio: "adaptive" is the default (reference / i2v runs); a pure text-to-video call needs a concrete ratio (adaptive renders 16:9). Reference videos are 2–15s each (≤ 15s combined) and bill unit × (input + output) duration at the selected resolution’s per-second rate; input images beyond the first 5 (counting folded frames) add a per-image surcharge; reference audio is free but must accompany an image or video reference.

Wan 3.0 (model: "wan-3" / "wan-3-prime") takes reference_image_urls (≤ 10), reference_video_urls (≤ 5) and reference_audio_urls (≤ 5) on generate_video / animate_image, each reference video and audio clip 1–15 s with a ≤ 15 s combined cap per type. Its references are mutually exclusive with image_url / end_frame_url on the provider’s wire, so — exactly as on Seedance 2 and Hailuo 3 — the platform folds instead of failing: with any reference wired, a start/end frame is appended to reference_image_urls after your own images (their ordinals unchanged) and named in the prompt as the opening/closing frame. The pair is never sent together, and the call is not rejected. duration is a whole number of seconds from 2 to 30 (default 5); with a reference video wired, input duration + output duration must be ≤ 30 s. resolution is "480p" / "720p" / "1080p" — send the lowercase display value (the platform normalizes to the provider’s uppercase enum), and an omitted or unsupported value renders and bills at 720p. aspect_ratio defaults to "adaptive"; the model’s set is adaptive / 16:9 / 4:3 / 1:1 / 3:4 / 9:16 (no 21:9). Audio is on by default and can be switched off. Reference-video runs bill output seconds only — no input-duration surcharge. wan-3-prime is the high-speed SKU: faster, priced above wan-3, identical schema.

Gemini Omni Flash (model: "gemini-omni-flash") is the cheaper, faster sibling of gemini-omni-video on an identical request shape: the same image_urls reference surface under a 7-unit quota (each image 1 unit, a source video 2), the same video-edit mode through the same handle, duration one of "4" / "6" / "8" / "10" (an omitted duration renders and bills as 8 s), aspect_ratio restricted to "16:9" or "9:16", and resolution "720p" / "1080p" / "4k" (4K is not available on the free tier). Like the Pro SKU it forwards no audio_ids: the model still generates its own audio track (steer it in the prompt), but there is no platform-managed voice on this path, so both SKUs are excluded from character voice.

video_analysis

Scope: workflows:execute

Analyze a video into a scene-by-scene breakdown built for AI re-creation. Scenes are cut at natural boundaries, each at most 8 seconds (one image/video generation per scene). Every scene carries visualResolved — a self-contained, prompt-ready visual description and the field downstream consumers read — plus shot type, camera movement, an array of concurrent audio layers (speech quoted verbatim; music/sfx as generation-ready descriptions; an empty array [] means silence), and recurring people/objects/places extracted as castable entity slots so they can be re-cast with your own characters. Returns a job_id — poll get_job; the full analysis JSON (meta + slots + scenes[]) is in the job’s output_data.

Input:

Field Type Description
video_asset_id uuid, optional Nodaro video job id or uploaded-asset id.
video_url string, optional Direct URL of a video file.
youtube_url string, optional YouTube video URL (youtube.com / youtu.be).
llm_model enum, optional Analysis quality tier: fast (economy), pro (default, higher fidelity), or mixed / mixed-fast (advanced tiers — maximum completeness and accuracy).
selection_mode enum, optional Result strategy: choose (default — standard result) or combine (enhanced, verified result with maximum detail; slightly slower, recommended).
variations boolean, optional Cast-variations opt-in: the analysis also detects per-entity appearance looks — a plain wardrobe change between scenes counts exactly as much as a dream / flashback / disguise / era look — and binds each look to its scenes (slots[].variations + scenes[].slotVariations). Default false: the result keeps the pre-variations shape.
music_video boolean, optional Declare the clip a music video: the song IS the piece, so all sung lyrics are transcribed verbatim as per-scene speech layers (the instrumental bed stays its own music layer). Default false: soundtrack vocals nobody on screen performs are folded into the music layer’s description, and speech carries only words uttered inside the story world.
translate_speech_to_english boolean, optional Spoken and sung words come back in English. Default false: speech is quoted verbatim in the language actually spoken. Independent of the on-screen-text flag.
translate_on_screen_text_to_english boolean, optional Signs, captions, and titles come back in English (they live in visual, the generation prompt — a regenerated shot renders the English wording). Default false: transcribed verbatim in the original script. Brand, product, person, and place names keep their original form under both flags.
analysis_focus string ≤2000, optional Steer the analysis (e.g. “focus on the product shots and on-screen text”).

Pass exactly one of video_asset_id / video_url / youtube_url — passing zero or more than one returns a tool error naming what was provided. Maximum duration is 10 minutes (600s) for any source; YouTube live streams are rejected.

Pricing — duration-bucketed credits per quality tier. The bucket is the smallest of 60s / 180s / 360s / 600s that fits the video’s probed duration. The values below are the shared pricing formula’s current outputs:

Tier ≤60s ≤180s ≤360s ≤600s
fast (economy) 180 185 514 846
pro (default) 215 231 636 1050
mixed / mixed-fast 268 289 724 1169
smart (highest accuracy) 410 500 1259 2064

The live tool description carries these same numbers — it is generated from the shared pricing table at server start, so it is always current. This table is hand-maintained; if the two ever disagree, the tool description is right.

video_audit

Scope: workflows:execute

Re-watch a video against its analysis and fix what’s wrong — a fix-and-disclose pass, not a silent rewrite. Corrections are applied under guards and every one is reported: the job’s output_data carries a disclosed report of what was checked, what changed, and what was left open (flagged, not auto-fixed). Returns a job_id — poll get_job for the report.

Input:

Field Type Description
video_url string, required Direct URL of the video to audit.
analysis object, optional The analysis JSON (meta + slots + scenes[]) from a prior video_analysis or video_audit call, passed through verbatim. Wiring this prices the cheaper video-audit family; omit it and the tool auto-runs a fast analysis first (the pricier video-audit:auto family).

Pricing — duration-bucketed credits, selected by whether analysis was passed. The bucket is the smallest of 60s / 180s / 360s / 600s that fits the video’s probed duration. The values below are the shared pricing formula’s current outputs:

Family ≤60s ≤180s ≤360s ≤600s
video-audit (analysis wired) 213 289 659 1066
video-audit:auto (no analysis — auto-runs one first) 393 474 1173 1912

The live tool description carries these same numbers — it is generated from the shared pricing table at server start, so it is always current. This table is hand-maintained; if the two ever disagree, the tool description is right.


Audio generation tools

Scope (all): workflows:execute

Tool Description
generate_music Text-to-music generation (Suno via KIE). Accepts prompt, genre, mood, duration, modelsuno-v6 (default; greater musical expression, more natural vocals, richer details), suno-v6_wild (bolder, more distinctive, less predictable), suno-v6_mini (lightweight and fast), suno-v5_5 (alias suno-v5-5), suno-v5, suno; minimax for short instrumental loops. Also accepts presetId (from list_node_presets { nodeType: "generate-music" }) to apply a built-in or saved preset’s config server-side; any explicit field above overrides the preset, and prompt may be omitted when the preset supplies one. A preset’s promptPrefix / promptSuffix wrap your prompt.
generate_speech Text-to-speech. Accepts text, voice_id, model. Supports ElevenLabs v3 (default), turbo, and multilingual v2. Also accepts presetId (from list_node_presets { nodeType: "text-to-speech" }) to apply a built-in delivery preset (speed/stability/style) server-side; explicit fields override it, and text is always required (presets tune delivery; a preset’s promptPrefix / promptSuffix wrap your text).
generate_dialogue Multi-speaker dialogue as ONE audio file (ElevenLabs Dialogue v3, direct API). Accepts dialogue — an ordered array of { text, voice_id } lines (premade names or cloned/library UUIDs, mixed casts fine; [audio tags] allowed in line text) — plus optional stability (0 / 0.5 / 1), language_code, seed, apply_text_normalization. Limits: 5,000 chars total across lines, 10 unique voices. Use it instead of stitching per-line generate_speech calls.
text_to_audio Text-to-sound-effect (ElevenLabs SFX). Accepts prompt and optional duration. Also accepts presetId (from list_node_presets { nodeType: "text-to-audio" }) to apply a built-in or saved preset’s config server-side; any explicit field overrides the preset, and prompt may be omitted when the preset supplies one. A preset’s promptPrefix / promptSuffix wrap your prompt.
list_voices List the available premade voices (id + name, plus any gender/accent/description metadata) so you can pick a voice_id for generate_speech, voice_changer, or voice_changer_pro — all of which require a voice id. Read-only; returns the catalog as JSON.
voice_design Design a new synthetic voice from text descriptors (ElevenLabs /v1/text-to-voice/design). Accepts text, voice_description, model (default eleven_ttv_v3; eleven_multilingual_ttv_v2 is the legacy model), loudness, guidance_scale, seed, quality, should_enhance. Returns a voice_id.
voice_changer Transform the speaker identity in an audio clip — or a whole talking video — to a target voice. Accepts audio_url/audio_asset_id or video_url/video_asset_id (video is demuxed, revoiced, remuxed), voice_id (premade name or clone UUID; required), model, stability, similarity_boost, style, remove_background_noise.
voice_changer_pro Detect each speaker in a multi-speaker clip and convert each to a chosen voice, preserving words and timing (Cloud only). Accepts audio_url/audio_asset_id or video_url/video_asset_id; ordered_voices (required, positional: speaker N → entry N; each entry a voice id, a per-voice settings object with engine ("sts" default recast / "v3" Re-speak — regenerates the performance from the transcript with eleven_v3, [audio tags] supported, stability 0/0.5/1 only), stability/similarity_boost/style/use_speaker_boost/seed/volume_mode/volume, or null); analysis (a prior analyze run’s output_data — the recast works from the exact speaker list you mapped against; its segments[].text is the required transcript for a "v3" speaker, and omitting analysis re-speaks from the engine’s own transcription); voice_fx (preset + wet_dry_mix/delay_ms/decay); model; preserve_background; separation_quality (fast/best); music_volume_mode (match/normalize/manual) + music_volume; remove_background_noise; output (video default / stems). A null entry in ordered_voices is a keep-slot — that speaker keeps their original voice while later speakers are still recast. output: "stems" returns the dry per-track stems for interactive mixing instead of a finished video.
voice_changer_pro_analyze Detect the speakers in a clip WITHOUT recasting (Cloud only) — the first step of the interactive flow. Accepts audio_url/audio_asset_id or video_url/video_asset_id, separation_quality, suggest_title. The job output carries the separated stems + the detected speaker list (id, segments, first-appearance, word count, snippet) + language — inspect it to choose each speaker’s voice (and spot non-person “speakers” like applause) before committing to a recast.
voice_changer_pro_export Render a finished video from a mixed set of stems (Cloud only) — the last step of the interactive flow. Accepts video_url/video_asset_id (the source video) + tracks (stem url, gain 0–200, muted, kind voice/background; ≤16, at least one un-muted) + optional voice_fx, which lands on the voice tracks at render time. Stream-copied (never re-encoded).
voice_remix Re-stylize or re-arrange an existing audio clip.
dubbing Dub audio OR video into a target language with voice preservation. One source: audio_url/audio_asset_id, video_url/video_asset_id (delivers the dubbed VIDEO + audio track), or source_url (public YouTube/TikTok/direct link ElevenLabs fetches itself). Options: num_speakers (0=auto), disable_voice_cloning, drop_background_audio, start_time/end_time window, highest_resolution, use_profanity_filter, target_accent, watermark. Priced per minute of the dubbed span; max 30 minutes.
transcribe Speech-to-text transcription on the elevenlabs-stt engine. Returns a transcript, and per-word timings (ms) are always in output_data.json.words — this engine is word-level, so word_timestamps is accepted but changes nothing. Supports diarize and tag_audio_events. To caption a video with your own corrected text, map json.words into add_captions captions[] (one entry per word).
audio_isolation Isolate and clean the primary voice from a mixed clip (removes background music/noise). Returns one clean voice track.
separate_audio Separate ANY audio into vocals + instrumental, or full stems (drums/bass/other/guitar/piano), via Demucs. Works on non-Suno audio.
apply_audio_fx Apply a creative audio effect — scenario reverbs (room/hall/church/cave/arena/outdoor…) to place a voice in a space, plus telephone/megaphone/echo/custom (delay+EQ).
trim_audio Trim an audio file to a start/end timestamp.
download_youtube_audio Download the audio track from a YouTube URL. Returns an audio asset URL.

Suno music tools

All Suno tools require workflows:execute.

Tool Description
suno_generate Generate a new song from a prompt or lyrics using Suno (model: V6 default, V6_WILD, V6_MINI, V5_5, V5, V4_5PLUS, V4_5ALL, V4_5, V4).
suno_lyrics Generate song lyrics from a prompt.
suno_extend Extend an existing Suno song clip.
suno_cover Generate a cover version of a song.
suno_upload_extend Upload an audio clip and extend it with Suno.
suno_music_video Generate a music video from a Suno song clip.
suno_mashup Blend two audio clips into a mashup.
suno_replace_section Replace a section of a Suno song with new generated audio.
suno_style_boost Apply a style transfer / boost to a Suno song.
suno_add_instrumental Add an instrumental track to a Suno song.
suno_add_vocals Add a vocal layer to an instrumental track.
suno_separate_stems Separate a song into vocal + instrumental stems.
suno_convert_wav Convert a Suno output to WAV format.

Character tools

Character tools surface the caller’s saved characters from Character Studio so an LLM client can pick the right asset URL to pass as a reference image into a subsequent generation call.

list_characters

Scope: assets:read

Lists the caller’s characters with summary fields, ordered by most recently updated.

Input: { search?: string, limit?: integer }search is a case-insensitive substring of the name; limit defaults to 50, max 100.


get_character

Scope: assets:read

Returns full asset detail for one character including every expression / pose / motion / angle / lighting variant with its URL.

Input: { id: uuid }


create_character

Scope: assets:write

Creates a new character row with identity fields. No portrait — call generate_character (kind="main") afterwards.

Input: name, description, gender, style (realistic/anime/3d-pixar/illustration), base_outfit, seed_prompt, identity_lock (off/soft/strict — face-preservation strength for Studio assets, default off)


update_character

Scope: assets:write

Patches an existing character. Only the fields you supply are written. Supports optimistic concurrency via expected_updated_at.


approve_portrait

Scope: assets:write

Approves a completed generate_character job as the character’s canonical portrait. Fires an LLM caption inline to populate canonical_description.

Input: { character_id: uuid, candidate_job_id: uuid }


recaption_character

Scope: assets:write

Re-runs the LLM caption against the character’s current portrait and persists the new canonical_description.

Input: { id: uuid }


generate_character

Scope: workflows:execute

Generates either a fresh portrait (kind: "main") or an asset variant (kind: "asset") for a named character. The single tool covers two routes: POST /v1/generate-character (main portrait) and POST /v1/generate-character-asset (variants — expressions, poses, head angles, body angles, lighting, custom).

Input (main): kind, name, description, gender, style, base_outfit, model

Input (asset): kind, name, asset_type, variant, attach_to_character_id, attach_to_column, attach_name, source_image_url


generate_character_motion

Scope: workflows:execute

Animates a character into a motion clip via image-to-video. When attach_to_character_id is set, the source frame is auto-resolved from the character row and the resulting clip is appended to the motions[] bucket.

Input: motion_prompt, name, attach_to_character_id, source_image_url, description, motion_description, provider


Location tools

Eight tools for the location lifecycle — identity edits, establishing-shot generation, atmospheric motion clips, and LLM-captioned approval. Mirrored on the SDK at client.locations.

list_locations

Scope: assets:read

Summary list (name, main image URL, asset counts, identity copy).

Input: { search?: string, archived?: boolean }search is a case-insensitive substring of the name; archived lists the archive instead.


get_location

Scope: assets:read

Full detail including all asset arrays + reference photos + pendingJobs.

Input: { id: uuid }


create_location

Scope: assets:write

Create a new row with name + optional description / category / style.

Input: name, description, category, style


update_location

Scope: assets:write

Update identity fields (name, description, category, style, styleLock, canonicalDescription). Supports optimistic concurrency via expected_updated_at.


approve_main_image

Scope: assets:write

Approve a completed generate_location candidate as the location’s main image. Fires the LLM caption inline.

Input: { location_id: uuid, candidate_job_id: uuid }


recaption_location

Scope: assets:write

Re-run the LLM caption against the current main image.

Input: { id: uuid }


generate_location

Scope: workflows:execute

Generate a main image (kind: "main") or a variant asset (kind: "asset" + asset_type + variant).


generate_location_motion

Scope: workflows:execute

Animate the location’s establishing shot into an atmospheric motion clip (image-to-video). Pass refine_from_video_url to route through video-to-video for iterating on an existing clip.


Object tools

Six tools for the object (prop / product / vehicle / etc.) lifecycle — listing, detail, main-image approval, LLM recaption, motion clips, and verb-style generation. Mirrored on the SDK at client.objects.

list_objects

Scope: assets:read

Lists the caller’s objects — props, accessories and physical items reused across shots. Each row carries the name, description, main image and a COUNT of each variant bucket rather than the asset URLs themselves; call get_object for those. Newest first.

Input: { search?: string, limit?: integer }search is a case-insensitive substring of the name; limit defaults to 50, max 100.


get_object

Scope: assets:read

Returns full detail for one object — every variant asset with its name and URL, plus reference photos. Errors if the object is not found or not owned by the caller.

Input: { id: uuid }


generate_object

Scope: workflows:execute

Generate a main image or variant asset for an object. Parallel to generate_character / generate_location.


approve_object_main_image

Scope: assets:write

Approve a completed generate_object candidate as the object’s main image. Fires the LLM caption inline.

Input: { object_id: uuid, candidate_job_id: uuid } + optional expected_updated_at


recaption_object

Scope: assets:write

Re-run the LLM caption against the current main image.

Input: { id: uuid }


generate_object_motion

Scope: workflows:execute

Animate the object’s main image into a motion clip (image-to-video). Provider defaults to "kling-turbo", aspect ratio defaults to "1:1". Pass refine_from_video_url to use video-to-video refinement.

Input: motion_prompt, source_image_url (required), name, attach_to_object_id, provider, aspect_ratio, refine_from_video_url


Creature tools

Six tools for the creature / animal lifecycle — listing, detail, main-image approval, LLM recaption, motion clips, and verb-style generation. Mirrors the Object tools with the Animal/Creature delta (free-text species / category / style).

list_creatures

Scope: assets:read

Lists the caller’s creatures — animals and non-human beings with a locked look. Each row carries the name, description, main image and a COUNT of each variant bucket rather than the asset URLs themselves; call get_creature for those. Newest first.

Input: { search?: string, limit?: integer }search is a case-insensitive substring of the name; limit defaults to 50, max 100.


get_creature

Scope: assets:read

Returns full detail for one creature — every variant asset with its name and URL, plus reference photos and the stored voice. Errors if the creature is not found or not owned by the caller.

Input: { id: uuid }


generate_creature

Scope: workflows:execute

Generate a creature/animal main image (kind: "main") or a variant asset (kind: "asset" + asset_type + variant). Parallel to generate_object; species (free text, e.g. "dragon", "wolf") is the creature delta vs objects.

Input (main): kind, name, description, species, category, style, source_image_url, model

Input (asset): kind, name, asset_type (angles/poses/variations/custom), variant, species, category, style, source_image_url, model


approve_creature_main_image

Scope: assets:write

Approve a completed generate_creature candidate as the creature’s main image. Fires the LLM caption inline.

Input: { creature_id: uuid, candidate_job_id: uuid } + optional expected_updated_at


recaption_creature

Scope: assets:write

Re-run the LLM caption against the current main image.

Input: { creature_id: uuid }


generate_creature_motion

Scope: workflows:execute

Animate the creature’s main image into an ambient motion clip (image-to-video). Provider defaults to "kling-turbo", aspect ratio defaults to "1:1". Pass refine_from_video_url to use video-to-video refinement.

Input: motion_prompt, source_image_url (required), name, canonical_description, category, style, attach_to_creature_id, attach_name, provider, aspect_ratio, refine_from_video_url


Scope: assets:read

Browse your gallery or the public gallery. Renders an interactive grid widget in compatible clients.

Input: scope ("mine" default / "public"), limit, cursor, kinds[], query


browse_uploads

Scope: assets:read

Browse assets you’ve uploaded (source files — distinct from generated outputs). Use to retrieve existing upload URLs to feed into generation tools.

Input: kind, limit, cursor


list_favorites

Scope: assets:read

List your favorited gallery items, most recent first.

Input: limit, cursor


get_asset

Scope: assets:read

Fetch metadata for a single asset (job) by id, including output URL, prompt, provider. Visible for your own jobs (any status) and any user’s public completed jobs. For a failed job it returns the failure reason plus a retryable flag, a guidance sentence, and — when the provider’s safety filter blocked the output and the catalog offers a fallback model — suggestedProvider. retryable: false (a content-policy block, or a provider that refused the request outright — see below) means the same request will fail again unchanged; when suggestedProvider is present, retry the SAME prompt and references with that model id instead of guessing at a new one.

A job whose error_message says the provider rejected these settings for this model is the request-reject case: the provider answered the submission with a 4xx, so the combination of settings and input media is invalid for that model. It comes back retryable: false — change the settings or the input media (duration, aspect ratio, resolution, or the reference image/video/audio) before re-running, or pick a model whose list_models capability sheet allows the combination. A provider 5xx is the opposite case and stays retryable, even when its wording reads like a validation complaint. For a job in pending_review (a deployment’s job policy held the output for human review) it returns status: "pending_review", outputUrl: null, retryable: false and a guidance sentence: the status is in-flight, so keep polling and do not re-run the request — a duplicate would be held too.

Input: { job_id: string }


display_asset

Scope: assets:read

Render an asset visually in chat (the user sees the media, not JSON). Renders image, video, and audio assets inline via the universal job-auto widget; image assets also surface Animate / Edit / Recreate follow-up buttons and click-to-zoom fullscreen. For purely-programmatic metadata (no rendering) prefer get_asset.

Input: { job_id: string }


get_app_run

Scope: assets:read

Fetch status of a workflow / published-app execution by id. Returns per-node states and output URLs produced so far. Used by widgets to poll progress.

Input: { execution_id: string }


favorite_asset

Scope: assets:write

Mark or unmark a gallery asset as a favorite.

Input: { job_id: string, favorited: boolean }


Jobs tools

list_jobs

Scope: jobs:read

List your recent jobs with status, job type, and output URL. Supports cursor pagination.

Input: limit, cursor, status, job_type


get_job

Scope: jobs:read

Fetch full metadata for a single job by id, including output_url, status, progress, provider, and output_data. On a failed or cancelled job the payload also carries retryable, a guidance sentence, and — when available — suggestedProvider: see get_asset for what these mean and when the fallback model appears.

A job may also report status: "pending_review" on a deployment that registers a job policy: the output exists but a human is reviewing it. That is an in-flight status, not a terminal one — keep polling rather than treating it as a failure. The payload then carries retryable: false and a guidance sentence saying so: do not re-run the request, since a duplicate would be held too. The job later resolves to completed (approved), failed (rejected, with error_hint.kind === "policy-block" and a user-safe reason) or cancelled.

A client driving the same job through the MCP tasks/* API sees that state as task status input_required. The decision belongs to a human reviewer, not to you: do not prompt the user for more parameters and do not re-run the job — call tasks/result again later, and it completes on approval or fails with a policy reason if the review rejects it.

Input: { job_id: uuid }

Job envelope (structuredContent): jobId, status, progress, jobType, assetKind (image / video / audio / null), outputUrl, outputData, errorMessage, credits, createdAt, startedAt, completedAt, plus retryable, guidance and suggestedProvider on a failed, cancelled or held job. get_asset and wait_for_job return the same envelope. Poll every 5–10 s (an image usually finishes within a minute, a video in 2–10 minutes), or call wait_for_job to block.


wait_for_job

Scope: jobs:read

Block until one of your jobs finishes and return the job envelope above.

Input: job_id, timeout_s? (seconds to wait, default 60, max 120)

If the job is still running at the deadline the result has status: "timeout" — it is not an error; call wait_for_job again or poll get_job. A held job answers pending_review at once (do not re-run it). For a long video render prefer polling get_job every 5–10 s over repeated waits. —

diagnose_run

Scope: jobs:read

Diagnose why a workflow run or single job failed. Pass a workflow execution id or a job id; the tool tries the execution first and falls back to the job. For an execution it walks node_states, surfacing each failed node with its error message, provider, and the credits actually charged. Each failure gets a best-effort classcontent_policy, validation, rate_limited, timeout, post_processing, provider_error, or unknown — and a remediation hint. Classes are heuristic (derived from the stored error string, not the error type), so treat them as guidance. Reserved credits are auto-refunded except for post_processing (post-delivery) failures; check creditsActual per node.

Input: { id: string } (a workflow execution id or a job id)


Apps tools

list_apps

Scope: apps:read

List published apps. Supports scope: "public" | "mine" and ordering by recency.

Input: scope, limit, cursor


get_app_inputs

Scope: apps:read

Returns the typed input schema for a published app (the same schema the published-app page renders). Use this before run_app to learn the available input keys and their types.

Input: { slug: string }


run_app

Scope: workflows:execute

Run a published app by slug. inputs is a FLAT object keyed by the schema input keys (from get_app_inputs). Returns an execution_id. inputOverrides (advanced) sets raw node fields such as promptPrefix / promptSuffix per run.

Input: slug, inputs?, inputOverrides?, client_request_id? (retry token — reuse it when retrying after a timeout so the run is not started or charged twice)


delete_app_run

Scope: workflows:execute

Soft-delete (archive) a published-app run. The run can be restored or permanently deleted from the Nodaro web UI at /archived-runs.

Input: { slug: string, runId: uuid }


Component tools

list_components

Scope: workflows:read

List your saved workflow components (reusable sub-graphs). Ordered by most recently updated.

Input: limit, cursor


get_component_inputs

Scope: workflows:read

Returns the typed input schema for a saved component. Use before run_component to learn available input keys.

Input: { component_id: uuid }


run_component

Scope: workflows:execute

Execute a saved component by id. inputs is a FLAT object keyed by the component’s input schema keys. Returns an execution_id.

Input: component_id, inputs?, client_request_id? (retry token — reuse it when retrying after a timeout so the run is not started or charged twice)


Models and credits tools

list_models

Scope: none (always visible)

Browse AI models available on this Nodaro instance. Returns grouped JSON with per-model capability sheets (aspect ratios, resolutions, qualities, durations, features, and — on editions with a credit system — per-variant credit pricing; community/business installs omit pricing) and a recommendations array. Models with model-family prompting guidance (e.g. Seedance 2.0) also carry a promptTips array — short prompting rules worth applying before calling generate_video / animate_image — and every model carries doctrineCovered: true only when a sourced per-family prompt doctrine exists for it. Gate “vendor doctrine · real rewrite” badges on that flag and show a generic label otherwise — never overclaim.

Input: kind (image/video/audio), mode, family, featuredOnly


check_balance

Scope: credits:read (cloud edition only)

Returns your current credit balance split by pool (subscription vs topup, with total = subscription + topup), plus tier and effectiveTier"payg" means pay-as-you-go: no subscription, but purchased credits (all models unlocked, no watermark, no daily cap). Top-up credits are valid for 12 months from purchase; subscription credits reset each billing cycle and are spent first.

On a deployment with a billing account (billing.payerAccount in the surface profile), this tool and credit_transactions refuse a session that acts as that account through a token — the deployment’s pool balance is visible only to the billing account’s own browser session and its in-app Copilot, never to a connected client — with the error payer_balance_jwt_only. Every other user sees their own figures as usual.

Input: none


credit_transactions

Scope: credits:read (cloud edition only)

Lists recent purchase-ledger rows (subscriptions, top-ups, refunds): type, amount_usd, credits_granted, tier, created_at, and receipt_url (the Stripe receipt link, when present). Note this is the purchase history — per-generation credit spend is a different ledger, served by REST GET /v1/credits/transactions, not by this tool.

Input: limit, cursor


list_node_presets

Scope: presets:read

List saved node presets — reusable named node configurations. Returns names, ids, and descriptions for discovery; fetch the full config data via the REST API / SDK (GET /v1/node-presets, GET /v1/node-presets/factory).

Input:

Field Type Notes
nodeType string Filter to one node type, e.g. "generate-image". Required when source includes factory.
source enum custom / factory / all Which presets to return. Default custom (your own saved presets).

get_node_preset

Scope: presets:read

Fetch ONE preset’s full saved configuration by id — the provider/model, prompt, aspect ratio, resolution, quality, and negative prompt it ships. Use it to apply a preset faithfully: get the id from list_node_presets, then either read these fields and pass them to the matching generate_* tool, or pass presetId directly to generate_image. Works for built-in (factory) and your own custom presets. Returns isError when the id resolves to neither.

Input:

Field Type Notes
nodeType string Required. Node type, e.g. "generate-image".
presetId string Required. Preset id from list_node_presets (factory slug like generate-image/location-board, or a custom uuid).

Upload tools

All upload tools require assets:write. Three upload strategies are provided — prefer the one suited to your client environment.

Widget uploads (preferred for Claude.ai web)

Tool Description
upload_image_widget Opens an in-chat file picker for images. Supports max_files (1–10). Auto-announces the resulting URL(s) back to the chat.
upload_audio_widget Opens an in-chat file picker for audio.
upload_video_widget Opens an in-chat file picker for video.

Browser-handoff uploads (works everywhere)

Tool Description
request_image_upload Returns an upload_page_url the user opens in their browser to drop the file, plus the deterministic public_url. Works in all MCP clients including Claude.ai web/Android.
request_audio_upload Browser-handoff for audio.
request_video_upload Browser-handoff for video.

Presigned-URL uploads (CLI clients with unrestricted bash)

Tool Description
prepare_image_upload Returns a presigned R2 PUT URL. Stream the file via curl -X PUT --data-binary @file -H 'Content-Type: <mime>'. Use in Cursor / Cline / Claude Desktop / Claude Code only — fails on Claude.ai web/Android.
prepare_audio_upload Presigned upload for audio.
prepare_video_upload Presigned upload for video.

Pipeline tools

Pipeline tools appear only when your authorization grants the relevant pipelines:read / pipelines:execute / pipelines:approve scopes (the enterprise Story-to-Video pipeline engine; Cloud/Business).

Tool Scope Description
branch_pipeline pipelines:execute Create a branch of an existing pipeline from a given stage.
start_pipeline pipelines:execute Start a new Story→Video pipeline from a prompt. Mode "auto" runs end-to-end unattended; "manual"/"guided" pause at approval gates.
chat_pipeline_stage pipelines:approve Send a chat message to the Showrunner Refinement Director for a stage awaiting approval (guided mode). Returns the assistant reply and an optional proposed_change JSON Patch.
apply_chat_proposal pipelines:approve Accept a proposed edit from a prior chat_pipeline_stage reply and advance the stage to approved.
get_pipeline_stage_chat pipelines:read List all chat turns for a pipeline stage ordered by turn number.
get_pipeline_status pipelines:read Get current pipeline state: status, current_stage, credit counters, mode, failure_reason. Poll after start_pipeline to track an Auto run.
pipeline_pending_approvals pipelines:read List stages currently awaiting approval with their output snapshots.

Shot-sequence tools

Tools for authoring narrated, time-coded motion-graphics videos (HyperFrames methodology on the Remotion engine). The execution tools (forced_alignment, resolve_shot_sequence, render_shot_sequence) require workflows:execute. The catalog discovery tools (list_shot_shapes, get_shot_shape) are ungated.

list_shot_shapes

Scope: none — always visible (all editions, free).

Return the catalog of all registered shot-sequence blueprints (id, roles, description, defaultDurationFrames). Blueprints are text/shape only and carry no pricing or credit information. Use before authoring a ShotSequenceBrief to pick the right blueprint for each beat role. Zero credits.

Input: none


get_shot_shape

Scope: none — always visible (all editions, free).

Return detailed information for one blueprint: its metadata (roles, description, defaultDurationFrames), a JSON-schema descriptor of the params it accepts, and a filled worked example. Unknown id returns an error with the list of known ids. Zero credits.

Input: id (string) — blueprint id, e.g. "titlecard-reveal". Call list_shot_shapes to browse all ids.


list_brand_presets

Scope: none — always visible (all editions, free).

Return the catalog of all 8 brand-token presets (id, label, mood, description, palette summary, fonts). A brand preset is a named palette+font pairing (e.g. midnight-violet, editorial-cream) passed as the brand param to the video director so every blueprint accent and text style stays consistent across the video. Use before authoring a brief that specifies a brand to pick the right preset id. Zero credits.

Beyond the font family, a preset’s fonts.headingType / fonts.bodyType can each carry a weight (100–900), a casing ("uppercase" / "lowercase" / "none"), and a tracking (letter-spacing, in em, -0.2 to 0.5) — independent levers for headings vs. body text. Precedence: an explicit value on the element itself wins, otherwise the brand’s headingType/bodyType applies, otherwise the blueprint’s own hardcoded default. Two edge cases to know before authoring: letter-spacing is never applied to Arabic text (it breaks cursive letter joining — Hebrew is unaffected since it doesn’t join), and a weight only renders if that weight is actually loaded for the chosen font family — requesting an unloaded weight silently snaps to the nearest one that is loaded. See Brand Typography Ramp for the full model.

Input: none


forced_alignment

Scope: workflows:execute

Align a known transcript to an audio clip (ElevenLabs forced alignment), returning per-word start/end timings. Returns a job_id; the alignment array is in output_data.alignment. Use the result to drive element reveals in resolve_shot_sequence.

Input: audio_url or audio_asset_id, transcript


resolve_shot_sequence

Scope: workflows:execute

Bake an authored shot-sequence brief together with forced_alignment word timings into a render-ready plan. Pure and synchronous — returns the plan inline (no job). Feed the plan directly to render_shot_sequence.

Input: brief (a ShotSequenceBrief), audio_url, alignment (from forced_alignment)


render_shot_sequence

Scope: workflows:execute

Render a resolved shot-sequence plan to an MP4 on Nodaro’s Remotion engine. Returns a job_id; in hosts with interactive tool cards (claude.ai), progress and the finished video render inline in the tool card. The video is also saved to your Nodaro library.

Input: plan (a resolved ShotSequencePlan from resolve_shot_sequence)


Video Director tools

One-shot tools that author + render a narrated motion-graphics video in a single call (author → speech → alignment → resolve → render). The director writes the VO script and shot-sequence brief for you. These tools are the motion-graphics (typography + shapes) path — for a bare “explainer” ask with no stated visual style, the tool descriptions instruct the LLM to confirm the method with the user first; illustrated/animated-footage explainers route to get_recipevideo-explainer instead. See Video Director for credit costs, honest Phase-1 limits, and the full brief format.

start_video_director

Scope: none — always visible (all editions, free).

Returns the motion-director doctrine: pick a genre and arc, draft the VO as cue phrases, build a ShotSequenceBrief, then drive the Phase-0 pipeline yourself. Idempotent, non-destructive, zero credits.

Input: none


create_explainer

Scope: workflows:execute (Cloud only)

Author and render a narrated, time-coded concept-led explainer video in one call. Priced as the video-director entry in list_models (authoring, speech, alignment and render stages; credits vary by deployment). Returns a job_id.

Input: topic (string, 1–8000 chars) — what the explainer should cover.


create_launch_video

Scope: workflows:execute (Cloud only)

Author and render a narrated product-launch video. Pass brief describing the product. Passing url without brief returns a deferred-capability message (real-UI capture is not yet supported). Priced as the video-director entry in list_models. Returns a job_id.

Input: brief (string, 1–8000 chars), url (string, optional — not yet supported)


Utility tools

reduce

Scope: workflows:execute

Fold a list of candidates into one result — the engine behind the canvas Choose Best node. Six strategies: pick-best-llm (an LLM judge picks the best candidate against your criteria — works on texts or images via inputKind: "text" | "image-url", with an optional llmModel judge override; economy/standard/premium credit tiers apply), concat, first-non-empty, count, vote, and merge-json. Pass the candidates as inputs (up to 1000 strings — text fragments or URLs), the strategy as strategyId, and its config as strategyConfig. The judged winner comes back with its reasoning.


ping

Scope: none (always visible)

Returns "pong" plus the authenticated Nodaro user id and the calling MCP client name. Use to verify the connector is wired up correctly.

Input: none


start_film_director

Scope: none (always visible)

Returns the Film Director skill — a multi-step prompt that instructs the LLM to drive a 10-stage director workflow (script → characters → storyboard → animation → audio → final cut) and assemble an editable Nodaro workflow on your canvas in real-time.

Input: none


start_workflow_editor

Scope: none (always visible)

Returns the Workflow Editor skill — a step-by-step guide instructing the LLM how to create, edit, and run Nodaro workflows via MCP tools.

Input: none


get_node_skill

Scope: none (always visible)

Returns documentation for a specific node type — accepted inputs, outputs, and configuration options — so the LLM can correctly populate that node when building or editing a workflow.

Input: { node_type: string }


get_recipe

Scope: none (always visible)

Discover and load multi-step Nodaro content recipes — curated, terminal-verb-anchored playbooks (e.g. video-explainer) that walk the LLM through a full multi-tool flow. Call with no argument to list available recipes (name, description, trigger phrases); pass recipe to load that recipe’s full instructions; add file to read a bundled reference file inside it. Pure content delivery, no side effects — the actions a recipe instructs the LLM to take are scope-gated by their own tools. The video-explainer recipe is for explainers told through generated animated footage; for kinetic-typography/motion-graphics explainers use start_video_director instead. When the user hasn’t specified a style, the recipe itself asks (see Content Recipes).

Input:

Field Type Notes
recipe string Recipe name, e.g. "video-explainer". Omit to list all.
file string Relative path inside the recipe folder, e.g. "references/prompts.md". Requires recipe.

See Content Recipes for the current catalog and the RECIPE.md authoring format (frontmatter fields, folder layout, bundled reference files).


get_picker_catalog

Scope: none (always visible)

Discover the valid values for parameter-picker nodes (setting, mood, person, action-fx, lens, …) — curated catalogs that contribute a descriptive clause to a downstream node’s prompt rather than calling the API. Read-only, idempotent, no side effects. Call it before writing a picker node’s value field in update_workflow_json so you set a real catalog id instead of guessing.

Input:

Field Type Notes
node_type string Picker node type, e.g. "setting" (kebab-case, from start_workflow_editor’s catalog). Omit to list every picker.
detail enum compact / full compact (default): id, label, category, term, icon. full: additionally includes each option’s description and promptHint (the prompt fragment it injects).
category string Single-dim pickers: filter options to one category.
field string Return only this dimension’s field — multi-dim pickers (person / styling / framing), and the secondary parameters of a single-dim picker (transition / character-fx: position / duration / intensity; character-motion: position / pace).

Every option carries a term at both detail levels: the short professional phrase to write into a prompt when you want a compact instruction ("whip pan left"), where label is display-only and promptHint is the full mechanism sentence. It is "" for a no-op (auto / none) option that injects nothing — so compact prompt assembly needs no detail: "full" round-trip.

See Parameter Picker Catalogs for the underlying @nodaro/shared data and the prompt-fragment helpers.

3D scenes

3D scene tools: generate_3d_scene, edit_3d_scene, and render_3d_scene create editable scenes, revise them, and export MP4s.