ulams topics
Generated from front/cli (ulams schema)
ulams topics clone
Section titled “ulams topics clone”Clone topic.
Kind: write. Stability: stable. MCP tool: topics_clone. Scopes: courses:write.
Endpoints: POST /api/admin/topics/{id}/clone.
| Flag | Type | Required | Description |
|---|---|---|---|
--id (positional) |
integer | yes | id of Topic |
--body |
unknown | Request body (JSON) |
# Clone topiculams topics clone 1 --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "id": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "id of Topic" }, "body": { "description": "Request body (JSON)" } }, "required": [ "id" ], "additionalProperties": {}}ulams topics create
Section titled “ulams topics create”Create a topic of any registered type from raw fields (project, LTI, custom types).
Escape hatch for types without a dedicated command: pass topicable (the class name from ulams topics types), value and any extra fields in –input.
Kind: write. Stability: stable. MCP tool: topics_create. Scopes: courses:write.
Endpoints: POST /api/admin/topics.
| Flag | Type | Required | Description |
|---|---|---|---|
--lesson |
integer | yes | Lesson id (from ulams lessons list --course-id <id>). |
--title |
string | yes | Topic title. |
--order |
integer | Position in the lesson; default: after the last topic. | |
--summary |
string | Short summary. | |
--preview |
boolean | Visible without access to the course. | |
--active |
boolean | Visible to learners (default true). | |
--can-skip |
boolean | Learners may skip the topic. | |
--duration |
string | Estimated duration, e.g. ‘10 min’. | |
--topicable |
string | yes | Topic content class, e.g. Ulams\TopicTypeProject\Models\Project. |
--value |
unknown |
# A project topiculams topics create --lesson 12 --title Capstone --topicable 'Ulams\TopicTypeProject\Models\Project' --value 'Build X' --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "lesson": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Lesson id (from `ulams lessons list --course-id <id>`)." }, "title": { "type": "string", "description": "Topic title." }, "order": { "description": "Position in the lesson; default: after the last topic.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "summary": { "description": "Short summary.", "type": "string" }, "preview": { "description": "Visible without access to the course.", "type": "boolean" }, "active": { "description": "Visible to learners (default true).", "type": "boolean" }, "canSkip": { "description": "Learners may skip the topic.", "type": "boolean" }, "duration": { "description": "Estimated duration, e.g. '10 min'.", "type": "string" }, "topicable": { "type": "string", "description": "Topic content class, e.g. Ulams\\TopicTypeProject\\Models\\Project." }, "value": {} }, "required": [ "lesson", "title", "topicable" ], "additionalProperties": {}}ulams topics create-cmi5
Section titled “ulams topics create-cmi5”Create a cmi5 topic from a package .zip.
Uploads the cmi5 package and creates a topic for its assignable unit (the only one, or –au).
Kind: write. Stability: stable. MCP tool: topics_create_cmi5. Scopes: courses:write.
Endpoints: POST /api/admin/cmi5, POST /api/admin/topics.
| Flag | Type | Required | Description |
|---|---|---|---|
--lesson |
integer | yes | Lesson id (from ulams lessons list --course-id <id>). |
--title |
string | yes | Topic title. |
--order |
integer | Position in the lesson; default: after the last topic. | |
--summary |
string | Short summary. | |
--preview |
boolean | Visible without access to the course. | |
--active |
boolean | Visible to learners (default true). | |
--can-skip |
boolean | Learners may skip the topic. | |
--duration |
string | Estimated duration, e.g. ‘10 min’. | |
--package |
string | yes | Local cmi5 .zip. |
--au |
integer | Assignable unit id when there are several. |
# A cmi5 packageulams topics create-cmi5 --lesson 12 --title Module --package ./au.zip --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "lesson": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Lesson id (from `ulams lessons list --course-id <id>`)." }, "title": { "type": "string", "description": "Topic title." }, "order": { "description": "Position in the lesson; default: after the last topic.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "summary": { "description": "Short summary.", "type": "string" }, "preview": { "description": "Visible without access to the course.", "type": "boolean" }, "active": { "description": "Visible to learners (default true).", "type": "boolean" }, "canSkip": { "description": "Learners may skip the topic.", "type": "boolean" }, "duration": { "description": "Estimated duration, e.g. '10 min'.", "type": "string" }, "package": { "type": "string", "description": "Local cmi5 .zip." }, "au": { "description": "Assignable unit id when there are several.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "required": [ "lesson", "title", "package" ]}ulams topics create-file
Section titled “ulams topics create-file”Create a PDF, image or audio topic from a local file.
The topic type follows the extension: .pdf, .png .jpg .jpeg .gif .webp .svg, .mp3 .ogg.
Kind: write. Stability: stable. MCP tool: topics_create_file. Scopes: courses:write.
Endpoints: POST /api/admin/topics.
| Flag | Type | Required | Description |
|---|---|---|---|
--lesson |
integer | yes | Lesson id (from ulams lessons list --course-id <id>). |
--title |
string | yes | Topic title. |
--order |
integer | Position in the lesson; default: after the last topic. | |
--summary |
string | Short summary. | |
--preview |
boolean | Visible without access to the course. | |
--active |
boolean | Visible to learners (default true). | |
--can-skip |
boolean | Learners may skip the topic. | |
--duration |
string | Estimated duration, e.g. ‘10 min’. | |
--file |
string | yes | Local file. |
# A PDF topiculams topics create-file --lesson 12 --title Handout --file ./handout.pdf --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "lesson": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Lesson id (from `ulams lessons list --course-id <id>`)." }, "title": { "type": "string", "description": "Topic title." }, "order": { "description": "Position in the lesson; default: after the last topic.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "summary": { "description": "Short summary.", "type": "string" }, "preview": { "description": "Visible without access to the course.", "type": "boolean" }, "active": { "description": "Visible to learners (default true).", "type": "boolean" }, "canSkip": { "description": "Learners may skip the topic.", "type": "boolean" }, "duration": { "description": "Estimated duration, e.g. '10 min'.", "type": "string" }, "file": { "type": "string", "description": "Local file." } }, "required": [ "lesson", "title", "file" ]}ulams topics create-h5p
Section titled “ulams topics create-h5p”Create an H5P topic from a .h5p package.
Uploads the package to the H5P service (POST /h5p/contents/upload, field h5p_file) and creates a topic for the new content.
Kind: write. Stability: stable. MCP tool: topics_create_h5p. Scopes: courses:write.
Endpoints: POST /api/admin/topics.
| Flag | Type | Required | Description |
|---|---|---|---|
--lesson |
integer | yes | Lesson id (from ulams lessons list --course-id <id>). |
--title |
string | yes | Topic title. |
--order |
integer | Position in the lesson; default: after the last topic. | |
--summary |
string | Short summary. | |
--preview |
boolean | Visible without access to the course. | |
--active |
boolean | Visible to learners (default true). | |
--can-skip |
boolean | Learners may skip the topic. | |
--duration |
string | Estimated duration, e.g. ‘10 min’. | |
--package |
string | yes | Local .h5p file. |
# An H5P activityulams topics create-h5p --lesson 12 --title Quiz --package ./quiz.h5p --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "lesson": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Lesson id (from `ulams lessons list --course-id <id>`)." }, "title": { "type": "string", "description": "Topic title." }, "order": { "description": "Position in the lesson; default: after the last topic.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "summary": { "description": "Short summary.", "type": "string" }, "preview": { "description": "Visible without access to the course.", "type": "boolean" }, "active": { "description": "Visible to learners (default true).", "type": "boolean" }, "canSkip": { "description": "Learners may skip the topic.", "type": "boolean" }, "duration": { "description": "Estimated duration, e.g. '10 min'.", "type": "string" }, "package": { "type": "string", "description": "Local .h5p file." } }, "required": [ "lesson", "title", "package" ]}ulams topics create-interactive
Section titled “ulams topics create-interactive”Create an Interactive topic from a package .zip (or an uploaded package).
An Interactive topic plays an uploaded web app (3D scene, map, simulation) in a sandbox, inline or as the background of the page. Pass –file to upload a package (a .zip with ulams-interactive.json) or –package to use an uploaded one. The topic pins the package’s current version unless –version is given; –follow-latest plays every new upload instead. –start-step and –end-step choose the steps (ids from the manifest); the topic completes by –completion (default on_range_end). A manifest that lists network origins needs –accept-network.
Kind: write. Stability: stable. MCP tool: topics_create_interactive. Scopes: courses:write.
Endpoints: POST /api/admin/interactive, POST /api/admin/topics.
| Flag | Type | Required | Description |
|---|---|---|---|
--lesson |
integer | yes | Lesson id (from ulams lessons list --course-id <id>). |
--title |
string | yes | Topic title. |
--order |
integer | Position in the lesson; default: after the last topic. | |
--summary |
string | Short summary. | |
--preview |
boolean | Visible without access to the course. | |
--active |
boolean | Visible to learners (default true). | |
--can-skip |
boolean | Learners may skip the topic. | |
--duration |
string | Estimated duration, e.g. ‘10 min’. | |
--file |
string | Local .zip of a new package. | |
--package |
integer | Id of an uploaded package (from ulams interactive list). |
|
--version |
integer | Pin this version of the package (default: the current one). | |
--follow-latest |
boolean | Play the package’s current version instead of pinning one. | |
--start-step |
string | First step id of the range. | |
--end-step |
string | Last step id of the range. | |
--completion |
string | When the topic completes. | |
--pass-score |
integer | Pass percentage for –completion on_score. | |
--display |
string | Inline in the lesson, or the background of the page. | |
--height |
integer | Frame height in px (inline). | |
--text |
string | Lesson text in Markdown, or @path. | |
--accept-network |
boolean | Accept the network origins the manifest lists. |
# A step of a 3D scene as the page backgroundulams topics create-interactive --lesson 12 --title "Too slow" --file gravity.zip --start-step too-slow --end-step too-slow --display background --json# Another topic on an uploaded packageulams topics create-interactive --lesson 12 --title "Too fast" --package 3 --start-step too-fast --end-step too-fast --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "lesson": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Lesson id (from `ulams lessons list --course-id <id>`)." }, "title": { "type": "string", "description": "Topic title." }, "order": { "description": "Position in the lesson; default: after the last topic.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "summary": { "description": "Short summary.", "type": "string" }, "preview": { "description": "Visible without access to the course.", "type": "boolean" }, "active": { "description": "Visible to learners (default true).", "type": "boolean" }, "canSkip": { "description": "Learners may skip the topic.", "type": "boolean" }, "duration": { "description": "Estimated duration, e.g. '10 min'.", "type": "string" }, "file": { "description": "Local .zip of a new package.", "type": "string" }, "package": { "description": "Id of an uploaded package (from `ulams interactive list`).", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "version": { "description": "Pin this version of the package (default: the current one).", "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "followLatest": { "description": "Play the package's current version instead of pinning one.", "type": "boolean" }, "startStep": { "description": "First step id of the range.", "type": "string" }, "endStep": { "description": "Last step id of the range.", "type": "string" }, "completion": { "default": "on_range_end", "description": "When the topic completes.", "type": "string", "enum": [ "on_open", "on_range_end", "on_complete", "on_score" ] }, "passScore": { "description": "Pass percentage for --completion on_score.", "type": "integer", "minimum": 0, "maximum": 100 }, "display": { "default": "inline", "description": "Inline in the lesson, or the background of the page.", "type": "string", "enum": [ "inline", "background" ] }, "height": { "description": "Frame height in px (inline).", "type": "integer", "minimum": 240, "maximum": 2000 }, "text": { "fileInput": true, "description": "Lesson text in Markdown, or @path.", "type": "string" }, "acceptNetwork": { "description": "Accept the network origins the manifest lists.", "type": "boolean" } }, "required": [ "lesson", "title" ]}ulams topics create-layout
Section titled “ulams topics create-layout”Create a Layout topic from a document of learning components (flip cards, timelines, practice activities).
A Layout topic is a lesson body built from approved learning components instead of prose: Callout, Steps, ComparisonTable, H5PFrame, LiaScriptLesson, Timeline, FlipCards, CodeBlock and PracticeActivity (practice must use PracticeActivity). –document is a JSON (or YAML) list of nodes, [{ “component”: “Timeline”, “props”: {…}, “id”: “optional” }, …], inline or @path; the props of every component are listed in the learner layout manifest (front/ui/catalogue/learner-layout-manifest.json). –fallback is the Markdown shown by clients that do not render layouts and when the document cannot be rendered (inline or @path); leave hints and worked solutions out of it. The API validates the document and answers 422 with the node and prop path of every problem. The topic completes when the learner has viewed it, or after the first checked attempt when it holds a PracticeActivity.
Kind: write. Stability: stable. MCP tool: topics_create_layout. Scopes: courses:write.
Endpoints: POST /api/admin/topics.
| Flag | Type | Required | Description |
|---|---|---|---|
--lesson |
integer | yes | Lesson id (from ulams lessons list --course-id <id>). |
--title |
string | yes | Topic title. |
--order |
integer | Position in the lesson; default: after the last topic. | |
--summary |
string | Short summary. | |
--preview |
boolean | Visible without access to the course. | |
--active |
boolean | Visible to learners (default true). | |
--can-skip |
boolean | Learners may skip the topic. | |
--duration |
string | Estimated duration, e.g. ‘10 min’. | |
--document |
array | yes | Layout nodes: a JSON list of { component, props, id? }, inline or @path. |
--fallback |
string | yes | Markdown fallback, or @path to a Markdown file. |
# Flip cards and a timeline for a chapterulams topics create-layout --lesson 12 --title "Coffee through time" --document @layout.json --fallback @layout.md --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "lesson": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Lesson id (from `ulams lessons list --course-id <id>`)." }, "title": { "type": "string", "description": "Topic title." }, "order": { "description": "Position in the lesson; default: after the last topic.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "summary": { "description": "Short summary.", "type": "string" }, "preview": { "description": "Visible without access to the course.", "type": "boolean" }, "active": { "description": "Visible to learners (default true).", "type": "boolean" }, "canSkip": { "description": "Learners may skip the topic.", "type": "boolean" }, "duration": { "description": "Estimated duration, e.g. '10 min'.", "type": "string" }, "document": { "minItems": 1, "type": "array", "items": { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} }, "description": "Layout nodes: a JSON list of { component, props, id? }, inline or @path." }, "fallback": { "type": "string", "minLength": 1, "fileInput": true, "description": "Markdown fallback, or @path to a Markdown file." } }, "required": [ "lesson", "title", "document", "fallback" ]}ulams topics create-liascript
Section titled “ulams topics create-liascript”Create a LiaScript topic from Markdown or a .zip.
Kind: write. Stability: stable. MCP tool: topics_create_liascript. Scopes: courses:write.
Endpoints: POST /api/admin/liascript, POST /api/admin/topics.
| Flag | Type | Required | Description |
|---|---|---|---|
--lesson |
integer | yes | Lesson id (from ulams lessons list --course-id <id>). |
--title |
string | yes | Topic title. |
--order |
integer | Position in the lesson; default: after the last topic. | |
--summary |
string | Short summary. | |
--preview |
boolean | Visible without access to the course. | |
--active |
boolean | Visible to learners (default true). | |
--can-skip |
boolean | Learners may skip the topic. | |
--duration |
string | Estimated duration, e.g. ‘10 min’. | |
--markdown |
string | LiaScript Markdown, or @path. | |
--file |
string | Local .zip with the course and its assets. |
# A LiaScript courseulams topics create-liascript --lesson 12 --title Lia --markdown @course.md --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "lesson": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Lesson id (from `ulams lessons list --course-id <id>`)." }, "title": { "type": "string", "description": "Topic title." }, "order": { "description": "Position in the lesson; default: after the last topic.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "summary": { "description": "Short summary.", "type": "string" }, "preview": { "description": "Visible without access to the course.", "type": "boolean" }, "active": { "description": "Visible to learners (default true).", "type": "boolean" }, "canSkip": { "description": "Learners may skip the topic.", "type": "boolean" }, "duration": { "description": "Estimated duration, e.g. '10 min'.", "type": "string" }, "markdown": { "fileInput": true, "description": "LiaScript Markdown, or @path.", "type": "string" }, "file": { "description": "Local .zip with the course and its assets.", "type": "string" } }, "required": [ "lesson", "title" ]}ulams topics create-oembed
Section titled “ulams topics create-oembed”Create a topic that embeds a URL (YouTube, Vimeo and other oEmbed providers).
Kind: write. Stability: stable. MCP tool: topics_create_oembed. Scopes: courses:write.
Endpoints: POST /api/admin/topics.
| Flag | Type | Required | Description |
|---|---|---|---|
--lesson |
integer | yes | Lesson id (from ulams lessons list --course-id <id>). |
--title |
string | yes | Topic title. |
--order |
integer | Position in the lesson; default: after the last topic. | |
--summary |
string | Short summary. | |
--preview |
boolean | Visible without access to the course. | |
--active |
boolean | Visible to learners (default true). | |
--can-skip |
boolean | Learners may skip the topic. | |
--duration |
string | Estimated duration, e.g. ‘10 min’. | |
--url |
string | yes | Page URL of the video or content. |
# Embed a YouTube videoulams topics create-oembed --lesson 12 --title Demo --url https://www.youtube.com/watch?v=abc --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "lesson": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Lesson id (from `ulams lessons list --course-id <id>`)." }, "title": { "type": "string", "description": "Topic title." }, "order": { "description": "Position in the lesson; default: after the last topic.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "summary": { "description": "Short summary.", "type": "string" }, "preview": { "description": "Visible without access to the course.", "type": "boolean" }, "active": { "description": "Visible to learners (default true).", "type": "boolean" }, "canSkip": { "description": "Learners may skip the topic.", "type": "boolean" }, "duration": { "description": "Estimated duration, e.g. '10 min'.", "type": "string" }, "url": { "type": "string", "description": "Page URL of the video or content." } }, "required": [ "lesson", "title", "url" ]}ulams topics create-quiz
Section titled “ulams topics create-quiz”Create a quiz topic with questions from a YAML or JSON file.
Input: { value?, maxAttempts?, minPassScore?, questions: [{ prompt, options: [{ text, correct }], score? } | { gift, score? }] }. Multiple choice questions are converted to GIFT; raw gift strings pass through.
Kind: write. Stability: stable. MCP tool: topics_create_quiz. Scopes: courses:write.
Endpoints: POST /api/admin/topics, POST /api/admin/gift-questions.
| Flag | Type | Required | Description |
|---|---|---|---|
--lesson |
integer | yes | Lesson id (from ulams lessons list --course-id <id>). |
--title |
string | yes | Topic title. |
--order |
integer | Position in the lesson; default: after the last topic. | |
--summary |
string | Short summary. | |
--preview |
boolean | Visible without access to the course. | |
--active |
boolean | Visible to learners (default true). | |
--can-skip |
boolean | Learners may skip the topic. | |
--duration |
string | Estimated duration, e.g. ‘10 min’. | |
--max-attempts |
integer | ||
--min-pass-score |
number | ||
--questions |
array | yes | Questions (see the command description). |
# A quizulams topics create-quiz --lesson 12 --title Check --input @quiz.yaml --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "lesson": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Lesson id (from `ulams lessons list --course-id <id>`)." }, "title": { "type": "string", "description": "Topic title." }, "order": { "description": "Position in the lesson; default: after the last topic.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "summary": { "description": "Short summary.", "type": "string" }, "preview": { "description": "Visible without access to the course.", "type": "boolean" }, "active": { "description": "Visible to learners (default true).", "type": "boolean" }, "canSkip": { "description": "Learners may skip the topic.", "type": "boolean" }, "duration": { "description": "Estimated duration, e.g. '10 min'.", "type": "string" }, "maxAttempts": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "minPassScore": { "type": "number" }, "questions": { "type": "array", "items": { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} }, "description": "Questions (see the command description)." } }, "required": [ "lesson", "title", "questions" ]}ulams topics create-richtext
Section titled “ulams topics create-richtext”Create a rich text topic from Markdown or HTML.
Use for text lessons. Pass –markdown (inline text or @file.md) or –html. Markdown is converted to HTML on the client.
Kind: write. Stability: stable. MCP tool: topics_create_richtext. Scopes: courses:write.
Endpoints: POST /api/admin/topics.
| Flag | Type | Required | Description |
|---|---|---|---|
--lesson |
integer | yes | Lesson id (from ulams lessons list --course-id <id>). |
--title |
string | yes | Topic title. |
--order |
integer | Position in the lesson; default: after the last topic. | |
--summary |
string | Short summary. | |
--preview |
boolean | Visible without access to the course. | |
--active |
boolean | Visible to learners (default true). | |
--can-skip |
boolean | Learners may skip the topic. | |
--duration |
string | Estimated duration, e.g. ‘10 min’. | |
--markdown |
string | Markdown text, or @path to a Markdown file. | |
--html |
string | HTML text, or @path to an HTML file. |
# A text topic from a fileulams topics create-richtext --lesson 12 --title Intro --markdown @intro.md --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "lesson": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Lesson id (from `ulams lessons list --course-id <id>`)." }, "title": { "type": "string", "description": "Topic title." }, "order": { "description": "Position in the lesson; default: after the last topic.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "summary": { "description": "Short summary.", "type": "string" }, "preview": { "description": "Visible without access to the course.", "type": "boolean" }, "active": { "description": "Visible to learners (default true).", "type": "boolean" }, "canSkip": { "description": "Learners may skip the topic.", "type": "boolean" }, "duration": { "description": "Estimated duration, e.g. '10 min'.", "type": "string" }, "markdown": { "fileInput": true, "description": "Markdown text, or @path to a Markdown file.", "type": "string" }, "html": { "fileInput": true, "description": "HTML text, or @path to an HTML file.", "type": "string" } }, "required": [ "lesson", "title" ]}ulams topics create-scorm
Section titled “ulams topics create-scorm”Create a SCORM topic from a package .zip.
Uploads the package, picks its SCO (the only one, or –sco), then creates the topic. Several SCOs without –sco exit 2 with details.choices.
Kind: write. Stability: stable. MCP tool: topics_create_scorm. Scopes: courses:write.
Endpoints: POST /api/admin/scorm/upload, POST /api/admin/topics.
| Flag | Type | Required | Description |
|---|---|---|---|
--lesson |
integer | yes | Lesson id (from ulams lessons list --course-id <id>). |
--title |
string | yes | Topic title. |
--order |
integer | Position in the lesson; default: after the last topic. | |
--summary |
string | Short summary. | |
--preview |
boolean | Visible without access to the course. | |
--active |
boolean | Visible to learners (default true). | |
--can-skip |
boolean | Learners may skip the topic. | |
--duration |
string | Estimated duration, e.g. ‘10 min’. | |
--package |
string | yes | Local SCORM .zip. |
--sco |
integer | SCO id when the package has several. |
# A SCORM packageulams topics create-scorm --lesson 12 --title Safety --package ./pkg.zip --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "lesson": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Lesson id (from `ulams lessons list --course-id <id>`)." }, "title": { "type": "string", "description": "Topic title." }, "order": { "description": "Position in the lesson; default: after the last topic.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "summary": { "description": "Short summary.", "type": "string" }, "preview": { "description": "Visible without access to the course.", "type": "boolean" }, "active": { "description": "Visible to learners (default true).", "type": "boolean" }, "canSkip": { "description": "Learners may skip the topic.", "type": "boolean" }, "duration": { "description": "Estimated duration, e.g. '10 min'.", "type": "string" }, "package": { "type": "string", "description": "Local SCORM .zip." }, "sco": { "description": "SCO id when the package has several.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "required": [ "lesson", "title", "package" ]}ulams topics create-video
Section titled “ulams topics create-video”Create a video topic from a local file, or from a YouTube URL.
–file uploads the video (mp4, ogg, webm, mov; processed in the background: use ulams operations wait video:<topic id>). –youtube-url creates an embedded topic.
Kind: write. Stability: stable. MCP tool: topics_create_video. Scopes: courses:write.
Endpoints: POST /api/admin/topics.
| Flag | Type | Required | Description |
|---|---|---|---|
--lesson |
integer | yes | Lesson id (from ulams lessons list --course-id <id>). |
--title |
string | yes | Topic title. |
--order |
integer | Position in the lesson; default: after the last topic. | |
--summary |
string | Short summary. | |
--preview |
boolean | Visible without access to the course. | |
--active |
boolean | Visible to learners (default true). | |
--can-skip |
boolean | Learners may skip the topic. | |
--duration |
string | Estimated duration, e.g. ‘10 min’. | |
--file |
string | Local video file. | |
--youtube-url |
string | YouTube URL (embedded, no upload). |
# Upload a videoulams topics create-video --lesson 12 --title Intro --file ./intro.mp4 --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "lesson": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Lesson id (from `ulams lessons list --course-id <id>`)." }, "title": { "type": "string", "description": "Topic title." }, "order": { "description": "Position in the lesson; default: after the last topic.", "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "summary": { "description": "Short summary.", "type": "string" }, "preview": { "description": "Visible without access to the course.", "type": "boolean" }, "active": { "description": "Visible to learners (default true).", "type": "boolean" }, "canSkip": { "description": "Learners may skip the topic.", "type": "boolean" }, "duration": { "description": "Estimated duration, e.g. '10 min'.", "type": "string" }, "file": { "description": "Local video file.", "type": "string" }, "youtubeUrl": { "description": "YouTube URL (embedded, no upload).", "type": "string" } }, "required": [ "lesson", "title" ]}ulams topics delete
Section titled “ulams topics delete”Remove the specified Topic from storage.
Kind: destructive (idempotent). Stability: stable. MCP tool: topics_delete. Scopes: courses:write.
Endpoints: DELETE /api/admin/topics/{id}.
| Flag | Type | Required | Description |
|---|---|---|---|
--id (positional) |
integer | yes | id of Topic |
# Remove the specified Topic from storageulams topics delete 1 --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "id": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "id of Topic" } }, "required": [ "id" ], "additionalProperties": {}}ulams topics get
Section titled “ulams topics get”Display the specified Topic.
Kind: read (idempotent). Stability: stable. MCP tool: topics_get. Scopes: courses:read.
Endpoints: GET /api/admin/topics/{id}.
| Flag | Type | Required | Description |
|---|---|---|---|
--id (positional) |
integer | yes | id of Topic |
# Display the specified Topiculams topics get 1 --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "id": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "id of Topic" } }, "required": [ "id" ], "additionalProperties": {}}ulams topics list
Section titled “ulams topics list”Get a listing of the Topics.
Kind: read (idempotent). Stability: stable. MCP tool: topics_list. Scopes: courses:read.
Endpoints: GET /api/admin/topics.
# Get a listing of the Topicsulams topics list --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": {}, "additionalProperties": {}}ulams topics resources-add
Section titled “ulams topics resources-add”Post new resource.
Kind: write. Stability: stable. MCP tool: topics_resources_add. Scopes: courses:write.
Endpoints: POST /api/admin/topics/{topic_id}/resources/.
| Flag | Type | Required | Description |
|---|---|---|---|
--topic-id (positional) |
integer | yes | id of Topic |
--resource |
string | resource (path of a local file) |
# Post new resourceulams topics resources-add 1 --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "topic_id": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "id of Topic" }, "resource": { "type": "string", "description": "resource (path of a local file)" } }, "required": [ "topic_id" ], "additionalProperties": {}}ulams topics resources-delete
Section titled “ulams topics resources-delete”Delete resource.
Kind: destructive (idempotent). Stability: stable. MCP tool: topics_resources_delete. Scopes: courses:write.
Endpoints: DELETE /api/admin/topics/{topic_id}/resources/{resource_id}.
| Flag | Type | Required | Description |
|---|---|---|---|
--topic-id (positional) |
integer | yes | id of Topic |
--resource-id (positional) |
integer | yes | id of Resource |
# Delete resourceulams topics resources-delete 1 1 --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "topic_id": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "id of Topic" }, "resource_id": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "id of Resource" } }, "required": [ "topic_id", "resource_id" ], "additionalProperties": {}}ulams topics resources-list
Section titled “ulams topics resources-list”Get list of resources.
Kind: read (idempotent). Stability: stable. MCP tool: topics_resources_list. Scopes: courses:read.
Endpoints: GET /api/admin/topics/{topic_id}/resources/.
| Flag | Type | Required | Description |
|---|---|---|---|
--topic-id (positional) |
integer | yes | id of Topic |
# Get list of resourcesulams topics resources-list 1 --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "topic_id": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "id of Topic" } }, "required": [ "topic_id" ], "additionalProperties": {}}ulams topics resources-update
Section titled “ulams topics resources-update”Rename resource.
Kind: write. Stability: stable. MCP tool: topics_resources_update. Scopes: courses:write.
Endpoints: PATCH /api/admin/topics/{topic_id}/resources/{resource_id}.
| Flag | Type | Required | Description |
|---|---|---|---|
--topic-id (positional) |
integer | yes | id of Topic |
--resource-id (positional) |
integer | yes | id of Resource |
--name |
string |
# Rename resourceulams topics resources-update 1 1 --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "topic_id": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "id of Topic" }, "resource_id": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "id of Resource" }, "name": { "type": "string" } }, "required": [ "topic_id", "resource_id" ], "additionalProperties": {}}ulams topics types
Section titled “ulams topics types”Get a listing of the Availabe Topic Content Types Classes.
Kind: read (idempotent). Stability: stable. MCP tool: topics_types. Scopes: courses:read.
Endpoints: GET /api/admin/topics/types.
# Get a listing of the Availabe Topic Content Types Classesulams topics types --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": {}, "additionalProperties": {}}ulams topics update
Section titled “ulams topics update”Update the specified Topic in storage.
Kind: write (idempotent). Stability: stable. MCP tool: topics_update. Scopes: courses:write.
Endpoints: PUT /api/admin/topics/{id}.
| Flag | Type | Required | Description |
|---|---|---|---|
--id (positional) |
integer | yes | id of Topic |
--active |
boolean | active | |
--can-skip |
boolean | can skip | |
--description |
string | description | |
--duration |
string | duration | |
--introduction |
string | introduction | |
--json |
object | json | |
--lesson-id |
integer | lesson_id | |
--order |
integer | order | |
--preview |
boolean | preview | |
--summary |
string | summary | |
--title |
string | title | |
--topicable-id |
integer | topicable_id | |
--topicable-type |
string | topicable_type | |
--value |
string | value |
# Update the specified Topic in storageulams topics update 1 --jsonInput JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "id": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "id of Topic" }, "active": { "type": "boolean", "description": "active" }, "can_skip": { "type": "boolean", "description": "can skip" }, "description": { "type": "string", "description": "description" }, "duration": { "type": "string", "description": "duration" }, "introduction": { "type": "string", "description": "introduction" }, "json": { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {}, "description": "json" }, "lesson_id": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "lesson_id" }, "order": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "order" }, "preview": { "type": "boolean", "description": "preview" }, "summary": { "type": "string", "description": "summary" }, "title": { "type": "string", "description": "title" }, "topicable_id": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "topicable_id" }, "topicable_type": { "type": "string", "description": "topicable_type" }, "value": { "type": "string", "description": "value" } }, "required": [ "id" ], "additionalProperties": {}}