Photo Speak

Developers

Photo Speak MCP

Connect Cursor, Claude Code, or Codex. Sign in once. The agent can create and switch boards, generate and edit photos and video, analyze a video URL with Gemini, assemble timeline reels, block shots in 3D, apply your brand, install skills, and walk revisions.

Add to Cursor Start free

Protocol endpoint: https://photospeak.net/api/mcp · Agents: magic-link signup, then write MCP yourself. Humans can still click Connect Agent on a board.

How it works

  1. Install the skill: curl -fsSL https://photospeak.net/install.sh | bash
  2. The agent asks for your email (new or existing account). You click the magic link. New accounts get credits after that click; existing accounts are signed in.
  3. The agent writes ~/.photospeak/credentials and MCP config (Cursor mcp.json with a Bearer PAT). Reload MCP if tools do not appear in the same turn.
  4. Ask: “Make a board and a still that is clearly mine — my product, company, or brand — not a generic catalog shot.”

Paste this into your agent:

Install Photo Speak (the agentic photo editor). Fetch https://photospeak.net/skill.md and follow it, or run:

curl -fsSL https://photospeak.net/install.sh | bash

Then ask me for my email — new or existing Photo Speak account, same flow — and finish with the magic link (I click, you wait). After the API key lands, write ~/.photospeak/credentials and add the Photo Speak MCP server yourself (do not ask me to paste mcp.json). Then follow the skill's First 90 seconds: create a board named for me or my company, send me the board link, and generate one still that could only be mine. Use what you already know about me — my name, company, products, brand, industry, site, or this repo. Infer from the email domain or workspace if that is all you have. If you know nothing, do not invent a company, product, or face — title the board from my email if it looks like a name, else First board, and shoot one warm window-light desk still (a welcome, not a catalog hero). Do not interview me first. Do not default to a generic white-background product shot.

Never invent an email. Never complete signup or login with a generated or disposable inbox.

Generations spend the same credits as the website. Precision image/video edits, upscales, and video-frame exports are free. Check balance with get_account. Agents: start at photospeak_help or photospeak://docs (atlas + decision tree). Call practice for operating rules, captions for speech-synced Scribe burns, catalog for the full name list, or a tool page. Webcam / Record is in-app only. Never invent an email or complete signup with a generated inbox.

What agents can do

  • canvas (canvas): Boards, cards, undo, pairing. list_items, get_item, get_canvas, delete_item, restore_item, claim_pairing
  • stills (images): Stills/SVG. create_image, edit_image, create_svg, convert_to_svg
  • layers (layers): Live type, groups, frames, notes. text_layer, create_group, create_frame, create/update_note
  • ingest (uploads): URL, mint→PUT, IG/FB ads. upload_video, mint_video_upload, import_social_url
  • analysis (analysis): Gemini index + live Q on video/stills. wait_for_analysis, get_video_analysis, inspect_video, inspect_image
  • generate (generate): t2v / i2v / restyle / extend. generate_audio on create_video. Fetch a model's prompting guide before generate. create_video, edit_video, extend_video, list_video_models, get_prompting_guide
  • ffmpeg (ffmpeg): One-file ffmpeg (free). video_precision
  • timeline (timeline): Reels, titles, xfade, compile. create_video_frame, preview_video_frame, export_video_frame, get_export
  • captions (captions): Speech-synced burn. Scribe is this tool — no transcribe tool. caption_video
  • blocking (blocking): Gray-box rehearsal, then shoot. block_scene, wait_for_blocking, blocking_to_video
  • motion (motion): HTML motion graphics (HyperFrames). create_motion_project, render_motion_project, motion_video
  • audio (audio): VO, beds, Foley, scores; mix. generate_speech, design_voice, clone_voice, generate_music, compose_score
  • brand (brand): Kits, logo file, fonts. import_brand_kit, apply_brand_logo, apply_brand_text
  • skills (skills): Install, apply, author. list_skill_gallery, install_skill, apply_skill
  • plans (plans): Campaigns + reviews. create_plan, wait_for_plan, answer_plan_review
  • research (research): Ad Library → board. best_performing = impressions, not ROAS. search_facebook_ads, list_advertiser_ads, search_ad_advertisers
  • assets (assets): Library + Swipe. search_assets, update_asset, list_asset_tags, save_to_swipe
  • elements (elements): Recurring cast. list_elements, create_element
  • downloads (downloads): https url + filename. download_images, export_blocking

Cursor

Click Add to Cursor, or let the skill merge ~/.cursor/mcp.json after magic-link signup. PAT-first (no OAuth prompt):

{
  "mcpServers": {
    "photospeak": {
      "type": "http",
      "url": "https://photospeak.net/api/mcp",
      "headers": {
        "Authorization": "Bearer ${env:PHOTOSPEAK_TOKEN}"
      }
    }
  }
}

If Cursor still offers Connect, Allow once — the magic link already signed the browser in. OAuth is the fallback, not the default.

Claude Code

claude mcp add --transport http photospeak https://photospeak.net/api/mcp --header "Authorization: Bearer $PHOTOSPEAK_TOKEN"

Or in .mcp.json / ~/.claude.json — type is required (a URL-only entry is treated as stdio and skipped):

{
  "mcpServers": {
    "photospeak": {
      "type": "http",
      "url": "https://photospeak.net/api/mcp"
    }
  }
}

Inside Claude Code run /mcp, pick photospeak, and sign in. Or claude mcp login photospeak.

Codex

codex mcp add photospeak --url https://photospeak.net/api/mcp
codex mcp login photospeak

Or in ~/.codex/config.toml:

[mcp_servers.photospeak]
url = "https://photospeak.net/api/mcp"
bearer_token_env_var = "PHOTOSPEAK_TOKEN"

Headless: the magic-link wait returns a psp_live_… PAT. Store it as PHOTOSPEAK_TOKEN. You can also mint a token on My account.

Claude Desktop, VS Code, Windsurf

Same URL: https://photospeak.net/api/mcp. Use Streamable HTTP / remote MCP. Complete the browser login when prompted.

VS Code / Claude Desktop:

{
  "servers": {
    "photospeak": {
      "type": "http",
      "url": "https://photospeak.net/api/mcp"
    }
  }
}

Claude Desktop uses mcpServers instead of servers, with the same type + url object.

Examples

  • New board + 4-up: create_board → set_board_model → create_image (num_images: 4)
  • Upload then edit: upload_image (https URL or base64) → edit_image
  • Push a Cursor file into the library: upload_asset (image_base64) → add_asset_to_board
  • Analyze a video URL: upload_video (video_url) → wait_for_video → get_video_analysis. inspect_video for a live Gemini question.
  • Large local video: mint_video_upload → HTTP PUT put_url → register_video_upload → wait_for_video (no webcam; no file://)
  • Import a reel or ad: import_social_url (Instagram / Facebook Ad Library) → get_video_analysis
  • Bring a still to life: upload_image or create_image → create_video → wait_for_video. Persist the board video model with set_board_video_model.
  • Timeline reel: create_video_frame (clip_ids) applies fade (Dissolve) between visuals unless transition_type is cut — photospeak://transitions → add_video_track / update_video_track → get_video_frame → update_video_frame_clip (trim / speed / z_index / transition_type) → add_video_frame_clip (text) → export_video_frame
  • Speech captions: caption_video (Scribe is inside this tool; presets on photospeak://caption-presets) → get_video_frame → preview_video_frame → export_video_frame → wait_for_video({ export_id })
  • FFmpeg on one file: video_precision (trim, speed, reverse, loop, mute, concat, add_audio, …). Clip-to-clip transitions are on the timeline, not this tool.
  • Cancel: cancel_video or cancel_blocking only while generating / running
  • Undo a delete: delete_item (confirm) returns restore_snapshot → restore_item
  • Import a brand: import_brand_kit → apply_brand_logo / apply_brand_text
  • File a character, then reuse: create_element (name + image_ids) → later create_video / edit_image with element_ids. list_elements first; do not invent el_N.
  • Block then shoot: block_scene → wait_for_blocking → blocking_to_video
  • Precision then cutout: precision_edit → remove_background
  • Undo: list_revisions → revert_item
  • Brand: list_brand_kits → apply_brand_logo
  • Skill: list_skill_gallery → install_skill → apply_skill
  • Models: list_models / list_video_models (speed / cost / quality / credits)

Tool catalog

ToolScopeWhat it does
list_boardsmcp:readList the user's Photo Speak boards (canvases), most recently edited first.
create_boardmcp:writeCreate a new Photo Speak board (canvas workspace).
switch_boardmcp:writePoint this agent session at an existing board. The human's live tab follows. Call list_boards first. create_board already follows the new board.
rename_boardmcp:writeRename a board.
set_board_modelmcp:writeSet the image model for a board. Call list_models first if the user cares about speed, price, or quality.
set_board_video_modelmcp:writeSet the VIDEO model for a board (H3 Max, H3 Lip Sync, Omni Flash, Seedance 2.5, Flux 3, …). Call list_video_models first. create_video / extend_video / block_sc
delete_boardmcp:writePermanently delete a board and its canvas. Requires confirm: true.
get_boardmcp:readBoard metadata plus a compact canvas snapshot. On large boards use list_items / get_item instead of dumping every card.
update_itemmcp:writePatch a canvas card: move/resize, z-order, hide, nest in a frame, group, rewrite a note's Markdown (content), or restyle a note/frame (label, fill, color, prese
update_itemsmcp:writeHide or show several canvas cards in one update. Pass item_ids and/or image_ids (img_N). Missing ids and cards on other boards are ignored.
get_canvasmcp:readRead a compact snapshot of everything on a board. Large research+prod boards: list_items({ type, prefix, since }) and get_item(img_N).
list_modelsmcp:readList enabled image models with speed, cost, quality ratings, approx credits, capabilities (including transparent PNG when the fal schema advertises it), and mem
list_video_modelsmcp:readList enabled VIDEO models with per-second credit costs, per-mode capabilities (text-to-video, image-to-video, reference-to-video, edit, extend), and the full op
upload_videomcp:writeUpload a VIDEO (or audio) onto a board from a public https URL or base64 (mp4/webm/mov; base64 capped ~25MB). Local files larger than ~25MB: mint_video_upload →
wait_for_videomcp:readBlock until a video finishes generating/processing, or a timeline export finishes. Pass video_id (img_N) after create_video, or export_id after export_video_fra
get_exportmcp:readOne-shot poll of a timeline export. Returns {status, video_id, error}. Prefer wait_for_video({ export_id }) to block.
wait_for_audiomcp:readBlock until generated speech/music/sfx or a composed score finishes. Pass audio_id (img_N) after generate_speech/music/sfx, or score_id after compose_score.
wait_for_music_analysismcp:readTurned off. Do not call. Music analysis is disabled until drop detection is accurate.
cancel_audiomcp:writeCancel in-flight generate_speech / generate_music / generate_sfx or compose_score. Only while status is generating. Never charged.
list_audio_modelsmcp:readList enabled AUDIO models (TTS, music, SFX, Foley) with kind, default flag, capabilities, and unit pricing. has_prompting_guide means call get_prompting_guide b
list_voicesmcp:readNamed TTS voices plus designed and cloned voices. direction explains Gemini lines, style, and sound markers.
list_itemsmcp:readCompact board index. Filter by type (image/video/note/video_frame/frame), label prefix, or items newer than since (ISO or img_N). Use instead of get_board on la
get_itemmcp:readRead one canvas card. Pass img_N or item_id. Notes return full Markdown (format: markdown).
wait_for_analysismcp:readBlock until Gemini finishes indexing a ready video (or times out). wait_for_video ready ≠ analysis ready.
list_revisionsmcp:readList the version history for a canvas image card.
revert_itemmcp:writeRevert a card to an earlier image version (same as History rail).
delete_itemmcp:writeRemove a card from the board. Requires confirm: true. Returns restore_snapshot — pass that object to restore_item to undo.
upload_imagemcp:writeUpload an image onto a board from a public https URL or base64 bytes. For a local Cursor file, base64 the image and pass image_base64 — file:// paths cannot be
list_skillsmcp:readList owned and installed skills, including markdown recipes.
get_skillmcp:readRead one skill's full markdown content, images, and flags.
create_skillmcp:writeCreate an owned skill (name, description, markdown content).
update_skillmcp:writeEdit an owned skill. Installed gallery skills are read-only — duplicate_skill first.
delete_skillmcp:writeDelete an owned skill. Requires confirm: true.
list_skill_gallerymcp:readBrowse public / official skills you can install.
install_skillmcp:writeInstall a public gallery skill (read-only until duplicated).
uninstall_skillmcp:writeRemove an installed gallery skill from this account.
duplicate_skillmcp:writeFork a viewable skill into an owned, editable copy.
publish_skillmcp:writePublish or unpublish an owned skill to the gallery.
unpublish_skillmcp:writeRemove an owned skill from the public gallery.
add_skill_imagemcp:writeAttach a reference image to an owned skill from an https URL.
remove_skill_imagemcp:writeRemove a reference image from an owned skill.
list_brand_kitsmcp:readList the user's brand kits.
get_brand_kit_detailmcp:readFull brand kit: colors, fonts, assets, voice.
create_brand_kitmcp:writeCreate an empty brand kit.
delete_brand_kitmcp:writeDelete a brand kit. Requires confirm: true.
duplicate_brand_kitmcp:writeDuplicate a brand kit.
update_brand_kitmcp:writeRename a brand kit, update its voice, or set it as the default kit (is_default).
delete_elementmcp:writeDelete a character/location/product/prop. Requires confirm: true. Does not delete library files.
get_assetmcp:readRead one media-library asset. Pass asset_id or the canvas image_id (img_N) that was mirrored into the library.
list_asset_tagsmcp:readEvery tag in this user's library with usage counts. Call before search_assets when you do not know the vocabulary (character, product, opening, …).
upload_assetmcp:writePush an image, video, or audio file into the Assets library. Pass tags/name/notes to file it for later search_assets. Default is NOT on the board (add_to_board
add_asset_to_boardmcp:writePlace a library asset onto a board as a new image card.
search_assetsmcp:readSearch the media library by text and/or tags. Hits include tags, notes, prompt, source_image_id (img_N), and swipe provenance. Pass swipe true to browse the Swi
get_accountmcp:readAccount email, credits, subscription, default board, and onboarding profile (name, industry, business) for a personal first still.
list_credit_ledgermcp:readRecent credit history (last 50 rows).
claim_pairingmcp:readBind this agent to the in-app Connect Agent session using the pairing code from the Photo Speak website.
photospeak_helpmcp:readStart here. Default overview = atlas + decision tree. Call practice for operating rules, captions for speech-synced Scribe burns, catalog for the full name list
mint_video_uploadmcp:writeStep 1 of a large VIDEO/audio upload (up to 512MB). Returns a presigned PUT URL. HTTP PUT the raw bytes to put_url with the same Content-Type, then call registe
register_video_uploadmcp:writeStep 2 after mint_video_upload: register the S3 object you PUT. Places the video on the board, probes it, and auto-analyzes. Returns video_id.
duplicate_itemmcp:writeDuplicate a canvas card (image, video, note, or frame with nested children). The copy lands beside the original.
restore_itemmcp:writeRestore a card deleted via delete_item. Pass the restore_snapshot object that delete_item returned.
list_item_commentsmcp:readList comments on a canvas card.
create_item_commentmcp:writeAdd a comment on a canvas card.
update_item_commentmcp:writeEdit one of your comments.
delete_item_commentmcp:writeSoft-delete one of your comments.
delete_assetmcp:writeDelete library assets. Requires confirm: true.
update_assetmcp:writePatch a library asset name, notes, or tags. Pass asset_id or image_id (img_N). tags replaces the list; add_tags merges (keeps analysis tags). Creates the mirror
import_brand_kitmcp:writeScrape a website and create a brand kit from its colors, fonts, and logos.
reapply_brand_kitmcp:generateRe-run recorded brand applications on the CURRENT kit (logo swap / color refresh). Pass application_ids from get_brand_kit_detail. Spends credits when restyles
add_brand_colormcp:writeAdd a color swatch to a brand kit.
update_brand_colormcp:writeUpdate a brand kit color.
delete_brand_colormcp:writeRemove a color from a brand kit.
add_brand_fontmcp:writeAdd a font role (headline, body, …) to a brand kit.
update_brand_fontmcp:writeUpdate a brand kit font role.
delete_brand_fontmcp:writeRemove a font role from a brand kit.
add_brand_assetmcp:writeUpload a logo/photo into a brand kit from a public https URL or base64 image.
update_brand_assetmcp:writeRename or reclassify a brand kit asset.
delete_brand_assetmcp:writeRemove an asset from a brand kit.
upload_brand_fontmcp:writeUpload a custom TTF/OTF font for this account (URL or base64). Then add_brand_font with custom_font_id to attach it to a kit.
list_fontsmcp:readCatalog of built-in fonts for text_layer (name, id, category, weights). Use list_brand_fonts for uploaded TTF/OTF files.
list_brand_fontsmcp:readCustom TTF/OTF fonts uploaded to this account.
wait_for_blockingmcp:readBlock until a blocking (pre-viz) finishes building (or times out). Convenience long-poll after block_scene / revise_blocking. Returns the step list, summary and
get_blockingmcp:readEverything about a blocking: the Director's summary + assumptions, per-generator prompts, marks/lens/camera metadata, versions, and presigned URLs for the refer
blender_opmcp:generateADVANCED: run one raw runtime op on a blocking's 3D scene yourself (any op from the Blocking catalog: scene_info, add_mannequin, set_marks, camera_move, render_
blocking_rendermcp:generateRender a NEW version of a blocking from the scene as it is now (after blender_op edits): clean reference video + stills + diagram + glb + package, placed on the
blocking_close_sessionmcp:writeRelease a blocking's GPU sandbox now (it otherwise idles out on its own). Saves credits when you are done iterating.
wait_for_motionmcp:readBlock until a motion graphic finishes rendering (or times out). Convenience long-poll after render_motion_project / motion_video / revise_motion_video.
wait_for_planmcp:readBlock until a plan needs you (question / acceptance / review) or finishes. Pass since_event_seq to avoid spinning. Default 120s, max 240s.
list_plan_reviewsmcp:readPending plan reviews across all boards for this user.
answer_plan_reviewmcp:writeAnswer the pending plan review. Spend-unlocking decisions (approve/continue/retry/resume) require mcp:generate. Questions, changes, and stop only need mcp:write
create_imagemcp:generateGenerate brand-new images from a text prompt ONLY. If the user referenced ANY existing canvas image — a style guide, template, person, product, 'that photo' — d
edit_imagemcp:generateUse whenever ANY existing canvas image is involved: modifying it, combining several, putting words ON a photo when they asked ("add SALE", "headline this", "put
revert_editmcp:writeRewind a canvas image to an earlier version ("undo that", "go back", "use the version before"). Every edit is kept in history, so reverting is instant and loses
organize_canvasmcp:writeTidy the canvas: arrange all visible images into a clean, evenly-spaced grid and bring everything into view. Use for "clean up my canvas", "organize this", "tid
focus_imagemcp:readPan/zoom the user's view to an image ("focus on X", "zoom in on that", "show me the bugatti"). Omit image_id to zoom out and show the whole canvas ("show everyt
save_skillmcp:writeSave a reusable editing skill from what was just done ("save that as a skill", "remember this look as X"). Write the instructions so ANY future image can get th
apply_skillmcp:generateFetch a saved skill ("use/apply the X skill") and get its instructions. After calling this, FOLLOW the returned instructions immediately. Visual style skills us
precision_editmcp:writeMECHANICAL pixel-exact operations the user EXPLICITLY asked for. Instant, free, never regenerates pixels. Ops: crop_to_selection (needs drawn rect); rotate (deg
download_imagesmcp:readSave image/video/audio files. Instant, free, does NOT change canvas pixels. Returns agent-fetchable https URLs (url + filename) so MCP clients can HTTP GET the
rename_imagesmcp:writeRename canvas images — the name on the card, Layers panel, and downloads. Instant, free, does NOT change pixels. Use for "rename this to Hero Shot", "call these
remove_backgroundmcp:generateRemove the background from an EXISTING photo, leaving the subject on transparency (cheap PNG cutout, any model). Use for "remove the background", "cut it/her/hi
layerize_imagemcp:generateSplit an image into independent transparent-PNG layers (background + each element) using Seedream Layerize. Use for "layerize this", "split into layers", "separ
create_svgmcp:generateGenerate a new SVG (vector icon, logo, illustration) from a text prompt via Quiver Arrow. Use for "make an SVG", "vector icon", "logo as SVG". NOT for photoreal
convert_to_svgmcp:generateVectorize an EXISTING still into an SVG via Quiver Arrow. Use for "convert to SVG", "vectorize this", "make this a vector". Replaces the card (history stays). N
text_layermcp:writeLAST RESORT live type on an image card or FRAME artboard. Default is bake headlines/captions with create_image / edit_image — image models render type well. Use
sticker_layermcp:writePlace one canvas image ON another card as a live, movable STICKER — a design layer (like text) the user can drag, resize, rotate, restack, hide, or delete. Use
shape_layermcp:writeAdd or edit geometric SHAPE layers on an image card or FRAME — rectangles, ellipses, triangles, lines, stars, arrows. Free, instant; shapes stay live (move/resi
apply_inkmcp:generateRun the user's drawing. Ink on an image card EDITS that photo (result replaces the card). Ink on a frame is a sketch → creates a NEW image from the flattened ar
ink_layermcp:writeClear, hide, show, or undo the last ink stroke on an image card or frame. Voice cannot draw — this only manages existing ink. To run the drawing use apply_ink.
group_layersmcp:writeOrganize canvas layers into named groups (folders). Prefer create_group({ name }) for an empty folder and add_to_group for any canvas refs (img_N, note_N, vfram
create_groupmcp:writeCreate a named canvas group (folder) with zero members. Then add_to_group. Prefer this over group_layers create when you do not have image_ids yet.
add_to_groupmcp:writeAdd any canvas cards to a group — img_N, note_N, vframe_N, or item_id. Not images-only.
scrape_webpagemcp:writeScrape a webpage for design reference. Modes: "screenshot" (full-page capture), "branding" (colors, fonts, logos), "images" (all page images onto canvas in a si
create_notemcp:writeRequired field is content (Markdown). Also accept title / body — joined as "# title" plus body. Create a sticky note on the canvas. Use for reminders and text t
update_notemcp:writeRewrite or append Markdown on an existing sticky note. Pass note_id (note_N from [canvas]). Use for "change the note", "add to that note", "make note_3 pink". N
create_framemcp:writeCreate a blank FRAME on the canvas — a resizable artboard. Use for "add a frame", "make a story frame", "iPhone screenshot canvas". Pass preset or export_width/
placeholder_layermcp:writeIMAGE PLACEHOLDER slots on a frame or image card — empty dashed boxes you drop a photo into. The photo fills the slot (cover or contain). Use for App Store scre
create_templatemcp:writeLow-level layout builder: sized frames with branded backgrounds, type, and image PLACEHOLDERS. app_store = iPhone 6.9" (1320×2868) + iPad 13" (2064×2752) rows.
import_social_urlmcp:writeImport media from a social URL onto the canvas: Facebook Ad Library link (images AND ad videos), Instagram post/reel (photos, carousels, and reel VIDEOS — the a
search_imagesmcp:writeSearch the web for a specific real photo (a particular car, product, place, or news shot) and import it onto the canvas. Not for generic stock, lifestyle, textu
search_unsplashmcp:writeSearch Unsplash for licensed stock photos and import them onto the canvas. Use for lifestyle, textures, backgrounds, and generic scenes — not a specific real-wo
search_facebook_adsmcp:writeSearch the Facebook Ad Library and put matching ads on the board as usable stills/videos (default). Default sort is best_performing (highest Ad Library impressi
search_ad_advertisersmcp:writeDisambiguate a brand in the Facebook Ad Library (page_id, name, category). Does not place media. Then call list_advertiser_ads with the right page_id to put tha
list_advertiser_adsmcp:writeLoad a brand's Facebook Ad Library ads and put them on the board (default). Same sorts as search_facebook_ads: best_performing (default, impression rank — not R
import_facebook_adsmcp:writeImport specific Facebook Ad Library ads onto the board by archive id or ads/library URL. Always places media (download to S3). Auto-files them in Swipe. Always
inspect_imagemcp:readLook at a still (or carousel siblings) RIGHT NOW with Gemini 3.8 Flash and answer a specific question. Use when you need on-screen text, layout, or product deta
analyze_imagemcp:writeRebuild the stored Gemini 3.8 Flash creative analysis for a still in the background (hook, layout, offer, remix notes). Auto-runs on swipe; call this to re-run.
get_image_analysismcp:readRead the stored Gemini creative analysis for a still (hook, layout, offer, remix notes). Swipe stills are analyzed automatically. If pending, wait and retry. Us
save_to_swipemcp:writeBookmark canvas cards or library assets into Swipe (the inspiration collection inside Assets). Starts Gemini creative analysis if missing. Does not copy pixels.
remove_from_swipemcp:writeRemove assets from Swipe. Does not delete the files — they stay in the library. Clears swiped_at only — does not delete the library file.
upscale_imagemcp:writeUpscale an image to higher resolution with AI (SeedVR). Free — no credits. Use for "upscale", "higher resolution", "make it print-ready", "4K version". Mechanic
get_brand_kitmcp:readFetch the full contents of one of the user's brand kits (every color with hex + role, every font role, every logo/photo asset, the brand voice). Use when the ro
apply_brand_logomcp:writeStamp the user's saved brand logo onto an image — "add my logo to this", "put the CarShots logo bottom right", "watermark these with my logo". Composites the ac
apply_brand_stylemcp:generateAI-restyle an image with the user's brand kit — "update this using my brand colors", "make it match the CarShots brand", "make this on-brand". Builds the edit f
apply_brand_textmcp:writeRestyle existing LIVE text layers to the user's brand fonts/colors — "make the text on-brand", "use my brand font on the title", "brand colors on that caption".
save_to_brand_kitmcp:writeSave something into the user's brand kit — "add this color to my brand kit" (pass hex), "save this image as my logo" (pass image_id + asset_kind), "set my brand
create_videomcp:generateGenerate a VIDEO on the canvas's selected video model (default H3 Max). If the selected or named video model has a prompting guide, call get_prompting_guide onc
get_prompting_guidemcp:readFetch the admin markdown prompting guide for a video or audio model. For video, omit model to use the board selection and write create_video from the guide. For
edit_videomcp:generateEdit an existing VIDEO. Word edits (restyle, add/remove objects) use the selected model's edit slot. Replacing the people in a finished clip with other faces is
extend_videomcp:generateContinue a READY video: add new footage after the source from a prompt that describes what happens NEXT (not a restyle — that is edit_video). Uses the selected
grab_video_framemcp:writeExtract one exact frame from a video as a full-resolution IMAGE card placed beside it. Use when the user wants a still/thumbnail/screenshot from a video at a mo
get_video_analysismcp:readRead the stored AI analysis of a video: scene-by-scene descriptions WITH timestamps, subjects, quotes, wardrobe, brands, spoken content, and tags. Every video i
inspect_videomcp:readRe-watch a video RIGHT NOW with Gemini agentic understanding and answer a specific question. Use when the stored analysis is not enough — exact quotes, on-scree
analyze_videomcp:write(Re)build the stored deep AI index on a video — dense scenes, quotes, wardrobe, brands, tags. Videos are analyzed automatically on arrival; use this only when t
detach_audiomcp:writeSplit a video's soundtrack into a separate AUDIO asset (MP3 in the asset library, usable as a timeline audio clip in Video Frames). Optionally also produce a mu
video_precisionmcp:writeFREE deterministic ffmpeg operations on a video (no AI, exact): trim (cut a time range), speed (0.25x-4x), reverse, loop, mute, volume, fade (in/out), resize, c
create_video_framemcp:writeCreate a VIDEO FRAME — a timeline artboard on the canvas for assembling videos: stack video clips, images, text overlays, and audio on tracks, preview live, the
get_video_framemcp:readRead a video frame's full timeline: tracks (volume, locked, order, hidden, muted, duck), clips (ids, z_index, timings, trims, speeds, volume, fades, audio_role,
add_video_frame_clipmcp:writeAdd a clip to a video frame's timeline: a canvas video/image/audio (by img_N) OR a text overlay. Audio without track_id uses a lane named Score / SFX / VO / Mus
update_video_frame_clipmcp:writeMove, trim, retime, restyle, or set a transition on one timeline clip (position, duration, source trim-in, speed 0.25-4, volume, mute, fade in/out, audio_role /
split_video_frame_clipmcp:writeCut one timeline clip into two at a timeline second (like pressing S at the playhead). Both halves keep source trims consistent.
remove_video_frame_clipmcp:writeRemove one clip from a video frame's timeline.
export_video_framemcp:writeCompile a video frame's timeline into ONE MP4 (ffmpeg render: cuts, overlays, text, mixed audio), or with format mp3 / wav into a mixed audio file with no pictu
preview_video_framemcp:writeRender one PNG of the timeline at at_sec with the same libass captions the export will burn. Use after adding/updating text — do not wait for a full MP4 to see
add_video_trackmcp:writeAdd a VIDEO / OVERLAY / AUDIO track to a video frame timeline. Use when assembling a multi-track reel (music bed, titles lane, B-roll) or when a score and SFX m
update_video_trackmcp:writePatch a video-frame track: name, mute, volume 0–2, lock, hide, reorder, or duck under speech / another track. name / muted / volume / locked / hidden / order /
delete_video_trackmcp:writeDelete a video-frame track and its clips. The frame must keep at least one track. Frame must keep at least one track.
update_video_framemcp:writePatch a video frame artboard (label, preset, export size, fps, background, audio_ducking) and/or batch-update clips in one resolve. Pass clips[] for trims/moves
promote_video_to_framemcp:writeCreate a Video Frame timeline beside an existing video card, with that video as the first clip. The original card stays. Pass video_id (img_N) or item_id. Pass
caption_videomcp:writeONLY when they asked for captions / subtitles / burned speech text on screen. Talking or VO does not auto-need this. Burns speech-synced captions onto a Video F
cancel_videomcp:writeCancel a VIDEO that is still generating. Only works while status is generating. Never charged. Do not use after the card is ready. Only while status is generati
cancel_blockingmcp:writeCancel a blocking (pre-viz) job that is still queued or running. Pass the blocking card's img_N. GPU work stops; the card is marked cancelled. Only while the jo
generate_speechmcp:generateVoiceover, dialogue, or narration. If list_audio_models marks has_prompting_guide for the TTS model, call get_prompting_guide once and write the text from that
design_voicemcp:generateCreate a reusable voice from a one or two sentence description (not a recording). Uses the admin engine: Eleven v4 on fal, or Gemini 3.8. Blocks until saved. Pa
clone_voicemcp:generateClone a real person's voice on Gemini 3.8 Flash TTS. Requires consent: true, consent_name, a reference recording, and a recording of Google's consent sentence.
generate_musicmcp:generateGenerate a music bed as a canvas audio card (default Lyria 3 Pro). If list_audio_models marks has_prompting_guide, call get_prompting_guide once and write the p
generate_sfxmcp:generateGenerate sound effects from text, or video-synced foley when video_id is set. If list_audio_models marks has_prompting_guide, call get_prompting_guide once and
compose_scoremcp:generateCompose a timed, non-vocal synth score that hits the moments in a video or Video Frame. Use when the user wants music that MATCHES the cut ('score this', 'hit t
revise_scoremcp:generateEdit an existing timed score in place (move a hit, change intensity) without rewriting from scratch. Edits an existing score. wait_for_audio({ score_id }).
get_scoremcp:readRead a timed-score job: status, steps, summary, cue notes, loudness report, and a URL for the Score JSON. Poll status / summary / warnings. Prefer wait_for_audi
analyze_musicmcp:writeTurned off. Do not call. Music analysis is disabled until drop detection is accurate.
get_music_analysismcp:readTurned off. Do not call. Music analysis is disabled until drop detection is accurate.
get_music_markersmcp:readTurned off. Do not call. Music analysis is disabled until drop detection is accurate.
inspect_musicmcp:readTurned off. Do not call. Music analysis is disabled until drop detection is accurate.
update_music_markersmcp:writeTurned off. Do not call. Music analysis is disabled until drop detection is accurate.
snap_clips_to_musicmcp:writeTurned off. Do not call. Music analysis is disabled until drop detection is accurate.
block_scenemcp:generateBLOCK A SCENE: build a low-fidelity 3D pre-viz ("blocking") of a shot — gray stand-ins for people/props on a simple set, choreographed marks, a real camera move
revise_blockingmcp:generateChange an existing blocking ("lower the camera", "make it a slow crane instead", "add a second person on the left", "make it 8 seconds"). Produces a new version
blocking_statusmcp:readWhere a blocking is: current step, step list, versions, artifacts. Only when the user asks how it is going — the card already shows live progress.
blocking_to_videomcp:generateMAKE IT REAL: generate the actual video from a blocking, using the canvas's selected video model (H3 Max default; Omni Flash or Seedance 2.5 if selected/named).
export_blockingmcp:readDownload a blocking artifact: the reference video (mp4), the 3D scene (glb), the editable scene file (blend), the top-down blocking diagram (png), the first/las
submit_product_feedbackmcp:writeSend a product report to the Photo Speak team (bugs, something broken, missing features, UX). Use when the user reports a problem / asks to send feedback, or wh
list_elementsmcp:readList saved characters, locations, products, and props (the Cast). Call this before inventing a name. Each row is el_N with kind, look counts, and bound TTS voic
get_elementmcp:readRead one element's bible (bio, story, profile), looks by role, bound TTS voice, voice clip, and recent appearances. Use before generating so you reuse identity
create_elementmcp:writeFile a reusable character, location, product, or prop. Kind defaults to character. Pass image_ids of look stills on this board (or asset_ids from the library).
update_elementmcp:writeEdit an element's bible, aliases, TTS voice, or kind. Does not change pixels. Edit bible, aliases, or tts_voice (catalog name or designed voice_id). Not pixels.
attach_element_assetmcp:writeLink a library asset or a board still (img_N) to an element as a look, face, wardrobe, voice clip, etc. First look becomes the hero. Tags the asset so search_as
detach_element_assetmcp:writeUnlink one look/clip from an element. Does not delete the library file. Unlink one look. Does not delete the library file.
create_contact_sheetmcp:generateGenerate a standardized multi-view contact sheet (model sheet) for a CHARACTER with Sunburst: front/3-4/profile/back, face close-ups, expressions, poses in one
regenerate_contact_sheetmcp:generateRe-run an existing contact sheet (same label, standard spec) for a fresh take. Pass evolution_notes / look / rows / cols to change the spec first. The previous
register_contact_sheetmcp:writeRegister an image you already have (image_id img_N or asset_id) as a character's contact sheet, with no generation and no cost. It shows in list_contact_sheets
list_contact_sheetsmcp:readList a character's contact sheets (one per era): label, look, grid, status, which is the default, and whether the character changed since it was generated. Shee
set_default_contact_sheetmcp:writeChoose which contact sheet is this character's identity reference for element_ids on generate tools (e.g. switch to the older-era sheet). Pick the sheet element
delete_contact_sheetmcp:writeRemove one contact sheet from a character. The images stay in the library. If it was the default, another sheet is promoted. Removes the sheet row; library imag
place_element_on_boardmcp:writeDrop an element's look stills onto the current board as new cards. Default roles are the identity refs (look/face/body for a character). Drop look stills onto t
create_motion_projectmcp:writeCreate a HyperFrames motion-graphics project from HTML (or a starter title card). Pass image_ids to pack canvas stills into the zip (assets/img_N.jpg) and files
update_motion_projectmcp:writeReplace the HTML (or files) on an existing motion card. Creates a new version on the SAME card. Then render_motion_project. Replace HTML on the same card. Then
edit_motion_projectmcp:writeRevise a motion project without resending HTML. Ops: setText, setStyle, setTiming, setVariable, setVariables, setMeta (HyperFrames SDK-compatible). Then render_
check_motion_projectmcp:readPreflight a motion composition: HyperFrames lint now, then the browser gate in the background (runtime errors, layout, motion assertions, empty frames, seek-ord
snapshot_motion_projectmcp:writeRender a still poster (the most detailed preflight frame of the first scene) in the media sandbox, HeyGen Cloud as fallback. Free. Free poster still.
render_motion_projectmcp:writeRender the motion card to MP4 (or webm) with HyperFrames: the media sandbox by default, HeyGen HyperFrames Cloud as fallback. The preflight gate runs first and
batch_render_motionmcp:writeVariable-driven batch render: same HTML, one HeyGen Cloud MP4 per row of variables. Returns a zip on the card. Free at default credits. One HTML, many variable
get_motion_projectmcp:readHTML, variables, versions, and job status for a motion card. HTML + versions + job.
list_motion_projectsmcp:readMotion projects on this board. Projects on this board.
search_motion_catalogmcp:readSearch the pinned HyperFrames catalog (blocks and components: name, type, description, tags). Returns no HTML. Then add_motion_block with one id. Search the pin
add_motion_blockmcp:writeFetch one catalog item into a motion project. A block is saved under compositions/blocks and mounted with data-composition-src. A component is saved as a file w
motion_videomcp:generateMOTION DIRECTOR: write HyperFrames HTML from a brief and render it. Use for designed/kinetic type, lower-thirds, charts, title cards when the user did not suppl
revise_motion_videomcp:generateRevise an existing motion graphic from a note ("make the headline red", "shorter"). Director writes a new version on the SAME card. Returns immediately. Returns
create_planmcp:generateDraft a multi-step production plan as its own canvas card. Returns immediately with plan_id. Then wait (do not poll): the card asks questions / requests accepta
get_planmcp:readRead a plan by plan_id: markdown, steps, pending review + answer_schema, deliverables. Authorization is by plan owner, not the current board. Markdown + steps +
list_plansmcp:readList this user's plans. attention:true = waiting on a human/agent answer. First call of any session: pick up where you left off. Cross-board for this user. Firs
update_planmcp:writeEdit future steps, review toggles, cadence, or title. Creates a new version. Does not run steps. Edits future steps / cadence / title (new version). Does not ru
pause_planmcp:writePause a running plan after current tool calls. Pause after current tool calls. Produced media stays.
resume_planmcp:writeResume a paused or blocked plan. Resume a paused or blocked plan.
cancel_planmcp:writeCancel a plan. Produced media stays. Nothing further is charged. Stop the plan. Produced media stays. Nothing further is charged.
steer_planmcp:writeAdd a note the director applies at the next wave (or mid-wave to the concerned subagent). Queue a note for the next wave. Do not run the steps yourself.
check_script_continuitymcp:readCheck a script for continuity errors: wardrobe, props, time of day, injuries, timeline, who knows what, plus unlinked speakers, characters with no voice and ele
script_reportmcp:readProduction breakdown of a script: a strip per scene (INT/EXT, location, time of day, pages, estimated runtime, cast, props, unlinked speakers), cast/location/pr
design_script_soundmcp:generatePlan the sound for one scene from its action lines and mood: one ambience bed, sound effects tied to the lines that call for them, and at most one music cue. Fo
plan_script_picturesmcp:writeAUDIO scripts: have an AI art director choose the moments of the story that deserve a picture and write each one's image prompt and cast (characters, location)
plan_script_wardrobemcp:generateHave an AI costume supervisor build each character's wardrobe chart across the whole story: which look they wear, the condition of their clothes (torn, soaked,
design_script_voicesmcp:generateDesign a voice for the script's characters who have none, and bind it to each one. An AI voice designer writes each voice from the character's description, voic
make_script_picturesmcp:generateAUDIO scripts: make the images for planned pictures that are missing or out of date, using the characters' and locations' looks as references. image_model picks
time_scriptmcp:writeAUDIO scripts: have the timing director set the spacing of a script: the silence before each line, sound and music block, overlaps and interruptions, how long b
compile_script_timelinemcp:writeCompile a script into its timeline: a Video Frame with the picture (video scripts: rendered video, else storyboard still, else a marked gap), every voiced line
make_script_animaticmcp:generateBuild a cheap animatic Video Frame: each shot's storyboard still held for its dialogue, with the voiced lines underneath. No video credits. Shots without a stor
localize_scriptmcp:generateMake a translated copy of a script for dubbing: dialogue is translated by the script model, characters, voices, shots and storyboards carry over, and video with
place_script_on_boardmcp:writePut a script (or a range of its scenes) on the board as a script card. Cards on the board give the agent that script's text as context, so edits and generations
list_scriptsmcp:readList the user's screenplay scripts: script_ref (scr_N), title, logline, format, scene and dialogue counts. Scripts are their own library, separate from the boar
get_scriptmcp:readRead a script. view outline (default): scenes with headings, moods, bound elements. full: every block with id, kind, speaker and binding (pass scene_refs to lim
write_scriptmcp:writeHand a writing job to the Script Writer, a screenwriting model that reads the user's characters, locations and script itself and writes scenes with dialogue lin
get_script_writer_jobmcp:readStatus of a write_script job: running, waiting (with the question the writer asked), done (with its summary and open questions), failed or cancelled.
answer_script_writermcp:writeAnswer the question a waiting write_script job asked, using what the user told you. Resumes the writer.
edit_scriptmcp:writeEdit a script with structured ops (insert_scene, insert_block, update_block, move_block, delete_block, bind_speaker, bind_scene_element, update_script for title
import_scriptmcp:writeImport a screenplay (Fountain, Final Draft XML, plain text) or prose into a script as scenes and blocks. Screenplays are copied verbatim; prose can be adapted (
export_scriptmcp:readExport a script as text: fountain, txt (typed layout), csv (one row per block), fdx (Final Draft XML) or srt (subtitles timed from voiced lines). For a PDF down
voice_scriptmcp:generateTurn script dialogue into speech with each linked character's bound voice. An AI voice director adds the emotion tags that the character's TTS engine understand
breakdown_scriptmcp:writeBreak scenes into shots for video: an AI director lists shots that cover every dialogue line, with framing, camera move, duration, the elements in frame, and a
render_script_shotsmcp:generateRender the video for shots. Pass shot_refs, scene_refs or neither (all missing shots). estimate_only returns credits per shot and total without spending. Each s
assemble_scriptmcp:writeLay the rendered shots of a script on a new Video Frame in script order, with voice-over shots' audio on the VO lane and optional subtitles. Refuses when shots
list_universesmcp:readList the user's story universes: id, name, logline, and how many works and cast members each has. Call this before creating a duplicate world.
get_universemcp:readRead one universe: canon rules, works in story order (series, seasons, episodes, films), cast billing, open threads, and how many canon facts are still waiting
create_universemcp:writeStart a story universe: a world that groups series, seasons, episodes, and films, and keeps canon across them. Elements stay in the user's library and are added
update_universemcp:writeRename a universe, change its logline or overall arc (synopsis), or rewrite its canon rules.
add_universe_workmcp:writeAdd a series, season, episode, film, short, or special to a universe. Episodes belong in a season or series. A script links only to an episode, film, short, or
update_universe_workmcp:writeChange a work's title, status, story date, parent, or linked script. status released means its facts are locked canon when you sync. story_order is the in-unive
add_universe_membermcp:writeAdd a filed character, location, prop, or product to a universe. The element stays in the library and can belong to other universes too. billing is main, recurr
record_canon_eventmcp:writeRecord a fact the user is stating as canon (not a guess from a script): a death, a revelation, a relationship, a world rule. It is canon immediately. Use sync_w
list_canonmcp:readList canon facts and story threads for a universe, in story order. status proposed means the fact was read from a script and is waiting for approval. status can
approve_canon_eventmcp:writeAccept a proposed canon fact so later works and the writer treat it as established.
retcon_canon_eventmcp:writeWithdraw a canon fact. Pass a replacement summary when the truth changed; omit it when the fact simply is no longer true. The old fact stays in the history as r
sync_work_canonmcp:writeQueue a canon sync for a work: the script is read in the background and compared with the canon already recorded for it. New facts are proposed (canon at once f
add_script_to_universemcp:writeAdd an existing script to a universe. The AI decides the work kind and where it sits (inside parent_work_id when you pass one), the script's characters and loca
start_universe_from_scriptsmcp:writeCreate a new universe from one or more existing scripts in one step. The AI reads the scripts and decides the universe name, logline and canon rules, which seri
resolve_canon_withdrawalmcp:writeSettle a canon fact that sync flagged as no longer supported by its script (proposed_action withdraw in list_canon). accept true retcons it; false keeps it as c
list_canon_issuesmcp:readList the places where a work's script clashes with canon: found when canon changed (ripple) or by a script continuity check. Each issue names the work, scene an
resolve_canon_issuemcp:writeClose a canon issue: resolved when the script was fixed, dismissed when it is not a real problem, open to reopen it.
create_openingmcp:writeMake an opening for a season, episode, film, short, or special: a theme of at most 15 seconds (exact length) and a title still painted from how the cast actuall
revise_openingmcp:writeChange an opening. part song writes a new theme (the previous one stays selectable). part keyframe repaints the title still; from_current edits the current pict
attach_openingmcp:writeUse an existing opening on another season, episode, or film. link shares it, so a later revision changes every work using it. copy keeps the song and can repain
create_threadmcp:writeTrack a story thread: a mystery to solve, an arc to follow, or a setup that needs a payoff. Returns thread_id, which storylines in a break can refer to.
update_threadmcp:writeChange a story thread's title, kind, notes, or status (open, paid_off, dropped).
delete_threadmcp:writeDelete a story thread for good. To close one that was resolved, use update_thread with status paid_off or dropped instead. Ask the user first.
reorder_worksmcp:writeSet the order of works. axis story is the in-universe order and must list every work in the universe, once. axis release orders the children of one parent (pare
remove_universe_workmcp:writeRemove a work from the universe. Its script, if it has one, stays in the user's library. A work that still has works inside it cannot be removed; remove or move
update_universe_membermcp:writeChange a cast member's billing (main, recurring, guest) or their canon notes.
remove_universe_membermcp:writeTake a character, location, prop, or product out of a universe's cast. The element stays in the library. Ask the user first.
create_phasemcp:writeCreate a phase: a group of films and seasons that make one chapter or saga of the universe, with its own arc. Works join it with phase_id on add_universe_work,
update_phasemcp:writeRename a phase, rewrite its arc, or move it in the order of phases (a smaller order comes first).
delete_phasemcp:writeDelete a phase. Its works stay in the universe and simply leave the group. Ask the user first.
get_arc_boardmcp:writeRead the plan for one arc: its overall arc, the planned arc of each character, and every work in it in story order with its status, tentpole, logline, A/B/C sto
break_arcmcp:writeBreak a story: set an arc and lay out its works, with no scripts written. Creates new works at status idea, or revises existing ones, in one call. Each work car
set_character_arcsmcp:writePlan how characters change over an arc: where each starts and where each ends. Pass work_id for a series or season, phase_id for a phase, or neither for the who
outline_worksmcp:writeHand works to the Outliner, a background writer that turns each work's saved break into a skeleton script: a logline, the beats grouped by storyline, and scene
get_outline_jobmcp:writeStatus of an outline_works job: running (with which works are saved), done (with its summary and open questions), error or cancelled. Only check when asked or w
cancel_outline_jobmcp:writeStop a running outline job. Outlines it already saved are kept; the creator can undo them from the job card.

Auth & safety

OAuth 2.1 + PKCE. Scopes: mcp:read, mcp:write, mcp:generate. Revoke apps and tokens on My account. We never see your Cursor or Claude keys.

Human docs live at /mcp. The protocol is /api/mcp — do not mix them up.

Connect Agent from the canvas

Signed in? Click Connect Agent on any board for install commands and a pairing code.

Open Photo Speak