Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Clueso

REMOTE · CONNECT.CLUESO.IO

Make videos and docs with your AI agent — describe what you need, every output stays editable.

−1 this week 90 Trust /100

Last scanned (10 hours ago)

Scores higher than 98% of remote servers

Reachable. Last reached 5 Nov 2026.

Category Design and Media

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security89
Transport & Reachability100
Schema Quality & AI Usability73
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 42092 tokens (~568/item across 74 items; 55 tools + 19 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management98
  • Stability check failed: schema churn in the 30 days we've observed: 1 tool removals, 0 breaking changes, 0 auth/transport breaks, 7 additions. See how to fix → Fail
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 99% of tool parameters carry a description.Partial
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • All 3 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
  • An AI judge read all 57 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 5 Nov 26 0
    • The server rewrote its instructions, which are the text every model session reads security
    • New tool “translation_glossary”, which the server declares destructive security
    • Tool “add_article_media” rewrote its description, which is the text the model reads security
    • Tool “add_elements” rewrote its description, which is the text the model reads security
    • Tool “captions” rewrote its description, which is the text the model reads security
    • Tool “edit_animation” rewrote its description, which is the text the model reads security
    • Tool “read_animation” rewrote its description, which is the text the model reads security
    • Tool “run_script” rewrote its description, which is the text the model reads security
    • New tool “get_media_job” functional
    • “remove_elements” added an optional parameter “clip_index” cosmetic
    • “remove_elements” added an optional parameter “element_ids” cosmetic
    • “get_clip” reworded the description of “select” cosmetic
    • “remove_elements” reworded the description of “removals” cosmetic
    • “edit_animation” dropped the optional parameter “target” cosmetic
    • “remove_elements” made “removals” optional cosmetic
  • 4 Nov 26 −1
    • The server rewrote its instructions, which are the text every model session reads security
    • Tool “add_audio” rewrote its description, which is the text the model reads security
    • Tool “add_elements” rewrote its description, which is the text the model reads security
    • Tool “edit_animation” rewrote its description, which is the text the model reads security
    • Tool “find” rewrote its description, which is the text the model reads security
    • Tool “get_clip” rewrote its description, which is the text the model reads security
    • Tool “get_design_guide” rewrote its description, which is the text the model reads security
    • Tool “read_animation” rewrote its description, which is the text the model reads security
    • Tool “run_script” rewrote its description, which is the text the model reads security
    • Tool “upload_file” rewrote its description, which is the text the model reads security
    • Resource “animation-guide” was removed ▼ functional
    • New resource “guide-pages” functional
    • “edit_animation” added an optional parameter “confirm_breaking” cosmetic
    • “edit_animation” added an optional parameter “for_element” cosmetic
    • “edit_animation” added an optional parameter “probe” cosmetic
    • “edit_animation” added an optional parameter “request” cosmetic
    • “edit_animation” added an optional parameter “wait_s” cosmetic
    • “get_design_guide” added an optional parameter “path” cosmetic
    • “get_design_guide” added an optional parameter “skill” cosmetic
    • “read_animation” added an optional parameter “rev” cosmetic
    • “edit_animation” reworded the description of “animation” cosmetic
    • “edit_animation” reworded the description of “base_rev” cosmetic
    • “edit_animation” reworded the description of “checkpoint” cosmetic
    • “edit_animation” reworded the description of “detail” cosmetic
    • “edit_animation” reworded the description of “dry_run” cosmetic
    • “edit_animation” reworded the description of “edits” cosmetic
    • “edit_animation” reworded the description of “element_id” cosmetic
    • “edit_animation” reworded the description of “files” cosmetic
    • “edit_animation” reworded the description of “folder” cosmetic
    • “edit_animation” reworded the description of “name” cosmetic
    • “edit_animation” reworded the description of “patch” cosmetic
    • “edit_animation” reworded the description of “place” cosmetic
    • “edit_animation” reworded the description of “preview” cosmetic
    • “edit_animation” reworded the description of “project_id” cosmetic
    • “edit_animation” reworded the description of “scope” cosmetic
    • “edit_animation” reworded the description of “slug” cosmetic
    • “edit_animation” reworded the description of “target” cosmetic
    • “edit_animation” reworded the description of “upload_ids” cosmetic
    • “find” reworded the description of “detail” cosmetic
    • “find” reworded the description of “page” cosmetic
    • “find” reworded the description of “project_id” cosmetic
    • “get_design_guide” reworded the description of “topic” cosmetic
    • “read_animation” reworded the description of “all” cosmetic
    • “read_animation” reworded the description of “animation” cosmetic
    • “read_animation” reworded the description of “element_id” cosmetic
    • “read_animation” reworded the description of “format” cosmetic
    • “read_animation” reworded the description of “path” cosmetic
    • “read_animation” reworded the description of “pattern” cosmetic
    • “read_animation” reworded the description of “project_id” cosmetic
    • “read_animation” reworded the description of “range” cosmetic
    • “edit_animation” dropped the optional parameter “update_dependents” cosmetic
    • “get_design_guide” dropped the optional parameter “query” cosmetic
    • Tool “edit_animation” changed its title: Edit an animation → Edit an HTML animation cosmetic
    • Tool “read_animation” changed its title: Read an animation → Read an HTML animation cosmetic
  • 3 Nov 26 +1
    • New resource “animation-guide” functional
  • 31 Oct 26 −1
    • Tool “find” rewrote its description, which is the text the model reads security
    • Tool “update_clips” rewrote its description, which is the text the model reads security
    • Resource “animation-guide” was removed ▼ functional
    • “find” reworded the description of “source” cosmetic
  • 30 Oct 26 0
    • New resource “animation-guide” functional
  • 29 Oct 26 0
    • Tool “add_article_media” rewrote its description, which is the text the model reads security
    • Tool “export_project” rewrote its description, which is the text the model reads security
    • Tool “get_article” rewrote its description, which is the text the model reads security
    • Tool “update_article” rewrote its description, which is the text the model reads security
    • Resource “animation-guide” was removed ▼ functional
    • “add_article_media” added an optional parameter “after” cosmetic
    • “add_article_media” added an optional parameter “aspect_ratio” cosmetic
    • “add_article_media” added an optional parameter “prompt” cosmetic
    • “add_article_media” added an optional parameter “replace” cosmetic
    • “add_article_media” added an optional parameter “style_id” cosmetic
    • “update_article” added an optional parameter “article_version” cosmetic
    • “export_project” reworded the description of “format” cosmetic
  • 28 Oct 26 0
    • Tool “find” rewrote its description, which is the text the model reads security
    • Tool “remove_clip” rewrote its description, which is the text the model reads security
    • Tool “split_clip” rewrote its description, which is the text the model reads security
    • Tool “update_clips” rewrote its description, which is the text the model reads security
    • Tool “update_elements” rewrote its description, which is the text the model reads security
    • New resource “animation-guide” functional
    • New resource “element-schema-form” functional
    • New resource “element-schema-question” functional
    • New resource “element-schema-results” functional
    • “find” added an optional parameter “similar_to” cosmetic
    • “find” added an optional parameter “avoid” cosmetic
    • “find” added an optional parameter “bpm_max” cosmetic
    • “find” added an optional parameter “bpm_min” cosmetic
    • “find” added an optional parameter “energy” cosmetic
    • “find” added an optional parameter “genre” cosmetic
    • “find” added an optional parameter “mood” cosmetic
    • “find” added an optional parameter “sfx_type” cosmetic
    • “find” added an optional parameter “vocals” cosmetic
    • “find” reworded the description of “provider” cosmetic
    • “get_clip” reworded the description of “select” cosmetic
    • “get_element_schema” reworded the description of “element_type” cosmetic
  • 27 Oct 26 0
    • The server rewrote its instructions, which are the text every model session reads security
    • New tool “manage_brand_kit”, which the server declares destructive security
    • Tool “create_clueprint” rewrote its description, which is the text the model reads security
    • Tool “create_project” rewrote its description, which is the text the model reads security
    • Tool “find” rewrote its description, which is the text the model reads security
    • Tool “get_clueprint” rewrote its description, which is the text the model reads security
    • Tool “get_design_guide” rewrote its description, which is the text the model reads security
    • Tool “get_project” rewrote its description, which is the text the model reads security
    • Tool “set_voice” rewrote its description, which is the text the model reads security
    • Tool “update_clueprint” rewrote its description, which is the text the model reads security
    • Tool “update_project” rewrote its description, which is the text the model reads security
    • Resource “animation-guide” was removed ▼ functional
    • “create_clueprint” added an optional parameter “brand_locked” cosmetic
    • “create_project” added an optional parameter “brand_kit_id” cosmetic
    • “find” added an optional parameter “brand_kit_id” cosmetic
    • “find” added an optional parameter “library” cosmetic
    • “get_design_guide” added an optional parameter “brand_kit_id” cosmetic
    • “get_design_guide” added an optional parameter “clueprint_id” cosmetic
    • “get_design_guide” added an optional parameter “project_id” cosmetic
    • “update_clueprint” added an optional parameter “brand_locked” cosmetic
    • “update_project” added an optional parameter “brand_kit_id” cosmetic
    • “find” reworded the description of “detail” cosmetic
    • “find” reworded the description of “project_id” cosmetic
    • “get_design_guide” reworded the description of “select” cosmetic
    • “record_screen” reworded the description of “voice_version” cosmetic
    • “set_voice” reworded the description of “voice_version” cosmetic
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 5 Nov 2026 · Probed https://connect.clueso.io/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=connect.clueso.io CN=Amazon RSA 2048 M01,O=Amazon,C=US 21 Sept 2026 6 Apr 2027 RSA 2048 SHA256-RSA 6811120213476e032df46bf730d66ce
SANs: connect.clueso.io, connect.eu.clueso.io
CN=Amazon RSA 2048 M01,O=Amazon,C=US (CA) CN=Amazon Root CA 1,O=Amazon,C=US 23 Aug 2022 23 Aug 2030 RSA 2048 SHA256-RSA 77312380b9d6688a33b1ed9bf9ccda68e0e0f
CN=Amazon Root CA 1,O=Amazon,C=US (CA) CN=Starfield Services Root Certificate Authority - G2,O=Starfield Technologies\, Inc.,L=Scottsdale,ST=Arizona,C=US 25 May 2015 31 Dec 2037 RSA 2048 SHA256-RSA 67f944a2a27cdf3fac2ae2b01f908eeb9c4c6

Background: What to check on a remote MCP endpoint →

DNSSEC insecure

Validation of connect.clueso.io. — Not signed

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
io. present 38690 8 Verified
clueso.io. absent Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation
Authentication Enforced and verified

The endpoint asked for a token and published valid RFC 9728 metadata describing how to get one.

Result Enforced and verified
Enforced On tool calls
HTTP status 200

WWW-Authenticate challenge Bearer resource_metadata="https://connect.clueso.io/.well-known/oauth-protected-resource/mcp"

Bearer resource_metadata="https://connect.clueso.io/.well-known/oauth-protected-resource/mcp"

Protected resource metadata

Document https://connect.clueso.io/.well-known/oauth-protected-resource/mcp
Retrieved Yes
Resource https://connect.clueso.io/mcp
Authorisation server https://auth.clueso.io/oauth/2.1

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://connect.clueso.io/mcp Verified 200
http (plaintext) http://connect.clueso.io/mcp HTTPS enforced
MCP tools · 55 exposed · ~37,689 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
reorder_elements ~223

Reorder the elements inside a clip. List position IS the z-index — later entries in `ordered_element_ids` render on top of earlier ones. You MUST pass the full set of element IDs currently in the clip. The handler rejects partial lists so a reorder can never silently drop an element. Get the current list via get_clip — the order it returns is exactly the order this takes. Works on grouped clips. Elements keep their group; moving a group's members together moves the whole group relative to everything else. The one thing a group cannot do is render in two pieces, so an order that puts a non-member BETWEEN two members of the same group is rejected and names the group — put the group's elements next to each other, or take the element out of the group first with update_elements(group).

NameTypeReqDescription
clip_indexintegeryesZero-based clip index.
ordered_element_idsarrayyesAll element IDs currently in the clip, in the new order. Position N = z-index N (later = on top).
project_idstringyesProject ID.

No output schema declared.

No examples provided.

run_script ~2,636

Write a JavaScript program that calls this server's other tools. You have the whole language: loops, arithmetic, functions, conditionals, and values carried from one call into the next — all running next to the tools instead of across the conversation. Use it whenever code says the thing more directly than a sequence of separate calls would, which is often. COMPUTE, don't hand-write. Anything you would otherwise work out in your head and type as literals is better computed here — eased keyframe tracks, staggered start times, grid coordinates, derived palettes, positions from measured text widths. This is usually what makes motion look right: sample a curve at ten points and emit the values, rather than guessing four. THE STDLIB IS LOADED: anim (interpolate, spring, stagger, cues), ease, math, vec, rng, noise, color, scale, layout (row, column, grid, split, place, inset), shape, path, camera, field. `native` turns their values into editable elements (effects over a recording, captions, translatable copy; visuals themselves are pages): native.box(rect) and native.text(rect, {align, valign, ...type_data}) place elements from layout rects; native.tween(start, duration, from, to, {ease: "power3.out"}) gives two keyframes an editor can drag; native.keys(start, end, (t) => props) samples a spring or any curve; native.merge(...lists) combines tracks; native.hex(colour). Signatures: get_design_guide({select: ['stdlib', 'stdlib.<module>', 'stdlib:<words>']}). const cards = layout.row({ x: 160, y: 380, w: 1600, h: 300 }, [{}, {}, {}], { gap: 48 }); add_elements({ project_id, defaults: { clip_index: 0, element_type: "rectangle" }, elements: cards.map((r, i) => ({ ...native.box(r), type_data: { backgroundColor: "#1E1A26" }, keyframes: native.tween(1.2 + anim.stagger(i, 3, { each: 0.12, from: "center" }), 0.5, { opacity: 0, positionY: r.y + 40 }, { opacity: 100, positionY: r.y }, { ease: "back.out" }) })) }); DON'T COMMENT THE SCRIPT. Nobody reads it — it runs once a…

NameTypeReqDescription
codestringyesJavaScript. Tools are globals called synchronously — no async/await, no network or filesystem; `return` a value to hand it back.
dry_runboolean–Read-only tools still run; anything that writes is recorded and skipped. Use it to check what a script would do before it does it.
idempotency_keystring–Pass a unique string so a retry cannot run the same build twice. If a script with this key already ran in this workspace, its job is returned and nothing executes again — including when that run FAIL…
timeout_secondsinteger–Wall-clock budget for the SCRIPT — separate from wait_seconds, which is only how long this call stays open. By default a script gets 50s while you are waiting on it, and is raised to 15 minutes the m…
wait_secondsinteger–How long to hold this call open waiting for the script, default 50s. If it finishes in time you get the result here; if not you get a job_id to poll with get_script_job, and the script keeps running…

No output schema declared.

No examples provided.

set_voice ~405

Set the voiceover voice for every clip in a project, or only for the clips in `clip_ids`. Use this to apply a clueprint's voice (read `voiceover.voice.name` and `voiceover.voice.engine` from the clueprint source data), or to switch all clips to a specific voice in one call. When the user names specific clips, pass their ids in `clip_ids` so the other clips keep their voice. The voice is looked up by name (case-insensitive; a saved voice's code also works), preferring `voice_engine`. Never guess a name: a name that matches nothing applies the workspace default and returns `matched: false` with a note. Then pick a real voice with find(type='voices'), re-apply, and tell the user. `engine_substituted: true` means the named voice exists only on another engine and was applied there. Common engines: 'eleven' (ElevenLabs), 'cartesia', 'google'. ElevenLabs voices use the latest voice generation unless `voice_version` says otherwise; a voice the workspace saved keeps its saved version. Leave it unset; pass "legacy" ONLY when the user explicitly asks for the legacy/older voice generation.

NameTypeReqDescription
clip_idsarray–Clip ids to change the voice on. Omit to change EVERY clip in the project.
project_idstringyesThe project (guide) ID
voice_enginestringyesVoice engine — 'eleven', 'cartesia', 'google', etc.
voice_namestringyesVoice name exactly as find(type='voices') lists it (e.g. 'Alex').
voice_versionstring–ElevenLabs voice generation. Leave unset: latest, except a voice the workspace saved keeps its saved version. Use 'legacy' ONLY when the user explicitly asks for the legacy/older voice generation; ne…

No output schema declared.

No examples provided.

split_clip ~243

Split a video clip into two clips at the given timestamp. The left clip keeps the original clip ID; the right clip gets a new ID and is inserted immediately after. Elements spanning the split point are duplicated into both clips with adjusted timing. Exception: a question, results card, form, or any element with a clickaction stays whole in the left clip (trimmed to end at the split), so it is never asked or paused on twice. Voiceover transcript and transcribed words are split proportionally. Concurrency: whole-project mutation (conflict domain: the entire project) — serialize. Do not run it in parallel with ANY other mutation on the same project_id, including element/voiceover edits; run them one at a time. (Mutations to different projects run in parallel freely.)

NameTypeReqDescription
clip_indexintegeryesIndex of the clip to split
project_idstringyesThe project ID
split_timenumberyesTime in seconds within the clip where to split (clip-relative, not timeline-relative). Must be > 0.1s and < clip_duration − 0.1s; values outside this range are rejected.

No output schema declared.

No examples provided.

switch_workspace ~65

Switch the active workspace. The choice sticks for this client until you change it again — including across reconnects — so every later call operates in the new workspace. Use find(type='workspaces') to see available options.

NameTypeReqDescription
workspaceIdstringyesWorkspace ID to switch to

No output schema declared.

No examples provided.

translation_glossary ~681

Read and edit the workspace's translation glossary and translation rules (Settings → Translation). Every translation in the workspace follows them: captions translate, translated videos and articles. Use it when the user says how a term must be translated, that a product or brand name must stay untranslated, or how translations into a language should read (tone, formality). Do NOT hand-edit translated captions or text for this instead: the next translation repeats the mistake. Glossary terms: `original` (source text) → `translated` (the original itself keeps it as is), for `languages` (codes or names; omit for every language), optionally `case_sensitive`. Rules: ONE per language: `prompt` (instructions the translator follows), optional `title` and `examples` [{original, translation}]. Changes are WORKSPACE-WIDE and apply to translations made after them: tell the user when you add or change one, and translate again (captions action "translate") what should pick them up. action: • list — {terms: [{term_id, original, translated, languages, case_sensitive}], term_count, rules: [{rule_id, title, language, prompt, examples}]}; `language` keeps what applies to it, `query` filters terms by text (at most 200 terms per reply) • set_term — add a term or change one. An existing term is not overwritten: you get error "entry_exists" with `current`; show the user both, confirm, then call again with replace: true. Several terms with the same original → error "several_terms": pass the `term_id` you mean. • remove_term — delete the term with this `original` (exact text) or `term_id` • set_rule — set `language`'s rule; an existing one needs replace: true after the user confirmed (same "entry_exists" reply) • remove_rule — delete `language`'s rule Editing needs an editor or admin role, and saving needs a plan with the translation glossary (Enterprise); a refusal says which: tell the user, don't retry.

NameTypeReqDescription
actionstringyes–
case_sensitiveboolean–set_term: match only this exact casing (default false; unchanged on a replace).
examplesarray–set_rule: example translations the rule follows.
languagestring–set_rule/remove_rule: the target language (code or name); list: keep what applies to it.
languagesarray–set_term: target language codes or names; [] for every language. Omitted: every language on a new term, unchanged on a replace.
originalstring–set_term/remove_term: the term as written in the source language.
promptstring–set_rule: the instructions for this language.
querystring–list: keep terms whose text contains this.
replaceboolean–set_term/set_rule: overwrite an existing entry, only after the user confirmed.
term_idstring–set_term/remove_term: one term from list, when several share an original.
titlestring–set_rule: a label (default the language name).
translatedstring–set_term: what the term becomes in the translation.

No output schema declared.

No examples provided.

update_article ~198

Update article text content from markdown. Use <SCREENSHOT {id}> placeholders to position screenshots. Screenshots in the markdown are kept. Screenshots removed from markdown are deleted. Order in markdown defines final order. Keep each <EMBED {id}> placeholder unchanged, or what it stands for is deleted. Get the current article first with get_article, modify the markdown, then call this with the article_version of the article you edited (from get_article, or from your last add_article_media / update_article_media / update_article on it). If the article changed since, the update is refused: read it again and redo the change.

NameTypeReqDescription
article_versionstring–The article_version of the article this markdown was written from. Recommended: without it, an edit someone else made since is overwritten.
markdownstringyesUpdated article content as markdown with <SCREENSHOT {id}> placeholders
project_idstringyesProject ID

No output schema declared.

No examples provided.

update_article_media ~231

Update an article image/GIF (screenshot), or inspect its current state. - Provide one or more of `zoom_factor`, `crop`, `shapes` to change metadata. - Pass `render=true` (with no other updates) to fetch the current details without mutating. To DELETE an article image/GIF: call `update_article` with markdown that omits the `<SCREENSHOT id>` reference. Unreferenced media is pruned server-side on save. There is no separate delete tool — the markdown IS the source of truth for what's present.

NameTypeReqDescription
cropobject–Crop data: { position: [x,y], size: [w,h] } in fractional coords.
project_idstringyesProject ID.
renderboolean–If true (and no other updates supplied), returns current details and a PNG preview without mutating.
screenshot_idstringyesScreenshot ID (from get_article).
shapesarray–Array of shape objects for annotations.
zoom_factornumber–Zoom magnification (1.0 = no zoom).

No output schema declared.

No examples provided.

update_audio ~252

Mutate fields on an existing music/SFX track by id. Read existing tracks via `get_project.audio_tracks` — the per-entry shape there matches this tool's args, so you can flip a knob (volume, fades, timing, loop) and write it back without losing the track's id. Only fields you pass are changed; omitted fields are preserved. To delete a track entirely, use `remove_from_project(target='audio')` instead.

NameTypeReqDescription
fade_innumber–Fade-in duration (seconds)
fade_outnumber–Fade-out duration (seconds)
guide_end_timenumber–New end time on the project timeline (seconds)
guide_start_timenumber–New start time on the project timeline (seconds)
loop––Whether the track loops
music_end_timenumber–New end offset within the source file (seconds)
music_idstringyesID of the audio track (from get_project.audio_tracks[].id)
music_start_timenumber–New start offset within the source file (seconds)
project_idstringyesThe project ID
volumenumber–New playback volume 0-100

No output schema declared.

No examples provided.

update_clips ~1,305

Update one or more clips in a single call — background, transition, duration, title, visibility, position, and (video clips) the footage transform via video_styling. Always batch. Each entry: { clip_index, duration?, title?, background_color? | background?, transition?, hidden?, position?, voiceover_volume?, video_styling?, after_clip?, subtitle_settings? } - duration: sets the clip's length WITHOUT rescaling anything (unlike generating speech, which rescales the whole clip). A shrink clamps every end_time past the new end to it; a grow carries an element that ended at the old end to the new end and leaves the rest where they were. A placed trim animation keeps its animation_duration: it holds its last frame on a grow and is cut on a shrink; only a stretch animation placed to fit keeps filling its window at the same speed. Keyframes keep their timestamps. Each clip's result lists what moved as extended / clamped. - voiceover_volume: 0-100. This is how you make a clip SILENT — set 0 to mute the narration while keeping the text and its word timings. get_clip and get_project report the current value, so read it before muting to restore it later. There is no "delete voiceover" tool; muting is the supported way. - background_color: hex (keeps the existing pattern/image, changes color). background: replaces the whole background — a full object from find(type='backgrounds'), or any image/video: { src (URL or upload id), media_type?: 'image'|'video' (inferred), color?, padding? (% around the footage, 0-100), border_radius? (px), shadow? (0-100), volume? (a video's audio, 0-100, default 100) }. - transition: { type, duration, direction?, color?, bezier? }, or null to remove. Set on the OUTGOING clip — the transition plays at the END of clip_index, into the next clip. Types: circleWipe, rainbowWipe, cornerWipe, stack, colorWipe, dissolve, pushPull, fadeToColor, flip. Directions: rainbowWipe/cornerWipe take topLeft|topRight|bottomLeft|bottomRight; colorWipe left|right; stack…

NameTypeReqDescription
project_idstringyesProject ID
updatesarrayyesOne entry per clip to update.

No output schema declared.

No examples provided.

update_clueprint ~481

Update a clueprint's metadata and/or file contents in one call. Metadata fields (`name`, `description`, `tags`, `visibility`, `thumbnail_path`) are applied as a patch — only the fields you pass change. Pass at least one to update metadata. `files` is a list of file mutations: - Write text: `{ path, content }` - Write binary: `{ path, content, encoding: "base64" }` - Write from URL: `{ path, source_url }` (presigned URL, e.g. from get_clip with save=true) - Delete: `{ path, content: null }` You can mix writes and deletes in a single call. Existing files at the same path are overwritten. `brand_locked`: true keeps the clueprint's own colors, fonts and logos for projects in this workspace; false (the default) re-skins them to each project's brand kit. Only this workspace's clueprints; a community clueprint is always re-skinned. `decisions` records the build-time choices create_clueprint left pending, after you ask the user: animation_modes / image_modes ({id: mode}), voiceover_policies ({source_clip_id: policy}), split_decision, slide_count_strategy, allowed_element_types, the *_by_role variants for all-slides sources ({role: ...} from the *_by_role groups), and finalize_layout_texts: true (once every layouts/<NN>-<slug>/layout.md exists). Each applies on its own; failures come back in decision_errors.

NameTypeReqDescription
brand_lockedboolean–true: projects built from it keep its own colors, fonts and logos; false: re-skinned to each project's brand kit.
clueprint_idstringyesID of the clueprint to update.
decisionsobject–Build-time decisions to record (see the description).
descriptionstring–New description.
filesarray–File mutations — writes and deletes. Empty/omitted for metadata-only updates.
namestring–New name.
tagsarray–New tags (replaces existing).
thumbnail_pathstring–Relative path of a screenshot in the clueprint to use as thumbnail (e.g. 'screenshots/title-slide.png').
visibilitystring–New visibility.

No output schema declared.

No examples provided.

update_elements ~1,138

Update many elements across one or more clips in a single tool call. Replaces the per-element tool — always batch. SEND LESS, GET BACK LESS. `defaults` carries what every item shares (clip_index, element_type, and type_data entries like font_setting or alignment) so you send it once instead of per item; each item overrides any key it sets. `returning` declares what comes back, the way `select` shapes a get_clip read — omit it for a sensible default, or pass [] for just the counts. defaults: { clip_index: 1, element_type: 'text', type_data: { font_setting: {...} } } returning: [] → { total, succeeded, failed }, plus error codes + element ids if any returning: ['layout'] → + the measured text fit per element returning: ['qa.codes'] → + the clip audit with prose stripped from non-errors (any returning value → error findings regardless; only warnings are opt-in) Each item can update position/timing fields alone, or type-specific fields via type_data (use get_element_schema in 'update' mode to see what's settable for an element_type). Items within one call are applied in order; partial success is fine. Interactive elements (question/results/form): options and form fields sent WITHOUT an id keep the id of the stored one with the same text/label, so reordering is safe; the merged result is re-checked (answer key, jump targets, logic options). On a text or shape, type_data.clickaction: null removes its click action; a partial clickaction keeps the stored wait_for_click/wait_at. You do NOT need clip_index here — an element_id is unique within the project, so the server locates the clip itself. Pass it only as a hint; a wrong one is corrected rather than rejected. Grouping: pass `group: "<name>"` to move an element into a named group (created on demand), or `group: ""` to pull it back out to the clip root. Several items sharing a name collect into one group — the way to tidy loose elements into units the user can move or hide together. Grouping…

NameTypeReqDescription
defaultsobject–Values shared by every item, sent once rather than repeated. Items win per key; type_data merges one level. E.g. defaults:{clip_index:1, element_type:'text', type_data:{font_setting:{font:'Inter',wei…
project_idstringyesProject ID
returningarray–What comes back, the way get_clip's `select` shapes a read. Omitted: ids, the measured layout and the clip audit in compact form. 'ids': element_id per result. 'layout': the measured text fit (font_s…
updatesarrayyesElement updates — at least one entry.

No output schema declared.

No examples provided.

update_groups ~917

Transform, keyframe, rename, nest or lock GROUPS. A group moves, scales, rotates and fades as ONE unit, without touching any child's stored position — which is how you get a camera push instead of building the target layout twice and crossfading it. Address by `group_id`, never by name. Ids come from get_clip, or from the `group_id` that add_elements/update_elements hands back when you pass `group`. An unknown id is an error, never a silent create. There is no add_groups: a group is CREATED by putting elements in one — `add_elements(group: "hero-card")` — which also returns its id. That is not a shortcut; a group's pivot comes from its children's bounding box, so an empty group has no geometry to transform. The shortest path, in one script: const clip = get_clip({ project_id, clip_index: 2, select: ["groups"] }); const byName = new Map(clip.groups.map(g => [g.name, g.id])); update_groups({ project_id, items: [{ clip_index: 2, group_id: byName.get("hero-card"), anchor_px: [960, 540], keyframes: [ { timestamp: 0, scaleX: 1, scaleY: 1 }, { timestamp: 1.2, scaleX: 2.4, scaleY: 2.4, offsetX: -400, offsetY: -120, interpolation: "easeOut" }, ], }]}); Units are canvas pixels, as everywhere else: `offset_px`, `blur_px` and `anchor_px` are pixels; `scale` is a multiplier; `rotation`/`rotate` are degrees; `opacity` is 0-100. `anchor_px` is the pivot everything rotates and scales about. Give it as a point on the canvas — the server converts it to a fraction of the group's child bounding box and reports back both that fraction and the box, so you can check it. Default is the box's centre. Set it when you want a push that favours one corner. Because it is stored as a fraction of the members' box, adding or removing members moves the pivot on the canvas; set `anchor_px` again after changing a transformed group's membership. Only fields you pass are changed. `keyframes: []` CLEARS every track; omitting `keyframes` leaves them…

NameTypeReqDescription
itemsarrayyesOne entry per group to update
project_idstringyesThe project ID
returningarray–What comes back, the way get_clip's `select` shapes a read. Omitted: ids, the measured layout and the clip audit in compact form. 'ids': element_id per result. 'layout': the measured text fit (font_s…

No output schema declared.

No examples provided.

update_project ~653

Update a project's metadata: rename, change description, move to a different folder, or change aspect ratio. Only fields you provide are changed. To move a project to the workspace root, pass folder_id="" (or "root"). Aspect ratio: pass any "W:H" (positive integers). The canvas is fit inside 1920×1080 keeping the ratio, so element pixel coordinates use the resulting canvas. Common values: - "16:9" → 1920×1080 (landscape, YouTube/web — default) - "9:16" → 608×1080 (portrait — TikTok/Reels/Shorts) - "1:1" → 1080×1080 (square — Instagram feed) - "3:4" → 810×1080 (portrait card) - "4:5" → 864×1080 (portrait — Instagram feed) Element coordinates are stored as fractions of the canvas, so existing elements reflow to the new canvas automatically — no element coordinates are rewritten. Brand kit: brand_kit_id sets the kit this project is built with (an id from find(type='brand_kits')); 'default' returns it to following the workspace default kit. It changes the kit get_design_guide({project_id}) returns; elements already placed keep their colors, fonts and logos until you edit them. The reply's brand_kit is {id, name, follows_default}. Only workspace editors and admins can change it. Tags: add_tags / remove_tags change the project's tags (the home page Tags menu and filter), by NAME. Adding a name the workspace doesn't have creates it; existing names match ignoring case. List them with find(type='tags'). Only workspace editors and admins can change tags. To tag many projects, loop update_project over their ids in run_script. When tags are given, the reply also has tags (the project's full list after the change), created_tags and not_found_tags (remove_tags names the workspace doesn't have). Concurrency: whole-project mutation (conflict domain: the entire project) — serialize. Do not run it in parallel with ANY other mutation on the same project_id, including element/voiceover edits; run them one at a time. (Mutations to different projects run in parallel freely.)

NameTypeReqDescription
add_tagsarray–Tag names to add; missing tags are created.
aspect_ratiostring–New aspect ratio as 'W:H' (positive integers). Common: '16:9' landscape, '9:16'/'4:5'/'3:4' portrait, '1:1' square.
brand_kit_idstring–Brand kit for this project: an id from find(type='brand_kits'), or 'default' to follow the workspace default kit.
descriptionstring–New description
folder_idstring–New folder ID. Pass '' (empty string) to move to workspace root.
project_idstringyesThe project ID to update
remove_tagsarray–Tag names to remove.
titlestring–New project title

No output schema declared.

No examples provided.

upload_file ~1,170

Upload one or more files to Clueso. Pick a mode by client + where the file lives: 0. **files** — ChatGPT only: files the user attached in the conversation. ChatGPT fills each entry (download_url + file_id) itself; pass the attachments here rather than asking the user to re-upload. Returns one mcp_upload_id per file. 1. **file_name** — HOSTED upload, the default for any non-UI / programmatic upload (Claude Code, Cursor, Claude Desktop, scripts). Returns an upload URL on Clueso's OWN base domain + a ready-to-run curl that streams a single local file to it; Clueso relays the bytes to storage server-side. The PUT targets the base domain — NOT cloud storage directly — so it works on desktop/agent clients that can't reach or are blocked from S3. Requirement: the client must be able to PUT bytes to the Clueso base domain (run the returned curl, or any HTTP PUT). The agent (or the user at a shell prompt) runs the curl. Prefer this whenever there's no human at a browser. **file_names** (without request_hosted_upload) is the same for many files in ONE call: a token and URL per name plus ONE `curl` that sends them all. Run it from the folder the names are relative to (for edit_animation `upload_ids`, the page site's root, names like 'index.html' or 'js/scene.js'). 2. **file_url**: Pass a public https URL. Server fetches and stages the file. Returns mcp_upload_id immediately. Use when the file is already on the open web — no user interaction needed. 3. **request_hosted_upload** (UI mode — use ONLY when a human should pick files in a browser: many files at once, or a host with no shell / no PUT capability): Returns a single upload_token + upload_page URL. Share the link with the user; they open it in a new browser tab, drop their files, click Done. Then call check_uploads(upload_token) to retrieve all mcp_upload_ids. Call once for all files. Hosted uploads cover any number of files per call: one call issues one upload_token, and that token covers every file the user drops…

NameTypeReqDescription
display_namestring–With purpose 'font' and one file (file_name, file_url, one files entry, or one file_names entry): the name to list the font under. Default: its family name without build dates or versions.
file_namestring–File name with extension. Returns a Clueso upload URL + curl command that streams this single local file to us (single file).
file_namesarray–Hosted mode: the file names the user will upload, shown on the page. Without request_hosted_upload: upload these local files in one call (one token + URL each, and one curl for all), max 50.
file_urlstring–Public URL to fetch the file from
filesarray–ChatGPT file attachments, one entry per file (filled by ChatGPT).
purposestring–'font': add the file to this workspace's brand fonts once it arrives (see above). With request_hosted_upload, every file dropped on the page is one, reported by check_uploads.
request_hosted_uploadboolean–If true, returns a hosted upload page. Call once for all files — the page accepts multiple uploads under one token.

No output schema declared.

No examples provided.

voiceover_batch ~938

Set voiceover text and/or trigger speech generation for any number of clips in a single call. Each entry chooses its own action: - "set_text" — set transcript for a clip (clip_index + text) - "generate_speech" — async TTS for a clip (returns immediately; wait: true blocks until it lands) - "set_and_generate" — set text and kick off TTS in one entry (+ text) Emotion tags: put ElevenLabs emotion/audio tags in square brackets in the text, e.g. "[excited] And it just works." or "[whispers] Here's the trick." — the voice performs them and they're never spoken or shown. Use them sparingly, before the phrase they colour. Pauses: <pause:1.5s> in the text is exact silence of that length, anywhere including the very start (a lead-in before the first word) and the very end (a hold after the last); word timings account for it, and get_clip's voiceover_text shows existing pauses the same way, so keep them when you rewrite. Unlike the [pause] emotion tag, which is a performed beat of no set length. Sizing a script: narration runs roughly 2–2.5 words per second depending on the voice — size the script to the target length, generate the voiceover, then read the real clip durations back (get_clip, once `busy` is empty) before timing visuals. Address a clip the same way as everywhere else: `clip_index`. Pass `clip_id` instead if you already have it — it survives clips being inserted or reordered mid-build — but you never need both; whichever you omit is looked up once for the whole call. Entries within one call are applied in order. Returns one result object per input entry. All text-set actions land in ONE save; the TTS for generate/set_and_generate runs async per clip after. Sync points: if get_clip's `voiceover_text` for the clip contains `<SYNC_MARKER N>` tokens (a screen recording's on-screen actions), your new text must carry every one of them, each exactly once and in order, placed where that action is narrated. Otherwise the entry is refused and nothing is…

NameTypeReqDescription
entriesarrayyesVoiceover entries — at least one.
project_idstringyesProject ID
waitboolean–true blocks until the speech this call starts has landed, so the clip durations, voiceover_words and element times you read next are the real ones: `ready` lists each landed clip with its new duratio…
wait_secondsinteger–With wait: the most to wait, default 50s.

No output schema declared.

No examples provided.

Install

How do I install the Clueso MCP server?

Clueso is a hosted endpoint at https://connect.clueso.io/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · connect.clueso.io

# add to Claude Code
claude mcp add --transport http io-clueso-video 'https://connect.clueso.io/mcp'
Common questions

What is the Clueso MCP server?

Clueso is an MCP server listed in the public MCP registry as io.clueso/video. Make videos and docs with your AI agent, describe what you need, every output stays editable. This page covers its hosted endpoint (https://connect.clueso.io/mcp).

Is the Clueso MCP server safe to use?

Clueso scores 90 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the Clueso MCP server expose?

Clueso exposes 55 tools: get_design_guide, read_animation, edit_animation, create_project, update_project, and 50 more. Their descriptions and schemas cost roughly 37,689 tokens of context every time the server is loaded.

Does the Clueso MCP server require authentication?

Yes. Clueso asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.

Is the Clueso MCP server still maintained?

Clueso is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.