cueframe
Turn footage into finished, production-quality video over MCP.
От сообщества: Добавлен пользователем или импортирован; проверьте владельца перед подключениемРаботаетБез входаГлобальныйБесплатноТолько чтение
Что умеет
- Create Composition: Start the async Director compose workflow: it authors an ensemble of full composition candidates, verifies each, and saves the winner to the project. Body must set EXACTLY ONE sour
- Apply Composition: Atomically apply an array of CompositionOps to a project composition. All ops succeed or none do (transactional). Pass `if_match` for optimistic-concurrency control (409 stale_etag
- Validate Composition: Dry-run a full Composition object against the SAME pure, DB-free authoring guards saveComposition enforces, WITHOUT persisting it (no project needed). Checks: wire shape (Zod), p
Какие данные видит
Нужен ли аккаунт
Не нужен: сервер работает без входа
Turn footage into finished, production-quality video over MCP. Content-aware reframing, captions behind the subject, and motion graphics, with free previews and keyless pay-per-render.
Список инструментов сервера (44)
Технические названия из tools/list. Нужны только разработчикам.
| create_composition | Start the async Director compose workflow: it authors an ensemble of full composition candidates, verifies each, and saves the winner to the project. Body must set EXACTLY ONE source (mutually exclusive): `fromComposition: true` — author from the project's CURRENT composition (the GENERAL path: first seed it with apply_composition to add your media clips = your intent, then compose); or `suggestionId` — author from an AI clip suggestion (the CLIPPING path, paired with trigger_suggestions). Returns { composeJobId, workflowId, status, streamUrl }. Then call wait_job(kind="compose", id=composeJobId, projectId=...) to block until the winner is selected. |
| apply_composition | Atomically apply an array of CompositionOps to a project composition. All ops succeed or none do (transactional). Pass `if_match` for optimistic-concurrency control (409 stale_etag on mismatch) and `dry_run: true` to validate the batch without persisting. Use this to seed a composition (add media clips) or make targeted edits (set a crop intent, add a caption, reorder clips, set the format). Brand is NOT set here — it lives on the project (create_project / PATCH /projects/:id with brandKitId). |
| validate_composition | Dry-run a full Composition object against the SAME pure, DB-free authoring guards saveComposition enforces, WITHOUT persisting it (no project needed). Checks: wire shape (Zod), primitive membership (unknown_primitive / custom_missing_sourcecode), required-param shape (invalid_primitive_params), clip↔track family (clip_source_track_mismatch), and reframe coverage (reframe_coverage_gap). Always returns ONE shape — 200 { valid, errors } — for BOTH malformed wire shapes and deep-invariant failures (so branch on `valid`, not on HTTP status); errors[] lists every problem at once as a sanitized envelope { code, stage, category, retryable, message, fix } you can fix before composing/rendering. `valid:true` means save-safe EXCEPT for the two genuinely DB-bound checks that can only run at save/render: trim-bounds (needs the media duration) and image/asset-on-a-video-track (needs the media kind). Pass the Composition as `body`. |
| create_render | Queue an MP4 render of a project's composition. Returns { id (renderId), status, warnings? } — `warnings[]` carries non-fatal advisories (omitted when none). The render themes from the project's brand kit (bind one via create_project / PATCH /projects/:id with brandKitId; without one the output is unbranded). Then call wait_job(kind="render", id=renderId, projectId=...) to block until the file is ready and get the download URL, or register a webhook (create_webhook on render.complete). |
| open_session | Open a warm per-tenant render/compose box for interactive work and return its sessionId. The box stays warm between calls, so it is the fast path for an author→preview→fix loop: pass the returned sessionId to preview_component (one graphic still), render_frame (a whole-composition still), and verify_composition (judge scores) — all render in this same box. CLOSE IT with close_session when done (it holds a billable warm box; it auto-stops at the idle TTL, but closing promptly is cheaper). |
| render_frame | Render still(s) of the WHOLE composition at the given timestamps inside an open warm box, returning presigned PNG(s) — the live full-composition preview. Needs a sessionId from open_session. `body.composition` is the composition to render and `body.timestamps` the seconds to sample. (One component instead of the whole composition? use preview_component.) |
| preview_component | Queue a still render of ONE org-installed component inside an open warm box — ASYNC: returns a jobId immediately; then wait_job(kind="preview", id=jobId) for the presigned PNG. The author→preview→fix loop for a graphic. Needs a sessionId from open_session. `body.componentId` selects the component; pass `body.params` to render it with props. Failures land on the job terminal with typed codes: component_does_not_compile / component_runtime_error carry the sanitized author-fixable message — read it, fix the tsxSource via create_component, and re-preview. Idempotent per (componentId, params, dims). |
| verify_composition | Queue the server-side judge for a compose-session composition — ASYNC: returns a verifyJobId immediately (the judge takes minutes: it samples eval beats, renders them in the warm box, and grades editorial/spatial/brand/caption). Then wait_job(kind="verify", id=verifyJobId) for per-criterion scores 0–10, a weighted composite, and a worst-first critique; fix the lowest criterion via apply_composition and re-verify. Idempotent per composition state (same composition → same job while it runs). Do NOT apply/render on this session while its verify job runs — the version gate fails the job loud. |
| commit_session | Promote the session scratch onto the project's active composition and discard the scratch. Returns the new active etag. |
| consult | Ask the Director for editing advice on the project's CURRENT composition — it NEVER writes your composition (you stay the decider). Async: returns a job; wait_job for it, then read `advisoryResult` from the job detail. `body.mode`: 'advise' = the planner agent (fast, ~30s-2min) returns a `plan` (framing/cuts/captions/graphics intents) as GUIDANCE you re-author from — no grounded scores, nothing to select; 'amend' (default) = the full author→judge→refine loop (minutes) returns a graded `assessment` + a fix candidate you ADOPT via the compose `select` endpoint with its candidateIndex. ('explore' is coming soon → use amend.) `body.intent` = your goal in plain English; optional `body.focus` (editorial|spatial|brand|caption); `body.ifMatch` binds to your current etag. Use advise for a fast directional nudge, amend for a grounded, adoptable fix. |
| resume_compose | Answer a compose checkpoint that wait_job reported as awaiting_input. `body.stage` = the held stage (content|layout|motion); `body.decision`: 'approve' (proceed as-is), 'revise' (proceed with `body.edits` — your edited stage artifact), or 'reject' (abandon the compose). `body.version` MUST echo the version wait_job reported (a stale version is a 409 — re-read the job detail). On approve/revise the Director rehydrates its warm box from the persisted composition and continues; then wait_job again to reach the next checkpoint or the winner. Only valid while the job is awaiting_input. |
| close_session | Tear down a warm compose session and free the box. Call this when you finish an interactive open_session → preview/render/verify loop — it stops the billable warm box immediately (it would otherwise auto-stop only at the idle TTL). |
| create_component | Create and store a custom graphic component (a reusable overlay/title/lower-third etc.) for the tenant. Returns the ComponentResponse (id + metadata) you can then reference from a composition. No project arg — components are tenant-scoped. |
| list_components | DISCOVER WHAT TO BUILD WITH — list the component catalog: the FULL built-in primitive catalog (87 primitives + 7 scenes: lower-third, cinematic-title, color-grade, product-launch-trailer, …) PLUS your org-installed components. Do this BEFORE hardcoding hex/positions or authoring a custom graphic — a built-in probably already exists. Narrow with filters: `category` (text|effects|transitions|layouts|backgrounds|ui-blocks|scenes), `kind` (component|transition|scene), `tier` (recommended|standard|niche), `useCase` (intro|outro|full-scene|title-over-footage|transition|background|grade|emphasis|explainer|social-cut), `mood`, or free-text `q`/`intent` (e.g. intent='intro'). When any filter is set, results are recommended-tier-first. With NO `limit` the whole filtered catalog returns in one page. Each entry carries a `placement` hint = exactly how to author it via apply_composition ({kind:'overlay'|'effect', primitiveId} for built-ins; {kind:'component', componentId} for installed), `tier`/`useCase` to pick by, and `fixedCopy` (on-screen strings it BAKES that no param changes — fork via get_component_source to edit). Read cueframe://component/{id} for the full prop schema. |
| get_component_source | Read a component's editable TSX source. Pass a BUILT-IN primitive id (e.g. "cinematic-title", "lower-third", "kinetic-type") to get it as a SINGLE self-contained module — the server-native FORK path: edit the returned tsxSource, then create_component it back to own a customized copy. Also returns an org-installed component's own authored source. Returns { id, name, tsxSource, origin, ejectedFrom, propSchema, … }; 404 if the id is neither a known primitive nor an installed component carrying source. |
| get_media_context | Fetch the authoring context for a media item: detected faces (subject boxes per frame) and the transcript. Use this before composing/applying so your crop intents, captions, and timing line up with what is actually in the footage. |
| list_media | List the videos in your CueFrame library. Returns media item IDs and metadata. Use the ID with get_media_context, trigger_suggestions, or as the source for a composition. |
| create_project | Create a new project — the unit you compose and render into. create_composition / apply_composition / create_render / open_session all require a projectId; this mints one. Pass name (required) plus optionally a format (aspectRatio/fps/resolution) and brandKitId. brandKitId binds a brand kit to the PROJECT (pass the kitId from create_brand_kit): colors/fonts/motion theme every render of this project automatically (omit it and the output is unbranded). Bind or change it later via PATCH /projects/:id. Returns the ProjectResponse (id + metadata). |
| new_video | Create a NEW composition (a new video) inside a project — a project is a workspace that holds many videos. Returns { compositionId, format, etag }. Pass an optional name and format (aspectRatio/fps/resolution); format defaults to the project's compositionFormat. The first composition becomes the project's active default. To author it, seed with apply_composition then create_composition({ fromComposition: true }); to render a specific one, pass its compositionId to create_render. (For a reframed sibling in another aspect, use derive_composition.) |
| list_compositions | List every composition (video) in a project, with its format and which one is active. Use a returned compositionId with create_render(compositionId=...) to render a specific video, or apply_composition to edit it. |
| derive_composition | Derive a reframed SIBLING composition for a different aspect ratio (the agent-native Auto-Reframe / Magic-Resize). Pass projectId + body { fromCompositionId, targetFormat: { aspectRatio, fps?, resolution? } }. CueFrame copies the source composition's authored intent and content-aware-reframes every clip for the new aspect (point/face/active-speaker focus), then saves a new independent composition in the same project. Returns { compositionId } — render it with create_render, or refine it with apply_composition. Use this to make 9:16 + 1:1 + 4:5 cuts from one 16:9 edit. (To only change resolution within the SAME aspect, pass create_render.format instead — that is a scale-only export override, not a new composition.) |
| import_media | Import a media item into your library from a public URL — the agent-friendly ingest path (single call, no upload protocol). Pass url (https) + filename (+ optional contentType). Returns { id, status:"importing" }. Processing is async: poll list_media for processingStatus, or register a webhook (create_webhook on media.ready / media.failed). Use the returned id with get_media_context, trigger_suggestions, or as a composition source. |
| generate_media | Generate a media item from a prompt (generator: manim | text-to-video | text-to-image | image-to-video | auto). Returns { id, status:"generating", estimateUsd? }; returns 402 if the estimate exceeds the per-call ceiling. Async — poll list_media or use a webhook (media.ready / media.failed). Use the returned id like any other media item. |
| search_resources | Search licensed STOCK media to compose with — video/photo (Pexels + Pixabay fallback), sfx (Freesound, CC0-only), gif (Klipy). Pass query (+ optional kind [default video], provider pin, limit ≤50). Returns ranked candidates, each with an opaque candidateId + attribution (author, assetUrl) + license. FREE + rate-limited + 7-day cached — reach for this before generate_media when real footage beats synthesis. Import a chosen candidate into a project with import_resource. Candidates expire after 7 days (re-search to refresh a candidateId). |
| search_fonts | Search web font families by name/style — returns family names to use in composition/component params. Pass query (+ optional perPage ≤50). Read-only + free; surfaces the Google Fonts catalog (family + category + variants + css2 stylesheet URL). An empty result set means no match (or the upstream catalog was unavailable). |
| import_resource | Import a stock candidate (candidateId from search_resources) into a project as an ORG-OWNED media item — provider/externalId/license provenance preserved, bytes deduped across orgs. Pass projectId + candidateId. Returns { id, status:"importing"|"ready" }; processing is async — poll list_media / get_media_context, then use the returned id as a composition source. Gated on the resource_import plan feature (402 billing_required if your plan lacks it). 422 candidate_mismatch if the candidate expired — re-run search_resources. |
| trigger_suggestions | Run AI clip-suggestion analysis on a long-form media item — the CLIPPING path (find the best short-form moments, à la CrowdCut). Returns { workflowId, status }; then wait_job(kind="suggestions", id=mediaItemId) and pass a returned suggestion id to create_composition({ suggestionId }). NOTE: clipping vertical, NOT the general path — to compose from your own media, seed via apply_composition then create_composition({ fromComposition: true }). |
| create_webhook | Register a webhook so long-running jobs notify you instead of blocking on wait_job — the right pattern for fan-out/async agents. Pass url + events (e.g. render.complete, render.failed, compose.complete, media.ready). DELIVERY: a POST { event, timestamp, projectId?, data } with Standard-Webhooks headers (webhook-id, webhook-timestamp, webhook-signature: v1,<base64>); the secret (whsec_<base64>) is returned ONCE — verify the RAW body with new Webhook(secret).verify(rawBody, headers). ACTIVATION is synchronous: CueFrame POSTs a signed webhook.verify challenge and your endpoint must reply 2xx echoing data.token — otherwise it returns status:"pending" and receives NO events (recover with verify_webhook, no delete/recreate). Read the cueframe://webhook-events resource (or GET /webhooks/events) for the full contract + every event's data shape BEFORE building your receiver. |
| verify_webhook | Re-run ownership verification on a PENDING webhook — one whose endpoint did not echo the challenge at create time (check its verification.reason: token_not_echoed / non_2xx_<code> / unreachable / ssrf_blocked). After you fix the receiver to reply 2xx echoing data.token, call this to re-send the signed webhook.verify challenge and flip it active IN PLACE (id + secret preserved — no delete/recreate). Returns { id, status:"active"|"pending", verification? }. An already-active webhook returns active unchanged. |
| register_critic | Register a custom eval into the compose critic panel. Three tiers: rules (declarative constraints — keep-out regions, required elements, max overlays, brand colors), rubric (a text criterion scored by the judge as an extra column), or evaluator (your HTTPS webhook — CueFrame POSTs the composition+stills+facts, you return { score, critique }). A low client score drives a refine like a built-in criterion. You see your eval output + our scores, never our rubric. Re-registering the same criticId upserts. Evaluator tier returns a signing secret ONCE. |
| update_project | Update a project's mutable fields (e.g. name, format, brandKitId). Pass projectId + the changed fields as `body`. Setting brandKitId binds/changes the project brand kit so every render of this project themes from it. Returns the updated ProjectResponse. |
| delete_project | Permanently delete a project you created (cleanup). Removes its composition and render history. Irreversible — only call on a project you own and no longer need. |
| delete_media | Permanently delete a media item from your library (cleanup). Irreversible. Compositions referencing it will fail to render — only delete media no composition still needs. |
| update_component | Update an authored component's tsxSource/metadata IN PLACE (same id) — the correct verb for the author→preview→fix loop (preview_component returns the compiler error; fix the source here and re-preview, instead of creating a new component each iteration). Pass componentId + the changed fields as `body`. |
| update_webhook | Update a webhook subscription (its url or event list). Pass webhookId + changed fields as `body`. The signing secret is NOT rotated here. |
| delete_webhook | Delete a webhook subscription (stop receiving its deliveries). Irreversible — the signing secret is invalidated. |
| cancel_render | Cancel an in-flight render (stop a runaway/queued job). Needs projectId + renderId (from create_render). No-op if already terminal. |
| retry_render | Re-render an existing render job's FROZEN composition snapshot — it inherits that job's exact composition/intent/priority and queues a fresh renderJob; it does NOT re-read the project's current composition. So it only helps a TRANSIENT failure (the failed render's `retryable:true` / `category:"transient"` — a flaky pipeline/infra fault): re-attempting the same snapshot may succeed. For a DETERMINISTIC failure (`retryable:false` / `category:"authoring"` — a bad param, an unresolvable media/brand ref), retry_render reproduces the SAME failure: FIX the composition first via apply_composition, then create_render (a retry alone is futile). Check `retryable` on getRender / wait_job to pick the path. Returns the new render; then wait_job(kind="render", id=<new id>). |
| get_account | ORIENT FIRST — show THIS key's account before you spend a metered call: the org it is bound to, the current plan/tier, a per-feature entitlements map (included? + remaining/limit for metered features), and per-call cost ceilings. Use it to see what your plan/credits allow so create_render / create_composition / generate_media / create_brand_kit do not fail mid-workflow with 402 billing_required — entitlements.exports gates create_render AND generate_media output, entitlements.compose gates create_composition, entitlements.brand_kits gates create_brand_kit, and costCeilings.generateMediaUsdPerCall is the generate_media per-call USD cap. No args — identity is resolved from your key (never echoed from input). |
| list_plans | List the plan catalog (tiers, intervals, product ids, prices) BEFORE a checkout, so create_checkout requests a real {plan, interval} instead of guessing an id. No args — reads the platform catalog. |
| create_checkout | Upgrade the CURRENT org. Body { plan: "pro"|"business"|"studio", interval: "month"|"year" } → returns { url }: a hosted Stripe checkout page to open in a browser and confirm payment. Always a URL — an existing saved card is NEVER charged silently; the human confirms on Stripe. interval:"year" is annual. The org is resolved from your key, never the body. Requires the billing:write scope. Discover valid plans with list_plans. |
| create_brand_kit | Create or UPSERT a brand kit (re-POSTing the same kitId updates it in place — this is also the brand-kit UPDATE path). Sets fonts/colors/logo. This is brand step 0 of the workflow: author the kit, then bind it to a PROJECT so colors/fonts/motion theme the output AUTOMATICALLY — pass its kitId as brandKitId to create_project, or attach it to an existing project via PATCH /projects/:id. Without a bound kit, create_render produces UNBRANDED output. Tenant-scoped (no project arg). |
| extract_brand_kit | Queue brand-token extraction from a website URL — ASYNC: returns a jobId immediately; then wait_job(kind="brand_kit_extract", id=jobId) for the tokens (colors/fonts/title/description, fetched + regex-parsed from the site's HTML/CSS — NOT a screenshot/vision pass). It does NOT persist — review the tokens, then call create_brand_kit to save a kit. A blocked (private/SSRF), non-2xx, non-HTML, or slow (>20s) URL degrades to EMPTY token arrays (a succeeded job) rather than erroring — JS-rendered SPAs typically extract empty; author the kit manually from the compiled CSS in that case. |
| wait_job | Wait for a long-running job and return the resolved result — a BOUNDED long-poll. Polls the job status (render / compose / clip-suggestions / verify) and blocks up to the transport window (30s on the hosted transport); if the job is still running at the window it returns a `Still running` continuation — call wait_job again with the same arguments to keep waiting (the job keeps executing server-side; nothing is lost between calls). Call this right after create_composition / create_render / trigger_suggestions / verify_composition. For event-driven fan-out, create_webhook delivers the terminal instead. |