Manual 12 ai assistance - orlandomenke/Lightbox GitHub Wiki

AI assistance

Inbetweens

Set the number of inbetweens and an easing, then οΌ‹ Inbetween fills the run the playhead is in. Because a frame is a stroke record, the inbetweener matches strokes, not pixels.

Lines swing on arcs. Each line turns about its joint β€” the end of it that moves least between the keys, the hip for a thigh, the knee for a shin β€” while that end travels, so a limb swinging between the keys keeps its length and follows a curve instead of sliding along a straight line and shrinking on the way. Whatever else changes between your keys, a bend straightening, a line growing, is blended in on top, and at the keys themselves the line is exactly what you drew. A line that only moves, without turning, moves as it always did. Lines that meet in both keys β€” a thigh and a shin at the knee β€” still meet in every inbetween. Two limits: a line that turns more than half a circle between two keys goes the short way round (add a breakdown to steer it), and a line that turns a lot and changes shape a lot can bulge on the way.

A run is extreme to extreme, and a breakdown is a stop along the way rather than the end of it. Mark a cel as a breakdown and οΌ‹ Inbetween fills every gap of the run in one go β€” the drawings either side of the breakdown, in one action and one undo β€” and the easing runs once across the whole span instead of restarting at each drawing. That is the difference between one slow-out and slow-in across the movement and two of them with a hitch in the middle. Your breakdown is never moved or redrawn: it keeps its frame and its pose, and the inbetweens are spaced around it. If it does not sit where the easing would have put it, the graph editor's spacing curve is what shows you that β€” the app will not quietly re-space a drawing you placed.

A sequence with no breakdowns behaves exactly as before, because every drawing is an extreme until you say otherwise.

A timing chart on the extreme wins over both controls. Right-click the key's cel on the X-sheet and choose Timing chart… to pencil the classic ladder onto it: each rung is one inbetween, placed at its fraction of the travel across the run. Drag a rung to re-space it, click the rail to add one, right-click a rung to remove it; the preset buttons write the standard shapes (even, ease in, ease out, ease in-out) to start from. With a chart on the extreme, οΌ‹ Inbetween draws exactly one inbetween per rung, exactly where the rung says β€” favour the next pose by bunching rungs toward the right. The chart is part of the document: it saves, undoes, and travels with the drawing through re-times and holds. The graph editor's Spacing (intended) curve reads it too, so the dashed line shows your chart where one exists and the bar's easing everywhere else β€” a chart whose rung count no longer matches the run's inbetweens is ignored rather than misread, and the curve falls back to the easing until the counts agree again.

The same ladder steers ✦ AI Inbetween: the model is asked for one frame per rung, at the rung's position, so accepting the AI's frames or the deterministic ones lands the same timing. One difference to know about, for now: ✦ AI Inbetween still works one gap at a time, so on a run with a breakdown it fills the gap you are in rather than the whole run. Sending the model a third drawing costs materially more per request, and that trade has not been taken yet.

Telling the inbetweener which line is which

The inbetweener pairs each line of one key with a line of the next by where it sits and what shape it has. When you drew the two keys with the same strokes, that is almost always right. When you did not β€” the outline of a leg in one stroke in one key and in three in the next, a line drawn the other way round, a drawing traced from pixels β€” it can pair the wrong lines, and the inbetween scrambles. Match lines is how you tell it.

Put the playhead on an inbetween (or on the key before it) and turn on Match lines: the toggle beside οΌ‹ Inbetween, or Animation β–Έ Match lines between keys. Both keys appear over the canvas in your onion skin colours β€” the key before in its colour, the key after dashed in its own β€” with each stroke shown cut into pieces where another line meets it and at sharp corners, so one piece is one line of the drawing. Your strokes are not changed; the pieces are only for matching.

  • Click a line of the first key, then click the line or lines it becomes in the second key. The pair takes a colour of its own, and the inbetweens of the run redraw at once.
  • Shift-click more lines of the first key to match several to the same lines β€” a line you drew as two pieces in one key and one in the other.
  • Click a matched line to take it out of its match; a match with nothing left on one side is removed.
  • Right-click a matched line to switch its match between one solid object and lines that bend (below). A solid match is drawn on a dark outline.
  • Click empty canvas to stop adding to the open match, and Esc to leave Match lines.

Every click that changes a match is one step to undo, and it redraws the inbetweens with it. Lines you have not matched are paired the usual way, so you only need to match the ones it got wrong.

Solid objects and bending lines. A long line drawn in pieces β€” the front of a leg β€” bends from its shape in one key to its shape in the next. A part made of many small lines β€” a shoe, a cuff, a waistband β€” is treated as one solid object instead: the whole thing moves, turns and scales between the keys, and each inbetween shows the shoe you drew in the nearer key, put in place, rather than lines bending towards each other into a tangle. Lightbox decides which a match is from its lines; right-click a matched line to say otherwise.

Your own inbetweens are left alone. A match redraws only the inbetweens Lightbox drew and nobody has changed since. One you drew yourself, touched up, or got from ✦ AI Inbetween keeps your drawing, and the status bar says how many were left as they are. Matching on a hidden or locked layer is refused, as drawing on one is.

The matches are saved on the first key, for the gap to the next one, the way a timing chart is: they survive saving and reopening, merging the layer down and splitting a group. A match that names a line you have since erased is dropped rather than guessed at. One thing to watch: the pieces of a line are counted from where other lines meet it, so drawing a new line that ends on a matched line, or erasing one that did, can shift which piece a match names β€” check the colours in Match lines after changing a key. A document in which you never match a line saves nothing extra.

Redraw inbetweens (Animation menu) redraws the inbetweens of the run under the playhead from its keys, breakdowns and matches as they are now, without inserting any new frames β€” use it after changing a key. Unlike a match, it replaces every inbetween in the run, including one you drew or touched up by hand; undo brings it back.

Nothing is invented. Only lines you drew are inbetweened. Once you have matched lines in a gap, a line you did not match is paired with a line of the other key only when the two are clearly the same line β€” about the same length and shape, and for a tiny mark, in the same place β€” and, for a detail drawn on a matched part (a crease on a knee), only where that part carried it. A line only one key has β€” a sock the other key hides behind a leg, a speck β€” fades out (or in) where you drew it; it is never turned into a mark that neither key has.

AI inbetweens

✦ AI Inbetween asks the model for the frames between two keys. It needs a provider; until one is chosen the AI controls are disabled and say where to choose it.

Anything the AI produces arrives as ordinary strokes β€” undoable, editable, and subject to every rule your own strokes are, including the layer ones. Each stroke wears the brush of the stroke in your keys it came from β€” tip, texture, pressure response and alpha lock β€” so a pencil line comes back a pencil line and a stroke colouring your ink still only colours the ink. The model chooses the size, and the opacity where your keys differ (a fade); past halfway the brush is key B's. A stroke Lightbox cannot trace to a nearby stroke in your keys β€” a line the motion revealed β€” keeps a plain round brush rather than borrowing one. A hidden or locked layer refuses the AI exactly as it refuses a brush.

There is no way to ask for a drawing from nothing. Everything the AI does starts from something you drew: here, the two keys it works between. You can add a note to steer it (below), but a note always rides on your keys β€” there is no box that makes a drawing out of words alone, and that is a decision rather than a gap: the AI is here to take the tedious parts off an artist, not to make the drawing.

What gets sent. Along with the frames, the first two views on your character sheets that have a visible layer go out as pictures, so the model can see who it is drawing. In a project those are the sheets filed above the document β€” the knight's animations ride with the knight's sheet, wherever it was drawn. They are sent at up to 768 pixels on the long edge β€” your sheet keeps whatever size you drew it at, and only the copy in the request is smaller. Hide every layer in a view and it stops being sent.

What you erased is not sent. The AI is given the drawing, not the drawing's history: erasures and the lines they rubbed out are both left out of the request, whether you erased with the Eraser or cleared a selection. This is worth knowing for two reasons β€” you are not billed for artwork you deliberately removed, and the model never inbetweens a line you took off the page. The record still keeps all of it so the drawing rebuilds exactly and undo still works; it just is not part of what the request describes.

Frames the AI cannot defend are refused. Every frame that comes back is checked against your two keys before it can touch the document: it has to lie between them, carry every stroke both keys draw, keep a closed shape's volume, and sit smoothly against the frames beside it. A frame that fails is not inserted β€” its slot on the timeline simply stays a hold β€” and the status bar says which frame was refused and why, so a three-of-four result is a decision you can read rather than a puzzle. Lightbox never quietly substitutes its own deterministic inbetween for a refused frame; that engine is οΌ‹ Inbetween, one click away, and asking for the AI means getting the AI or nothing.

A refused frame gets a second and third go before it is given up on. When a frame fails a check, Lightbox does not simply try again and hope β€” it asks the model once more, telling it exactly what was wrong and handing back the drawing it just rejected, so the model can correct that frame rather than start over. Up to two of these re-asks happen per frame, and only the frames that failed are re-asked; the ones that already passed are never redrawn. The status bar says which attempt it is on while it works, and Cancel stops it between attempts.

Two things worth knowing about what this costs and what it protects:

  • It can take a while. A frame that never comes good occupies three requests before it is refused, and each one is a full round-trip to the model. When nothing survives, the status says so and says how many attempts it took β€” "Nothing was inserted after 3 attempts" β€” so a long wait for an empty result is at least legible.
  • A re-ask can never lose you a frame you already had. If correcting one frame would upset a frame that already passed β€” usually by making the two read as a jitter next to each other β€” Lightbox keeps what it had and leaves the other frame refused. It will not trade a good frame for a different one.

Frames that needed more than one attempt remember it, so the record of what the AI drew includes what it cost. Nothing changes about the drawing itself: a repaired frame is checked against exactly the same rules as one the model got right first time, and it is inserted only if it passes them.

When the status says a frame "matched what οΌ‹ Inbetween would have drawn", read it. It means the model returned the same answer the free deterministic inbetweener would have given for nothing. That is not a failure and the frame is perfectly usable β€” but it is worth knowing, because it is the safest thing a model can do when it is being pushed to correct itself, and if you are seeing it often you are paying a model to do what οΌ‹ Inbetween does instantly.

The check is not "did the model invent something" β€” invention is the point. Revealed lines behind something that moved away, follow-through trailing a motion β€” a tail or a cape drawn as a chain of strokes counts, however long, because each link may hang off the one before β€” and departures near the drawing all pass. What gets refused is ink nothing explains, a stroke that went missing, or a frame that jitters against its neighbours β€” the noise that reads as boiling when played at speed.

AI frames remember where they came from. A frame the AI drew carries a small provenance note in the saved file β€” which provider, and the model name when there is one. Frames you drew carry nothing, and a document that never used the AI is byte-for-byte what it would have been before the feature existed. Provenance is a record, never behaviour: it changes nothing about how the frame renders, and deleting it changes no pixel. When you gave a direction, the note is kept with the frames it produced, so you can see later what was asked.

Telling the model what you want, and revising what it drew

✦ AI Inbetween is one click and asks nothing. To add a note first, either Shift+click it, or open the arrow beside it and choose AI Inbetween with a direction…. Type what the keys cannot say on their own β€” "running, this is the far arm", "let the head lead", "ease in hard to B" β€” and press Enter. Leaving the note empty is the same as the plain button.

A note goes with one layer's request. The AI inbetweens the active layer and sees only that layer's strokes, so on a character split across layers it cannot tell on its own that a shape is the far arm of somebody running. Saying so is the most useful thing a note can do β€” and because each layer is its own request, say it again on the next layer.

The same arrow holds Revise AI frames…. Put the playhead between two drawings you made, choose it, and say what should change: the model is handed the AI frames between those drawings together with your note, and redraws them in place. Select some of those frames on the timeline first to redraw only them β€” the frames either side of them go along unchanged, so the redraw sits smoothly among them. The selection has to be on the active layer; with nothing selected there, every AI frame between the two drawings is redrawn, and the status line says how many before the model starts. A revise is one undo step, and it needs a note: "redraw it" with nothing to go on is a reroll, not a revision.

Each frame is revised at its place between the two drawings β€” the second of three frames sits halfway β€” or by the key's timing chart when it has one. A frame the AI drew still counts as the AI's after you touch it up by hand, so a revise would redraw it too; select the ones you want redrawn. If you change the timeline while the model is working, nothing is written and the status says so.

A note steers what happens between the keys, never what is accepted. Every frame that comes back is checked against your keys exactly as before, and a revised frame that fails keeps the drawing it had β€” the status says which. Ask for more energy and you should get a rounder arc and a stronger ease; ask for an overshoot past a key and the frame is refused. That is a breakdown for you to draw, and the AI will inbetween either side of it. Notes are kept to 500 characters β€” a sentence or two is what the model can use.

Both commands are in Edit β–Έ Configure β–Έ Shortcuts under Timeline, with no key set, for anyone who wants one.

Reading a folder

Right-click a folder in the Project panel and choose Read this folder…. The model looks at the sheets you have drawn and writes down what it is β€” a biped, say, with a head, a torso and two arms, and which arm is normally in front. That reading then rides along with every inbetween of a drawing in that folder, so the model knows the arm passes in front of the body instead of guessing.

Any folder can be read, and reading it is what makes it a character as far as Lightbox is concerned β€” you do not declare one first. Put the work in a folder, read it, and give it a glyph if you want it to look like one.

Once per folder, not once per frame. The answer is kept on the folder in the project, so a twenty-four frame cycle pays for it once and the next animation in the same folder pays nothing at all. A drawing in a sub-folder inherits the reading above it, and a sub-folder with its own reading overrides it β€” nearest wins, the same rule palettes follow.

It is yours to correct. Once you have edited a reading, Lightbox will not overwrite it β€” asking again says so rather than throwing your corrections away. A reading is a starting point, and where you have said what something is, that is what it is.

Two things it deliberately does not do. It never describes a pose β€” where an arm is in frame 12 changes every frame and is not worth keeping. And it never reaches a pixel: delete every reading in a project and your drawings render exactly the same, because the reading tells the model what it is looking at and nothing else.

A folder with no sheets has nothing to read; draw one first, or make a layer on it visible.

Turning AI off

Edit β–Έ Configure β–Έ AI β–Έ Use AI assistance. On by default. Off removes the AI bar rather than greying it out β€” a row that can never do anything is worse than no row.

Everything below the switch keeps working while it is off, so a provider can be set up and tested before AI is turned on. That is the useful order, and refusing to test until the switch is on would invert it.

Choosing a provider

Edit β–Έ Configure β–Έ AI. Pick a service from the dropdown and the fields below it change to what that service needs β€” a key and a model for a hosted one, a URL for a local one, a command line for an agent of your own.

Provider What it needs Notes
Claude (Anthropic) API key, model What Lightbox is tuned against, and the strongest inbetweener here.
Claude Code (your account) Nothing, if Claude Code is installed Uses the Claude Code you are signed in to, so no API key is needed. Your drawing still goes to Anthropic β€” see below.
GPT (OpenAI) API key, model Strict JSON schema, so replies parse by construction.
OpenRouter API key, model One key for many vendors' models.
Ollama Model Local, no key, no network. Weaker inbetweens β€” good for working offline.
Custom (OpenAI-compatible) Endpoint, model LM Studio, vLLM, llama.cpp's server, your own gateway. The key is optional.
Custom agent (MCP) Command, tool An MCP server you supply that owns the model.

How hard the model thinks

Both Claude providers have an Effort field: low, medium, high, xhigh or max. It is how much the model reasons before it draws, and it is most of what an inbetween costs β€” measured on real drawings, thinking was 60–90% of a request's output and most of its time.

It starts at low, on purpose. On four layers of one running-character drawing, low effort was 1.4 to 7 times faster and up to 5 times cheaper than the model's own default, every frame still passed the checks, and side by side we could not tell the drawings apart. The one frame that came out wrong was equally wrong at every level, so more effort would not have fixed it.

That is a small test, of easy motion. If overlaps, forms that turn, or layers with many strokes come out wrong, raise it and compare. A word that is not a level is read as low rather than failing a request halfway. Type model to send no effort at all and use the model's own β€” the way out if a model you named, or an older Claude Code, does not accept the setting; Lightbox says so when that happens. A capability reading notes the effort it was taken at and goes stale when you change it.

Testing it

Test connection asks for real work rather than pinging, because most of the ways this fails are not reachability. Both depths ask for an inbetween β€” that is the only thing Lightbox asks a model for, so testing anything else could pass on a provider that cannot do the job. There are two depths:

What it does Cost
Quick test One inbetween of a two-point line on a small canvas Seconds; a few hundred tokens
Test with a drawing The quick test, then a real inbetween between two keyframes Minutes on a local model

Both check that the output is usable, not just that it parsed: strokes with fewer than two points, or every point in the same place, are reported as a problem rather than counted as a pass. The thorough test adds the one check that separates a working connection from a working inbetweener β€” the frame it returns has to land between the two keys. A small model that answers in perfect JSON and copies a keyframe fails there, and nowhere else.

The verdict comes in three colours, because "unreachable" and "reachable but drawing nonsense" need different fixes:

  • Green β€” connected, and what came back is usable.
  • Amber β€” connected, but the output is not usable. The connection is fine; the model may be the wrong one.
  • Red β€” nothing answered, or the key, endpoint or tool name is wrong.

A test shows a progress bar and an elapsed clock while it runs, and says which stage it is on. Past two minutes it says so explicitly rather than sitting silent, and Cancel stops it β€” a thorough test against a local model genuinely takes that long, and silence for that long is indistinguishable from a hang.

A field left empty is not necessarily unset. Its placeholder says what it resolves to: a default, or an environment variable that is already supplying it (ANTHROPIC_API_KEY, OPENAI_API_KEY, OPENROUTER_API_KEY, LIGHTBOX_OLLAMA_URL). What you type wins over the environment, which wins over the default β€” and only what you type is saved, so a rotated key is not shadowed by a stale copy.

Changing provider takes effect immediately; there is no restart and no Save button.

Grading a model

A connection test says the model answers. Grade this model says what it can do. It asks a committed set of keyframe pairs β€” a swing, an arc, a rotation, an occlusion, and a ladder of drawings with more and more strokes in them β€” and scores every answer with the same checks that judge the model's real work.

The result is numbers rather than a pass mark, deliberately. There is no overall verdict because there is no single answer: a model weak on arcs is still worth using where straight interpolation is weak, and one that gives up past twelve strokes is fine if you send it ten. What you get is a reading:

Schema adherence: 100 %
Label retention: 60 %
Degrades past 8 strokes β€” send it fewer than that.
Swing: clean (1/1)
Arc: clean (1/1) β€” departed 12.4 px from the free engine's answer
Rotation: clean (1/1)
Occlusion: clean (1/1)
StrokeLadder: 2/6 β€” ladder-16: out of context
Organic: not measured β€” ships with no pairs

The line worth reading is the stroke one. It is the number nobody usually measures, and it is the one that decides whether a model is usable on a real drawing: a frame with forty strokes is ordinary, and a model that copes with eight will quietly produce nonsense on it.

Two run sizes, and the page tells you what each will send before you spend it β€” a full run is roughly five times the short one, almost all of it the long stroke ladder. The short run grades every category and places the stroke limit roughly; the full run places it precisely. Start short.

A run shows its progress and an elapsed clock, and Cancel stops it. A cancelled run records nothing on purpose: half a ladder would report a limit that is really just where you clicked.

The reading is kept, so it is still there next time you open the window. It is stored against the model it was taken on β€” point the connection at a different model and the page says so in amber rather than letting an old reading pass as a new one. The old reading is not thrown away; it is still true about the old model, and re-running costs money.

One row always says "not measured". Organic is for complex organic subjects β€” a quadruped's gait, a figure turning β€” and it ships empty, because those need answers drawn by hand rather than computed. It appears anyway so that a question nobody asked can never read as one the model passed.

Claude Code, without an API key

If Claude Code is installed and signed in on this machine, the Claude Code (your account) provider asks it instead of calling the API with a key. Nothing needs filling in when it was installed with the native installer: the command defaults to claude, and the model to the same one the Claude API provider uses. Give the full path to claude.exe if it is not on your PATH β€” an npm install's claude.cmd is refused, because a batch file cannot be handed a prompt safely.

Lightbox uses it as a model, not as an agent. Each request starts Claude Code once and hands it the same instructions and the same reply format the API provider gets. Its tools, MCP servers, skills, hooks and instruction files are switched off, and Lightbox checks the run's own start-up report and refuses the answer if anything beyond the reply form was offered. The reply is checked and repaired by the same rules as an API reply β€” the same instructions, though not a promise of the identical drawing, since Claude Code chooses its own thinking and output settings.

Things to know:

  • Your drawing goes to Anthropic, under the account Claude Code is signed in to, and under that account's terms. On a Claude subscription those are the consumer terms, where whether your conversations may be used to improve models is a setting in your Claude account's privacy settings β€” unlike the API provider, which is under Anthropic's commercial terms. Check that setting before sending work that is not yours to share.
  • It always uses the signed-in account. An ANTHROPIC_API_KEY in your environment is not passed on β€” use the Claude (Anthropic) provider for a key. Claude Code's own telemetry and update checks are switched off for these runs.
  • Claude Code adds a little context of its own to each request, such as today's date and the account's email address. Nothing from your other projects or files.
  • It spends your plan's usage, and a long run of inbetweens can reach your plan's limits. A rate limit is reported and can be retried.
  • If Claude Code is not signed in, Test connection says so. Run claude in a terminal once, sign in, and try again.
  • It is usually slower than the API, because a program is started for each request, and a request that runs past ten minutes is stopped.

This is separate from letting Claude drive the document over Lightbox's own MCP server: that still works as before, from Claude's window. This provider is for staying in Lightbox and pressing the AI buttons there.

An agent of your own, over MCP

The Custom agent (MCP) provider launches a server you name and calls one tool on it:

tools/call { name: <tool>, arguments: {
  system: string,   // the role and the rules
  prompt: string,   // the task, with the keyframes as JSON
  schema: object    // JSON Schema the reply must match
}}
β†’ { content: [{ type: "text", text: "<json matching schema>" }] }

Anything behind that contract works β€” your own agent, your own retrieval, a model with no public API. If the tool is named something else, Test connection lists the tools the server actually offers.

This is the opposite direction from Lightbox's own MCP server, and the two are independent. Here Lightbox calls out to a model. There, an agent you already run calls in and works the document directly β€” no provider needed on this page at all.


Working with an agent (MCP)

Lightbox runs an MCP server, so an agent can work the document directly: read the scene, add strokes and frames, request inbetweens. It can also see β€” a timeline frame or a character-sheet view comes back to it as a rendered image, which is how it checks a drawing before inbetweening it and its own results afterwards. Everything it does goes through the same stroke record as everything else, so its work is undoable and indistinguishable in kind from yours.

Reading a drawing without reading all of it

An agent has a working memory, and everything it looks at stays in it for the rest of the session. A busy drawing is a lot to look at: a 120-stroke frame is around 37,000 tokens of geometry, and an agent that fetches two of those has spent a good part of what it had before it draws anything. So there are two ways to read a drawing, and the cheap one comes first:

Tool What it does
list_frame_strokes One line per stroke β€” its number, its label, its colour, how many points it has and the box it occupies. No geometry, and about a twelfth the size.
get_frame_strokes The actual points. Give it labels or indices and it returns only those strokes; give it neither and it returns the whole drawing.

The pairing is the point: an agent lists the drawing, sees that a stroke labelled near-arm sits where it is about to work, and asks for that one stroke instead of the other hundred and nineteen.

Labels come from strokes an agent or the AI drew, not from ones you drew. There is no way to name a stroke by hand today, so a drawing you made yourself lists as numbers, colours, point counts and boxes β€” still enough to find a stroke by where it sits, and less pointed than a name. It also means the listing is a starting point rather than an answer: a box says where a line is and never what it does, and a straight line and a curve between the same two points look almost identical in a listing. An agent that treats a stroke as unchanged without looking at it is guessing.

If it asks for a label that is not there, it gets an error naming the labels that are, rather than an empty answer. An agent cannot see your drawing, and an empty answer would read as "that line is gone" and send it redrawing something you already have. For the same reason, a request that names strokes has to say which layer it means rather than relying on whichever layer is active β€” otherwise clicking a different layer while an agent works would quietly point it at the wrong drawing.

Pictures are capped. render_frame comes back at up to 768 pixels on the long edge β€” a fraction of the cost of a full canvas, and enough to judge pose, timing and staging by. It is not enough for fine marks: eyebrows, eyes and small hands thin out or disappear at that size, and the bigger your canvas the more of them go. On a 4K scene a face can arrive with no eyes at all.

So a reduced picture arrives with a line saying so β€” what fraction of the canvas it is, and that fine marks are gone at that size β€” and an agent can re-render at full size before judging them. A picture that was not reduced comes with no such line. If you are ever puzzled that an agent seems blind to a small detail it should have caught, this is the first thing to check: ask it what scale it looked at the frame at.

Character sheet views are never capped: render_reference_view gives the view exactly as you drew it, because there the reference art is the thing being asked for rather than a look at it.

Timing, not just drawing

An agent can author the exposure sheet as well as read it. Four tools cover it, and all of them are one undo step on your side:

Tool What it does
set_key Makes a frame a key β€” a new empty drawing where there was a hold, or a changed role (key, breakdown, inbetween) on a drawing already there. A frame past the end of the timeline extends it.
extend_exposure Holds one drawing a frame longer, on that layer only β€” the rest of the layer shifts right and other layers stay put, the way an X-sheet works.
reduce_exposure Shortens a hold by one frame.
set_exposure_step Re-times a range so every drawing in it is held for the same number of frames β€” step 2 is animating on 2s.

None of them can lose a drawing. reduce_exposure removes a hold and never a drawing, so on a frame that is not held it reports an error rather than quietly doing nothing; set_exposure_step absorbs the holds already in the range instead of multiplying them, so asking for 2s twice leaves you on 2s rather than 4s. Thinning a range by discarding drawings is a destructive edit and is deliberately not offered over MCP.

A key the agent created says so; a frame it merely re-labelled does not. If an agent makes a new drawing, that frame carries its provenance, the same as an AI inbetween. If it only changes the role of a drawing you made, the frame stays yours and unmarked β€” the timing changed, not the art.

A locked or hidden layer refuses all four, and says which.

An agent can organise layers into folders too, with the same folders the docker shows (get_scene lists them, topmost first, and says which folder each layer is in):

Tool What it does
create_folder Makes an empty folder at the top of the stack, or at the top inside another folder.
move_to_folder Puts a layer or a whole folder at the top inside a folder, or takes it out of every folder.
group_layers Puts layers and folders into a new folder where the topmost of them was β€” Ctrl+G, for an agent.

None of them deletes anything, and none changes your picture unless asked. Filing a layer into a folder puts it at the folder's top, and grouping layers that are apart gathers them β€” either can change which layer is in front, on every frame. An agent's request that would do that is refused, naming the layers it would pass, unless the agent says it means it; and every reply says whether the stacking changed. Ungrouping and deleting a folder are left to you.

Each is one undo step, named Agent: … in the history so you can find it, and an agent is stricter than your own hand about locks: a locked layer or folder β€” or anything inside a locked folder β€” is not moved or grouped, and nothing is put into a locked folder.

If an agent reports a bug you know was fixed, check which build it is talking to. The server is a separate published program that your MCP client launches, so it goes on running an old copy until you rebuild it and fully quit and reopen the client β€” reloading is not enough. Ask the agent for get_scene: it returns appBuild for the running Lightbox and mcpBuild for the server, and they should name the same commit. Different means only one half was republished. mcpBuild missing altogether means the server is older than this feature, which settles it.


⚠️ **GitHub.com Fallback** ⚠️