A side-by-side look at the Creative Claw and OpenFlow MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.
Verdict: choose Creative Claw for multimedia process work over a hosted endpoint; choose OpenFlow for multimedia process over a hosted endpoint. You can also run both side by side in one mcpServers block.
mcp_ui_action, read_settings, update_settings.generate_with_face, generate_image, music_generate.Rows where the two servers differ are marked.
| Spec | ||
|---|---|---|
| Category | Multimedia Process | Multimedia Process |
| Quality signal | 59/100 · Good | 57/100 · Good |
| Install command | Confirmed | Confirmed |
| Transport | Remote HTTP/SSE | Remote HTTP/SSE |
| Auth | Not declared | Not declared |
| Pricing | Not declared | Not declared |
| Required env vars | None listed | None listed |
| Verified owner | Community listing | Community listing |
| GitHub stars | 2 | 8 |
| Directory activity | 3 views 0 installs 0 upvotes | 1 views 0 installs 0 upvotes |
| Tools | 55 | 45 |
| Full listing | View Creative Claw | View OpenFlow |
mcp_ui_actionRoute Creative Claw UI-only actions, including strict video approval, video render mode, job notifications, and narrowly scoped UI diagnostics. Unknown actions and invalid payloads are rejected.read_settingsRead Creative Claw plugin settings for the settings page.update_settingsSave changed Creative Claw plugin settings from the settings page.search_mentionsFind Characters, film projects, and brand themes to mention in a message.generate_imageGenerate or edit images using AI models. Use this for AI-generated visual assets, including branded social cards, banners, posters, product images, and images guided by a saved theme or reference image.
An explicit image-model choice always takes precedence: when the user names GPT Image 2.5, GPT Image 2, Nano Banana, Seedream, or another image model, call generate_image with that model. render_html_image is only for when the user explicitly asks to render HTML/CSS, supplies HTML, or requests a deterministic code-based layout.
**Two modes:**
- **Generate** (no image_url): Create an image from a text prompt.
- **Edit** (with image_url): Transform an existing image based on the prompt.
The result renders automatically in an inline widget that polls for completion on its own — the user sees the image without any further action from you. Do NOT call check_job just to display or confirm the result; that only adds redundant round-trips. Call check_job ONLY when YOU need the final image URL for a follow-up step (editing it, reusing it as a reference, saving, or posting it).
Recommended models (pass as the "model" parameter). The default is Google Nano Banana 2:
- "image/nano-banana-2": Google Nano Banana 2. Default for generation and targeted edits: strong instruction following, reference consistency, and balanced quality, speed, and cost [generate + edit]
- "image/nano-banana-pro" - Google Gemini 3 Pro Image. Complex professional assets, precise multilingual typography, multi-reference compositions, and demanding edits [generate + edit]
- "image/gpt-image-2.5-flare" - OpenAI GPT Image 2.5 Flare. Fast, high-quality everyday generation and editing [generate + edit]
Both GPT Image 2.5 variants support transparent backgrounds; otherwise use remove_background.
- "image/gpt-image-2.5-sunburst" - OpenAI GPT Image 2.5 Sunburst. Precision-focused instruction following, text rendering, and controlled editing [generate + edit]
Default to image/nano-banana-2 as the cost-efficient choice for most work, including targeted edits that should preserve the existing scene. For localized edits, keep the source aspect ratio unless reframing is requested, identify the small region to change, and inspect the result for unintended changes. Exact preservation outside that region requires compositing the edited region back into the original. Use image/gpt-image-2.5-flare for fast OpenAI image work, image/gpt-image-2.5-sunburst for precision-focused generation and tightly controlled edits, or image/nano-banana-pro for complex professional assets. Use list_models to discover other available models only when the user asks or the brief requires a capability these models do not cover. Use get_model_params with the selected model ID before passing model-specific parameters.
Chaining rule: if a downstream step depends on this image, you MUST call check_job with the returned job ID until status=completed, then pass the returned permanent image URL to the downstream tool. A queued or in_progress job ID is not a usable media input.
Tips:
- Use top-level `aspect_ratio` for the output shape when get_model_params lists it for the selected model. Unsupported shapes fail before credits are charged. The older `size` presets remain accepted for existing calls.
- For output detail, use the selected model's control in extras: `resolution` for Nano Banana and Seedream, or `image_size` for GPT Image pixel dimensions.
- In ChatGPT, call import_chatgpt_media for files already pasted, attached, or generated in the conversation. Call import_media only when the user needs the interactive upload picker. Use the durable Creative Claw URL returned by either tool.
- For custom dimensions, output format, or transparency, use only the settings returned by get_model_params for the selected model and pass them in extras.
- Put model-specific controls such as seed, strength, num_inference_steps, and guidance_scale in extras only when get_model_params lists them for the selected model. GPT Image 2.5 ignores legacy calls that include these controls.
- Models marked [edit only] require image_url. Models marked [generate only] cannot edit.
- Prompt rewriting is off by default. Preserve the user's prompt as written unless they ask for model-specific optimization; then set agentic_prompting=true.
- Use get_model_params to discover model-specific parameters. Pass output shape as top-level aspect_ratio and other model-specific controls through extras.
- extras.image_urls provides additional style/character reference images — NOT for compositing. Every URL must be public/directly fetchable or returned by import_media/import_chatgpt_media. The source image should always be passed via image_url. If you pass extras.image_urls without image_url, the first URL is automatically used as the source image.
- GPT Image 2.5 accepts up to 16 reference images. Keep individual references below the provider upload limit; compress oversized references or use a Nano Banana model when needed.generate_videoGenerate a video clip from text or references, animate a photo, or edit and extend footage. Generate film shots separately.
Prepare one keyframe per shot with generate_image at the final ratio unless the user wants text-to-video or supplies ready media. Use shared visual anchors. Use image_urls for visual references, image_url for a literal start frame, last_frame_url for a supported end frame. Describe subject, action, camera, timing, and audio. Use get_model_params for inputs, reference syntax, and limits.
Models (default video/gemini-omni-flash; list_models has more):
- gemini-omni-flash: also edits sources up to 10 s; no audio input.
- minimax-h3-max / -turbo: fast scenes with native audio, up to 15 s.
- seedance-2.5: cinematic, up to 30 s; 480p drafts, 1080p final.
- wan-3.0: scenes up to 30 s.
- heygen-avatar-4 / minimax-h3-max-lip-sync: talking photo with extras.audio_url. Lip Sync accepts 5 s to 15 min; length equals audio.
- kling-3.0-motion-control-pro: face/person swaps and motion transfer. Use a prepared scene image and face binding; see get_model_params.
- minimax-h3-max-recast: recast existing footage from an image reference. See get_model_params.
- Lip sync: sync-3 supports video_urls + audio_urls (or embedded audio), with automatic or manual speaker selection. heygen-lipsync accepts a video and replacement audio; its mode defaults to Precision.
- minimax-h3-max-extend / -insert: continue or replace an interval in video_urls.
Use check_job for completion when the client has no live result viewer. force_new requests another variation. Submitted renders cannot be canceled. Add sound with generate_music/generate_sound_effect and merge_media (compose_video or merge_audio_video with audio_mode=mix); plain merge_audio_video replaces sound. Captions: add_subtitles. Motion graphics: render_html_video.generate_speechGenerate speech from text or change the voice in existing speech with Cartesia. Returns completed media or a queued job ID that resolves through check_job.
ElevenLabs v4 (model: "speech/elevenlabs-v4") is the default for stock voices, general narration, expressive delivery, and multi-speaker dialogue. It supports 90+ languages, audio and sound-effect tags, and extras.dialogue with a public voice_id or saved character_id per turn. For dialogue, omit top-level text or pass text: "" if a cached client schema requires it. It accepts Stability and Similarity voice settings. The Creative Claw speech tool returns a queued audio asset.
Speak a cloned voice with its provider's model. clone_voice creates Cartesia clones by default: use Cartesia Sonic (model: "speech/cartesia-sonic") with the Character's character_id; it also speaks stock voices by voice_id. For an ElevenLabs clone, use Multilingual v2 (model: "speech/elevenlabs-v2") for a steady read, or v4 when expressive delivery or dialogue is needed. V2 has no square-bracket audio tags; use punctuation or sparse SSML breaks.
Use clone_voice to create a consented reusable voice first, then pass its returned character_id to generate_speech. Passing audio_url to generate_speech does not create a clone. A missing Cartesia provider copy can be created from the Character's retained consented source when needed.
Fish Audio Drama 3 (model: "speech/fish-drama-3") supports natural-language performance directions in brackets, scoped delivery tags and multi-speaker extras.dialogue. Use a curated public voice_id or a private cloned or designed Character. Native word timings drive transcript highlighting without another transcription pass. For a new synthetic Fish voice use design_voice with provider fish; for a consented recording use clone_voice with provider fish. Prices use UTF-8 bytes, including direction and speaker tags.
HeyGen Voice (model: "speech/heygen-voice-1") speaks public Orca voices with stock speed and voice-dependent pauses, or existing consented HeyGen instant Character clones with extras.expressiveness_boost (default 0.5). Get curated voices and exact control restrictions from get_model_params. Other providers' Characters are not automatically cloned into HeyGen.
Google Gemini 3.8 Flash TTS (model: "speech/gemini-3.8-flash-tts") is a direct expressive option with multilingual public voices and extras.style. It supports two-speaker extras.dialogue with public voice IDs; ElevenLabs v4 supports up to 10 voices in one dialogue request. Google voice replication is not available here.
Call get_model_params for each model you intend to use before generation. Read its current voice IDs, prompting techniques, supported parameters, limits, and dialogue syntax. Do not carry settings or tags from one model into another. Use list_models only when the user asks for more alternatives or the requested capability requires them.
Choose the model explicitly:
- speech/cartesia-voice-changer: pass an existing workspace speech clip as extras.audio_url and a public Cartesia voice_id or cloned Character character_id. Omit text. Price is based on the measured input duration.
- speech/fish-drama-3: Fish Audio directed speech with [natural language performance directions], sounds, pauses and paired delivery tags. Use voice_id for a public voice or character_id for a consented private clone. extras.dialogue supports multiple speakers with per-turn public voices or private Characters. Missing Fish Character copies are made from retained private source recordings and reused. UTF-8 byte pricing includes delivery and speaker tags. Call get_model_params for settings and curated voices.
- speech/cartesia-sonic: the default for cloned voices, with fast, natural delivery. Call clone_voice with provider cartesia first, then use the returned character_id here. Use voice_id for a stock public voice. get_model_params returns curated voices and Cartesia prompting controls. If a Character needs a Cartesia provider copy, it is created from the retained consented source when needed. Providers are never substituted silently.
- speech/gemini-3.8-flash-tts: direct Google premium speech with built-in and public Extended Library voices, or a saved Google designed Character voice via character_id. It supports extras.style performance direction and two-speaker extras.dialogue with public voices. Omit top-level text for dialogue; it is derived from the turns. Use design_voice with provider google to create a synthetic custom voice.
- speech/elevenlabs-v4: the default for stock voices, produced narration, expressive voiceovers, and multi-speaker dialogue. It supports up to 10 voices in one extras.dialogue request, using public voice IDs or saved Character voices, including voices created through design_voice, with contextual delivery, inline audio and sound-effect tags, and 90+ languages.
- speech/elevenlabs-v2 (Multilingual v2): the recommended ElevenLabs model for an existing cloned Character voice, especially for a steady read. Pass its character_id. V4 remains available when that clone needs expressive delivery or a dialogue turn. Do not select v2 for a stock voice merely because the script is corporate, educational, or long-form.
- speech/chatterbox: English-only one-off reference-audio voice matching, up to 5,000 characters.
- speech/chatterbox-multilingual: one-off reference-audio voice matching in its 23 listed languages, up to 300 characters. Without reference audio, pass the target language as voice_id. With extras.audio_url, omit voice_id, pass extras.custom_audio_language for the sample, and write the text in the target language. Persian is not supported.
- V2 does not support square-bracket performance tags: [calm], [excited], [pause], and [laughs] may be spoken aloud or misinterpreted. Use plain text and punctuation; sparse <break time="0.5s" /> pauses up to 3 seconds are supported by v2. V2 does not support phoneme tags.
- Put supported settings in extras.voice_settings. V2 supports stability, similarity_boost, style, use_speaker_boost and speed (0.7–1.2). V4 supports stability and similarity_boost; its dialogue path focuses on per-turn performance and does not take single-speaker voice settings.
- V4 supports stability and similarity_boost in extras.voice_settings. V4 does not use speed, style, or use_speaker_boost, and SSML is unsupported. Use inline [long pause], [whispers], [laughs], [door slams], or other concise audible directions. Inline IPA can guide a difficult pronunciation. Requests accept up to 10,000 characters.
- V2 example: generate_speech({ model: "speech/elevenlabs-v2", character_id, text: "Welcome to our annual conference.", extras: { voice_settings: { stability: 0.5, similarity_boost: 0.75, style: 0, use_speaker_boost: true, speed: 1 } } }). Reuse the same character_id to compare ElevenLabs and Cartesia; do not replace the source voice to switch models.
- V2 permits 10,000 characters per request. Split long copy at paragraph boundaries; extras.previous_text and extras.next_text supply adjacent context without speaking it. V2 detects language from the text; language_code is not sent to its API.
For every model you intend to use, call get_model_params({ model }) before generation. Read its current voice choices, prompting techniques, supported parameters, limits, and dialogue syntax. Do not copy settings or tags between providers.
Voice and language:
- generate_speech has no voice_description parameter and never creates a new voice from a prose description. A requested quality such as "young woman" must be satisfied by calling get_model_params and passing a matching existing voice_id. If the user explicitly wants a newly designed reusable voice, use design_voice preview and save instead.
- For stock ElevenLabs voices, call get_model_params for current voice IDs and settings. Select a voice matching the requested language, regional accent, and tone. If the user wants a choice, suggest at most two relevant voices; otherwise choose one. Hale is the default for an unspecified English voice, not a universal language default.
- Omitting voice_id for ElevenLabs selects Hale (dXtC3XhB9GtPusIpNtQx), a smooth, confident American male. Never claim Hale or any returned voice ID was synthesized from the user's prose. When reporting the selected voice, use only its catalog label and description from get_model_params; do not invent a name, biography, gender, accent, or voice description.
- The curated IDs are recommendations, not an allowlist. Users may pass an exact public ElevenLabs Voice Library ID from https://elevenlabs.io/app/voice-library. If it is not yet available in the Creative Claw ElevenLabs collection, the first generation verifies it is public, adds it on demand, and retries once. Private IDs from another account remain unavailable.
- Write the text in the target language; for v4, use extras.language_code for short or ambiguous text (for example, "es" for Spanish). A language code does not guarantee a native regional accent. Use normal spelling and punctuation; audition a short passage before generating a long script when pronunciation matters.
- For Roman Urdu advertising, use v4 with extras.language_code: "ur" and consider Haseeb (aPfeouerZvEVukwmLSP0), an energetic Hindi/Urdu male voice, over Viraj, whose slow breathy suspense delivery is a poor default for ads. Keep apply_text_normalization at "auto" unless there is a tested reason to disable it. Audition code-switched English terms first; v4 accepts inline IPA wrapped in slashes for a difficult word (for example /nʌld/), but pronunciation remains probabilistic.
Clone and reuse a voice:
- For the user's own voice or a voice they have permission to use, load the clone-voice skill and call clone_voice with the required consent. Cartesia is the default for a cloned voice. If the user wants an ElevenLabs clone, use v2 for a steady read or v4 when expressive delivery or a dialogue turn is required.
- Select an existing Character with list_characters or create one with manage_character. Upload a clean voice sample using get_upload_url or import_media with purpose: "voice_clone". Call clone_voice({ provider: "cartesia", character_id, audio_asset_id, consent: true }) for the preferred Cartesia route, or provider: "elevenlabs" when requested. Clone only after explicit agreement to the voice-cloning terms and privacy notice.
- After clone_voice succeeds, pass its returned character_id to generate_speech with the matching provider model. For example, generate_speech({ model: "speech/cartesia-sonic", character_id, text }) or generate_speech({ model: "speech/elevenlabs-v2", character_id, text }). A retained consented source can create the Character's Cartesia provider copy when needed. Passing audio_url to generate_speech does not create a reusable clone.
ElevenLabs v4 delivery (model "speech/elevenlabs-v4"):
- Use the existing voice_id or character_id. Voice identity is more faithful to the source recording, including its artifacts. Instant clones need no separate training; existing Professional Voice Clones need v4 fine-tuning. Audition before using a long script.
- Square-bracket directions support emotion, pacing, reactions and sound effects. Use only spoken lines and audible tags; SSML and speed sliders are unavailable.
- When a clone speaks another language, v4 normally uses a fluent accent in that language instead of carrying over the source-language accent. Test accent-sensitive localization first.
- For a multi-speaker scene, pass extras.dialogue: [{ speaker, text, voice_id }, { speaker, text, character_id }, ...]. Each turn selects a public voice_id or a saved Character clone with character_id. Omit top-level text and top-level voice selectors. If a cached client schema still requires text, pass text: "". V4 supports up to 10 voices. ElevenLabs recommends at most 2,000 total turn characters for reliable dialogue, but Creative Claw permits longer v4 requests up to the model's 10,000-character request limit. Longer dialogue may end early or be rejected by ElevenLabs; see get_model_params for the selected model. One job returns one audio file with speaker timing segments.
Async result: speech from ElevenLabs, Cartesia, Google, HeyGen, xAI, and Pika returns a job ID immediately (status "queued") instead of the audio. The Creative Claw player polls and posts the finished audio into the conversation, so do not wait when the user only wants to listen. When you need the audio for a next step (merge_media, editing, another tool), or no player is shown, call check_job with the job ID until it completes. Never call generate_speech again for the same text while its job is running.
Duplicate safety: if the exact same normalized parameters were submitted in this Creative Claw workspace within the last 10 minutes, an active job is reused or a completed result is returned without another provider submission or charge. The fingerprint includes every public top-level parameter and every nested extras value, regardless of model. Set force_new=true only when the user explicitly wants another paid variation from identical parameters.
If the user explicitly selects another speech model, honor that choice. Call get_model_params for each selected model and use only its supported parameters and prompting syntax.generate_musicGenerate a music track and return a permanent audio URL with an inline player. For full-length instrumentals or vocal songs, music/mureka-v9.5 supports custom lyrics, automatic lyrics, and audio style references. For background music or image-inspired tracks with approximate timing, music/lyria-3.5 accepts text and optional images. For exact duration or a selectable output format, use music/elevenlabs-music-v2.5. For remixing an existing vocal song or producing a song from a vocal recording, use music/mureka-remix with audio_url. Models: music/lyria-3.5 (default, optional image inspiration), music/mureka-v9.5 (direct V9.5, one MP3, optional audio_url or extras.reference_audio_url for style inspiration (extras wins if both are provided), automatically cut to its first 30 seconds; reference controls style instead of prompt; instrumental by default without lyrics, or custom-lyric songs for 30 credits; force_instrumental: false without lyrics generates automatic vocal songs for 100 credits; no duration or format controls), music/mureka-remix (remix an existing vocal song or turn a raw vocal recording into a produced song; requires audio_url; uploads managed internally; 40 credits with lyrics, 42 with automatic recognition; one MP3, provider chooses length), music/minimax-music-3 (lyrics-led songs up to five minutes, with seed and quality controls; WAV), and music/elevenlabs-music-v2.5 (exact duration and selectable format). Unknown IDs are rejected before charging. Resolve queued Lyria, Mureka, and MiniMax jobs with check_job. Use generate_sound_effect for non-musical sounds.generate_sound_effectGenerate a sound effect, Foley cue, transition, impact, texture or ambience. sfx/elevenlabs-sound-v2 stays the default, with seamless loops and up to 30 seconds. Choose sfx/mirelo-sfx-2.0 for text effects or video-conditioned audio using video_url, up to 600 seconds (video clamped to source length). Mirelo defaults to one sample and returns queued audio; use check_job. preserve_speech requests speech retention but does not guarantee identical dialogue. All final audio is saved with a permanent URL and inline player. Use generate_music for scores and songs.transcribeTranscribe audio or video to text. Social links use SocialKit first: YouTube and TikTok retrieve available captions; Instagram, Facebook, X/Twitter and LinkedIn use their transcript endpoints. If retrieval fails or cannot satisfy language_code, the same job downloads the source, extracts durable audio through Modal, and transcribes it with Scribe. Reddit (beta) skips transcript retrieval and imports available complete video attachments for Scribe. Private, deleted and streaming-only posts can fail.
Pass exactly one of audio_url or video_url. Direct media files and public Google Drive video links are also supported. Social links are accepted directly here; other media tools require upload_asset first. Returns a job ID; use check_job until completion. Captions have segment timestamps without speaker diarization. Scribe adds word timestamps, speakers and a linked diarization JSON.
Completed transcripts are cached per organization, source URL and requested language. Cache hits cost no credits. YouTube/TikTok caption retrieval costs 2 credits per source. Other SocialKit transcripts cost 4 credits per started minute. Download fallback costs 2 credits per started minute for hosted audio, plus Scribe (44 credits/hour direct, or 1.6 credits/minute through fal, rounded once). X/LinkedIn/Reddit attachment lookup costs 2 credits per post plus Scribe. Failed jobs are refunded. Existing provider fallbacks keep the same public job ID.isolate_audioClean up an audio file using ElevenLabs Voice Isolator. It removes background noise, music, and reverb so only the voice remains. The attached viewer shows the playable source, progress, and cleaned output.
**Workflow:** in ChatGPT, call `import_chatgpt_media` for an audio file already attached or pasted; call `import_media` only to open the upload picker. Then pass the durable URL here. Returns a job ID — poll `check_job` until status="completed" to get the cleaned audio URL.
**Supported formats:** audio — mp3, wav, m4a, ogg, aac. Video files such as mp4 or mov are also accepted in audio_url; the voice is isolated from the soundtrack and the output is audio only. To put the cleaned voice back on the video, use merge_media afterwards.
**Pricing:** 80 credits flat per call, sized from current fal pricing and recent production usage.render_html_imageRender HTML/CSS to a PNG image via headless Chromium. Use this when the user explicitly asks to render HTML/CSS, provides HTML, requests a deterministic, pixel-controlled layout assembled with web code, or needs an exact text watermark graphic for merge_media operation=overlay_images.
Do not choose this tool for ordinary AI image generation or editing, for applying a theme reference image generatively, or when the user names an image model. A request for a social card, banner, poster, or OG image by itself is not enough to select this tool; use generate_image unless the user specifically asks for HTML/CSS rendering or deterministic code-based layout.
**Tailwind CSS:** All Tailwind utility classes work out of the box — no CDN script or stylesheet needed. Just use classes like bg-blue-500, text-white, flex, rounded-xl, shadow-lg directly in your HTML.
**Full CSS surface:** flexbox, grid, filter (blur, grayscale, hue-rotate, drop-shadow), mask-image, object-fit, transform, gradients, <style> blocks, class selectors, pseudo-elements, variable fonts (all weights 100-900 + italic). Write HTML like you would for a real browser.
For a watermark graphic to place over video with merge_media operation=overlay_images, use transparent_background=true and keep the HTML canvas close to the visible text or logo. An opaque canvas covers the video behind it.
**Fonts:** Any web font works — this is a real browser. Load fonts directly in the HTML: `<link rel="stylesheet" href="...">`, `@import url(...)`, or `@font-face`. Works with Google Fonts, Bunny Fonts, Adobe Fonts, your own CDN, etc. For a custom/local font, pass it via inline_images and reference it from `@font-face { src: url('{{my_font}}') format('woff2'); }`. The renderer waits on `document.fonts.ready` before screenshotting, so whatever the page declares is what gets rendered. No default font is injected — be explicit.
**Typical cold-render time:** ~1-3s (first render pays the browser cold-start; subsequent renders reuse the browser and complete in ~700ms-1.5s). Concurrency is capped server-side.
For reusable code-based layouts, use create_template + render_template instead.generate_with_faceGenerate a NEW image of the SAME PERSON/character as an existing photo or
portrait — dress them differently, move them somewhere else, make an avatar. This
is the tool for "here is my photo, now put me in a suit / in a park", and also
the ONLY tool for "generate another picture of <character I already made>".
Pass exactly ONE of:
character: the name you gave a character via create_character_from_description
or create_character_from_photo(..., name=...). Looked up in your own list —
see list_characters(). This is the normal way once a character has a name.
photo_media_id: a mediaId directly (create_character_from_photo's
`portrait_media_id`, or any earlier generate_image media_id) — for a one-off
face you haven't registered as a named character.
prompt: describe the NEW scene/outfit and say it is the same person, e.g.
"the same man, now in a navy suit in a bright office".
Why this and not entity_id/character_slot_index: a character's Flow CARD is not
what carries resemblance into a NEW scene — the reference image itself does
(verified live, repeatedly). Combining entity_id with an image reference in the
same call also fails outright (HTTP 500). So this always generates from the
reference image alone, never from entity_id — that is deliberate, not a
workaround to fix later.
project_id: put the result into a project made with create_project instead of the
account's default one. photo_media_id itself stays account-bound, as always.
generate_imageGenerate an image from a text prompt via Google Flow.
model — pass ONE of these exact ids (from GET v1/flow/models, verified 2026-07-25):
BELUGA = "Nano Banana 2" — the DEFAULT, ~30s (legacy id NARWHAL is accepted as an alias)
GEM_PIX_2 = "Nano Banana Pro" — highest quality, ~40s, has a separate DAILY
per-account quota (429 rotates accounts)
HARBOR_SEAL = "Nano Banana 2 Lite" — ~40s
Anything else is rejected with HTTP 400 — there is no silent fallback, so a wrong id
wastes a round trip, not credits. Do NOT guess names like "nano_banana_pro": that is
the model FAMILY key from the config, not the id the generate call takes.
image_inputs: mediaIds from prior generations, edit-in-place (keeps them pixel-exact).
control_images: base64 image bytes (no data: prefix) of a locally rendered layout/control
image — uploaded first, then prepended to image_inputs so the generator follows an exact
spatial layout instead of prose. For whole-scene layout control prefer generate_scene.
seed: 1..900000, fixes the generation so the same request returns the same image. Omit
for a random seed. Needed to compare two prompts, two models or two control images
honestly — without it every run is a fresh roll and the difference you are measuring
drowns in noise. Measured 2026-08-09: with an UNCHANGED control image a fixed seed
reproduces the frame to ~0.1%; once the control image changes, the seed no longer keeps
the character — for that use image_inputs with a reference frame's mediaId.
project_id: put the result into a project made with create_project instead of the
account's default one — one project per end client keeps their work separate. Omit it
and nothing changes from before.
include_preview: ON by default since 2026-08-21 — a generated image nobody can see
in the chat is half a result. Pass False to get the plain dict back and nothing else
(worth doing in a loop of many generations, where the previews would fill the
context). When on and the job finished with at least one url, the call returns the
usual result dict, a short card naming the parameters actually used, and a small
compressed JPEG (long side capped at 768px, ~100-160KB once base64-encoded) as an
inline image content block, so a human can actually see the result without leaving
the chat. This is deliberately a shrunk preview, never the original — the real Flow
image is ~0.5MB (~740KB in base64), enough to burn a whole tool call's worth of a
client's context budget on its own. The preview is for EYES ONLY: urls/media_ids
stay the authoritative result in both modes, and every downstream call (upscale_image,
image_inputs edit-in-place, ...) must keep using media_ids, never the preview bytes.
If the preview download/shrink fails for any reason, this silently falls back to the
plain (no-preview) result instead of failing the whole call.
SAVE THE RESULT INTO THE USER'S PROJECT. A finished job also carries `download_urls`
(plain URLs, no auth header needed) and `save_as` (the filenames to use). Unless the
user said otherwise, write them to ./media/<save_as> in their working directory and
tell them the path. The server keeps its own copy, but only the file in their project
is theirs: our copy can be reclaimed when the disk fills, and the URLs expire within
the hour. Downloading costs no credits and no quota.
Returns {"urls": [...], "media_ids": [...]} when done, or a job_id to poll
with check_job if it's not ready within ~60s (rare for images unless the
device is cold). With the default include_preview=True and a finished result,
returns [that dict, <card>, <inline image>] instead — see include_preview above.
music_generateGenerate a full song from a text brief via Google Flow Music (Lyria).
prompt — free text: genre, mood, BPM, instruments, and whether you want vocals or an
instrumental (e.g. "dreamy synthwave, retro 80s, 110 bpm, instrumental"). The Producer
agent turns it into a finished track (usually ~2-3 minutes, and it returns TWO variants).
model — "lyria" (Lyria 3.5, the default flagship) or "lyria-pro" (Lyria 3 Pro, legacy).
lyrics — optional explicit words to sing; omit for the model to write its own / stay
instrumental.
SAVE THE RESULT. Each returned clip carries a public `audio_url` (a Google Cloud Storage
.m4a, no auth header needed) plus `download_path` on our server. Unless the user said
otherwise, download the audio into their project. Fields per clip: clip_id, title,
duration (seconds), lyrics, audio_url, wav_url, image_id (cover, feeds music_video),
image_url. Returns {"clips": [...], "media": [...], "conversation_id": "..."} when done,
or a job_id to poll with check_job if it isn't ready within ~90s.
conversation_id — pass the one from an earlier result to keep working on the same track
("same song but 30 seconds shorter"); the Producer remembers what it just made. Omit it
for a fresh start. Every result carries one, so a follow-up is always possible.
music_chatTalk to the Google Flow Music Producer agent instead of one-shotting a track.
Use this when the work is a conversation rather than a single brief: asking what it can
do, having it write lyrics first, or editing a track it already made ("drop the vocals",
"same song, 30 seconds shorter", "make the chorus bigger"). For a plain "make me a song
about X", music_generate is the shorter path.
message — what to say. conversation_id — omit on the first message, then pass the one
that comes back so the Producer keeps its memory of the track. model — same choices as
music_generate.
Returns {"conversation_id", "text", "suggested_actions", "clips": [...], "media": [...]}.
`text` is the Producer's reply. `suggested_actions` are the follow-ups it offers — show
them to the user, they are good prompts for the next turn. `clips` is EMPTY when the
Producer only talked, and filled when it decided to actually make audio; treat a filled
`clips` exactly like a music_generate result and save the audio.
A reply is usually seconds, but a turn that produces a song takes minutes and comes back
as a job_id to poll with check_job.
music_stemsSplit a track we generated into stems (vocals, instrumental, drums, bass, …).
clip_id — the id of a clip returned by music_generate (or music_video's song). Runs on
the same account that made the track. Returns {"stems": {name: "/v1/media/..."}, "media":
[...]} when done, or a job_id to poll with check_job. Each stem is a downloadable .m4a on
our server (public download_path). Save the ones you need into the user's project.
music_listList the user's music tracks.music_getGet metadata for a single music track.music_downloadDownload the raw .m4a file of a track to the server.music_creditsCheck remaining flowmusic credits and subscription tier.generate_sceneBuild a location precisely from a scene-layout/v2 map and generate its plate.
This is the "exact location building" path: instead of describing the room in prose
(which the model reinterprets — furniture drifts, depths change between shots), it
renders a control image from the map's boxes (each object a colored block at its true
position/size/depth, plus a 1-meter floor grid in true perspective), then asks the
generator to REPLACE each block with its real object in the same camera — so the plate
follows the geometry pixel-wise. Same room from another camera_id is the same space.
scene_layout: a scene-layout/v2 dict — {format, units, room{w,d,h}, objects{...boxes},
cameras{<id>:{pos,look_at,fov_deg,framing?}}, ...}. The camera must carry fov_deg.
camera_id: which camera in scene_layout.cameras to render from.
aspect: PORTRAIT (9:16), LANDSCAPE (16:9) or SQUARE. 9:16 and 16:9 from one camera share
the vertical FOV, so depths are identical across aspects.
style / extra: prepended / appended prose (art style, mood) — geometry comes from the map.
A box may carry `rot: [rx, ry, rz]` (degrees around the world X/Y/Z axes) and `pivot:
[x, y, z]`, applied as p' = Rx·Ry·Rz·(p − pivot) + pivot, pivot defaulting to the box
centre. That is how a POSE is expressed — a raised arm is a box rotated about the
shoulder. Measured live 2026-08-09: moving a hand by 2–20 cm is ignored by the
generator, rotating the arm by 15–60° comes through. Build motion out of angles.
seed / image_inputs: same meaning as in generate_image. For a SEQUENCE of frames of one
character, generate a reference frame first, then pass its mediaId as image_inputs on
every following frame — that is what keeps the face, clothes and colours identical.
A fixed seed alone does not: it only repeats an unchanged control image.
depth: render the guide as a plain greyscale depth map instead of the colour hybrid
(for an external depth-ControlNet). calibration: add frame markers, a back-wall grid
and a 2 m ruler with 10 cm ticks — measured to cut the framing drift roughly fourfold.
background: "dark" (default, unchanged) or "light". Use "light" when the plate must be
on a white background: the generator sometimes copies the guide's own palette into the
result, and a light guide makes that leak land as white rather than as a dark grid.
control_png: return the layout guide itself, base64-encoded. OFF by default because it is
hundreds of thousands of characters of TEXT — one guide can cost more context than the
whole conversation around it. `control_png_kb` always reports its size.
Returns {"urls", "media_ids", "legend", "control_png_kb"} — legend maps block colors to
objects. Add control_png=True to also get the guide itself for inspection/acceptance.
generate_videoGenerate a video from a text prompt via Google Flow (Veo models).
video_model_key options: abra_t2v_4s (default, 7 credits), veo_3_1_t2v_lite
(10cr, visibly cleaner), veo_3_1_t2v (100cr, "Quality" tier), veo_3_1_t2v_fast (20cr).
project_id: put the clip into a project made with create_project instead of the
account's default one — one project per end client keeps their work separate.
Video generation routinely takes 1-3+ minutes, so this almost always returns
a job_id rather than a finished result — call check_job with it, waiting a
few seconds between checks, until status is 'done' or 'failed'.
beats: how many DISTINCT action phases the prompt describes — "ears flick back",
"tail lashes", "strikes the ball", "ball flies off" are four. Give it and the server
picks the clip length for you (about two phases per second) and says in the reply what
it picked and why. Measured 31.08.2026: the model STRETCHES whatever you describe over
whatever length you ask for, so one phase in four seconds comes out as slow motion, and
the same text at six seconds instead of four loses 15% of its movement. Adjectives are
not phases: "springy cartoon motion" adds nothing. Leave beats out and the length you
passed is used unchanged.
seed (all video tools): the result always reports the seed it used. Same seed + same
prompt + same inputs = the same clip, so a good take can be re-made. A fixed seed does
NOT keep the composition when the prompt changes — use edit_video for that.
edit_videoRewrite a video from a plain description: "make the sky stormy", "take the
passer-by out of the shot", "warmer light", "put the product from the image on the
table".
Source — ONE of:
media_id: id from a previous generate_video* result (OUR OWN generation). Job is
pinned to the account that produced it.
video_base64: base64-encoded YOUR OWN clip (mp4/mov/avi/3gp, up to 60s/1GB).
Worker uploads it via Flow's Scotty resumable upload (reversed via
Flow Web Ingredients, 2026-10-14) onto a healthy account, then runs
the edit on that account. The upload itself costs no credits.
start_sec / end_sec: edit only this piece of the source (both or neither, at most
10 s). The result is ONLY that piece — not the full clip with the piece replaced.
reference_images_base64: up to 3 raw base64 images (no data: prefix); the object in
the image is put into the clip — say in the prompt what to do with it.
20 credits per edit (abra_edit_360p: 10). Not a mask tool — describe the change and
where it goes ("on the left", "in the sky"); mask/style image types are not honored.
Prompt template that lands best — fill each part, one or two sentences each:
Goal: what changes ("Replace the man on the left with the character from image 1").
Source: "The source video drives camera, motion, timing and lip movement."
Reference: what to take from each image ("use only the character's look; ignore
the image background").
Scene: describe the room/background in words (helps the model keep it intact).
Keep: "Everything else stays exactly as in the source."
Timing: "The new character inherits the exact movement and position of the one
it replaces, from the first frame to the last."
Draft on abra_edit_360p (10 credits) to check the edit lands, then run abra_edit; the
seed does not carry an edit take across resolutions, so the final can differ in details.
Only edit footage the user owns or is licensed to use; do not put real people's
likeness into clips without their consent.
Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.
{
"mcpServers": {
"creative-claw": {
"url": "https://app.creativeclaw.co/mcp/chatgpt"
}
}
}
{
"mcpServers": {
"openflow": {
"url": "https://openflowmcp.com/mcp"
}
}
}