Skip to content

MCP tools

python -m engine.mcp_server starts an MCP server with 45 tools, so Claude Code, Claude Desktop or any MCP client can build sites with the engine. The repository's .mcp.json registers it for Claude Code. The tools are read from engine/mcp_server.py.

Renders and recordings run in the background: the tool returns a job id, and job_status or wait_for_job reports on it. snapshot returns screenshot paths, so the client can look at its own work.

Tool What it does
list_projects List user projects and bundled examples (good starting points: copy one with create_project).
create_project Create a project in the projects folder, empty or copied from an example.
remake_site Read a live landing page (public content only; its robots.txt is honoured) and write a new project that tells it as a scroll site: the hero picture as the opening scene …
spec_schema JSON Schema of site.yaml. part = a scene/block type (film, artwork, scene3d, sequence, parallax, type, inside, intro, features, stats, timeline, quote, cta, gallery) or …
get_spec Read a project's site.yaml.
set_spec Validate and write a project's site.yaml (the whole file).
list_inputs Files in the project's inputs/ folder (reference them in the spec as inputs/<name>).
add_input Copy a local file (image, video, 3D model, .blend) into the project's inputs/.
build Start building the site into dist/ (in the background).
storyboard Storyboard the site before the full render, and review it: returns sheet (sheet.jpg, one image with a card per shot: its frames, prompt, motion, caption, length …
inspect_film Polish report of a built film (studio inspect): scores it second by second and beat by beat for pops (jumps, flicker, judder, crossfades between shots that should line …
storyboard_shots The storyboard as an editing workspace sees it (the same one studio storyboard <project> --edit opens): every shot with its editable fields (name, current value …
storyboard_notes The inbox of plain-language notes the owner wrote in the storyboard editor ("warmer light", "she should look older", "tighten the pacing", ...).
resolve_note Close a storyboard note with a short plain-language reply for the owner (what you understood and what you did, or why you did not: "made the light warmer (new variant 4 …
set_shot_field Set one field of a storyboard shot in site.yaml (comments and layout kept, validated first, the previous text is kept in storyboard/history/). field: a name from …
regenerate_shot_image Render one image of a storyboard shot again and return the new image's path (Read it).
pick_shot_variant Make a kept variant of a shot's image the one in use: its seed (and text) are written into site.yaml, and the build's cache holds it, so the full build reproduces that …
approve_shot Mark a storyboard shot approved (kept in storyboard/state.json, not in the spec).
journey_plan The one-take page (journey: on a film section): which approach it uses (a chain of camera moves between stop pictures, or one take through a blockout), every move …
camera_guide For a beat with camera: keys: make its camera guide (depth, the moving people's mask, the guide videos) without generating anything, and return the paths.
diorama_layout Miniature worlds (scene type diorama): lay the section's world out (CPU, seconds, no GPU) and return what was decided: the places and where they are, which step lives …
camera_check Measure a built beat with camera: keys: how far the camera is from the keyed view (zoom error in %, shift in view widths, per frame and rms), how far the people …
cinemagraphs Build the site's cinemagraphs (any image input with cinemagraph: {moves: "the steam above the cup", ...}: a still where only that moves) and return a measured report …
world_check Check the in-world type of a built film (steps with place: {kind: behind \| surface \| sky}, see the field docs of place): per title, how steady the track is (jitter …
job_status Progress, status and log tail of a background job.
wait_for_job Block until a job finishes (or the timeout passes) and return its status.
snapshot Screenshot the built site at scroll positions and return the image paths (read them to review the page). at: 'scene_id:progress' (e.g.
cuts The film grammar between the built site's sections (transition: on a section: cut, dissolve, wipe, iris, whip, match, carry): each cut with its length and, for a match …
record Start recording a smooth scroll-through MP4 of the built site (background job).
trailer Cut the launch trailer from the site's own renders (background job): dist/trailer/trailer-16x9.mp4 and trailer-9x16.mp4 + posters, from the spec's trailer: (an empty …
list_styles The looks a site can take with theme.style (name, label, what it looks like).
looks Build the (already built) site once per style into dist/looks/<style>/ with a gallery at dist/looks/index.html, so the user can compare looks. styles: names from …
copy_deck Write the site's visible text to <project>/copy.md: a Markdown deck the client can edit and send back.
apply_copy_deck Apply an edited copy deck to site.yaml (comments kept, invalid edits refused).
brand_from_logo Set theme colours from a logo inside the project (contrast-checked) and use it as the nav logo.
brand_from Read a brand from a web page URL, a saved .html page, a logo image or a brand.yaml in the project (colours, fonts, radius, logo) and write its tokens into site.yaml as …
inside_route The route of a type: inside scene (the camera flying into the site's product): per stop the parts it found, the view, the camera side, where it rests and where its …
product_parts The site's product model, normalised (cached): size (m), triangles, units, and every part with its materials and size, so product.parts rules can target names …
product_still Render a still of the site's product (Cycles, studio light; cached) and return its path to look at. view: front, three-quarter, side, top, back, hero-low, exploded …
directions Art directions for a site, pitched like a studio (studio directions): several complete directions (a concept line, palette, type pairing, one of the engine's styles …
direction_reroll Another idea in place of one direction on the boards (by its letter), keeping the others: the best other school that fits the brief and differs from the rest.
direction_pick Write one direction (its letter, or its name) into site.yaml: theme (style, colours, fonts, weights), imagery (how every image and film prompt is phrased) and scroll …
direction_undo Put site.yaml back as it was before the last direction_pick (only if nothing has changed it since).
light_report What a built type: light scene made (one place relit from dawn to night): per time of day the drift from the world (how far the editor moved the place, px at 1024 …
doctor Which tools are installed (Blender, FFmpeg, GPU, ComfyUI...) and which scene types need them.

list_projects

List user projects and bundled examples (good starting points: copy one with create_project).

Takes no arguments.

create_project

Create a project in the projects folder, empty or copied from an example. Returns its path.

Argument Type Default Description
name string required
example string null

remake_site

Read a live landing page (public content only; its robots.txt is honoured) and write a new project that tells it as a scroll site: the hero picture as the opening scene, the sections as blocks, the calls to action with their links, the brand as theme.from tokens, the pictures in inputs/. style: one of list_styles. Returns the project, its sections, warnings and next steps. The content belongs to the site's owner: tell the user the remake is for their own use or with the owner's permission.

Argument Type Default Description
url string required
name string null
style string null
no_gpu boolean false

spec_schema

JSON Schema of site.yaml. part = a scene/block type (film, artwork, scene3d, sequence, parallax, type, inside, intro, features, stats, timeline, quote, cta, gallery) or 'Site'/'Theme'/'Step'/'Hud' to get just that definition.

Argument Type Default Description
part string null

get_spec

Read a project's site.yaml.

Argument Type Default Description
project string required

set_spec

Validate and write a project's site.yaml (the whole file). Returns validation errors instead of writing if invalid. A spec that uses deprecated fields is written, with deprecations naming each one and what replaces it.

Argument Type Default Description
project string required
yaml_text string required

list_inputs

Files in the project's inputs/ folder (reference them in the spec as inputs/<name>).

Argument Type Default Description
project string required

add_input

Copy a local file (image, video, 3D model, .blend) into the project's inputs/. Returns the spec path to use.

Argument Type Default Description
project string required
source_path string required

build

Start building the site into dist/ (in the background). Returns a job id for job_status. only: section and beat ids to render (the rest keep their cache or show their storyboard stand-in). plan_only=True returns at once what would render and the estimate on this machine, without building. The job log starts with the same plan. draft=True renders sequences at half size. Cached stages are skipped; locked scenes and beats are kept. Storyboard first (the storyboard tool) to check frames cheaply.

Argument Type Default Description
project string required
section string null
draft boolean false
force boolean false
only list of string null
plan_only boolean false

storyboard

Storyboard the site before the full render, and review it: returns sheet (sheet.jpg, one image with a card per shot: its frames, prompt, motion, caption, length, fidelity, status new/changed/unchanged/locked/rendered and the full render estimate; Read it), html (storyboard.html), site (the real page with stills standing in for unrendered films), animatic (animatic.mp4 at level animatic) and a JSON summary per card. level: sketch (no ComfyUI: blockouts, cached stills, placeholder cards; seconds), stills (the real first frames: keyframes, beat stills, product stills at low samples; ~10-30 s a new shot) or animatic (stills in motion and animatic.mp4). only: shot ids (beats, sections, blocks) to redo; the rest keep their frames. motion=True with animatic: a tiny LTX preview per shot. Frames reuse the full build's caches, so approved frames are the real first frames. Runs as a job; waits up to timeout_s, else returns the job to poll with job_status.

Argument Type Default Description
project string required
level string "stills"
only list of string null
motion boolean false
timeout_s integer 900

inspect_film

Polish report of a built film (studio inspect): scores it second by second and beat by beat for pops (jumps, flicker, judder, crossfades between shots that should line up), softness (looks upscaled: fine detail lost), halos (bright rims and seams along edges: depth-warp halos, double edges), style drift (the look moving from the scene's start: sketchier, different grain) and morphs (shapes rebuilding instead of moving), so problems are found before the owner sees them. CPU only; a film that has not changed answers at once from the saved report. section: a film section id (default: every film section with a built film); video: any video file instead, judged as one shot. embed=True adds a CLIP-embedding drift check (local weights only, slow). Returns per section: report_html (open it or Read its pictures: one JPEG per worst moment, under .build/inspect/<section>/), report_json, a summary (verdict clean/slight/visible/bad, counts), the worst issues (metric, level, time span, beat, a one-line reason and what to try) and every beat's scores (0-100, 100 clean, for pops/softness/halos/drift/morphs) and worst issue. The storyboard editor shows each beat's worst issue as a badge that links to the report. Runs as a job; waits up to timeout_s, else returns the job to poll with job_status.

Argument Type Default Description
project string required
section string null
video string null
force boolean false
embed boolean false
issues integer 12
timeout_s integer 900

storyboard_shots

The storyboard as an editing workspace sees it (the same one studio storyboard <project> --edit opens): every shot with its editable fields (name, current value, type), its images (slots, each a chain of steps: generate, edit..., with seeds) and the variants kept for each image, plus the steps shared between shots. Use the field names with set_shot_field and the shot/slot names with regenerate_shot_image. shot: only that shot.

Argument Type Default Description
project string required
shot string null

storyboard_notes

The inbox of plain-language notes the owner wrote in the storyboard editor ("warmer light", "she should look older", "tighten the pacing", ...). Each open note comes with its shot's current spec values (every editable field by name), its images (path to read, state, seeds, the steps of the edit chain) and the variants kept; a note for 'general' comes with the list of all shots. Interpret each note yourself: then act with set_shot_field (text, seconds, seeds), regenerate_shot_image (mode rerun after changing an image's prompt or instruction, step 1 for a shared base), pick_shot_variant, or by editing site.yaml for page-wide changes (copy, order, pacing); LOOK at the new image (Read its path) before you resolve. Then call resolve_note with a short plain reply. claim=True marks the notes as 'working' (the page shows it, and attaches the edits you make to the note).

Argument Type Default Description
project string required
claim boolean true
include_working boolean false
include_done boolean false

resolve_note

Close a storyboard note with a short plain-language reply for the owner (what you understood and what you did, or why you did not: "made the light warmer (new variant 4, seed 5231); the other shots keep their look"). changed: extra things worth listing (edits and new variants made through the editing tools are attached automatically). status: done (default), or open to hand it back, or working.

Argument Type Default Description
project string required
note_id string required
reply string required
changed list of string null
status string "done"

set_shot_field

Set one field of a storyboard shot in site.yaml (comments and layout kept, validated first, the previous text is kept in storyboard/history/). field: a name from storyboard_shots, e.g. caption, prompt, motion, seconds, seed, trim, strength, motion_seed, duration, still.instruction, still.seed, still.region (an edit's region: what it may change), still.region.prompt / .pick / .grow / .feather, key.<name>.prompt, locked (true/false). Changing text does not render anything: follow with regenerate_shot_image (mode rerun) to redraw the image.

Argument Type Default Description
project string required
shot string required
field string required
value any required

regenerate_shot_image

Render one image of a storyboard shot again and return the new image's path (Read it). Only that image's stage runs (a beat's start or end image, an edit, a take keyframe, a product still), through the build's own code and cache, as one background job; videos are never rendered. mode: regenerate (a new seed; written into site.yaml) or rerun (the same seed, after set_shot_field changed its text). slot: the image's name from storyboard_shots (default: the shot's first, e.g. still, end, key.<name>, image). step: 0 = the image's own step, 1 = the step under it (the base image of an edit chain; its shots then need a rerun). Every render is kept as a variant; pick_shot_variant goes back to one. Returns image (path), seed, variant, shot, slot.

Argument Type Default Description
project string required
shot string required
slot string null
mode string "regenerate"
step integer 0
seed integer null
timeout_s integer 1500

pick_shot_variant

Make a kept variant of a shot's image the one in use: its seed (and text) are written into site.yaml, and the build's cache holds it, so the full build reproduces that image.

Argument Type Default Description
project string required
shot string required
variant integer required
slot string null
step integer 0

approve_shot

Mark a storyboard shot approved (kept in storyboard/state.json, not in the spec). The sheet and build --plan list shots that are not approved; editing a shot makes its approval read 'changed'.

Argument Type Default Description
project string required
shot string required
approved boolean true

journey_plan

The one-take page (journey: on a film section): which approach it uses (a chain of camera moves between stop pictures, or one take through a blockout), every move and hold with the film seconds and scroll screens it gets, and, once built, where each stop's blocks sit on its picture (the calmest side), the lettering surface, the scrim and the contrast reached. Cheap: nothing is rendered.

Argument Type Default Description
project string required
section string null

camera_guide

For a beat with camera: keys: make its camera guide (depth, the moving people's mask, the guide videos) without generating anything, and return the paths. preview is a pure-camera video of the keyed move over the start image (no video model): look at it before spending minutes on the beat. The beat itself is made by build (only: [beat id]).

Argument Type Default Description
project string required
beat string required
section string null

diorama_layout

Miniature worlds (scene type diorama): lay the section's world out (CPU, seconds, no GPU) and return what was decided: the places and where they are, which step lives at which place, where the camera dives from, how far it orbits, what the world is made of. Writes diorama/<id>-map.jpg (a flat map with the places numbered: look at it before building) and <id>-plan.json in the project.

Argument Type Default Description
project string required
section string null
full boolean false

camera_check

Measure a built beat with camera: keys: how far the camera is from the keyed view (zoom error in %, shift in view widths, per frame and rms), how far the people walked, against the floor of a perfect camera. Writes camera.json and a contact sheet (camera_sheet.jpg: generated, the camera alone, the guide, and the generated beat with the camera taken out) beside the beat; read the sheet.

Argument Type Default Description
project string required
beat string required
section string null

cinemagraphs

Build the site's cinemagraphs (any image input with cinemagraph: {moves: "the steam above the cup", ...}: a still where only that moves) and return a measured report for each: the loop's seam ratio (about 1 is seamless), how much of the picture moves, the largest change of any pixel held still, bytes, and the files (cine_*.mp4, its mask, report json under .build/_cinemagraph/). Runs in the background (a video model per cinemagraph; minutes each): returns a job id for job_status. only: text matched against moves or the spec path. list_only: just what is built and what is not.

Argument Type Default Description
project string required
only string null
force boolean false
list_only boolean false

world_check

Check the in-world type of a built film (steps with place: {kind: behind | surface | sky}, see the field docs of place): per title, how steady the track is (jitter in pixels of a 960-wide frame), how much of its window the type is on screen, the surface's slant, the depth it sits at and, where something is off, what to change (anchor, follow, at, y, quad). Writes .build/<section>/world/sheet.jpg (the title's box on the film's own frames, with the depth map beside them for behind and sky type): Read it. section: a film section id (default: every film with in-world type).

Argument Type Default Description
project string required
section string null
frames integer 6

job_status

Progress, status and log tail of a background job.

Argument Type Default Description
job_id string required
log_lines integer 40

wait_for_job

Block until a job finishes (or the timeout passes) and return its status.

Argument Type Default Description
job_id string required
timeout_s integer 240

snapshot

Screenshot the built site at scroll positions and return the image paths (read them to review the page). at: 'scene_id:progress' (e.g. 'hero:0.5'), 'top', 'bottom' or 'y:<px>'. Default: every scene at 15/50/85%.

Argument Type Default Description
project string required
at list of string null

cuts

The film grammar between the built site's sections (transition: on a section: cut, dissolve, wipe, iris, whip, match, carry): each cut with its length and, for a match cut, how its shapes were found (prompt, box, contour). With strip=True also a frame strip around each cut (headless Chrome; read the images to judge the cut): the page before, through the cut's stretch of scroll, and after. mobile: a 390 px phone. reduced_motion: what a visitor who asks for less motion gets (plain cuts).

Argument Type Default Description
project string required
strip boolean false
only list of integer null
mobile boolean false
reduced_motion boolean false

record

Start recording a smooth scroll-through MP4 of the built site (background job).

Argument Type Default Description
project string required
section string null
seconds number 12.0

trailer

Cut the launch trailer from the site's own renders (background job): dist/trailer/trailer-16x9.mp4 and trailer-9x16.mp4 + posters, from the spec's trailer: (an empty trailer: {} derives the cut). formats: 16x9, 9x16. plan_only=True returns the cut (shots, timings, captions) at once without rendering.

Argument Type Default Description
project string required
formats list of string null
force boolean false
plan_only boolean false

list_styles

The looks a site can take with theme.style (name, label, what it looks like).

Takes no arguments.

looks

Build the (already built) site once per style into dist/looks/<style>/ with a gallery at dist/looks/index.html, so the user can compare looks. styles: names from list_styles (default: all).

Argument Type Default Description
project string required
styles list of string null

copy_deck

Write the site's visible text to <project>/copy.md: a Markdown deck the client can edit and send back.

Argument Type Default Description
project string required

apply_copy_deck

Apply an edited copy deck to site.yaml (comments kept, invalid edits refused). Returns the changed fields.

Argument Type Default Description
project string required
deck_path string required
dry_run boolean false

Set theme colours from a logo inside the project (contrast-checked) and use it as the nav logo.

Argument Type Default Description
project string required
logo string required
mode string "light"
dry_run boolean false

brand_from

Read a brand from a web page URL, a saved .html page, a logo image or a brand.yaml in the project (colours, fonts, radius, logo) and write its tokens into site.yaml as theme.from, where they can be edited.

Argument Type Default Description
project string required
source string required
dry_run boolean false

inside_route

The route of a type: inside scene (the camera flying into the site's product): per stop the parts it found, the view, the camera side, where it rests and where its copy sits on the scroll (0-1), plus the notes (automatic stops). With stills (stop numbers as strings, 'all', 'wide', or 'strip:8' for 8 frames along the route) it renders quick Cycles stills and a contact sheet and returns their paths to look at. A stop that matches no part or a model without parts returns the error with the part names the model has.

Argument Type Default Description
project string required
section string null
stills list of string null
samples integer 24
scale number 0.5

product_parts

The site's product model, normalised (cached): size (m), triangles, units, and every part with its materials and size, so product.parts rules can target names (match/material globs, region, facing).

Argument Type Default Description
project string required

product_still

Render a still of the site's product (Cycles, studio light; cached) and return its path to look at. view: front, three-quarter, side, top, back, hero-low, exploded, detail (with part = a name glob). background: transparent, theme or a hex colour. scene: a prompt to render it into a generated scene (needs ComfyUI).

Argument Type Default Description
project string required
view string "three-quarter"
width integer 1600
height integer 1200
background string "transparent"
part string null
scene string null

directions

Art directions for a site, pitched like a studio (studio directions): several complete directions (a concept line, palette, type pairing, one of the engine's styles, an imagery treatment that phrases every generated image and film prompt, motion notes), each drawn as a board of storyboard stills (the hero and key sections in Z-Image Turbo), side by side on one page. Returns sheet (board.png, one image: Read it and judge: do the directions differ in kind, do the stills look like the palette and type, would a client pick between them?), page (board.html), and every direction with its stills. The writer is deterministic (curated design vocabularies combined by seed; no model): the same brief and seed give the same directions, another seed gives another set. The site's directions: block (brief, moods, keep, styles/fonts/ palettes only/avoid/brand colours, count, seed, stills) steers it; brief and count here override it. images=False draws placeholder cards (no ComfyUI). show_only=True returns the saved boards without writing new ones. Then call direction_pick. Runs as a job; waits up to timeout_s, else returns the job to poll with job_status.

Argument Type Default Description
project string required
count integer null
seed integer null
brief string null
images boolean true
show_only boolean false
timeout_s integer 1800

direction_reroll

Another idea in place of one direction on the boards (by its letter), keeping the others: the best other school that fits the brief and differs from the rest. Returns the new boards as directions does.

Argument Type Default Description
project string required
id string required
images boolean true
timeout_s integer 900

direction_pick

Write one direction (its letter, or its name) into site.yaml: theme (style, colours, fonts, weights), imagery (how every image and film prompt is phrased) and scroll pace, as the smallest readable diff, keeping the old file in directions/backups/. Copy is never touched. Returns the changed paths and the diff. Next: storyboard redraws the images in that direction's imagery. Ask the owner before picking unless they chose.

Argument Type Default Description
project string required
id string required

direction_undo

Put site.yaml back as it was before the last direction_pick (only if nothing has changed it since).

Argument Type Default Description
project string required

light_report

What a built type: light scene made (one place relit from dawn to night): per time of day the drift from the world (how far the editor moved the place, px at 1024 across: raw, and after its global move is undone) and edge agreement, per neighbouring pair how far apart the light is, how far structure still differs (glide) and how many lamps switch. Writes light/<section>/sheet.jpg (every time with its drift: Read it) and light.json. Build the project first (build); a time whose drift is over the limit says so (ok: false): give it another seed: on that time. Frame strips across the transitions: snapshot with at=['<section>:0.3', ...].

Argument Type Default Description
project string required
section string null

doctor

Which tools are installed (Blender, FFmpeg, GPU, ComfyUI...) and which scene types need them.

Takes no arguments.