Tool tree
gradeNot graded
page: Every page
theater_startAction
READ THIS FIRST. What this page is, what the tools do, and the order to use them in. Also says what is already here, so a show in progress can be picked up rather than started over. Costs one call and saves several.
View tool JSON
{
"name": "theater_start",
"kind": "act",
"impl": "imperative",
"description": "READ THIS FIRST. What this page is, what the tools do, and the order to use them in. Also says what is already here, so a show in progress can be picked up rather than started over. Costs one call and saves several.",
"inputSchema": {
"type": "object",
"properties": {}
},
"page": "/"
}theater_avatarAction
Optional: change the floating avatar when the person asks. Pass url 'default' for bundled Codey, or the person's selected Codex pet sheet as a complete data:image/webp;base64 URL. This reads a local pet file and sends its bytes in the tool call; large sheets may exceed browser review limits. Do not choose another installed pet without the person's direction. If available, ~/.codex/config.toml names the selected-avatar-id. Standard grids are 8 by 11.
View tool JSON
{
"name": "theater_avatar",
"kind": "act",
"impl": "imperative",
"description": "Optional: change the floating avatar when the person asks. Pass url 'default' for bundled Codey, or the person's selected Codex pet sheet as a complete data:image/webp;base64 URL. This reads a local pet file and sends its bytes in the tool call; large sheets may exceed browser review limits. Do not choose another installed pet without the person's direction. If available, ~/.codex/config.toml names the selected-avatar-id. Standard grids are 8 by 11.",
"inputSchema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "The complete local pet sheet as a base64 data:image URL, or 'default'."
},
"name": {
"type": "string",
"description": "The selected pet's display name. Omit when url is 'default'."
},
"columns": {
"type": "number",
"description": "Sheet columns; standard Codex pets use 8."
},
"rows": {
"type": "number",
"description": "Sheet rows; standard Codex pets use 11."
}
},
"required": [
"url"
]
},
"page": "/"
}theater_clearAction
Start a separate new play on this canvas. Before changing the canvas, this tool saves the current pieces, scenes, script and title locally for theater_restore. It refuses to proceed if that local undo cannot be saved. The previous play can be restored while the new canvas is empty. Nothing is uploaded or published. The canvas stays empty for 30 seconds, then a fresh sticker scatter appears.
View tool JSON
{
"name": "theater_clear",
"kind": "act",
"impl": "imperative",
"description": "Start a separate new play on this canvas. Before changing the canvas, this tool saves the current pieces, scenes, script and title locally for theater_restore. It refuses to proceed if that local undo cannot be saved. The previous play can be restored while the new canvas is empty. Nothing is uploaded or published. The canvas stays empty for 30 seconds, then a fresh sticker scatter appears.",
"inputSchema": {
"type": "object",
"properties": {}
},
"page": "/"
}theater_restoreAction
Undo the last theater_clear: restores every piece, scene and title exactly as they were. Only works while the canvas is empty.
View tool JSON
{
"name": "theater_restore",
"kind": "act",
"impl": "imperative",
"description": "Undo the last theater_clear: restores every piece, scene and title exactly as they were. Only works while the canvas is empty.",
"inputSchema": {
"type": "object",
"properties": {}
},
"page": "/"
}theater_backgroundAction
Fade the canvas background to a colour, e.g. dark blue for a night scene. Works any time, including during a show; the fade takes about 1 second. Pieces are unaffected. Prefer muted tones so cut-outs stay readable. Pass 'paper' to reset. Scenes and beats can also set this: stage_create 'background' and a beat's 'background'.
View tool JSON
{
"name": "theater_background",
"kind": "act",
"impl": "imperative",
"description": "Fade the canvas background to a colour, e.g. dark blue for a night scene. Works any time, including during a show; the fade takes about 1 second. Pieces are unaffected. Prefer muted tones so cut-outs stay readable. Pass 'paper' to reset. Scenes and beats can also set this: stage_create 'background' and a beat's 'background'.",
"inputSchema": {
"type": "object",
"properties": {
"color": {
"type": "string",
"description": "A hex colour like \"#1B2440\" — or \"paper\" for the house default."
}
},
"required": [
"color"
]
},
"page": "/"
}theater_art_promptAction
Get a ready-to-use image-generation prompt for the art this show needs, then paste it into whatever can draw. Ask for one SHEET — a grid of separate pictures in a single image — because that is what piece_sheet cuts apart, and because one sheet comes back looking like one set rather than nine unrelated drawings. For a new play, use 'scenery' for separate trees, bushes, doors and other set pieces, and 'actors' for the full-body cast. Import both as cut-out pieces. A finished-looking scene cannot be rearranged or animated. The legacy 'backgrounds' kind can still make wide pictures for old plays, but new scenes use the open canvas and stage_create no longer accepts a backdrop. All are written in one house style so the cast and the set match. Brand and studio names in your topic are replaced with what they actually describe, and the reply says which. Ask for a FULL SHEET each time — 5 × 5 for actors and scenery, which is 25 pieces in one go. A set is made of a lot of small things, and generating them one at a time is the slowest possible way to build one. The exception is a sheet of BIG things — a throne, a door, a wall, a tree meant to fill the stage. Cells share the sheet's pixels, so 25 of them land around 250px each and look soft the moment one is drawn large; ask for columns 3, rows 3 and each piece gets two thirds again the size. Keep 5 × 5 for anything played small.
View tool JSON
{
"name": "theater_art_prompt",
"kind": "act",
"impl": "imperative",
"description": "Get a ready-to-use image-generation prompt for the art this show needs, then paste it into whatever can draw. Ask for one SHEET — a grid of separate pictures in a single image — because that is what piece_sheet cuts apart, and because one sheet comes back looking like one set rather than nine unrelated drawings. For a new play, use 'scenery' for separate trees, bushes, doors and other set pieces, and 'actors' for the full-body cast. Import both as cut-out pieces. A finished-looking scene cannot be rearranged or animated. The legacy 'backgrounds' kind can still make wide pictures for old plays, but new scenes use the open canvas and stage_create no longer accepts a backdrop. All are written in one house style so the cast and the set match. Brand and studio names in your topic are replaced with what they actually describe, and the reply says which. Ask for a FULL SHEET each time — 5 × 5 for actors and scenery, which is 25 pieces in one go. A set is made of a lot of small things, and generating them one at a time is the slowest possible way to build one. The exception is a sheet of BIG things — a throne, a door, a wall, a tree meant to fill the stage. Cells share the sheet's pixels, so 25 of them land around 250px each and look soft the moment one is drawn large; ask for columns 3, rows 3 and each piece gets two thirds again the size. Keep 5 × 5 for anything played small.",
"inputSchema": {
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": [
"actors",
"scenery",
"backgrounds"
],
"description": "Use 'actors' for the cast or 'scenery' for separate set pieces. 'backgrounds' is for legacy plays; new scenes have no backdrop panel."
},
"topic": {
"type": "string",
"description": "What the play is about, in the words the person used — 'Little Red Riding Hood', 'a robot who loses a bolt'."
},
"columns": {
"type": "number",
"description": "Cells across, 1–5. Leave it alone: the defaults are 5 × 5 for actors and scenery — 25 pieces from one generation. The legacy backgrounds kind uses wide cells."
},
"rows": {
"type": "number",
"description": "Cells down, 1–5."
},
"shape": {
"type": "string",
"enum": [
"wide",
"square",
"tall"
],
"description": "The shape of one cell. Actors and scenery usually stay square; use wide or tall only when an individual cut-out needs that shape."
},
"subjects": {
"type": "array",
"items": {
"type": "string"
},
"description": "What goes in each cell, in reading order. Worth giving: the defaults are a generic folk tale and you know the story. Keep the same order when you pass labels to piece_sheet and every piece arrives named."
}
},
"required": [
"kind"
]
},
"page": "/"
}piece_sheetAction
Add a grid image to this canvas as separate pieces, one per cell. The image pixels are passed to a FastCut iframe on a separate Needle-hosted origin for background removal; this tool does not publish the play. Use 'actors' for movable characters and cut-out scenery. 'backgrounds' is retained for legacy sheets; new scenes have no backdrop panel. Pass labels in reading order to name the pieces. For large sheets, upload the raw image to POST /api/sheets first and pass its short URL here; avoid putting multi-megabyte base64 data in a tool argument.
View tool JSON
{
"name": "piece_sheet",
"kind": "act",
"impl": "imperative",
"description": "Add a grid image to this canvas as separate pieces, one per cell. The image pixels are passed to a FastCut iframe on a separate Needle-hosted origin for background removal; this tool does not publish the play. Use 'actors' for movable characters and cut-out scenery. 'backgrounds' is retained for legacy sheets; new scenes have no backdrop panel. Pass labels in reading order to name the pieces. For large sheets, upload the raw image to POST /api/sheets first and pass its short URL here; avoid putting multi-megabyte base64 data in a tool argument.",
"inputSchema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Image URL: http(s), a small data:image/ URL, or /api/sheets/<id>. For a large PNG/WebP, POST its raw bytes to /api/sheets (5 MB maximum) and use the returned URL within two hours. Other origins must allow CORS so the image can be cut."
},
"columns": {
"type": "number",
"description": "Cells across."
},
"rows": {
"type": "number",
"description": "Cells down."
},
"as": {
"type": "string",
"enum": [
"actors",
"backgrounds"
],
"description": "What is on it. 'actors' is for anything that stands on a stage — use it for scenery too, since a tree is cut out exactly as a person is. 'backgrounds' is a legacy import mode and is not used by stage_create in new plays."
},
"labels": {
"type": "array",
"items": {
"type": "string"
},
"description": "What each cell is, in reading order — left to right, then down."
}
},
"required": [
"url",
"columns",
"rows",
"as"
]
},
"page": "/"
}piece_listAction
Everything on the canvas, the output page, and any resolution problems. Call before changing anything, and call show_look to actually see it.
View tool JSON
{
"name": "piece_list",
"kind": "act",
"impl": "imperative",
"description": "Everything on the canvas, the output page, and any resolution problems. Call before changing anything, and call show_look to actually see it.",
"inputSchema": {
"type": "object",
"properties": {}
},
"page": "/"
}piece_addAction
Put an image on the canvas from an http(s), data:image/, or /api/sheets/ URL. The background is removed automatically by default: its pixels are passed to a FastCut iframe on a separate Needle-hosted origin. This changes the local canvas; it does not publish the play. FastCut is already embedded; do not open it in another tab first. An image that is already transparent is left alone. Pass removeBackground: false to keep a background on purpose. The result says what happened, and what to do if the cut could not run. A picture holding several distinct objects — a poster, a sheet of stickers, things laid out on a table — comes apart into one layer per object, each where it was, so what arrives is editable rather than flat. That is usually the point of handing one over: generate the picture, pass it here, and every part of it can then be moved, restyled or replaced. Objects are found by transparency, which only separates things that do not touch. When they DO touch — three figures standing together, anything posed as a group — pass "regions": you can see the picture and the page cannot, so say where each subject is and it will be cut out and cleaned up inside that box.
View tool JSON
{
"name": "piece_add",
"kind": "act",
"impl": "imperative",
"description": "Put an image on the canvas from an http(s), data:image/, or /api/sheets/ URL. The background is removed automatically by default: its pixels are passed to a FastCut iframe on a separate Needle-hosted origin. This changes the local canvas; it does not publish the play. FastCut is already embedded; do not open it in another tab first. An image that is already transparent is left alone. Pass removeBackground: false to keep a background on purpose. The result says what happened, and what to do if the cut could not run. A picture holding several distinct objects — a poster, a sheet of stickers, things laid out on a table — comes apart into one layer per object, each where it was, so what arrives is editable rather than flat. That is usually the point of handing one over: generate the picture, pass it here, and every part of it can then be moved, restyled or replaced. Objects are found by transparency, which only separates things that do not touch. When they DO touch — three figures standing together, anything posed as a group — pass \"regions\": you can see the picture and the page cannot, so say where each subject is and it will be cut out and cleaned up inside that box.",
"inputSchema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Image URL: http(s), a small data:image/ URL, or /api/sheets/<id>."
},
"label": {
"type": "string",
"description": "A name you will recognise later, e.g. 'red sneaker'."
},
"removeBackground": {
"type": "boolean",
"description": "Default true. Set false only to keep the background deliberately."
},
"x": {
"type": "number",
"description": "Canvas x. Omit to place it automatically."
},
"y": {
"type": "number",
"description": "Canvas y."
},
"width": {
"type": "number",
"description": "Canvas width. Height follows the aspect ratio."
},
"slice": {
"type": "boolean",
"description": "Default true. Set false to keep a picture of several things as one layer."
},
"heal": {
"type": "boolean",
"description": "Default false. Also keep the scene behind the objects as a backdrop layer. Costs a second model download and a slow pass, so ask for it when the background is worth having, not by habit."
},
"regions": {
"type": "array",
"description": "Where each subject is, for a picture whose subjects touch. Fractions of the image, 0–1, from the top left — not pixels, because you are looking at a resized copy. One box per thing you want as its own layer. Draw them generously: a box that clips a subject loses whatever it clipped, while a box that catches some of the neighbour is cleaned up.",
"items": {
"type": "object",
"properties": {
"x": {
"type": "number",
"description": "Left edge, 0–1."
},
"y": {
"type": "number",
"description": "Top edge, 0–1."
},
"width": {
"type": "number",
"description": "Width, 0–1."
},
"height": {
"type": "number",
"description": "Height, 0–1."
},
"label": {
"type": "string",
"description": "What it is, e.g. 'woman with the star cape'."
}
},
"required": [
"x",
"y",
"width",
"height"
]
}
}
},
"required": [
"url"
]
},
"page": "/"
}piece_textAction
Put a headline or caption on the canvas. It stays real text in the exported HTML.
View tool JSON
{
"name": "piece_text",
"kind": "act",
"impl": "imperative",
"description": "Put a headline or caption on the canvas. It stays real text in the exported HTML.",
"inputSchema": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "What it says."
},
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"fontSize": {
"type": "number",
"description": "In canvas units. Default 48."
},
"color": {
"type": "string",
"description": "Any CSS colour."
},
"align": {
"type": "string",
"enum": [
"left",
"center",
"right"
]
},
"rotation": {
"type": "number",
"description": "Degrees of tilt."
}
},
"required": [
"text"
]
},
"page": "/"
}piece_moveAction
Change one layer's position, size, rotation or stacking order, by id. Use `scale` to make it bigger or smaller relative to what it is now (1.5 is half again, 0.5 is half), or `width` for an exact canvas size. Rotation is in degrees. Moving a piece that is (held by …) sets it down at the given spot — explicit coordinates always mean the paper, never a hand.
View tool JSON
{
"name": "piece_move",
"kind": "act",
"impl": "imperative",
"description": "Change one layer's position, size, rotation or stacking order, by id. Use `scale` to make it bigger or smaller relative to what it is now (1.5 is half again, 0.5 is half), or `width` for an exact canvas size. Rotation is in degrees. Moving a piece that is (held by …) sets it down at the given spot — explicit coordinates always mean the paper, never a hand.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"description": "Exact canvas width. Height follows the aspect ratio. Clamped to 0.5–1.5× the current width — big jumps in size are how worlds get monsters."
},
"scale": {
"type": "number",
"description": "Multiply the current size, clamped to 0.5–1.5 per call. Ignored if width is given."
},
"rotation": {
"type": "number",
"description": "Degrees, clockwise. 0 is straight."
},
"order": {
"type": "string",
"enum": [
"front",
"back"
],
"description": "Move it in front of or behind everything."
}
},
"required": [
"id"
]
},
"page": "/"
}piece_copyAction
Duplicate an existing layer, sharing its picture — a crowd of the same sheep, three copies of the hero spawning at different doors, a forest from one tree. Each clone is its own layer with its own id: cast them at different spots, on different planes, in different scenes, and script them separately. Cheap — no generation, no cutting.
View tool JSON
{
"name": "piece_copy",
"kind": "act",
"impl": "imperative",
"description": "Duplicate an existing layer, sharing its picture — a crowd of the same sheep, three copies of the hero spawning at different doors, a forest from one tree. Each clone is its own layer with its own id: cast them at different spots, on different planes, in different scenes, and script them separately. Cheap — no generation, no cutting.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The layer to clone."
},
"count": {
"type": "number",
"description": "How many clones, 1–12. Default 1."
},
"at": {
"type": "array",
"description": "Where each clone goes, as {x, y} canvas coordinates (top-left). Fewer entries than clones and the rest fan out beside the original.",
"items": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
}
}
}
}
},
"required": [
"id"
]
},
"page": "/"
}piece_removeAction
Take one layer or frame off the canvas, by id.
View tool JSON
{
"name": "piece_remove",
"kind": "act",
"impl": "imperative",
"description": "Take one layer or frame off the canvas, by id.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
},
"required": [
"id"
]
},
"page": "/"
}piece_sayAction
Make a piece speak a line in a speech bubble right now, outside a play — e.g. to react to something the person placed, or to answer through a character. Same bubble and voice as in a play. The page speaks the line out loud, so do not repeat it in your own reply. Pass an array of lines for several bubbles in a row. Does not work while a show is playing; use a say beat then.
View tool JSON
{
"name": "piece_say",
"kind": "act",
"impl": "imperative",
"description": "Make a piece speak a line in a speech bubble right now, outside a play — e.g. to react to something the person placed, or to answer through a character. Same bubble and voice as in a play. The page speaks the line out loud, so do not repeat it in your own reply. Pass an array of lines for several bubbles in a row. Does not work while a show is playing; use a say beat then.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Which piece speaks."
},
"say": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"description": "The line — or lines, delivered one bubble after another."
}
},
"required": [
"id",
"say"
]
},
"page": "/"
}show_watchAction
Wait until something changes on the canvas, then return what happened — images added, layers moved, styles changed, exports — together with a picture of the result, so you can see what the person did and act on it. Blocks until there is news or the wait runs out, so call it in a loop to follow along while they work. This loop plus piece_say is NARRATOR MODE: the person (often a child) plays with the pieces by hand and you tell the story of what they do — the wolf creeps toward the house, have the pig gasp. Watch, react through the characters' own bubbles, repeat. Pass the `nextCursor` from the previous call so nothing is missed between calls.
View tool JSON
{
"name": "show_watch",
"kind": "act",
"impl": "imperative",
"description": "Wait until something changes on the canvas, then return what happened — images added, layers moved, styles changed, exports — together with a picture of the result, so you can see what the person did and act on it. Blocks until there is news or the wait runs out, so call it in a loop to follow along while they work. This loop plus piece_say is NARRATOR MODE: the person (often a child) plays with the pieces by hand and you tell the story of what they do — the wolf creeps toward the house, have the pig gasp. Watch, react through the characters' own bubbles, repeat. Pass the `nextCursor` from the previous call so nothing is missed between calls.",
"inputSchema": {
"type": "object",
"properties": {
"cursor": {
"type": "number",
"description": "The nextCursor from your last call. Omit to start from now."
},
"timeoutSeconds": {
"type": "number",
"description": "How long to wait, 1–30. Default 25."
},
"preview": {
"type": "boolean",
"description": "Include a picture of the canvas. Default true."
}
}
},
"page": "/"
}show_lookAction
Render a frame and return it as an image, so you can see what you made and fix what is wrong. Call this after arranging or styling.
View tool JSON
{
"name": "show_look",
"kind": "act",
"impl": "imperative",
"description": "Render a frame and return it as an image, so you can see what you made and fix what is wrong. Call this after arranging or styling.",
"inputSchema": {
"type": "object",
"properties": {
"frameId": {
"type": "string",
"description": "Which frame. Omit when there is only one."
},
"maxSize": {
"type": "number",
"description": "Longest edge in pixels, 240–1024. Default 640."
}
}
},
"page": "/"
}theater_troupeAction
List the built-in cut-out art with no arguments. Pass add: [ids] to place selected pieces on this local canvas, ready to cast. This does not upload or publish anything. Pieces sharing a take are the same character in different poses.
View tool JSON
{
"name": "theater_troupe",
"kind": "act",
"impl": "imperative",
"description": "List the built-in cut-out art with no arguments. Pass add: [ids] to place selected pieces on this local canvas, ready to cast. This does not upload or publish anything. Pieces sharing a take are the same character in different poses.",
"inputSchema": {
"type": "object",
"properties": {
"add": {
"type": "array",
"items": {
"type": "string"
},
"description": "Piece ids to add, e.g. \"woodland/wolf\". Omit to see the catalogue."
}
}
},
"page": "/"
}stage_removeAction
Delete scenes by id. Only the scenes: every picture in them stays on the canvas, because a scene records where things stand rather than owning them — so removing the scene an actor was in does not remove the actor. Undoable, like anything else here. This is the tool for tidying up a false start: two empty scenes left over from a reload should be removed, not worked around, and NOT by clearing the whole canvas.
View tool JSON
{
"name": "stage_remove",
"kind": "act",
"impl": "imperative",
"description": "Delete scenes by id. Only the scenes: every picture in them stays on the canvas, because a scene records where things stand rather than owning them — so removing the scene an actor was in does not remove the actor. Undoable, like anything else here. This is the tool for tidying up a false start: two empty scenes left over from a reload should be removed, not worked around, and NOT by clearing the whole canvas.",
"inputSchema": {
"type": "object",
"properties": {
"stages": {
"type": "array",
"items": {
"type": "string"
},
"description": "Scene ids to delete. Call stage_describe for what there is."
}
},
"required": [
"stages"
]
},
"page": "/"
}show_titleAction
Set the show's title, language, byline and maker credits. The title shows on a card before the first scene and heads the end credits. Always set one. Cast credits come from stage_cast "as" values; pass "credits" for the maker lines and always include "directed by <your model or product name>". Set language to the language of the dialogue and narration, such as en or de; it is saved with the published play.
View tool JSON
{
"name": "show_title",
"kind": "act",
"impl": "imperative",
"description": "Set the show's title, language, byline and maker credits. The title shows on a card before the first scene and heads the end credits. Always set one. Cast credits come from stage_cast \"as\" values; pass \"credits\" for the maker lines and always include \"directed by <your model or product name>\". Set language to the language of the dialogue and narration, such as en or de; it is saved with the published play.",
"inputSchema": {
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "What the piece is called. Pass '' to drop the card."
},
"language": {
"type": "string",
"description": "Language code for dialogue and narration, e.g. en, de, or fr."
},
"byline": {
"type": "string",
"description": "One sentence about the story, shown under the title and used as the share link's preview text. E.g. 'a tale of a moon with an appetite'. Describe the story, not the art packs used. Strongly recommended."
},
"credits": {
"type": "array",
"items": {
"type": "string"
},
"description": "The maker's lines, rolled at the end after the cast, under the house cactus. ALWAYS include a direction credit naming yourself — 'directed by <your model or product name>' — and, when they took part, the person: 'staged with <their name, if they told you it>'. More lines welcome: 'story after Grimm', 'paper cut-outs — the woodland pack'. Saved with the play; pass [] to clear."
}
}
},
"page": "/"
}show_soundsAction
Every piece of music and every sound effect, with what it sounds like. Call it once before choosing: the ids alone do not tell you which of eight beds suits a scene, and picking by name is picking at random.
View tool JSON
{
"name": "show_sounds",
"kind": "act",
"impl": "imperative",
"description": "Every piece of music and every sound effect, with what it sounds like. Call it once before choosing: the ids alone do not tell you which of eight beds suits a scene, and picking by name is picking at random.",
"inputSchema": {
"type": "object",
"properties": {}
},
"page": "/"
}show_fullscreenAction
Ask the browser to show this theater page fullscreen, useful during playback. The browser may require a direct click in the theater tab and may disallow fullscreen inside an embedded browser. If it cannot enter fullscreen, this tool explains why; playback is unaffected.
View tool JSON
{
"name": "show_fullscreen",
"kind": "act",
"impl": "imperative",
"description": "Ask the browser to show this theater page fullscreen, useful during playback. The browser may require a direct click in the theater tab and may disallow fullscreen inside an embedded browser. If it cannot enter fullscreen, this tool explains why; playback is unaffected.",
"inputSchema": {
"type": "object",
"properties": {}
},
"page": "/"
}show_playAction
Run scenes. In text chat, omit stages and hold to play the full show without live narration. In voice mode, pass one stage id with hold:true to play that scene and HOLD — the stage stays lit, the music keeps playing, and the last frame stands — so you can narrate what happened and write the next scene AFTER seeing this one. Call again with the next stage to continue; a call without hold ends with the curtain call and credits. This scene-by-scene loop keeps voice narration in step with the story. Run the scenes one after another. Each one builds up — everybody with an entrance arrives — then its script plays, then they leave and the next scene begins. Returns the whole timetable at once and keeps playing, so in voice mode you can narrate to it rather than waiting. The build-up and the exits are made for you; you only write what happens in between, with stage_script. Narration saved on beats is returned in the play document; if using voice mode, speak those passages alongside their moments.
View tool JSON
{
"name": "show_play",
"kind": "act",
"impl": "imperative",
"description": "Run scenes. In text chat, omit stages and hold to play the full show without live narration. In voice mode, pass one stage id with hold:true to play that scene and HOLD — the stage stays lit, the music keeps playing, and the last frame stands — so you can narrate what happened and write the next scene AFTER seeing this one. Call again with the next stage to continue; a call without hold ends with the curtain call and credits. This scene-by-scene loop keeps voice narration in step with the story. Run the scenes one after another. Each one builds up — everybody with an entrance arrives — then its script plays, then they leave and the next scene begins. Returns the whole timetable at once and keeps playing, so in voice mode you can narrate to it rather than waiting. The build-up and the exits are made for you; you only write what happens in between, with stage_script. Narration saved on beats is returned in the play document; if using voice mode, speak those passages alongside their moments.",
"inputSchema": {
"type": "object",
"properties": {
"stages": {
"type": "array",
"items": {
"type": "string"
},
"description": "Scene ids, in the order to play them. Omit for all of them, as created."
},
"hold": {
"type": "boolean",
"description": "Hold the stage after these scenes instead of ending: lights stay down, music keeps playing, last frame stands. Continue with another show_play; end with one that leaves this off."
}
}
},
"page": "/"
}show_stopAction
Stop the show wherever it has got to. The scene it was on stays on screen, so the canvas is left somewhere sensible rather than blank.
View tool JSON
{
"name": "show_stop",
"kind": "act",
"impl": "imperative",
"description": "Stop the show wherever it has got to. The scene it was on stays on screen, so the canvas is left somewhere sensible rather than blank.",
"inputSchema": {
"type": "object",
"properties": {}
},
"page": "/"
}stage_scriptAction
Play a scene: who does what, and what they say, in order. Hand over the WHOLE scene in one call — you cannot animate by calling a tool per frame, and you do not need to. The page plays it and this returns at once with the timings, so in voice mode you can narrate over the top. One thing happens at a time: a beat starts when the last one ends, and there is no timing to work out. The scene KEEPS its script, so show_play can run it again as part of the whole show — pass rehearse:false to write it without playing it now. Use narration on beats for short storyteller passages. They are saved and timed with the play; the theatre does not speak them yet, so narrate them live when connected. Moves: walk, jump, shake, surprised, scared, nod, bow, turn, enter, exit. "walk" and "jump" leave the layer where they end: give them "at" to say WHERE on the canvas to end up (the coordinates piece_list and stage_describe report), or "by" to say HOW FAR to travel. "at" is almost always the one you want. There is no "to" — it meant a distance, read like a destination, and walked characters clean off the paper. Everything else finishes exactly where it started. A beat's "take" picks another cast member up — it rides along through every later move until a "drop" lets it fall. "with": true makes a beat run AT THE SAME TIME as the one before it, so two characters can move or speak together. "walk" and "jump" travel to any canvas point — a hero can cross the whole world, scene to scene, if the story sends them. An "effect" throws paper over a beat: sparkles, poof, confetti, hearts, rain, anger, smoke, explosion.
View tool JSON
{
"name": "stage_script",
"kind": "act",
"impl": "imperative",
"description": "Play a scene: who does what, and what they say, in order. Hand over the WHOLE scene in one call — you cannot animate by calling a tool per frame, and you do not need to. The page plays it and this returns at once with the timings, so in voice mode you can narrate over the top. One thing happens at a time: a beat starts when the last one ends, and there is no timing to work out. The scene KEEPS its script, so show_play can run it again as part of the whole show — pass rehearse:false to write it without playing it now. Use narration on beats for short storyteller passages. They are saved and timed with the play; the theatre does not speak them yet, so narrate them live when connected. Moves: walk, jump, shake, surprised, scared, nod, bow, turn, enter, exit. \"walk\" and \"jump\" leave the layer where they end: give them \"at\" to say WHERE on the canvas to end up (the coordinates piece_list and stage_describe report), or \"by\" to say HOW FAR to travel. \"at\" is almost always the one you want. There is no \"to\" — it meant a distance, read like a destination, and walked characters clean off the paper. Everything else finishes exactly where it started. A beat's \"take\" picks another cast member up — it rides along through every later move until a \"drop\" lets it fall. \"with\": true makes a beat run AT THE SAME TIME as the one before it, so two characters can move or speak together. \"walk\" and \"jump\" travel to any canvas point — a hero can cross the whole world, scene to scene, if the story sends them. An \"effect\" throws paper over a beat: sparkles, poof, confetti, hearts, rain, anger, smoke, explosion.",
"inputSchema": {
"type": "object",
"properties": {
"stage": {
"type": "string",
"description": "Which scene. Omit for the one being shown."
},
"rehearse": {
"type": "boolean",
"description": "Play it now as well as saving it. Default true."
},
"beats": {
"type": "array",
"description": "What happens, in order.",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Who this beat is about."
},
"do": {
"type": "string",
"description": "What they do: walk, jump, shake, surprised, scared, nod, bow, turn, enter, exit — or a hand-recorded move as \"clip:<name>\". A clip marked \"(travels)\" was recorded as a journey: it really moves them across the paper and leaves them there, no \"to\" needed. The rest gesture in place. Recorded so far: clip:left-right-anxious (travels), clip:crazy (travels), clip:say-hello-3 (travels), clip:say-hello-2 (travels), clip:say-hello (travels), clip:swing-from-left-right-an (travels), clip:running-in-a-circle (travels), clip:shake-up-down (travels), clip:shake-left-right (travels), clip:talk-3 (travels), clip:talk-2 (travels), clip:run-down (travels), clip:run-right (travels), clip:run-left (travels), clip:run-up (travels), clip:sad-no, clip:agree-yes, clip:shake-head, clip:talk, clip:swing-fly-softly, clip:shake-long, clip:surprise-up, clip:shake, clip:crawl-downwards, clip:swirl, clip:agent-flying-soft, clip:agent-flying, clip:hover-vertical, clip:fly-soft, clip:walk-right, clip:walk-left, clip:walk-downwards, clip:walk-upwards, clip:angry-talk-right, clip:surprised-backoff, clip:thinking-walking, clip:very-happy, clip:surprised, clip:walk, clip:thinking, clip:happy, clip:wave-animation."
},
"say": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"description": "A line, in a bubble above them — or an ARRAY of lines: the same speaker delivers them one after another, a fresh bubble each, and the beat's move plays under the first. Several short bubbles read far better than one long one."
},
"sound": {
"type": "string",
"enum": [
"alarm-comic-1",
"alarm-comic-2",
"alarm-comic-3",
"angry-stomping-1",
"angry-stomping-2",
"angry-stomping-3",
"anticipation-hushed-1",
"anticipation-hushed-2",
"anticipation-hushed-3",
"argument",
"awe-1",
"awe-2",
"awe-3",
"awe-4",
"awe-5",
"betrayal-1",
"betrayal-2",
"betrayal-3",
"big-beast-1",
"big-beast-2",
"big-beast-3",
"bird-chirp",
"blacksmith-strike",
"boredom-1",
"boredom-2",
"boredom-3",
"bow-courtly-1",
"bow-courtly-2",
"bow-courtly-3",
"cat-meow",
"choir-wonder-1",
"choir-wonder-2",
"choir-wonder-3",
"climb-up",
"clock-time-1",
"clock-time-2",
"cry-vocal",
"danger-glockenspiel",
"disappointed-banjo-1",
"disappointed-banjo-2",
"disappointed-banjo-3",
"dog-bark-1",
"dog-bark-2",
"drop-in-1",
"drop-in-2",
"drop-in-3",
"enter-bright-1",
"enter-bright-2",
"enter-bright-3",
"explosion-comic-1",
"explosion-comic-2",
"explosion-comic-3",
"fall-clumsy-1",
"fall-clumsy-2",
"fall-clumsy-3",
"flash-bright-1",
"flash-bright-2",
"flash-bright-3",
"flash-bright-4",
"flash-bright-5",
"flash-bright-6",
"fly-soar-1",
"fly-soar-2",
"forgive-1",
"forgive-2",
"frog-croak-1",
"frog-croak-2",
"frog-croak-3",
"frog-croak-4",
"frog-croak-5",
"greeting-1",
"greeting-2",
"greeting-3",
"greeting-4",
"greeting-5",
"grow-in-1",
"grow-in-2",
"grow-in-3",
"guitar-nightwatch-1",
"guitar-nightwatch-2",
"guitar-nightwatch-3",
"gulp-eat-1",
"gulp-eat-2",
"halt-comic",
"herald-fanfare",
"jump-springy-1",
"jump-springy-2",
"kiss-sweet",
"lie-told",
"light-and-airy-1",
"light-and-airy-2",
"lonely",
"longing-1",
"longing-2",
"longing-3",
"market-haggle",
"menace-near-1",
"menace-near-2",
"minstrel-air-1",
"minstrel-air-2",
"mischief-1",
"mischief-2",
"musicbox-down-1",
"musicbox-down-2",
"musicbox-down-3",
"musicbox-wind-1",
"musicbox-wind-2",
"musicbox-wind-3",
"owl-hoot",
"panic-1",
"panic-2",
"panic-3",
"pride-small-1",
"pride-small-2",
"pride-small-3",
"ray-zap",
"relief-resolve-1",
"relief-resolve-2",
"relief-resolve-3",
"rise-up-1",
"rise-up-2",
"rise-up-3",
"robot-chirp-1",
"robot-chirp-2",
"shame-1",
"shame-2",
"shame-3",
"shimmer-dream-1",
"shimmer-dream-2",
"shimmer-dream-3",
"shimmer-dream-4",
"shimmer-dream-5",
"shrink-down-1",
"shrink-down-2",
"singing-bowl-1",
"singing-bowl-2",
"sleepy-lullaby-1",
"sleepy-lullaby-2",
"sleepy-waltz-1",
"sleepy-waltz-2",
"sleepy-waltz-3",
"sneak-muted-1",
"sneak-muted-2",
"sorrowful-cello-1",
"sorrowful-cello-2",
"sorrowful-cello-3",
"spin-in-1",
"spin-in-2",
"spin-in-3",
"splash-1",
"splash-2",
"splash-3",
"spotlight-hushed-1",
"spotlight-hushed-2",
"spotlight-hushed-3",
"stage-shake-1",
"stage-shake-2",
"stage-shake-3",
"street-bustle-1",
"street-bustle-2",
"striving-climb-1",
"striving-climb-2",
"striving-climb-3",
"surf-chase-1",
"surf-chase-2",
"surprise-staccato-1",
"surprise-staccato-2",
"surprise-ukulele-1",
"surprise-ukulele-2",
"surprise-ukulele-3",
"suspense-crescendo-1",
"suspense-crescendo-2",
"suspense-crescendo-3",
"suspense-stalking-1",
"suspense-stalking-2",
"suspense-stalking-3",
"suspense-stalking-4",
"suspicion-1",
"suspicion-2",
"think-pondering-1",
"think-pondering-2",
"think-pondering-3",
"treasure-sparkle-1",
"treasure-sparkle-2",
"treasure-sparkle-3",
"villain-fuzz-1",
"villain-fuzz-2",
"villain-fuzz-3",
"wake-up-1",
"wake-up-2",
"wake-up-3",
"animal-call-1",
"animal-call-2",
"animal-call-3",
"applause-1",
"applause-2",
"applause-3",
"applause-4",
"bell",
"boing",
"boing-long",
"crowd-murmur",
"curtain-open-1",
"curtain-open-2",
"curtain-open-3",
"curtain-sweep-1",
"curtain-sweep-2",
"door-creak-1",
"door-creak-2",
"drop",
"footsteps-1",
"footsteps-2",
"footsteps-3",
"footsteps-4",
"gasp-1",
"gasp-2",
"gasp-3",
"hinge-creak-1",
"hinge-creak-2",
"knock-dull",
"laugh-cute",
"magic-transformation-1",
"magic-transformation-2",
"magic-transformation-3",
"paper-shuffle-1",
"paper-shuffle-2",
"paper-shuffle-3",
"phew",
"plop",
"potion-bubble-1",
"potion-bubble-2",
"potion-bubble-3",
"prop-clatter-1",
"prop-clatter-2",
"prop-clatter-3",
"snore-comic-1",
"snore-comic-2",
"spit",
"swoosh-small",
"sword-clash-1",
"sword-clash-2",
"sword-clash-3",
"sword-draw-1",
"sword-draw-2",
"thud",
"thunder-soft-1",
"thunder-soft-2",
"thunder-soft-3",
"vanish-poof-1",
"vanish-poof-2",
"vanish-poof-3",
"vanish-poof-4",
"whoosh",
"wind-gust-1",
"wind-gust-2",
"wind-gust-3"
],
"description": "A sting fired as the beat starts. Rides along with a move rather than taking its own time. Call show_sounds for what each is."
},
"at": {
"type": "object",
"description": "Where a walk or jump ENDS UP, in canvas coordinates — the same numbers piece_list and stage_describe report. Measured against where the walker is standing at that point in the scene, so two walks in a row both land where you said. This is a FLAT stage seen from the front, so crossing it means changing x — left and right. There is no into-the-distance to walk into; y moves somebody up or down the picture, which is a jump or a climb, not a journey.",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
}
}
},
"by": {
"type": "object",
"description": "How far a walk or jump travels from where it starts, in canvas units — a distance, not a place. For \"two steps back\". Use \"at\" whenever you know where they should end up. Ignored when \"at\" is given.",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
}
}
},
"camera": {
"type": "object",
"description": "Move the view to frame pieces. Use on:'all' for the whole cast at the start and end of a scene. A single id can put everyone else offscreen; use it only for a brief close-up, then return to on:'all' or a group. The move takes the beat's whole \"duration\": 600ms = fast cut, 3000ms = drift, 8000ms = slow zoom. Use slow moves often, not only cuts. Add \"with\": true to move the camera WHILE the previous beat plays, e.g. a slow push-in during a line: {id, say: \"...\"} then {camera: {on: [id], tight: 1.3}, with: true, duration: 6000}. To travel from one place to another, frame piece A, then piece B. Needs no \"id\".",
"properties": {
"on": {
"description": "Layer ids to frame, or \"all\" for the whole scene. Prefer \"all\" or a group when several characters matter.",
"oneOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "string",
"enum": [
"all"
]
}
]
},
"tight": {
"type": "number",
"description": "How much of the view they fill. 1 is snug (default), 0.6 leaves air around them, 1.4 is a close-up that crops other characters. Prefer 0.6–0.85 for a group."
},
"easing": {
"type": "string",
"enum": [
"glide",
"linear"
],
"description": "'glide' (default) slows down at the end. 'linear' moves at constant speed — use it for long slow zooms and pans."
}
},
"required": [
"on"
]
},
"effect": {
"type": "string",
"enum": [
"sparkles",
"poof",
"confetti",
"hearts",
"rain",
"anger",
"smoke",
"explosion"
],
"description": "A canned particle effect thrown over this character as the beat runs — little paper shapes, in the style of the stage. Rides along with a move or a line; alone it takes its own moment. \"sparkles\": Little paper stars pop around them and wink out. Magic, a wish granted, a potion working, something precious revealed. \"poof\": A burst of paper dust from their middle, gone in a blink. Appearing, vanishing, a transformation landing — pair it with \"becomes\". \"confetti\": Strips of coloured paper flutter down over them. Celebration, victory, a party, the happy ending. \"hearts\": Small paper hearts rise from them and fade. Love, gratitude, delight. \"rain\": Torn blue slivers fall across them. Rain, sadness, a bad day on stage. \"anger\": Big cut-paper symbols burst over their head — a hash, an at, a star, a bang. Comic swearing: fury, a tantrum, being told off, losing an argument. Fewer and much larger than the other effects, so it reads from across the stage. \"smoke\": Soft grey paper puffs climb from them and thin out as they go. A chimney, a kettle, a snuffed candle, a train pulling away — anything still going after the thing that caused it has stopped. The slowest effect here. \"explosion\": A hard burst of red and mustard shards thrown outward, with dark smoke left drifting up behind them. A blast, a crash, a machine giving up, a spell going wrong. The loudest thing on the stage — do not use it for a surprise, use \"poof\"."
},
"take": {
"type": "string",
"description": "The id of a cast member this character picks up. It animates into their hand and then belongs to them — walks, jumps and turns carry it along — until a \"drop\". A character holding a basket, sitting on a vehicle, carrying a lantern: all this."
},
"drop": {
"type": "string",
"description": "The id of a held cast member to let go of. It falls to the ground line and stays where it lands."
},
"becomes": {
"type": "string",
"description": "Another layer id to draw in this character's place from here on — a costume change. The only way a cut-out can do something its drawing does not already do: a bird with folded wings cannot open them, but it can BECOME the drawing of a bird with open wings, standing in the same place at the same size. Ask for both on the same sheet and they will match. Lasts until the scene ends or another beat changes it again."
},
"with": {
"type": "boolean",
"description": "Run this beat AT THE SAME TIME as the one before it — B recoils while A shouts, two people speak over each other, the wolf creeps while the girl talks. Reaction is what scenes are made of; use this often."
},
"wait": {
"type": "number",
"description": "Seconds of nothing. A beat with only this in it is a pause — before an answer that is being thought about, after a line that needs to land, while somebody looks at something. Needs no \"id\". A short breath between two different speakers is added for you; this is for the ones that mean something."
},
"background": {
"type": "string",
"description": "Fade the PAPER to this hex colour as the beat starts — the weather changing mid-scene: dusk falling, a fire catching. 'paper' returns the house colour. Rides along with whatever else the beat does; alone it takes no time and needs no id. It stays until something changes it again."
},
"spotlight": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"description": "Put a spotlight on a layer id (or an array of ids, or 'off'). Everything else dims; the lit pieces stay fully visible and the beam follows them when they move. Can ride along with another beat; alone it lasts 1.6 seconds and needs no id. By default it ends with this beat, so later dialogue is lit normally. Use spotlightHold:true only when the light should span later beats; then send spotlight:'off' when the moment ends."
},
"narration": {
"type": "string",
"description": "A short line for the AI narrator at this moment. Saved with the beat for future voice playback; it is not character dialogue and the theatre does not speak it yet. Can stand alone without an id, or accompany a move or camera shot. Keep each passage brief."
},
"spotlightHold": {
"type": "boolean",
"description": "Keep a spotlight across later beats until spotlight:'off'. Default false: this beat only."
},
"range": {
"type": "number",
"description": "Beam size for `spotlight`, as a multiple of the piece: 1 hugs it (default), 0.7 a tight face-spot, 2.5 a wide pool."
},
"duration": {
"type": "number",
"description": "Override the beat's length, in ms."
}
}
}
}
},
"required": [
"beats"
]
},
"page": "/"
}stage_createAction
Create a chapter: a named stretch of the story, with its own cast, script and music. Chapters do not own or move anything — the canvas is one continuous world, and a show is the camera following the story across it: chapter one leaves the hero at the forest's edge and chapter two picks her up exactly there. Walks and jumps really move the pieces; when the show ends, the arrangement is put back the way it was at curtain-up. Pass an existing id to rename a chapter.
View tool JSON
{
"name": "stage_create",
"kind": "act",
"impl": "imperative",
"description": "Create a chapter: a named stretch of the story, with its own cast, script and music. Chapters do not own or move anything — the canvas is one continuous world, and a show is the camera following the story across it: chapter one leaves the hero at the forest's edge and chapter two picks her up exactly there. Walks and jumps really move the pieces; when the show ends, the arrangement is put back the way it was at curtain-up. Pass an existing id to rename a chapter.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "An existing stage to change. Omit to make a new one."
},
"name": {
"type": "string",
"description": "What the scene is called, e.g. 'the rooftop'."
},
"music": {
"type": "string",
"enum": [
"bright-arrival",
"chase-comic-1",
"chase-comic-2",
"climb-steps",
"danger-close-1",
"danger-close-2",
"danger-close-3",
"feast-hall-1",
"feast-hall-2",
"feast-hall-3",
"forest-air-1",
"forest-air-2",
"hurdy-drone-1",
"hurdy-drone-2",
"hurdy-drone-3",
"march-army",
"meadow-open-1",
"meadow-open-2",
"meadow-open-3",
"menu-theatre-1",
"menu-theatre-10",
"menu-theatre-11",
"menu-theatre-2",
"menu-theatre-3",
"menu-theatre-4",
"menu-theatre-6",
"menu-theatre-7",
"menu-theatre-8",
"menu-theatre-9",
"night-hush",
"race-driving-1",
"race-driving-2",
"shanty-sea-1",
"shanty-sea-2",
"shanty-sea-3",
"shanty-sea-4",
"shanty-sea-5",
"skeleton-steps",
"street-bustle-long",
"surf-chase-long-1",
"surf-chase-long-2",
"surf-chase-long-3",
"underwater-1",
"underwater-2",
"village-lane-1",
"village-lane-2",
"village-lane-3",
"western-wide-1",
"western-wide-2",
"western-wide-3",
"none"
],
"description": "A bed to play under this scene, cross-fading in from the last one. Call show_sounds to hear what each is. 'none' removes it."
},
"musicEnd": {
"type": "string",
"enum": [
"bright-arrival",
"chase-comic-1",
"chase-comic-2",
"climb-steps",
"danger-close-1",
"danger-close-2",
"danger-close-3",
"feast-hall-1",
"feast-hall-2",
"feast-hall-3",
"forest-air-1",
"forest-air-2",
"hurdy-drone-1",
"hurdy-drone-2",
"hurdy-drone-3",
"march-army",
"meadow-open-1",
"meadow-open-2",
"meadow-open-3",
"menu-theatre-1",
"menu-theatre-10",
"menu-theatre-11",
"menu-theatre-2",
"menu-theatre-3",
"menu-theatre-4",
"menu-theatre-6",
"menu-theatre-7",
"menu-theatre-8",
"menu-theatre-9",
"night-hush",
"race-driving-1",
"race-driving-2",
"shanty-sea-1",
"shanty-sea-2",
"shanty-sea-3",
"shanty-sea-4",
"shanty-sea-5",
"skeleton-steps",
"street-bustle-long",
"surf-chase-long-1",
"surf-chase-long-2",
"surf-chase-long-3",
"underwater-1",
"underwater-2",
"village-lane-1",
"village-lane-2",
"village-lane-3",
"western-wide-1",
"western-wide-2",
"western-wide-3",
"loop",
"fade"
],
"description": "What happens if the music runs out before the scene does: 'loop' (default), 'fade' to let it die away, or the name of another bed to blend into."
},
"tint": {
"type": "string",
"description": "A hex colour for the room around the stage while this scene plays, e.g. '#2A1F3D'. You do not normally need this: the page reads the backdrop's own colour and dims it. Set it when the mood wants something the picture does not say — a cold surround on a warm scene. Pass 'auto' to go back."
},
"background": {
"type": "string",
"description": "The PAPER's colour while this chapter plays — the scene's weather, e.g. '#1B2440' for night. Fades in as the chapter begins and stays until another chapter, beat, or theater_background changes it. 'paper' resets to the house colour. A beat can also change it mid-chapter."
},
"hold": {
"type": "number",
"description": "Seconds to wait at the end before moving on."
},
"restage": {
"type": "boolean",
"description": "Put this chapter's cast back where it was blocked before the chapter starts. The first chapter of a fresh run does this automatically; later chapters leave it off by default. Turn it on for a chapter you wrote before the earlier ones were played: walks and jumps really move the pieces, so by chapter three everybody is somewhere else. Whoever has drifted fades out, moves, and fades back in."
},
"show": {
"type": "boolean",
"description": "Show this scene on the canvas. Default true for a new one."
}
}
},
"page": "/"
}stage_castAction
Say who is IN a chapter — who they play, which voice, how they arrive. Casting does not move anybody: the canvas is one continuous world, every piece stands exactly where it stands, and the arrangement on the paper IS the blocking. Pass x/y/width only to also move or resize the piece in the world (same units piece_list reports); leave them out to cast things right where they are. When you do place, leave AIR between pieces — at least a piece's own width apart; a piece set on top of another is nudged aside to clear paper. Give each an "as" — who they are playing — and they are credited by name at the end. Someone left out of a chapter is not deleted, only absent from its story.
View tool JSON
{
"name": "stage_cast",
"kind": "act",
"impl": "imperative",
"description": "Say who is IN a chapter — who they play, which voice, how they arrive. Casting does not move anybody: the canvas is one continuous world, every piece stands exactly where it stands, and the arrangement on the paper IS the blocking. Pass x/y/width only to also move or resize the piece in the world (same units piece_list reports); leave them out to cast things right where they are. When you do place, leave AIR between pieces — at least a piece's own width apart; a piece set on top of another is nudged aside to clear paper. Give each an \"as\" — who they are playing — and they are credited by name at the end. Someone left out of a chapter is not deleted, only absent from its story.",
"inputSchema": {
"type": "object",
"properties": {
"stage": {
"type": "string",
"description": "Which scene. Omit for the one being shown."
},
"cast": {
"type": "array",
"description": "Who stands where.",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The layer."
},
"x": {
"type": "number",
"description": "Move them here (canvas x, top-left corner) while casting — the same world units piece_list reports and piece_move takes. LEAVE IT OUT to cast them exactly where they stand: the arrangement on the canvas usually IS the blocking."
},
"y": {
"type": "number",
"description": "Canvas y (top-left corner). Leave out to keep their spot."
},
"width": {
"type": "number",
"description": "Resize them while casting (canvas units; height follows their shape). Clamped to 0.5–1.5× the current width per call. Leave out to keep their size — compare against piece_list's widths."
},
"rotation": {
"type": "number",
"description": "Degrees, clockwise."
},
"entrance": {
"type": "string",
"enum": [
"fade",
"left",
"right",
"above",
"below",
"grow",
"none"
],
"description": "How it arrives when the scene builds up."
},
"flip": {
"type": "boolean",
"description": "Mirror the artwork so they face the other way. A cut-out faces whichever way it was drawn — look with show_look to see which — and two people in conversation should face each other. The \"turn\" move flips somebody mid-scene."
},
"as": {
"type": "string",
"description": "Who this picture is playing — 'the grandmother', 'the wolf'. It is what the credits call them at the end, beside their picture, so cast everybody who should be thanked."
},
"voice": {
"type": "object",
"additionalProperties": false,
"properties": {
"speed": {
"type": "number",
"minimum": 0,
"maximum": 2,
"description": "0 is 1×, 1 is the default 1.7×, 2 is 2×."
},
"age": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "0 young, 0.5 medium, 1 old."
},
"tone": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "0 low, 0.5 medium, 1 high."
}
},
"required": [
"speed",
"age",
"tone"
],
"description": "The character's complete voice: exactly speed, age and tone. For troupe actors, leaving it out chooses a fitting voice from the character; passing it overrides that choice. Vary age and tone across the cast."
}
},
"required": [
"id"
]
}
},
"remove": {
"type": "array",
"items": {
"type": "string"
},
"description": "Layer ids to take out of this scene. They stay on the canvas."
}
}
},
"page": "/"
}stage_describeAction
List every chapter, its cast, and the selected chapter. With no arguments this only reads the canvas. Passing 'show' changes which chapter is displayed; pass 'none' to show the whole canvas.
View tool JSON
{
"name": "stage_describe",
"kind": "act",
"impl": "imperative",
"description": "List every chapter, its cast, and the selected chapter. With no arguments this only reads the canvas. Passing 'show' changes which chapter is displayed; pass 'none' to show the whole canvas.",
"inputSchema": {
"type": "object",
"properties": {
"show": {
"type": "string",
"description": "Switch the canvas to this scene first, or 'none' for the whole canvas."
}
}
},
"page": "/"
}show_publishAction
Upload the current play and its custom images to the theater server as public, then return its share URL. Only plays with a script appear in the community library. Supply an existing id to update that play. This is an online publication.
View tool JSON
{
"name": "show_publish",
"kind": "act",
"impl": "imperative",
"description": "Upload the current play and its custom images to the theater server as public, then return its share URL. Only plays with a script appear in the community library. Supply an existing id to update that play. This is an online publication.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Existing play id to update. Omit to create one."
},
"title": {
"type": "string",
"description": "Library title. Defaults to the play's title card."
}
}
},
"page": "/"
}show_listAction
Find public scripted plays made here — id, title, how many chapters, how long, which troupe packs, and the shareable URL. Arrangements and tableaux without scripted beats remain available by direct link, but are not listed. Narrow with title, theme, chapter count or length before loading anything.
View tool JSON
{
"name": "show_list",
"kind": "act",
"impl": "imperative",
"description": "Find public scripted plays made here — id, title, how many chapters, how long, which troupe packs, and the shareable URL. Arrangements and tableaux without scripted beats remain available by direct link, but are not listed. Narrow with title, theme, chapter count or length before loading anything.",
"inputSchema": {
"type": "object",
"properties": {
"limit": {
"type": "number",
"description": "1–50, default 20."
},
"title": {
"type": "string",
"description": "Match anywhere in the title, case-insensitive."
},
"theme": {
"type": "string",
"description": "A troupe pack the play draws on — \"fairy-tale\", \"ocean\", \"villains\", \"forest\". One at a time."
},
"minChapters": {
"type": "number",
"description": "Default 1. All results still require a script."
},
"maxChapters": {
"type": "number",
"description": "For finding something short to look at."
},
"minSeconds": {
"type": "number",
"description": "Runtime in seconds, holds included."
},
"maxSeconds": {
"type": "number",
"description": "Runtime in seconds. Plays saved before lengths were recorded are skipped when this is set."
}
}
},
"page": "/"
}show_loadAction
Download a published or unlisted play by id or share URL and replace the current canvas. Existing unsaved work on this canvas may be lost, so use this only when replacement was requested. This does not publish either play.
View tool JSON
{
"name": "show_load",
"kind": "act",
"impl": "imperative",
"description": "Download a published or unlisted play by id or share URL and replace the current canvas. Existing unsaved work on this canvas may be lost, so use this only when replacement was requested. This does not publish either play.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Play id or /p/<id> URL."
}
},
"required": [
"id"
]
},
"page": "/"
}theater_batchAction
Run up to 40 ordinary stage-editing tool calls in order on this canvas, such as moving pieces, casting, and writing scripts with rehearse:false. The edits share one undo step and appear 125ms apart. Each step is { tool, args }. Use separate calls when a later step needs an id returned by an earlier step; the batch does not substitute ids. Online save/publish, replacing or clearing a play, deletions, live playback, and image imports must be called separately so their effects can be reviewed individually.
View tool JSON
{
"name": "theater_batch",
"kind": "act",
"impl": "imperative",
"description": "Run up to 40 ordinary stage-editing tool calls in order on this canvas, such as moving pieces, casting, and writing scripts with rehearse:false. The edits share one undo step and appear 125ms apart. Each step is { tool, args }. Use separate calls when a later step needs an id returned by an earlier step; the batch does not substitute ids. Online save/publish, replacing or clearing a play, deletions, live playback, and image imports must be called separately so their effects can be reviewed individually.",
"inputSchema": {
"type": "object",
"properties": {
"steps": {
"type": "array",
"description": "The calls, in order.",
"items": {
"type": "object",
"properties": {
"tool": {
"type": "string",
"description": "A collage tool name, e.g. \"piece_move\"."
},
"args": {
"type": "object",
"description": "That tool's own arguments."
}
},
"required": [
"tool"
]
}
},
"stopOnError": {
"type": "boolean",
"description": "Stop at the first failure rather than carrying on. Default true — a later step usually assumes the earlier ones worked."
}
},
"required": [
"steps"
]
},
"page": "/"
}