Skip to content

ulams builder

Generated from front/cli (ulams schema)

Apply the generated course to the academy (an unpublished draft).

Creates or updates the course through the course services. Waits until the applied version is the current one. Pass –overwrite to replace edits an admin made in the course since the last apply.

Kind: write. Stability: stable. MCP tool: builder_apply. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions/{session}/apply.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--overwrite boolean Overwrite admin edits.
Terminal window
# Apply
ulams builder apply <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"overwrite": {
"description": "Overwrite admin edits.",
"type": "boolean"
}
},
"required": [
"session"
]
}

Show the Course Brief (audience, level, length, tone, assessments, language).

Kind: read (idempotent). Stability: stable. MCP tool: builder_brief_get. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}/brief.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
Terminal window
# The brief
ulams builder brief get <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
}
},
"required": [
"session"
]
}

Change fields of the Course Brief.

Editing the brief after the outline marks the outline and lessons stale: nothing is regenerated silently. Pass fields as flags or a whole brief object (JSON or @file).

Kind: write (idempotent). Stability: stable. MCP tool: builder_brief_set. Scopes: builder:write.

Endpoints: PUT /api/admin/course-builder/sessions/{session}/brief.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--brief object Brief fields as an object.
--audience string
--level string
--tone string
--language string Two-letter language code, e.g. en, pl.
--total-minutes integer Target course length in minutes.
--lesson-minutes integer Target lesson length in minutes.
--notes string
--per-lesson-quiz boolean A quiz after every lesson.
--final-test boolean A final test.
Terminal window
# Shorter lessons
ulams builder brief set <session> --lesson-minutes 5 --level beginner --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"brief": {
"description": "Brief fields as an object.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"audience": {
"type": "string"
},
"level": {
"type": "string",
"enum": [
"beginner",
"intermediate",
"advanced"
]
},
"tone": {
"type": "string",
"enum": [
"friendly",
"professional",
"playful",
"academic"
]
},
"language": {
"description": "Two-letter language code, e.g. en, pl.",
"type": "string"
},
"totalMinutes": {
"description": "Target course length in minutes.",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"lessonMinutes": {
"description": "Target lesson length in minutes.",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"notes": {
"type": "string"
},
"perLessonQuiz": {
"description": "A quiz after every lesson.",
"type": "boolean"
},
"finalTest": {
"description": "A final test.",
"type": "boolean"
}
},
"required": [
"session"
]
}

Ask the builder to change one element; it proposes a patch you approve or reject.

Scope the instruction to an element id from builder elements list (a lesson, block, objective or question). The builder proposes a change with citations; nothing changes until builder patches approve <version>. Waits for the proposal and returns the version id and the element-aware diff.

Kind: write. Stability: stable. MCP tool: builder_chat. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions/{session}/runs, GET /api/admin/course-builder/sessions/{session}/versions, GET /api/admin/course-builder/versions/{version}/diff.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--message (positional) string yes What to change, in plain words.
--element string yes Element id (from builder elements list).
Terminal window
# Shorten a block
ulams builder chat <session> "Make this shorter" --element blk_x1 --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"message": {
"type": "string",
"description": "What to change, in plain words."
},
"element": {
"type": "string",
"description": "Element id (from `builder elements list`)."
}
},
"required": [
"session",
"message",
"element"
]
}

Show which elements cite each section of the sources, and which sections nothing cites.

The sources panel as data: per source its sections in reading order with the elements of the current version that cite them (data.sources[].sections[].citedBy), the number of uncovered sections (data.sources[].uncovered) and, per element, the fragments it cites (data.elements).

Kind: read (idempotent). Stability: stable. MCP tool: builder_citations. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}/citations.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
Terminal window
# What is not covered yet
ulams builder citations <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
}
},
"required": [
"session"
]
}

List the elements of the course (ids to scope builder chat to).

Kind: read (idempotent). Stability: stable. MCP tool: builder_elements_list. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}/versions, GET /api/admin/course-builder/versions/{version}.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--version string Version id (default: the current version).
--type string Only this type: lesson, module, objective, question, paragraph, callout, steps, code, table, example, quiz.
Terminal window
# Lessons
ulams builder elements list <session> --type lesson --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"version": {
"description": "Version id (default: the current version).",
"type": "string"
},
"type": {
"description": "Only this type: lesson, module, objective, question, paragraph, callout, steps, code, table, example, quiz.",
"type": "string"
}
},
"required": [
"session"
]
}

Stream the session’s AG-UI events as NDJSON (one {“type”:“event”,“id”,“data”} line each).

Without –follow it prints the stored events up to now and exits. With –follow it keeps streaming (resuming across the server’s 25 s connection cap) until Ctrl-C or –timeout. –until-run stops after that run’s RUN_FINISHED (exit 0) or RUN_ERROR (exit 9, the event is in error.details). The last line is the normal envelope with the event count and the last event id (resume with –after).

Kind: stream (idempotent). Stability: stable. MCP tool: builder_events. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}/events.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--follow boolean Keep streaming new events.
--after string Resume after this event id.
--types string Only these AG-UI event types (comma-separated), e.g. RUN_STARTED,RUN_FINISHED,RUN_ERROR,TEXT_MESSAGE_CONTENT.
--until-run string Stop after this run finishes.
Terminal window
# Follow a run
ulams builder events <session> --follow --until-run <run> --output ndjson
# What happened so far
ulams builder events <session> --types RUN_FINISHED,RUN_ERROR
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"follow": {
"description": "Keep streaming new events.",
"type": "boolean"
},
"after": {
"description": "Resume after this event id.",
"type": "string"
},
"types": {
"description": "Only these AG-UI event types (comma-separated), e.g. RUN_STARTED,RUN_FINISHED,RUN_ERROR,TEXT_MESSAGE_CONTENT.",
"type": "string"
},
"untilRun": {
"description": "Stop after this run finishes.",
"type": "string"
}
},
"required": [
"session"
]
}

The stored AG-UI events of a session (bounded read, for agents).

Returns up to –limit events after –after (an event id). Use builder events --follow in a terminal to stream them as they happen.

Kind: read (idempotent). Stability: stable. MCP tool: builder_events_list. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}/events.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--after string Only events after this event id.
--types string Comma-separated AG-UI event types, e.g. RUN_FINISHED,RUN_ERROR.
--limit integer Maximum number of events (default 200; the newest are kept).
Terminal window
# Failures
ulams builder events list <session> --types RUN_ERROR --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"after": {
"description": "Only events after this event id.",
"type": "string"
},
"types": {
"description": "Comma-separated AG-UI event types, e.g. RUN_FINISHED,RUN_ERROR.",
"type": "string"
},
"limit": {
"description": "Maximum number of events (default 200; the newest are kept).",
"type": "integer",
"minimum": 1,
"maximum": 2000
}
},
"required": [
"session"
]
}

Show the source passage a citation points to (frg_…).

Kind: read (idempotent). Stability: stable. MCP tool: builder_fragments_get. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/fragments/{fragment}.

Flag Type Required Description
--fragment (positional) string yes Fragment id, e.g. frg_abcdefabcdef.
Terminal window
# A citation
ulams builder fragments get frg_abcdefabcdef --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"fragment": {
"type": "string",
"description": "Fragment id, e.g. frg_abcdefabcdef."
}
},
"required": [
"fragment"
]
}

Answer interview questions (one –key/–value, or –answers as JSON or a file).

Values: audience is free text; level is beginner, intermediate or advanced; tone is friendly, professional, playful or academic; language is a two-letter code; duration is “60|10” (total|lesson minutes) or {totalMinutes, lessonMinutes}; assessments is [“quiz”, “final”]. With –defaults the builder decides the questions you leave open. When the last question is answered the outline starts; this waits for it (–no-wait returns the run handle).

Kind: write. Stability: stable. MCP tool: builder_interview_answer. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions/{session}/runs.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--key string Question key (see builder interview show).
--value unknown The answer to –key.
--answers object Several answers by question key, as JSON or @file.json / @file.yaml.
--defaults boolean Let the builder decide every open question.
Terminal window
# One answer
ulams builder interview answer <session> --key level --value beginner --json
# From a file, defaults for the rest
ulams builder interview answer <session> --answers @answers.json --defaults --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"key": {
"description": "Question key (see `builder interview show`).",
"type": "string"
},
"value": {
"description": "The answer to --key."
},
"answers": {
"description": "Several answers by question key, as JSON or @file.json / @file.yaml.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"defaults": {
"description": "Let the builder decide every open question.",
"type": "boolean"
}
},
"required": [
"session"
]
}

Let the builder decide the open interview questions (or one with –key).

Uses the default it proposed for each question (justified by the source). The outline starts when nothing is left open.

Kind: write. Stability: stable. MCP tool: builder_interview_decide. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions/{session}/runs.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--key string Only this question.
Terminal window
# Decide everything
ulams builder interview decide <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"key": {
"description": "Only this question.",
"type": "string"
}
},
"required": [
"session"
]
}

Show the interview questions and which are still open.

Read from the session’s event stream. Each question has a key, options and a default; answer with builder interview answer.

Kind: read (idempotent). Stability: stable. MCP tool: builder_interview_show. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}/events.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
Terminal window
# Open questions
ulams builder interview show <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
}
},
"required": [
"session"
]
}

Create a new site (tenant) for the course in this session.

Starts creating a new site and returns its status (the request is queued). Only available to users allowed to create sites (a 403 otherwise). The slug defaults to the one in the Course Brief.

Kind: write. Stability: stable. MCP tool: builder_new_site. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions/{session}/new-site.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--slug string Site slug (default: the brief’s site slug).
--name string Site name.
Terminal window
# A new site
ulams builder new-site <session> --slug coffee-atlas --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"slug": {
"description": "Site slug (default: the brief's site slug).",
"type": "string"
},
"name": {
"description": "Site name.",
"type": "string",
"maxLength": 120
}
},
"required": [
"session"
]
}

Edit the course structure: rename, move, add or remove modules and lessons.

Saves the change as an approved author version (no approval step) and re-applies the course when it is applied. --action rename --id <id> --title <t>; move --id <id> --index <n> [--module <id>] (0-based position in the target list); add --kind lesson|module --title <t> --objective <o> --citation <frg_id> [--module <id>]; remove --id <id>; set-format --id <lesson> --content-type richtext|liascript|h5p|interactive. Ids come from builder versions get <version> --document.

Kind: write. Stability: stable. MCP tool: builder_outline_edit. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions/{session}/outline.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--action string yes
--id string Module or lesson id.
--title string
--index integer Target position (0-based, after the element is taken out).
--module string Target module id (move a lesson to it, or add a lesson to it).
--kind string
--objective string Learning objective of an added lesson.
--citation string Fragment id an added lesson rests on.
--content-type string
Terminal window
# Move a lesson up
ulams builder outline-edit <session> --action move --id <lesson> --index 0 --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"action": {
"type": "string",
"enum": [
"rename",
"move",
"add",
"remove",
"set-format"
]
},
"id": {
"description": "Module or lesson id.",
"type": "string"
},
"title": {
"type": "string"
},
"index": {
"description": "Target position (0-based, after the element is taken out).",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"module": {
"description": "Target module id (move a lesson to it, or add a lesson to it).",
"type": "string"
},
"kind": {
"type": "string",
"enum": [
"lesson",
"module"
]
},
"objective": {
"description": "Learning objective of an added lesson.",
"type": "string"
},
"citation": {
"description": "Fragment id an added lesson rests on.",
"type": "string"
},
"content-type": {
"type": "string",
"enum": [
"richtext",
"liascript",
"h5p",
"interactive"
]
}
},
"required": [
"session",
"action"
]
}

Approve the outline and generate the lessons.

Optionally edit learning objectives first with –edit = (repeatable). Generation takes a few minutes and costs model tokens (see builder usage); this waits for it (–no-wait returns the run handle). The result is a generated course in apply_review: nothing is in the academy yet.

Kind: write. Stability: stable. MCP tool: builder_outline_approve. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/versions/{version}/approve, GET /api/admin/course-builder/sessions/{session}/versions.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--version string Outline version id (default: the one waiting for approval).
--edit array Edit an objective: =; repeat.
Terminal window
# Approve
ulams builder outline approve <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"version": {
"description": "Outline version id (default: the one waiting for approval).",
"type": "string"
},
"edit": {
"description": "Edit an objective: <objectiveId>=<text>; repeat.",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"session"
]
}

Reject the outline with a comment; the builder proposes a new one.

Kind: write. Stability: stable. MCP tool: builder_outline_request_changes. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/versions/{version}/reject, GET /api/admin/course-builder/sessions/{session}/versions.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--comment string yes What to change, in plain words.
--version string Outline version id (default: the one waiting for approval).
Terminal window
# Ask for changes
ulams builder outline request-changes <session> --comment "Fewer modules, more practice" --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"comment": {
"type": "string",
"description": "What to change, in plain words."
},
"version": {
"description": "Outline version id (default: the one waiting for approval).",
"type": "string"
}
},
"required": [
"session",
"comment"
]
}

Show the outline waiting for approval (objectives, modules, lessons).

Kind: read (idempotent). Stability: stable. MCP tool: builder_outline_show. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}/versions, GET /api/admin/course-builder/versions/{version}.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--version string A specific version id (default: the one waiting for a decision, else the current one).
Terminal window
# The outline
ulams builder outline show <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"version": {
"description": "A specific version id (default: the one waiting for a decision, else the current one).",
"type": "string"
}
},
"required": [
"session"
]
}

Approve a proposed patch; an applied course is updated.

Kind: write. Stability: stable. MCP tool: builder_patches_approve. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/versions/{version}/approve.

Flag Type Required Description
--version (positional) string yes Patch version id (from builder chat).
Terminal window
# Approve
ulams builder patches approve <version> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"version": {
"type": "string",
"description": "Patch version id (from `builder chat`)."
}
},
"required": [
"version"
]
}

Reject a proposed patch.

Kind: write. Stability: stable. MCP tool: builder_patches_reject. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/versions/{version}/reject.

Flag Type Required Description
--version (positional) string yes Patch version id.
--comment string
Terminal window
# Reject
ulams builder patches reject <version> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"version": {
"type": "string",
"description": "Patch version id."
},
"comment": {
"type": "string"
}
},
"required": [
"version"
]
}

Publish the applied course so learners can enrol.

Kind: write (idempotent). Stability: stable. MCP tool: builder_publish. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions/{session}/publish.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
Terminal window
# Publish
ulams builder publish <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
}
},
"required": [
"session"
]
}

List what blocks publishing the applied course, plus warnings.

Runs the same checks builder publish runs and returns data.blocking, data.warnings and data.facts without publishing anything.

Kind: read (idempotent). Stability: stable. MCP tool: builder_publish_check. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}/publish-check.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
Terminal window
# Before publishing
ulams builder publish-check <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
}
},
"required": [
"session"
]
}

Redo the change you undid.

An applied course is re-applied to match; this waits for it.

Kind: write. Stability: stable. MCP tool: builder_redo. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions/{session}/redo.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
Terminal window
# redo
ulams builder redo <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
}
},
"required": [
"session"
]
}

Retry the interview or outline step that failed.

Kind: write. Stability: stable. MCP tool: builder_retry. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions/{session}/runs.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
Terminal window
# Retry
ulams builder retry <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
}
},
"required": [
"session"
]
}

Cancel a run that is still queued or running.

Kind: write (idempotent). Stability: stable. MCP tool: builder_runs_cancel. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/runs/{run}/cancel.

Flag Type Required Description
--run (positional) string yes Run id.
Terminal window
# Cancel
ulams builder runs cancel <run> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"run": {
"type": "string",
"description": "Run id."
}
},
"required": [
"run"
]
}

Show the status of one run (queued, running, succeeded, failed, cancelled) with its steps.

Kind: read (idempotent). Stability: stable. MCP tool: builder_runs_get. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/runs/{run}.

Flag Type Required Description
--run (positional) string yes Run id.
Terminal window
# A run
ulams builder runs get <run> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"run": {
"type": "string",
"description": "Run id."
}
},
"required": [
"run"
]
}

Retry one failed generation step of a run.

Kind: write. Stability: stable. MCP tool: builder_runs_retry_step. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/runs/{run}/steps/{step}/retry.

Flag Type Required Description
--run (positional) string yes Run id.
--step (positional) string yes Step id (from builder runs get).
Terminal window
# Retry a step
ulams builder runs retry-step <run> <step> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"run": {
"type": "string",
"description": "Run id."
},
"step": {
"type": "string",
"description": "Step id (from `builder runs get`)."
}
},
"required": [
"run",
"step"
]
}

Create an empty builder session.

Authors normally use builder start, which also uploads the source. At most 10 sessions per author per day (HTTP 429 after).

Kind: write. Stability: stable. MCP tool: builder_sessions_create. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions.

Flag Type Required Description
--title string Session title.
Terminal window
# New session
ulams builder sessions create --title "Onboarding" --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"title": {
"description": "Session title.",
"type": "string"
}
}
}

Delete a builder session (an applied course is kept).

Kind: destructive (idempotent). Stability: stable. MCP tool: builder_sessions_delete. Scopes: builder:write.

Endpoints: DELETE /api/admin/course-builder/sessions/{session}.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
Terminal window
# Delete
ulams builder sessions delete 01j9z3k8m2x4q7r5t6v8w0y1ab --yes --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
}
},
"required": [
"session"
]
}

Show a builder session: status, brief, sources, cost, links.

The status tells the next step: interviewing (answer), outline_review (approve), apply_review (apply), applied (publish). activeRunId is set while the builder works.

Kind: read (idempotent). Stability: stable. MCP tool: builder_sessions_get. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
Terminal window
# A session
ulams builder sessions get 01j9z3k8m2x4q7r5t6v8w0y1ab --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
}
},
"required": [
"session"
]
}

List my builder sessions.

Kind: read (idempotent). Stability: stable. MCP tool: builder_sessions_list. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions.

Terminal window
# My sessions
ulams builder sessions list --fields id,title,status --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {}
}

Wait until a session reaches a status with no run active.

Statuses: interviewing, outline_review, apply_review, applied (default: any of them). Fails fast when a run failed, with the run’s error. Exit 10 on timeout (details.operation resumes it).

Kind: read (idempotent). Stability: stable. MCP tool: builder_sessions_wait. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}, GET /api/admin/course-builder/runs/{run}.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--for string Comma-separated target statuses (default: interviewing,outline_review,apply_review,applied).
Terminal window
# Wait for the outline
ulams builder sessions wait 01j9z3k8m2x4q7r5t6v8w0y1ab --for outline_review --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"for": {
"description": "Comma-separated target statuses (default: interviewing,outline_review,apply_review,applied).",
"type": "string"
}
},
"required": [
"session"
]
}

Add a source (Markdown, PDF or DOCX) to a session, from a file or a URL.

Uploading starts ingestion; the interview starts by itself after the first source. Waits for ingestion (use –no-wait to return the run handle). The sources of one session may add up to about 400,000 tokens.

Kind: write. Stability: stable. MCP tool: builder_sources_add. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions/{session}/sources.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--file array Local file; repeat for several.
--url array URL of the document itself; repeat for several.
Terminal window
# Upload a file
ulams builder sources add 01j9z3k8m2x4q7r5t6v8w0y1ab --file ./handbook.pdf --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"file": {
"description": "Local file; repeat for several.",
"type": "array",
"items": {
"type": "string"
}
},
"url": {
"description": "URL of the document itself; repeat for several.",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"session"
]
}

Show a source with its section tree.

Kind: read (idempotent). Stability: stable. MCP tool: builder_sources_get. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}/sources/{source}.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--source (positional) string yes Source id (from builder sessions get).
Terminal window
# A source
ulams builder sources get <session> <source> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"source": {
"type": "string",
"description": "Source id (from `builder sessions get`)."
}
},
"required": [
"session",
"source"
]
}

Start a course from a source file or URL and drive it as far as you ask.

Creates a builder session, uploads the source(s), waits for the interview, then continues only as far as the flags say: –answers or –defaults answers the interview, –approve-outline approves the outline, –apply creates the course (unpublished) and –publish publishes it. Without them it stops at the first question or review and returns it in data.pending (exit 0), so you or an agent can decide. AI proposes, the author approves: every stage past the interview needs its flag. Needs AI to be enabled on the instance (FEATURE_DISABLED otherwise). Use –no-wait to return right after the upload.

Kind: write. Stability: stable. MCP tool: builder_start. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions, POST /api/admin/course-builder/sessions/{session}/sources, GET /api/admin/course-builder/sessions/{session}, POST /api/admin/course-builder/sessions/{session}/runs, POST /api/admin/course-builder/versions/{version}/approve, POST /api/admin/course-builder/sessions/{session}/apply, POST /api/admin/course-builder/sessions/{session}/publish.

Flag Type Required Description
--from array Source file (Markdown, PDF or DOCX); repeat for several.
--from-url array URL of a Markdown, PDF or DOCX document (the file itself, e.g. a raw GitHub link).
--session string Continue this session instead of creating one.
--title string Session title (default: the source’s title).
--answers object Interview answers by question key (audience, level, duration, tone, assessments, language) as JSON, or @file.json / @file.yaml.
--defaults boolean Let the builder decide every question that –answers leaves open.
--approve-outline boolean Approve the proposed outline and generate the lessons.
--apply boolean Apply the generated course to the academy (as an unpublished draft).
--publish boolean Publish the applied course.
--overwrite boolean With –apply on an already applied course: overwrite admin edits.
Terminal window
# Until the first question
ulams builder start --from ./guide.md --json
# A whole course from a Markdown file
ulams builder start --from ./guide.md --defaults --approve-outline --apply --json
# Answer the interview from a file, stop at the outline
ulams builder start --from ./guide.md --answers @answers.yaml --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"from": {
"description": "Source file (Markdown, PDF or DOCX); repeat for several.",
"type": "array",
"items": {
"type": "string"
}
},
"fromUrl": {
"description": "URL of a Markdown, PDF or DOCX document (the file itself, e.g. a raw GitHub link).",
"type": "array",
"items": {
"type": "string"
}
},
"session": {
"description": "Continue this session instead of creating one.",
"type": "string"
},
"title": {
"description": "Session title (default: the source's title).",
"type": "string"
},
"answers": {
"description": "Interview answers by question key (audience, level, duration, tone, assessments, language) as JSON, or @file.json / @file.yaml.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"defaults": {
"description": "Let the builder decide every question that --answers leaves open.",
"type": "boolean"
},
"approveOutline": {
"description": "Approve the proposed outline and generate the lessons.",
"type": "boolean"
},
"apply": {
"description": "Apply the generated course to the academy (as an unpublished draft).",
"type": "boolean"
},
"publish": {
"description": "Publish the applied course.",
"type": "boolean"
},
"overwrite": {
"description": "With --apply on an already applied course: overwrite admin edits.",
"type": "boolean"
}
}
}

Undo the last content change.

An applied course is re-applied to match; this waits for it.

Kind: write. Stability: stable. MCP tool: builder_undo. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions/{session}/undo.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
Terminal window
# undo
ulams builder undo <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
}
},
"required": [
"session"
]
}

AI calls of the session by task and model: tokens and cost.

Cost is in micro-USD (1,000,000 = 1 USD). Every call is logged; nothing here is estimated.

Kind: read (idempotent). Stability: stable. MCP tool: builder_usage. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}/usage.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
Terminal window
# Cost so far
ulams builder usage <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
}
},
"required": [
"session"
]
}

Ask for 2 or 3 options for one element and compare them.

Starts a variant run: one model call per option (the cost is count times a chat edit). The options are proposed versions that share a group; choose one with builder patches approve <version> (the other options stay proposed until you reject them) or builder patches reject <version>. Read them with builder versions list <session>.

Kind: write. Stability: stable. MCP tool: builder_variants. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/sessions/{session}/elements/{element}/variants.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
--element (positional) string yes Element id (from builder elements list).
--instruction string yes What to change, in plain words.
--count integer
Terminal window
# Two options
ulams builder variants <session> <element> --instruction "Harder distractors" --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
},
"element": {
"type": "string",
"description": "Element id (from `builder elements list`)."
},
"instruction": {
"type": "string",
"description": "What to change, in plain words."
},
"count": {
"default": 2,
"type": "integer",
"minimum": 2,
"maximum": 3
}
},
"required": [
"session",
"element",
"instruction"
]
}

Element-aware diff of a version against another (default: its parent).

Kind: read (idempotent). Stability: stable. MCP tool: builder_versions_diff. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/versions/{version}/diff.

Flag Type Required Description
--version (positional) string yes Version id.
--against string Version id to compare with.
Terminal window
# What changed
ulams builder versions diff <version> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"version": {
"type": "string",
"description": "Version id."
},
"against": {
"description": "Version id to compare with.",
"type": "string"
}
},
"required": [
"version"
]
}

Show one version (without the document unless –document).

Kind: read (idempotent). Stability: stable. MCP tool: builder_versions_get. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/versions/{version}.

Flag Type Required Description
--version (positional) string yes Version id.
--document boolean Include the full blueprint document (large).
Terminal window
# A version
ulams builder versions get <version> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"version": {
"type": "string",
"description": "Version id."
},
"document": {
"description": "Include the full blueprint document (large).",
"type": "boolean"
}
},
"required": [
"version"
]
}

List the blueprint versions of a session.

Kind: read (idempotent). Stability: stable. MCP tool: builder_versions_list. Scopes: builder:read.

Endpoints: GET /api/admin/course-builder/sessions/{session}/versions.

Flag Type Required Description
--session (positional) string yes Builder session id (from ulams builder sessions list).
Terminal window
# History
ulams builder versions list <session> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"session": {
"type": "string",
"description": "Builder session id (from `ulams builder sessions list`)."
}
},
"required": [
"session"
]
}

Restore an old version as a new current version.

Kind: write. Stability: stable. MCP tool: builder_versions_restore. Scopes: builder:write.

Endpoints: POST /api/admin/course-builder/versions/{version}/restore.

Flag Type Required Description
--version (positional) string yes Version id.
Terminal window
# Restore
ulams builder versions restore <version> --json
Input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"version": {
"type": "string",
"description": "Version id."
}
},
"required": [
"version"
]
}