This is the real application, not a separate script. The agent’s course and yours are the same
format, produced by the same code — which is why an agent can hand you a
.course file you then
open and keep editing.Setting it up
1
Find the binary
Wherever Compose is installed. On Linux that is inside the AppImage; on Windows, next to the
installed
MauvelyCompose.exe.2
Add it to your client's config
3
Check the tools loaded
Your client should report 25 tools. If it reports none, run the command by hand — anything
it prints to stderr is the reason.
What an agent can do
Every block type is reachable, including quizzes, flashcards, branching scenarios and custom code.
Writing a good prompt
Two things trip agents up, both worth saying explicitly in your instructions.A new course is not empty
A new course is not empty
new_course gives you one lesson that already contains a Welcome block — the same thing you
get opening the app, so a person has something to edit rather than a blank page.If you want exact control over what the course contains, tell the agent to pass empty: true,
or ask it to remove the Welcome block. Otherwise “make a course with one block” produces two.Newlines must be real newlines
Newlines must be real newlines
Text fields take actual line breaks. An agent that sends the two characters
\ and n gets
them rendered literally in the finished course, which looks like \n\n sitting in the middle
of a paragraph.Smaller models get this wrong fairly often. If you see it, the fix is in the prompt rather than
the course.Point it at list_block_kinds first
Point it at list_block_kinds first
Blocks carry every type’s fields at once, so setting the wrong ones is not an error — it just
produces an empty block.
list_block_kinds returns each type’s field list, and an agent that
reads it first makes far fewer silent mistakes.Checking the result
preview_course renders the real exported course and returns a PNG. This matters: it is the
same runtime a learner gets, not a sketch of it, so an agent looking at the picture is looking at
what you would actually ship.
On a server
Rendering needs a graphics backend. On a headless machine, run the whole thing under a virtual framebuffer:preview_course returns an error, and it says
why.
The screenshot is rendered in a separate process. A browser engine that cannot find a graphics
backend does not fail politely, it exits — and doing that inside the tool server would take your
agent’s unsaved work with it.
A worked prompt
Using Mauvely Compose, make a course called “Onboarding” with exactly two lessons. Callnew_coursewithempty: trueso there is no starter content. Readlist_block_kindsbefore adding anything. Lesson one gets a rich text introduction and a multiple-choice question with three answers; lesson two gets a flashcard set. Use real newlines in any text. Then callpreview_courseand tell me whether it looks right before saving to~/onboarding.course.
Limits
Worth knowing
- The server holds one course at a time.
new_courseandopen_coursediscard what is in memory. - There is no undo across tool calls — an agent that removes the wrong block has to add it back.
- Media has to exist on disk for
add_asset; the agent cannot generate an image. - Nothing here talks to Mauvely Cloud. Courses are saved and exported locally.