asset_place
ChatGPTBring assets found via asset_search onto a canvas. Pass the canvasId you're working on and one or more assetIds from the asset_search results. Places each ORIGINAL library asset as a file node in open space (no duplicate, no re-upload) and returns the new node id(s) so you can wire them into your generations. This is the ONLY correct way to reuse an existing library asset on a canvas — do NOT use url_to_canvas (it re-downloads and duplicates) or node_create with a src (it makes a broken node).
asset_search
ChatGPTSearch the current team's Files library by meaning (semantic), with exact filename/title matches ranked first. Returns up to 20 relevant assets. This tool only returns search results; it does not place assets, modify canvases, or post messages. Use when the member asks to find, reuse, bring in, or reference an asset from their files, uploads, generations, or DAM library (e.g. "use the black jacket shot", "my Product_Shot_05 photo"). For an exact filename, pass it verbatim as query, including its extension. To search only member-uploaded files, pass source: "upload"; to search only Melius-generated media, pass source: "generated"; otherwise omit source. When the member names a folder, resolve it with list_asset_folders: an exact folder name/path wins over partial matches. Then, to FILTER within it ("the red logo in my brand folder"), pass its id as folderId AND a query; to BRING IN THE WHOLE FOLDER ("add everything from my logos folder"), pass just folderId and OMIT query — that returns every asset in the folder (and its subfolders), so never invent a query for this. Omit folderId to search the whole library. If the member wants to PLACE the results, resolve/create the target canvas FIRST and pass placeOnCanvasId as context for the picker. The member selects results and confirms placement in the picker, which invokes the separate asset_place write tool; DO NOT place assets yourself. Omit placeOnCanvasId for a plain search.
asset_search_page
ChatGPTFetch the next page of asset_search results for the inline picker's 'More results' button. App-only — not for the model.
attachments_to_canvas
ChatGPTChatGPT only: add images or videos the member attached in this ChatGPT conversation to the canvas as file nodes, so they can be wired into generations as references. ChatGPT supplies each file's download_url and file_id; pass the attachments the member means, max 5 per call. In any other client, upload attachments with file_upload instead. Returns added node IDs.
audio_voice_list
ChatGPTList stock ElevenLabs voices for audio nodes in text-to-speech or audio-to-audio mode. Returns { voices: [{ voiceId, name, category, previewUrl, labels }] }. Use the filter parameters (search, gender, age, accent, language, quality, useCase) to narrow the catalog instead of scanning 100 voices — search by name when the user names a voice (e.g. 'Adam', 'Bella'), or by descriptor when the user describes one (e.g. 'villain', 'friendly female narrator'). Pass the chosen voiceId to node_create / node_update / bulk_create_nodes / run_start when running those modes — never guess voice ids. When hasMore is true, pass nextCursor as cursor with the same filters to read the next page. For team-owned voices the user calls 'custom voices', call custom_voice_list instead and pass the returned id as customVoiceId
bulk_create_edges
ChatGPTCreate multiple edges in one call. custom_text, file, and pdf nodes are source-only: use them as srcNodeId, never dstNodeId. Source node ID. When the destination needs all outputs of one type from a group, send one edge from the group ID, never one edge per child. This applies to text analysis nodes too: {"srcNodeId":"<groupId>","srcHandle":"image","edgeType":"image","dstNodeId":"<analysisNodeId>"}. Both default and unified groups expand only children of that media type. A child ID connects only that child; use child IDs for a deliberately selected subset. A group's image output excludes video last frames; use the video child's own last_frame handle for that.
bulk_create_nodes
ChatGPTCreate multiple nodes — and edges — in one call. Always call canvas_plan_layout first to get positions and edges, then pass both into this tool. Provide an id on each node you want to wire, then reference those ids in the edges array. custom_text and file nodes are source-only: use them as srcNodeId, never dstNodeId. Do NOT create group-type nodes here to group existing nodes — use node_group for that. If the response includes geometryCorrections, use placed coordinates (not your input) for show_presence bounds. Node overlaps are auto-corrected; group placements without groupId still fail on overlap — pass groupId when placing inside an existing group. Source node ID. When the destination needs all outputs of one type from a group, send one edge from the group ID, never one edge per child. This applies to text analysis nodes too: {"srcNodeId":"<groupId>","srcHandle":"image","edgeType":"image","dstNodeId":"<analysisNodeId>"}. Both default and unified groups expand only children of that media type. A child ID connects only that child; use child IDs for a deliberately selected subset. A group's image output excludes video last frames; use the video child's own last_frame handle for that.
bulk_delete_node
ChatGPTDelete multiple nodes from a canvas in one batch. First call without confirmed to surface the required confirmation, then retry with confirmed:true only after the user explicitly approves — if the user does not approve, do not retry.
bulk_run_download
ChatGPTCreate or replace the stored ZIP export of leaf outputs from a completed bulk run and return a presigned download URL. May attach the export to the connected agent session. The bulk run must be finished — use bulk_run_get to check status first. Does not regenerate or change the source media
bulk_run_get
ChatGPTGet the current state of a bulk run (returns immediately). Prefer bulk_run_wait after bulk_run_start; use bulk_run_get only for one-shot status checks, or with includeInputs: true to read in one call what every run sent to the model and which versions it wrote. Status: pending, running, finished, failed, cancelled. Once the run is final it carries credits (charged, refunded); a final run without credits is one whose charges you cannot see, so say so. Read the run before answering what a result costs or whether its credits come back, and state a charge or refund only from its credits. A generation that delivered any output is charged and is not refunded, even if the result isn't what the member wanted, the member calls it an error, or some of its outputs failed: say it stays charged, and offer both emailing support@melius.com and trying another model for a different result. A generation that delivered nothing is refunded automatically, and any refund shows in the run's credits (credits.refunded). Never promise or predict a refund. Refunds show in Team settings → Usage → Generation history.
bulk_run_start
ChatGPTRun all (or selected) nodes on a canvas in dependency order — use it whenever the workflow has more than one generation node (a 1-element array is fine), and to retry any node that is part of a multi-node workflow. To run a template box, pass its id (the groupType 'template' node) — the backend runs the whole hidden workflow; you never enumerate its internal nodes. To produce several outputs, set variations — never duplicate nodes. To deliver a GIF, set postProcess: "video-gif" — the run's final video converts in place once it finishes. To deliver new images with a transparent background, set postProcess: "remove-background" — each final image has its background removed in place. Returns a bulk run ID — use bulk_run_wait to block until complete (preferred), or poll bulk_run_get manually. For stitches with audio, follow the audio-overlay delivery rules in your final reply, including reruns
bulk_run_wait
ChatGPTWait for a bulk run to finish, fail, or be cancelled. Returns the final bulk run with per-node errorMessage on any failed entries. If the bulk run is still generating when the wait window elapses, returns the latest bulk run with waitTimedOut: true (not an error) — call bulk_run_wait again with the same bulkRunId to keep waiting; never start a new run or regenerate in response. Call once after bulk_run_start instead of polling bulk_run_get in a loop. Once the run is final it carries credits (charged, refunded); a final run without credits is one whose charges you cannot see, so say so. Read the run before answering what a result costs or whether its credits come back, and state a charge or refund only from its credits. A generation that delivered any output is charged and is not refunded, even if the result isn't what the member wanted, the member calls it an error, or some of its outputs failed: say it stays charged, and offer both emailing support@melius.com and trying another model for a different result. A generation that delivered nothing is refunded automatically, and any refund shows in the run's credits (credits.refunded). Never promise or predict a refund. Refunds show in Team settings → Usage → Generation history.
canvas_autoformat
ChatGPTTidy canvas items into a grid, like the canvas Autoformat button, in one call instead of moving nodes one at a time. Pass nodeIds (siblings, laid out in the order given) or groupId (that group's contents). Optional layout sets the column count, gaps and group padding; values left out use the team's Autoformat spacing. Items keep their current top-left corner, and a group keeps its position and resizes to fit
canvas_content
ChatGPTRead live canvas nodes, edges, sticky notes (body, geometry and groupId), and modelPresets (the canvas-wide default model and mode per category). A focused read includes the node's incident edges; history includes saved versions and assets. For a whole-canvas read, pass canvasId only; omit nodeId and includeAllVersions. For one node, copy its ID from a tool response or an explicit node reference; never substitute canvasId, invent an ID, or pass the all-zero UUID. For saved history, supply that real nodeId and includeAllVersions: true; discover the node first if its ID is unknown. Use nodeQuery to find named character/product references across the whole canvas, including outside a truncated sample. It matches titles case-insensitively and returns at most 10 compact candidates in nodeLookup, with empty nodes/edges (not an empty canvas). Read a candidate with nodeId to inspect its current asset/version before using it. Continue with nextOffset only when needed to resolve the reference.
canvas_create
ChatGPTCreate a canvas in a project. Title must be unique within the project (case-insensitive) — use canvas_list to check existing names first
canvas_delete
ChatGPTDelete a canvas and all its nodes/edges
canvas_get
ChatGPTGet canvas metadata (title, projectId, settings). For full content use canvas_content instead
canvas_list
ChatGPTList canvases in a project. Returns { data: [...], total }
canvas_plan_layout
ChatGPTCompute positions for new nodes before creating them — reads the current canvas state and returns { positions, edges } that avoids overlapping existing content and respects edge topology (left→right DAG). Edge metadata is returned unchanged so explicit handles survive into bulk_create_nodes. Call this before bulk_create_nodes to get correct positions and edges, then pass both into bulk_create_nodes. This is the only reliable way to place nodes without overlap on a busy canvas.
canvas_update
ChatGPTRename a canvas
cast_batch_prepare
ChatGPTOnly for an explicitly requested Cast workflow. For two or more requested Cast videos, prepare every script and setting in one review card with a combined credit estimate. Reuse confirmed selections and honor explicit settings. Does not generate. Show the review, then call cast_batch_run once for a generation request; no extra inline or chat approval. Draft-only requests stop here.
cast_batch_result
ChatGPTOnly for an explicitly requested Cast workflow. Check all exact items from cast_batch_run together, including when the member explicitly asks for progress. Returns data without opening another card. Returns ready, failed, pending and unsubmitted counts, video previews/download references and platform links. Status failures remain unknown, never reported as still generating or failed. Never starts replacement videos; may finish already-requested subtitles. Apps cards call this automatically; text clients repeat until terminal.
cast_batch_run
ChatGPTOnly for an explicitly requested Cast workflow. Generate a requested batch of 2–20 Cast videos with ONE native MCP approval and ONE result card. First show cast_batch_prepare and use its normalized input unchanged. Validates all videos and total estimated budget before submitting any; existing credit and queue limits apply. Stops further submissions on errors or cancellation, preserving accepted references. Not idempotent: never retry an ambiguous submission. The card shows all results and a link to Cast in the platform. Use this instead of separate cast_run calls for a batch.
cast_download
ChatGPTOnly for an explicitly requested Cast workflow. Get an authorized download link for the video in this exact run. Can finalize already-requested paid subtitles and update the saved output before returning the link; also records the download. The inline video has a Download video button. Never start a replacement video to retrieve a download.
cast_event
ChatGPTRecord a bounded Cast inline interaction for analytics. Does not generate media or modify existing work.
cast_library
ChatGPTOnly for an explicitly requested Cast workflow. Browse avatar choices ONLY when the member asks to browse or has not named/chosen an avatar. If their prompt names Loopy or any avatar, do not call this tool: pass avatar: {name: 'Loopy'} to cast_prepare or use cast_resolve_selection. The name in the initial request is already their choice. Show saved team and curated avatars for the member to choose. End your turn after showing the picker; a library result is not a confirmed avatar. Do not call cast_prepare or choose an avatar until the member confirms. Browse backgrounds only if explicitly requested; otherwise infer the scene from chat. If a member has already selected an avatar by name but its ID is missing, use cast_resolve_selection; never reopen this picker for an ID lookup. Apps hosts keep unselected IDs private to the picker; other hosts receive numbered choices.
cast_options
ChatGPTOnly for an explicitly requested Cast workflow. Internal planning data for the chat agent: discover available Cast models, voice compatibility, resolution, aspect ratios, duration limits, subtitle styles and waits. Call before drafting. Infer a compatible configuration from the member's prompt; do not show a model picker or ask them to configure technical settings.
cast_prepare
ChatGPTOnly for an explicitly requested Cast workflow. Prepare a read-only Your cast review showing avatar preview, full script, voice, background/prop, aspect ratio, model, resolution, subtitles, template and estimate. Show it before native approval; text-only clients present the same details in chat. For a request to generate, continue from the visible ready review to cast_run with returned input; do not ask for another chat confirmation. cast_run triggers native client tool permission (manual or always allow). Draft/review/estimate-only requests stop here. Pass avatar: {name: 'Loopy'} directly for a named avatar; no picker needed. Honor explicit settings, otherwise use Seedance 2.5 and Auto and infer from the brief. Returns normalized input and duration/credit/wait estimates. Failed preflight returns a tool error for correction, not a usable review. Fix validationError without changing explicit requirements; clarify if the estimate is unavailable or exceeds a stated budget. Once ready, reuse that review and input; do not prepare unchanged input again.
cast_prop
ChatGPTOnly for an explicitly requested Cast workflow. When the member asks to find or choose a prop from their DAM/Assets, search image assets using the same semantic and exact-name ranking as asset_search. Pass an exact filename unchanged as search. Resolve named folders with list_asset_folders, then pass folderId; tags and source filters apply only when requested. Wait for the member's selection; reuse propAssetId without downloading, re-uploading or placing it on a visible canvas. Without Assets access, offer upload/skip. An already pasted/attached or Cowork project image goes directly to cast_prop_upload without opening this picker.
cast_prop_upload
ChatGPTOnly for an explicitly requested Cast workflow. Upload a pasted/chat image, Cowork project image or supplied local image as a Cast prop. For a pasted or attached Claude image, use the client's file tools to inspect /mnt/user-data/uploads/ for the actual file. For a Cowork project image, check the client's working directory first, then /mnt/user-data/uploads/ if needed. If the client exposes both a sandbox path and its mapped Mac path, preserve that mapping and use the verified Mac path for a local MCP backend. Never shorten a project path to Desktop or infer its parent directory. Use the exact discovered path or the local path the member supplied; never guess filenames or assume the remote MCP server shares the client's filesystem. If the client cannot expose or transfer the image bytes, explain that limitation and ask for an accessible attachment instead of generating a replacement. This tool creates its own hidden upload target; do not create a canvas or file node yourself. Returns assetId when complete, or pending_curl using the regular file_upload handshake: transfer the actual file inside the client, then call file_upload_complete and use its assetId as propAssetId. Keep transfer commands private. Use cast_prop for DAM images rather than downloading and re-uploading them.
cast_render
ChatGPTOnly for an explicitly requested Cast workflow. Generate four avatar or background images from a brief. Uses Cast's generation recipe and credits. Returns a run; inline cards wait automatically. In text-only clients use cast_wait, then cast_result once to show the choices. Show the choices and wait for the member to select one before saving or making a video.
cast_replacement_prepare
ChatGPTReview replacing one or more characters, props and backgrounds together in a supplied video. Use an ordered replacements array with one image and optional target description per item. Returns measured duration, all edit models with duration/reference-count eligibility reasons, normalized input, one quote and stable attemptId. Does not generate. Show every source/reference and target plus the complete quote before run. Never trim or switch an explicit model silently.
cast_replacement_run
ChatGPTStart the requested paid video edit after showing cast_replacement_prepare. Native tool permission is the approval boundary; do not add a chat confirmation. Keep attemptId and exact input unchanged when recovering a lost response. Check generationId with cast_wait/result/download. A new attemptId buys a new generation. Never run for estimate-only requests or bypass a denial.
cast_replacement_upload
ChatGPTUpload the supplied video or replacement image as a standalone asset; do not create a canvas. Source accepts MP4/MOV, reference accepts images. Server inspects actual media in prepare. For pending_curl perform the private client-side transfer then file_upload_complete with returned metadata, ETag and size. Keep signed URLs and transfer commands private.
cast_resolve_selection
ChatGPTOnly for an explicitly requested Cast workflow. Look up an existing Cast avatar or background named in the member's prompt, including their first request: 'make a UGC video of Loopy talking about chemistry class' already selects Loopy. Match names ignoring case and return the exact ID without a picker. No prior inline selection is required. Also recovers lost selection context. Never use cast_library for a named-avatar lookup. Clarify only missing or ambiguous names.
cast_result
ChatGPTOnly for an explicitly requested Cast workflow. Open a result using generationId for a video, or the original run for image choices. Can start the single already-requested paid subtitle pass and update the saved output; repeated checks reuse that pass. Do not pass canvas/node IDs when a generationId is available. Generating and processing mean keep polling this same run; do not start another. Preserve option numbers when some images fail. Wait for the member's selection before calling cast_save_choice. The inline result includes a video download button. For a finished video, add one brief completion sentence; discuss settings or repeat the script only when requested, and surface any warnings. Use cast_wait for background waiting or progress questions; do not open duplicate cards while an inline card is already tracking this run.
cast_run
ChatGPTOnly for an explicitly requested Cast workflow. Run one requested Cast UGC video. First use cast_prepare and show its cast/script/settings review. When the member asks to make a video and that review is ready and visible, CALL THIS TOOL with its input; do not ask 'shall I generate?' in chat or stop after quoting the estimate. This call is the native MCP approval boundary: the client can ask permission or always allow it. Starts a paid generation subject to credits/plan limits; honor stated count/budget and stop on denial. Never call for draft, review or estimate-only requests. Accepts avatar: {name: 'Loopy'} directly. Defaults to Seedance 2.5 and Auto; honor explicit settings. Returns the accepted run and an automatically updating video card in Apps clients. Submit every requested video before waiting for any render: prepare the full batch and combined estimate, submit each once, retain all accepted references. Do not poll merely to duplicate the card. For an explicit progress question, use cast_wait with timeoutSeconds: 1 and answer from the fresh result. Text-only clients poll after all submissions and show each finished result. Not idempotent: never retry or switch to cast_video after a denied call or ambiguous start failure.
cast_save_choice
ChatGPTOnly for an explicitly requested Cast workflow. Save the avatar or background the member selected into their team's Cast library. Call only after a member chooses a numbered image and a name; an inline picker can perform this action directly. Use the returned avatarId or backgroundId for cast_run.
cast_template
ChatGPTOnly for an explicitly requested Cast workflow. Only when requested: browse the current database-backed Cast catalog, or pass name for an explicitly named template (exact title, ignoring case) or templateId to read its current revision, script sections and direction. An exact lookup is a confirmed selection; continue to cast_prepare without asking to choose it again. Clarify unavailable or duplicate names. The chat agent must fill placeholders and supply the final script; this does not generate scripts. Pass the returned scriptTemplate reference and creationSettings to cast_prepare.
cast_video
ChatGPTCompatibility name for cast_run with the same input, native permission and paid generation behavior. Prefer cast_run for new requests. Call only one of these tools per video; never switch names to retry an ambiguous start or bypass denied permission. Submit every requested video before waiting for any render. Apps clients get an automatically updating result card; text clients poll after all submissions.
cast_voice
ChatGPTOnly for an explicitly requested Cast workflow. Only when the member explicitly asks to browse or choose voices: show inline audio previews, team voices, searchable stock voices, and Auto. Otherwise infer from chat and default to Auto without opening this picker. Wait for their choice when shown.
cast_wait
ChatGPTOnly for an explicitly requested Cast workflow. Wait on a video generationId, or the exact legacy/image run object. Can start the single already-requested paid subtitle pass and update the saved output; repeated checks reuse that pass. Submit every requested video before waiting for any render. Use for an explicit progress question even when an inline card exists; set timeoutSeconds: 1 for a quick check and answer from the returned status. Never tell the member to keep watching a card instead of checking. Also use for background waiting in text clients. Each call returns within a short wait window to avoid client timeouts. For background waits in text clients, if waitTimedOut is true, call cast_wait again with the same generationId (or original legacy run) without asking permission in chat. For an explicit progress question, answer with the current status after this one check. A failed status is terminal: show its error and stop. Never recreate a run ID, start another generation, or guess that a timeout means approval is pending. Once ready, show cast_result only if there is no existing inline card; otherwise answer briefly and let that card show the video. Cancellation stops waiting, not the generation.
create_agent_team_skill
ChatGPTSave a reusable team skill (a named set of agent instructions the user can apply from chat). Only call this when the user explicitly asks to save, create, or remember a skill — never proactively.
creative_download
ChatGPTPrimary tool for downloading creative outputs. Creates a new stored ZIP export of generated creatives (or specific nodes) from a canvas and returns a presigned download URL. May attach the export to the connected agent session. Does not regenerate or change source media. Use this instead of run_download or bulk_run_download unless you need outputs from a specific run
custom_font_list
ChatGPTList the team's uploaded custom fonts for use with the Better Fonts model (better-font-32b). Returns { data: [{ id, familyName, previewUrl, ... }] }. To render text in one of these fonts, set the better-font-32b node's modelConfig.font to { source: "custom", familyName } using the exact familyName returned here. For a standard/global typeface the team has NOT uploaded, skip this tool and pass { source: "google", familyName } with any Google Fonts family name (e.g. "Playfair Display", "Inter"). Call this whenever the user asks for text rendered in a specific brand or custom font — never guess a custom family name.
custom_voice_list
ChatGPTList the team's saved custom voices (the 'Custom' tab of the voice picker — voices the team cloned, designed, or imported from ElevenLabs). Returns { voices: [{ id, name, description, previewUrl, ... }] }. Pass the chosen voice's id as customVoiceId to node_create / node_update / bulk_create_nodes / run_start when running text-to-speech or audio-to-audio. Use this whenever the user references a 'custom voice', a team-specific voice, or names a voice that does not appear in audio_voice_list — never guess. Stock and custom voices use distinct id namespaces
display_canvas
ChatGPTRender an interactive visual preview of a canvas inline in the chat. Shows all nodes, edges, and media thumbnails with an 'Open in Melius' link
edge_create
ChatGPTConnect two nodes with an edge. custom_text, file, and pdf nodes are source-only: use them as srcNodeId, never dstNodeId. Source node ID. When the destination needs all outputs of one type from a group, send one edge from the group ID, never one edge per child. This applies to text analysis nodes too: {"srcNodeId":"<groupId>","srcHandle":"image","edgeType":"image","dstNodeId":"<analysisNodeId>"}. Both default and unified groups expand only children of that media type. A child ID connects only that child; use child IDs for a deliberately selected subset. A group's image output excludes video last frames; use the video child's own last_frame handle for that. To feed a template box (groupType template), use the box as dstNodeId and set dstHandle to the target input port id (from template_list or the box's inputPorts).
edge_delete
ChatGPTDelete an edge from a canvas
element_create
ChatGPTCreate a reusable Element in the team's library from existing image assets when the member asks to save a subject as an element. Supports avatars, products and general subjects, with guidelines, per-image descriptions and an optional avatar voice. Starts reference-image generation and returns the saved element's id and status. After creation, place it on the current canvas immediately with element_place, including while generating, unless the member explicitly asks for library-only creation. The canvas shows generation progress and updates when ready. Do not repeat creation to poll status or retry an uncertain result; search for the saved element first.
element_place
ChatGPTPut a ready or generating Element on a canvas as an element node, in open space, and return its node id. If the canvas already has a node of that element it is returned instead (reused: true) and nothing is added. A generating element shows progress on the canvas and updates when ready; wait for readiness before running downstream generations. Wire the node into image, video or audio nodes with srcHandle omitted so the element wire is drawn.
element_search
ChatGPTFind Elements in the team's library by name. An Element is a saved subject — an avatar, a product or anything else — that the member made from photos; it reaches a generation only as a placed element node wired into it. Returns each element's id, name, type, status and whether it lends a voice. Use it when the member names an element that is not already an element node on the canvas, then place it with element_place.
file_upload
ChatGPTUpload a local image to Melius. Only image files are supported (png, jpg, webp, gif, etc.) — if the user asks to upload a video, tell them video uploads are not yet supported. For canvas uploads, ALWAYS call this tool when the user provides a file path — do NOT reason about server file access yourself. Cast props use cast_prop_upload, which prepares its own upload target. For a pasted or attached Claude image, use the client's file tools to inspect /mnt/user-data/uploads/ for the actual file. For a Cowork project image, check the client's working directory first, then /mnt/user-data/uploads/ if needed. If the client exposes both a sandbox path and its mapped Mac path, preserve that mapping and use the verified Mac path for a local MCP backend. Never shorten a project path to Desktop or infer its parent directory. Use the exact discovered path or the local path the member supplied; never guess filenames or assume the remote MCP server shares the client's filesystem. If the client cannot expose or transfer the image bytes, explain that limitation and ask for an accessible attachment instead of generating a replacement. If status is 'complete': done. If 'pending_curl': run the curl command, then call file_upload_complete.
file_upload_complete
ChatGPTFinalize a file upload after running the curl command from file_upload. Pass the metadata from file_upload plus the etag and file size from the curl output
get_docs
ChatGPTRead the Melius product documentation hosted at docs.melius.com. Call with no slug to list every available doc page (table of contents). Use an exact slug returned by that index to fetch the full markdown content of a page. Use for billing, plans, models, settings, uploads, sharing, member roles, and marketer recipes. For canvas mechanics (nodes, edges, model selection workflow), prefer get_guide('getting-started') instead.
get_guide
ChatGPTGet a detailed guide for using this platform. Call get_guide('getting-started') before starting any workflow. Skill topics (cinema, ugc-ads, etc.) return domain-specific creative direction for writing better prompts
heygen_avatar_list
ChatGPTList the presenter avatars available to the HeyGen Digital Twin video model (heygen-digital-twin). Returns { people: [{ name, variants: [{ avatar, description }] }], totalPeople, totalAvatars }, one entry per presenter, each with their poses and settings. Pass a chosen avatar as modelConfig.heygenAvatar on node_create / node_update / bulk_create_nodes / run_start; a run of that model fails without one, and avatar ids must never be guessed. Use search to narrow by name, pose, or setting. The catalog carries no gender, age, or ethnicity metadata, only names and poses. Do not infer these characteristics from names or avatar ids. If the user requires them, explain the catalog limitation and ask the user to choose a presenter. When the user wants several DIFFERENT presenters, take one variant from each of several people entries. Different variants of one person are the same presenter in a different pose.
import_agent_context
ChatGPTMaterialize the team's agent-context images on the canvas as a default group with matching description text nodes. Use this when the user references their team's brand/style/reference images and they aren't yet on the canvas. The team's active context is resolved automatically — pass contextId only if you have it explicitly. Idempotent: calling twice returns the existing group. The output references array maps each imageNodeId to its matching descriptionNodeId and includes preformatted imageMention/descriptionMention strings. When wiring imported references downstream, paste those exact mention strings into prompt lines like "Description for @[image]{imageNodeId} is @[description]{descriptionNodeId}"; do not substitute filenames, raw UUIDs, or raw description text.
list_agent_team_skill_assets
ChatGPTFetch the current team's uploaded image assets for a saved agent skill. Use this when a selected skill has image assets and the user asks what assets are in the skill, or when those assets should influence a generation without being shown as chat attachments or placed on the canvas. Pass the skill's /command handle in slashCommand when available. The tool returns asset filenames, descriptions, and signed image URLs, but it does not itself attach pixels to the chat turn. On a run where a team skill is applied, run_start exposes an imageUrls parameter and the returned runStartImageUrl values can be passed to it as hidden generation inputs; doing that does not create file nodes or visible canvas edges.
list_agent_team_skills
ChatGPTList saved agent skills for the active Melius team, including their slash commands and instructions. Use this when the user asks what team skills exist or wants to apply one by name.
list_asset_folders
ChatGPTList the current team's Files folders (id, name, full path, and file count). Use before asset_search when the member asks to look in a specific folder (e.g. "search my logos folder", "look in brand assets"). A case-insensitive exact name or full path wins over partial matches. Pass the best match's id as asset_search's folderId to scope the search to that folder and its subfolders. If several matches remain at the best tier, ask the member which one using their full paths; if none match, say so.
load_agent_team_skill
ChatGPTLoad a saved agent skill from the active Melius team by skillId or slashCommand. Returns the skill instructions and uploaded asset metadata.
media_verify
ChatGPTInspect the actual saved audio/video before claiming a narration or loop repair succeeded. Decodes the export, checks requested minimum duration, detects silent/missing audio, transcribes speech when requested, and checks loop boundaries only when requested. Returns passed, failed, or unverified for the exact version. No media generation or generation credits. Keep failed/unverified exports downloadable and explain the findings; never regenerate paid inputs to fix a verification or download failure without permission. Limits: 180 seconds and 100 MiB per export. Automated transcription and loop judgments can be uncertain. Starts a new inspection workflow for the exact team-owned asset; repeating the call starts another inspection job. Does not accept arbitrary media URLs or modify the source media.
model_defaults
ChatGPTShow which model is used when none is specified — the platform Auto default for each category and variant, including resolved default capabilities like supportedDurations, supportedAspectRatios, supportedResolutions, and requiredInputs
model_list
ChatGPTList available AI models for a category. Returns models with their variants, requiredInputs, and capabilities. MUST be called before run_start or bulk_run_start — never guess model names. For audio, also call audio_voice_list when using text-to-speech
node_create
ChatGPTCreate a node on a canvas. Changes sync to connected browser clients in real-time. When inputEdges is available and the new node consumes existing canvas nodes, pass it so the node is placed downstream and connected in this call; do not create it first and call edge_create later. For file nodes: create with nodeType 'file' and mediaType 'image' first (without src), then call file_upload with the nodeId to add the image. NEVER pass src for file nodes — it creates a broken node that displays the image but cannot be used for generation. Always use the file_upload workflow for ANY image from ANY source (chat attachments, project files, local paths).
node_delete
ChatGPTDelete exactly one node from a canvas. First call without confirmed to surface the required confirmation, then retry with confirmed:true only after the user explicitly approves — if the user does not approve, do not retry. Use bulk_delete_node instead when deleting multiple nodes
node_group
ChatGPTThe only correct way to group nodes. Computes group bounds from node positions and converts child coordinates correctly. Never create a group with node_create or bulk_create_nodes and reparent children manually. Group type. Use "default" for organizing nodes, including mixed media. Preserve "unified" when explicitly requested. Both default and unified groups expose outputs by media type; no conversion or ungrouping is needed to use a group output. A child ID connects only that child.
node_set_text
ChatGPTSet literal text content on an existing custom_text node. Use this when you need to write or replace the node's displayed text
node_set_version
ChatGPTSwitch a node's active version — changes which generated output is displayed. Use canvas_content with nodeId + includeAllVersions first to see available version IDs
node_ungroup
ChatGPTUngroup ordinary groups. Equivalent to the canvas ungroup action / shortcut (Cmd+Shift+G). Reparents direct children while preserving their visual positions. Template boxes cannot be ungrouped. Do NOT use when a unified style/reference group exceeded maxImageInputs and the user chose to ungroup for a subset — the user ungroups in the canvas themselves; you only wire file IDs they name after re-reading canvas_content.
node_update
ChatGPTUpdate a node on a canvas. Only provided fields are changed. Changes sync to connected browser clients in real-time
note_create
ChatGPTCreate a sticky note on a canvas, for labels or annotations. Width and height are set separately (w 240–960, h 120–960); a short wide note works as a label bar. Text stays at its chosen size when the note is resized and long text scrolls inside the note. Read canvas_content first to align it with existing content. Returns the saved note with its ID and geometry; changes sync to open canvases.
note_update
ChatGPTEdit a sticky note's text, position or size. Read canvas_content with noteId first. Change only supplied fields; preserve group membership and styling. Coordinates are relative to the note's groupId when grouped. Each side given is clamped (w 240–960, h 120–960); a side not given keeps its stored size. Returns the saved note.
plan_update
ChatGPTReturn the supplied workflow plan as structured data for the calling assistant to present in the conversation. Validates and echoes the title and steps; it does not save a plan, update a pinned checklist, send notifications, or modify a canvas. Call before the first canvas mutation with all intended steps, then again after each step transition (prior step "complete", next step "active" in the same call). Reuse stable step ids across updates. Skip for pure Q&A or read-only inspection.
project_create
ChatGPTCreate a project with an empty canvas. Returns the project with its canvasId. Title must be unique within the team (case-insensitive) — use project_list to check existing names first
project_get
ChatGPTGet a project by ID. Returns id, title, description, canvasId
project_list
ChatGPTList projects in the current team
release_presence
ChatGPTRelease your presence claim on a canvas — the overlay disappears for all viewers. Pass the presenceId that show_presence returned. Call when you've finished the user's task on this canvas, and before show_presence when switching focus. Returns removed: false when no claim with that presenceId was showing — check you passed the presenceId show_presence returned. removed: null means the server could not tell.
run_download
ChatGPTCreate or replace the stored ZIP export for a finished node run and return a presigned download URL. May attach the export to the connected agent session. The run must be finished — use run_get to check status first. Does not regenerate or change the source media
run_get
ChatGPTGet the current state of a node run (returns immediately). Prefer run_wait after run_start; use run_get only for one-shot status checks. Status: pending, running, finished, failed, cancelled. When present, inputs lists the sources the run sent to the model (node, version, asset, label at run time, role, position) and outputVersionIds the versions it wrote; a run without them has no record. Once the run is final it carries credits (charged, refunded); a final run without credits is one whose charges you cannot see, so say so. Read the run before answering what a result costs or whether its credits come back, and state a charge or refund only from its credits. A generation that delivered any output is charged and is not refunded, even if the result isn't what the member wanted, the member calls it an error, or some of its outputs failed: say it stays charged, and offer both emailing support@melius.com and trying another model for a different result. A generation that delivered nothing is refunded automatically, and any refund shows in the run's credits (credits.refunded). Never promise or predict a refund. Refunds show in Team settings → Usage → Generation history.
run_image_background_removal
ChatGPTRemove the background from an existing image node, producing a transparent PNG. This is the only operation that yields real transparency — a generation prompt asking for a transparent or white background returns an opaque image — and it works on an uploaded file node as well as a generated image node, keeping the subject's pixels as they are. The output is checked for real alpha before the version activates; an opaque or empty result fails the run instead of being delivered. A version whose sourceToolName is pixelcut, birefnet-v2 or rembg already has its background removed: when the user asks for that again, say it is already transparent and point them to that version instead of re-running; the call is rejected unless redo is set, which you pass only when the user explicitly asks to redo the removal. The node must already hold a finished image. Returns a run ID — call run_wait to block until complete. The finished run activates the background-removed version automatically; do NOT call node_set_version afterward. Costs 20 credits
run_latest
ChatGPTGet the most recent run for every node on a canvas — useful for checking which nodes have been generated
run_magic_resize
ChatGPTResize an existing image into multiple aspect ratios in one call. Give the source image node and the target ratios — this creates a magic-resize node to its right, wires the image in, and runs it. The source must already have a finished image generation (a ready asset). Returns the created nodeId plus a run ID — call run_wait with the returned nodeId to block until the variants are ready. Magic resize is a terminal node: the user downloads each variant from the node, so do NOT wire its output into other nodes. It costs 100 credits per run plus 300 per ratio; quote that total when the member asks the price. In the Melius app the member approves the run and its price before it starts, unless they turned on Auto-run; the resize node appears first with those ratios selected, and a denied run leaves it on the canvas for the member to run. The result's creditCost is the exact amount charged
run_start
ChatGPTStart an AI generation run on ONE node — use it for a single standalone node; for more than one node, or any node in a multi-node or dependency workflow, use bulk_run_start instead. Uses existing generation credits and updates the node's output; repeating a start can submit and charge another run. Returns a run ID — use run_wait to block until complete (preferred), or poll run_get manually. IMPORTANT: call model_list first to get valid model names and check the variant's requiredInputs — if it requires image_url, connect an image edge from the source file node to this node before running
run_video_background_removal
ChatGPTRemove the background from an existing video node using Bria Video Background Removal 3.0, producing a transparent WebM by default. The video must already have a finished generation (an asset to process). Returns a run ID — call run_wait to block until complete. The finished run activates the background-removed version automatically; do NOT call node_set_version afterward. Costs ~168 credits per second of video. Max input duration is 30 seconds
run_video_gif
ChatGPTConvert an existing video node into a GIF. Works on video nodes and on file nodes that hold an uploaded video. The video must already have a finished generation (an asset to process) and be at most 30 seconds long. A GIF is always made this way: when the user asks for a GIF and no video exists yet, generate a short video first, then convert it here. Returns a run ID — call run_wait to block until complete. The finished run activates the GIF version automatically; do NOT call node_set_version afterward. The GIF becomes the node's active output, so the node stops working as a source for video edges and other video tools until the user switches back to the video version. Costs 60 credits
run_video_subtitles
ChatGPTAdd subtitles to an existing video node. The video must already have a finished generation (an asset to process). Returns a run ID — call run_wait to block until complete. The finished run activates the subtitled version automatically; do NOT call node_set_version afterward. Costs ~120 credits per minute of video
run_video_trim
ChatGPTTrim an existing video to the range startTimeMs–endTimeMs. Works on video nodes and on file nodes that hold an uploaded video. The trimmed clip becomes a new version of the same node, so every node wired to it receives the trimmed clip; the original stays in the node's version history. Use it when a run is refused because a clip is too long, with an error like "<model> accepts input videos up to 15s each. This clip is 15.8s": ask the user before trimming, naming the clip, its length and the limit, and trim only after they agree, from 0 to the limit unless they choose another part. Returns a run ID — call run_wait to block until complete, then start the run again. The finished run activates the trimmed version automatically; do NOT call node_set_version afterward. Free
run_wait
ChatGPTWait for a single node run to finish, fail, or be cancelled. Returns the final node run with errorMessage on failure. If the run is still generating when the wait window elapses, returns the latest run with waitTimedOut: true (not an error) — call run_wait again with the same runId to keep waiting; never start a new run or regenerate in response. Single-node equivalent of bulk_run_wait — call once after run_start instead of polling run_get in a loop. Once the run is final it carries credits (charged, refunded); a final run without credits is one whose charges you cannot see, so say so. Read the run before answering what a result costs or whether its credits come back, and state a charge or refund only from its credits. A generation that delivered any output is charged and is not refunded, even if the result isn't what the member wanted, the member calls it an error, or some of its outputs failed: say it stays charged, and offer both emailing support@melius.com and trying another model for a different result. A generation that delivered nothing is refunded automatically, and any refund shows in the run's credits (credits.refunded). Never promise or predict a refund. Refunds show in Team settings → Usage → Generation history.
show_presence
ChatGPTREQUIRED before every node-scoped canvas action (canvas_content with a nodeId, node_, edge_, run_*, bulk_run_start, template_apply, node_group, node_ungroup). Renders a dashed cyan claim region with a status pill so the user can see what you're doing in real time. Pass agentName to put your own name on that pill. Pass nodeIds when working on existing nodes; pass bounds (x, y, w, h in canvas coordinates) when about to create nodes in empty space — use the rect from canvas_plan_layout. Always call release_presence before show_presence when switching focus, so the previous claim clears first. Returns a presenceId: pass it to every later show_presence and release_presence call for this task. Never call show_presence with only canvasId and status; wait until you have nodeIds for existing-node work or bounds from canvas_plan_layout for empty-space work. The first broad canvas_content call may run without presence because it discovers the claim target.
team_list
ChatGPTList teams you belong to
template_apply
ChatGPTApply a template to a canvas — drops a ready-made workflow as a single collapsed box with input/output ports. Find the template with template_list, then call canvas_content immediately before applying, even on an empty canvas. Auto-positions to avoid overlapping existing canvas content. Pass inputs to wire the box's input ports in the same call so it is runnable immediately
template_list
ChatGPTList available canvas templates — every global template plus any template created by your team. Each template is a ready-made workflow that applies as one collapsed box with declared input/output ports
update_agent_team_skill
ChatGPTUpdate a saved agent skill in the active Melius team. Only call this when the user explicitly asks to change, rename, or edit an existing team skill.
url_to_canvas
ChatGPTDownload image or video URLs and add them as file nodes on the canvas. Use this when web_fetch returns imageLinks or links pointing to media files the user wants on the canvas — for example, product photos, reference images, or video clips. Supports image/* and video/mp4, video/webm, video/quicktime. Unsupported types are skipped. Nodes are placed in a single row whose origin is shifted past existing canvas content, so successive calls stack into clean rows instead of overlapping. Returns added node IDs so you can wire them into generation nodes.