The tools follow the production flow end to end:
create → estimate → generate → review → render → publish.
An agent can drive the whole pipeline with nothing but these tools and the
self-describing get_schema / get_status.
Workflows
| Tool | Maps to |
|---|
list_workflows | GET /v1/workflows |
get_workflow | GET /v1/workflows/{id} |
create_workflow | POST /v1/workflows |
update_workflow | PUT /v1/workflows/{id} |
delete_workflow | DELETE /v1/workflows/{id} |
create_workflow accepts a shots array and compiles it into grouped scenes
(an image → video pair per shot, wired and laid out) so you describe intent, not
node geometry.
Assets
| Tool | Maps to |
|---|
import_asset | POST /v1/storage/ingest |
import_asset({ url, kind }) pulls an external image / video / music URL into
Lavendly so you can use it in a workflow (e.g. as an imageSource). The server
downloads it and enforces the same limits as the app uploader - size (image
25 MB / video 300 MB / music 50 MB), duration (video 3 min / music 10 min), and
your storage quota - then returns the hosted URL. It is URL-only: local files
on the user’s machine must be uploaded in the app (they stream straight to
storage there), not through the MCP.
Generate
| Tool | Maps to |
|---|
estimate_cost | GET /v1/workflows/{id}/cost-estimate |
generate_scene | POST /v1/workflows/{id}/generate |
get_generation_status | GET /v1/workflows/{id}/generation-status |
estimate_cost returns { total, remaining, per_scene, available_credits, sufficient } so you can state the price and get approval before spending.
generate_scene generates one scene (node_id) or every ungenerated scene
(omit node_id → the default is the whole video); it charges per clip and
stitches nothing. Poll get_generation_status for the narratable phase +
progress and the per-scene artifacts as they land.
Render is free after the scenes are generated. Generation is the only
charged step; create_render just stitches the clips you already paid for and
reuses anything already generated, so it never re-charges.
Audio
| Tool | Maps to |
|---|
get_workflow_audio | GET /v1/workflows/{id}/audio |
set_clip_native_audio | PATCH /v1/workflows/{id}/clips/{clip_id}/audio |
attach_track | POST /v1/workflows/{id}/clips/{clip_id}/tracks |
update_track | PATCH /v1/workflows/{id}/tracks/{track_id} |
detach_track | DELETE /v1/workflows/{id}/tracks/{track_id} |
Render
| Tool | Maps to |
|---|
create_render | POST /v1/workflows/{id}/renders |
get_render | GET /v1/workflows/{id}/renders/{job_id} |
list_renders | GET /v1/workflows/{id}/renders |
list_all_renders | GET /v1/renders |
create_render is reuse-aware: scenes that already have a clip are folded
into the stitch untouched and never re-charged. A render that fails after
producing some clips charges only for the clips delivered (the rest is
released), never a blanket refund of work that already cost upstream.
Review
| Tool | Maps to |
|---|
quality_check | POST /v1/workflows/{id}/quality-check |
get_scene_frame | POST /v1/workflows/{id}/scene-frame |
quality_check runs ffprobe sanity (duration, video + audio streams) plus a
vision rubric that catches AI “tells” (waxy skin, melting hands, identity
drift) and returns { pass, score, failures, reroll_hint }. If pass is
false, regenerate the scene with generate_scene and append reroll_hint to
the prompt. get_scene_frame returns a still-frame thumbnail URL so a human (or
a multimodal agent) can eyeball a scene before rendering. Both take an optional
node_id; omit it to target the final video.
Publish
| Tool | Maps to |
|---|
list_channels | GET /v1/channels |
publish_video | POST /v1/workflows/{id}/publish |
schedule_video | POST /v1/workflows/{id}/publish (with when) |
list_channels returns the connected social channels (or connected: false - tell the user to connect one in Settings; an agent can’t). publish_video posts
the rendered video now; schedule_video posts it at a future when (ISO 8601)
via Lavendly’s own scheduler. Platform AI-disclosure is set automatically (e.g.
TikTok), and the media upload + post payload are built server-side, so you only
pass { channel_id, caption?, title?, when? }.
publish_video posts publicly and is hard to undo. Confirm the channel and
content with the user first.
Capabilities & ledger
| Tool | Maps to |
|---|
get_ledger | GET /v1/ledger |
get_monthly_usage | GET /v1/usage/monthly |
get_status | GET /v1/_status |
get_schema | GET /v1/_schema |
Idempotency from MCP
create_workflow, attach_track, create_render, generate_scene, and
publish_video accept an idempotency_key argument. The MCP server forwards it
on the underlying HTTP request; the same key within 5 minutes returns the same
response, byte-for-byte.
Use this whenever an agent might retry a tool call after a timeout: generate the
key once per logical action (e.g. ${workflow_id}:${date}) and pass it on every
retry.
Sample agent prompt
Using Lavendly:
- Check my ledger; bail out if I have less than 50 credits available.
- Create a workflow called Bookshop fox with three shots:
a sleepy fox finding an old map, the map glowing, the fox stepping
through a door of light. 5 s each.
estimate_cost and tell me the price; wait for my go-ahead.
generate_scene for the whole video. Poll get_generation_status and
tell me each scene as it lands.
quality_check every scene. If any scene fails, regenerate it with the
reroll_hint. Send me a get_scene_frame thumbnail of each.
- Render it (free), poll until done, send me the video URL.
- List my channels and, once I confirm, schedule it to YouTube for 9am
tomorrow.
The agent needs no other context: the tool descriptions are self-explanatory and
get_status tells it which providers are wired up.