Cubite LMS: Learning Management System
Server Details
LMS (learning management system): manage courses, SCORM/xAPI, learners, certificates and reports.
- Status
- Healthy
- Uptime
- 99.6% over 42 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- ChatGPT
- –
- Claude
- –
TDQS
Scored across 19 tools
Tools target clearly distinct resources and actions, and descriptions explicitly separate overlapping-looking pairs such as application_list vs enrollment_list, course_get vs fetch, and enrollment_create vs enrollment_bulk_create vs enrollment_update. No two tools appear interchangeable.
The set uses a consistent resource_action snake_case pattern (course_create, enrollment_list, application_review), with only `fetch`, `search`, and `block_type_list` deviating as single verbs or noun-first names. These deviations remain understandable and form a recognized search/fetch pair.
At 19 tools the set is slightly above the ideal 3–15 band, but each tool maps to a distinct LMS surface area: course settings, content versions, applications, enrollments, block catalog, and public search/fetch. No tool feels redundant or trivially overlapping.
Core course and enrollment lifecycles are well covered, including create/duplicate/update/delete, content versioning, bulk enrollment, waitlist handling, applications, and public search/fetch. Minor gaps exist for direct user/account management, certificate operations, and discussions, which are referenced elsewhere but not directly manageable.
Available Tools
19 toolsapplication_listList course applicationsARead-onlyInspect
List applications to courses that require applying before enrollment (requiresApplication), newest first, each with the applicant and their answers; an applicant is not enrolled until the application is approved. For enrolled or waitlisted learners use enrollment_list instead. status:"pending" is the review queue; add courseId for one course's queue. Learners apply from the course page, one application per learner per course; a rejected learner can apply again, which reopens the same application as pending with new answers. applicationData is {responses: [{label, value}]}, one entry per application question, or {message} when the course asks no questions (older applications may hold a flat question-to-answer object). Returns {total, count, applications: [{id, status, applicant {id, name, email}, course {id, name}, applicationData, decisionNote, reviewedAt, createdAt, updatedAt}]}. Approve or reject one with application_review, using its id.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max rows (default 100; values above 500 are capped at 500). | |
| offset | No | Rows to skip (default 0); compare with total to page. | |
| status | No | Only applications in this state: pending (awaiting a decision), approved or rejected. Omit for all. | |
| courseId | No | Only applications to this course (must be on this site). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/destructive=false, and the description layers on non-obvious domain behavior: an applicant is not enrolled until approved, one application per learner per course, and a rejected learner reapplying reopens the same application as pending with new answers. That lifecycle detail materially affects how an agent interprets 'pending' rows.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then routing, then data shape; every clause carries information. It is dense and runs long with stacked semicolons, and the full return-object enumeration is heavy, though defensible since no output schema exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return envelope ({total, count, applications:[...]}) and field list, plus the applicationData shape variants. Nothing an agent needs to call or interpret this list tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description adds semantics the schema lacks, framing status:'pending' as the review queue and courseId as scoping to one course's queue. Limit/offset paging semantics are left entirely to the schema, so it stops short of a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List applications to courses that require applying before enrollment'), plus ordering ('newest first') and payload scope ('each with the applicant and their answers'). It explicitly contrasts itself with the sibling enrollment_list, so an agent can pick between them without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing: use enrollment_list for enrolled or waitlisted learners, status:'pending' is the review queue, add courseId for a single course's queue, and application_review handles decisions by id. Both when-to-use and when-to-use-something-else are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
application_reviewReview course applicationADestructiveInspect
Approve or reject one course application from application_list. Approving ENROLLS the applicant right away (prerequisites skipped, the course's access period applied) and emails them an approval with a link into the course; rejecting records the decision and emails them your decisionNote, enrolling no one. Repeating the decision an application already has does nothing (no second enrollment or email), and rejecting an application that was already approved does not remove the enrollment: use enrollment_revoke for that. To enroll someone who never applied, use enrollment_create. Returns {id, status, decisionNote, reviewedAt}.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Application id from application_list. | |
| decision | Yes | "approved" enrolls the applicant and emails an approval; "rejected" emails a rejection and enrolls no one. Either email is skipped if the site has turned it off. | |
| decisionNote | No | Optional note saved on the application; it appears in the rejection email only (the approval email does not show it). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only flag a destructive, non-read-only write; the description goes well beyond them by disclosing the concrete side effects (immediate enrollment, prerequisites skipped, access period applied, emails sent), the idempotency semantics, and the non-reversal of a rejection. These are the high-value operational facts an agent must know before invoking a destructive tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences, front-loaded with the action and its irreversible consequence, then sibling routing, then the return shape. Nothing is padding; each clause carries a distinct fact.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite there being no output schema, the description states the return shape {id, status, decisionNote, reviewedAt} and covers the edge cases (repeat decisions, rejection-after-approval, unsolicited enrollment). Nothing material for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning by tying each enum value to a downstream consequence (approved enrolls and emails a link; rejected records and emails the note) and explicitly notes decisionNote appears in the rejection email only. That linkage is richer than the per-field schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb pair (approve/reject) and a precise resource (one course application from application_list), and it explicitly delineates itself from enrollment_revoke and enrollment_create. An agent can distinguish this from every sibling without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit routing: use enrollment_revoke to remove an existing enrollment, and enrollment_create to enroll someone who never applied. It also states the idempotency behavior (repeating a decision does nothing; rejecting an already-approved application does not unenroll), which is exactly the when/when-not guidance an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
block_type_listList content block typesARead-onlyInspect
Return the EditorJS block catalog: the block types you can write as blocks and the exact data shape of each. It is static reference data and reads nothing from your site. Prose needs no catalog: markdown (headings, paragraphs, lists, quotes, tables, code) is converted to blocks for you. Call it with no arguments for a compact index (each type, its tier and when to use it), then again with types set to only the blocks you will emit. Tiers: prose = in-column text, section = full-width layout, visual = charts and summaries, media = embeds needing an external id or URL. Sections: blocks suit any content unless an entry's note says otherwise (courses is for pages and the homepage only); courseAssessments (quiz, assignment, form, poll and other graded or interactive blocks) are valid ONLY in course content; notForBlogContent, despite its name, lists types never to emit anywhere. course_content_set accepts these blocks to replace a course's lessons.
| Name | Required | Description | Default |
|---|---|---|---|
| types | No | Block types to expand in full (data shape, enums, example), e.g. ["header","quiz"]. Omit for the compact index. When set, section and detail are ignored; unknown names come back in unknownTypes. | |
| detail | No | 'index' (default) = one line per block type. 'full' = the entire catalog in one large response (ignored when types is set); prefer `types`. | |
| section | No | Limit the compact index to one section. Default 'all'. Ignored when types is set or detail is 'full'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false; the description reinforces this ('static reference data and reads nothing from your site') and adds behavioral context beyond the annotations: the tier taxonomy, section eligibility rules, and the unknownTypes error behavior. It stops short of describing pagination or response size limits beyond 'one large response.'
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: the core purpose and read-only nature come first, then the call pattern, then tier/section reference. Every sentence carries information, though the section rules compress several distinct caveats into a long sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-shape burden and does so well, explaining both the compact index and the expanded `types` response (data shape, enums, example) plus error handling. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so a baseline of 3 is warranted, but the description adds semantic meaning the schema lacks: what 'compact index' returns per row (type, tier, when to use it), what tier labels mean (prose/section/visual/media), and the section semantics/caveats (courseAssessments is course-only; notForBlogContent despite its name lists types never to emit).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Return the EditorJS block catalog') and immediately clarifies scope: 'the block types you can write as `blocks` and the exact `data` shape of each.' This distinguishes it clearly from siblings like course_content_set, which it references as the consumer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit two-call workflow ('no arguments for a compact index... then again with `types` set to only the blocks you will emit') and an explicit exclusion: prose content needs no catalog because markdown is auto-converted. The routing condition for the tool is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
course_content_getGet course contentARead-onlyInspect
Get a course's lessons as EditorJS blocks (H2 headers are sections, H3 headers are units): the current version, or an older saved revision when you pass version (list revisions with course_version_list). This is the authoring source with each block's id and data; course_get returns the course's settings and fetch only its catalog summary. Returns {courseId, version, blocks}, plus savedAt for an older revision; version 0 with no blocks means nothing has been written yet, and a version number that does not exist is a not-found error. Read the current version before course_content_set so you can keep each block's id. To roll back, read the old version and write its blocks with course_content_set, which saves a new version rather than erasing history.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Course id. | |
| version | No | Saved version number to read (1 or higher, from course_version_list). Omit for the current version. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare a read-only, non-destructive operation, and the description adds substantial behavior beyond that: version 0 with no blocks means nothing written, nonexistent versions are not-found errors, older revisions include savedAt, and writing is additive rather than history-erasing. This is rich context an agent cannot get from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then scoping, return shape, and workflow in a dense multi-sentence block. Every sentence carries information, though the rollback sentence and sibling routing make it longer than strictly minimal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by naming the return shape ({courseId, version, blocks} plus savedAt) and edge-case semantics. Nothing needed to call or interpret the result is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds real meaning: what `version` selects (a saved revision from course_version_list), its valid range, and the effect of omitting it. Slightly exceeds the schema's own wording.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource and the exact representation returned (EditorJS blocks), plus the H2/H3 structural convention. It also distinguishes itself from siblings course_get and fetch by naming what those return instead.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes: use course_version_list to find revisions, course_get for settings, fetch for catalog summary, and read the current version before course_content_set to preserve block ids. It also covers the rollback workflow. When/when-not guidance is fully present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
course_content_setReplace course contentADestructiveInspect
Replace a course's lessons by saving a complete new content version, which enrolled learners see immediately; settings such as price or visibility are changed with course_update instead. Earlier versions stay readable with course_content_get, so a bad write can be rolled back. This is not a patch: send the whole course every time, as blocks (EditorJS) or markdown (prose only), with H2 headers as section titles and H3 headers as unit titles. Keep each existing block's id from course_content_get: learners' answers, submissions and completion records are tied to block ids, so a block saved without its id (and every block written as markdown) no longer shows its learners' history. Get block shapes from block_type_list; its courseAssessments blocks (quiz, assignment, form, poll and similar) are valid ONLY in course content. Every call adds a version, even an identical one; returns the new version number and block count.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Course id (required). | |
| blocks | No | The complete lesson list as EditorJS blocks [{id?, type, data}], in order (must not be empty). Include each existing block's id to keep its learner records; blocks without one get a new id. Wins over markdown if both are sent. | |
| authorId | No | User recorded as this version's author; must belong to this site. Defaults to the site's first admin. | |
| markdown | No | The whole course as Markdown (headings, paragraphs, lists, checklists, quotes, tables, code), converted to blocks with new ids; it cannot express graded blocks. Use this OR blocks. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral context beyond the destructiveHint=true annotation: learners see changes immediately, every call creates a version, earlier versions remain readable for rollback, and block ids are essential for preserving learner history. It also discloses the return value (new version number and block count) despite no output schema, which is unusually thorough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-structured, front-loading the core action and then covering usage, format, ids, and versioning in a logical order. Every sentence carries actionable information, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of a destructive replace operation with no output schema, the description covers everything an agent needs: scope, alternatives, format requirements, id handling, rollback path, and return values. It is complete and leaves no critical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description goes further by explaining the semantics of `blocks` versus `markdown` (EditorJS vs prose only, markdown cannot express graded blocks), the heading conventions (H2 for sections, H3 for units), the importance of block ids, and that blocks wins over markdown if both are sent. This meaningfully enriches the schema's own descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and scope: 'Replace a course's lessons by saving a complete new content version.' It distinguishes itself from siblings by naming course_update for settings and course_content_get for reading earlier versions, so the agent knows exactly what this tool does and doesn't do.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use guidance by contrasting this tool with course_update ('settings such as price or visibility are changed with course_update instead') and clarifies that it is not a patch ('send the whole course every time'). It also points to course_content_get for rollback, naming alternatives directly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
course_createCreate courseAInspect
Create a new course on this site: settings only, no lessons yet; to copy an existing course with its lessons, use course_duplicate. The public catalog lists a course once it has a slug and isVisibleInCatalog is true (the default), so build with isVisibleInCatalog:false and publish later with course_update. Prerequisites, application questions and certificateConfig (completion and certificate rules) are not accepted here; set them afterwards with course_update. New courses start with the reading-time gate on, so a text unit counts as complete only after a minimum reading time (course_update's certificateConfig turns it off). Creating a course emails no one and fires no webhook. A rejected call (bad value, unknown instructor, taken slug) creates nothing, but names need not be unique, so every successful call adds another course. Returns the new course's name, id and slug; add lessons next with course_content_set.
| Name | Required | Description | Default |
|---|---|---|---|
| xp | No | Gamification points awarded (whole number). | |
| name | Yes | Course title (required, max 191 chars). | |
| slug | No | URL slug used in /course/<slug>/..., lowercased with other characters turned into hyphens. Must be unique across all Cubite sites (a taken slug is a 409 error). Without one the course is not listed in the catalog or reachable by learners. | |
| level | No | Difficulty label shown in the catalog, e.g. "Beginner" (max 191 chars). | |
| price | No | List price in US dollars; omit or 0 for a free course. | |
| banner | No | Wide banner image for the course about page. | |
| topics | No | Topic tag names; an existing tag with the same name is reused, otherwise it is created. | |
| credits | No | Credits/CEUs awarded on completion (decimals allowed). | |
| endDate | No | Course end, ISO 8601 date or date-time. | |
| discount | No | Sale price in US dollars that learners pay INSTEAD of `price` (the discounted price, not an amount off). Omit or 0 for no sale. | |
| duration | No | Content length in hours (whole number), shown in the catalog; not an access limit. | |
| featured | No | Highlight the course in featured catalog slots (default false). | |
| subjects | No | Subject tag names; an existing tag with the same name is reused, otherwise it is created. | |
| metaTitle | No | SEO meta title (<=60 chars recommended, max 191). | |
| startDate | No | Course start, ISO 8601 date or date-time. | |
| coverImage | No | Catalog card image: absolute URL or Cloudinary public id (max 191 chars). | |
| introVideo | No | Intro video: a YouTube or Loom URL, or a direct video file URL (max 191 chars). | |
| description | No | Catalog summary shown on the course page; not the lessons. | |
| instructors | No | Instructor user ids. Each must already be on this site (a site role or site admin); one unknown id fails the call and nothing is created. | |
| metaDescription | No | SEO meta description (<=155 chars recommended). | |
| discussionEnabled | No | Turn on the course discussion forum (default false). | |
| enrollmentEndDate | No | When enrollment closes, ISO 8601. | |
| isSyllabusVisible | No | Show the syllabus to visitors who are not enrolled (default true). | |
| accessDurationDays | No | Days of access from each enrollment (whole number); omit for unlimited access. | |
| isVisibleInCatalog | No | List the course in the public catalog. Defaults to TRUE, so pass false while you are still building the course. | |
| enrollmentStartDate | No | When enrollment opens, ISO 8601. | |
| requiresApplication | No | Learners must apply and be approved before they are enrolled (default false). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, openWorldHint=false and destructiveHint=false, so the mutation/safety profile is covered. The description still adds real value beyond them: no emails or webhooks fire, a rejected call creates nothing but names need not be unique so each success adds another course, and the reading-time gate starts on.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and dense with no filler sentences; each clause carries routing or behavior information. It is a wall of text for a 27-parameter tool, but nearly every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a large create tool: it covers side effects, defaults with workflow consequences, error/failure behavior, the return shape (name, id, slug) despite no output schema, and the next step. Little an agent needs before calling it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the 27 properties are already fully documented and the baseline is 3. The description adds some scope knowledge not derivable from the schema (prerequisites, application questions and certificateConfig are deliberately absent here), but the field-level semantics themselves duplicate what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a precise verb+resource and immediately scopes it: 'Create a new course on this site: settings only, no lessons yet.' It explicitly distinguishes itself from the sibling course_duplicate, so an agent can pick between them without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when/when-not routing ('to copy an existing course with its lessons, use course_duplicate'), a build-then-publish workflow (create with isVisibleInCatalog:false, publish later with course_update), and directs follow-on work to course_update and course_content_set.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
course_deleteDelete courseADestructiveInspect
Delete a course from this site. If other sites share the course it is only detached from this one and nothing is deleted. Otherwise it is permanently deleted with its content versions, enrollments, learner progress, issued certificates, discussions, payment records (they drop out of purchase history and revenue reports), applications, learning-path steps and group course links, which cannot be undone; while it has enrolled (non-waitlisted) learners the call is refused unless force:true. To hide a course but keep everything, set isVisibleInCatalog:false with course_update instead. Returns whether the course was deleted or detached. Check who is enrolled with enrollment_list (courseId) before forcing a delete.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Course id. | |
| force | No | Delete even if the course has enrolled learners, removing their enrollments, progress, certificates and payment records too. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, but the description goes far beyond: it enumerates exactly what is destroyed (content versions, enrollments, progress, certificates, discussions, payment records and their effect on revenue reports, applications, learning-path steps, group links), states irreversibility, and describes the detach-vs-delete branch. This is precisely the behavioral context an agent needs before a destructive call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: the detach/delete distinction comes first, then destruction list, then the refusal+force condition, then the alternative and the pre-check. Every clause carries actionable information and nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly supplies the return value ('whether the course was deleted or detached'). Combined with the destruction list, force semantics, and the alternative route, nothing needed to call this safely is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds real meaning: it frames force as the override for the enrolled-learners refusal and implies id identifies the course. It stops short of documenting types/defaults beyond what the schema already carries.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (delete a course) and immediately distinguishes the two possible semantics — detach from this site vs. permanent deletion. An agent can tell this apart from siblings like course_update or enrollment_revoke without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names alternatives and conditions: use course_update with isVisibleInCatalog:false to hide instead of delete, and use enrollment_list(courseId) before forcing. It also states the exact precondition (enrolled non-waitlisted learners) under which the call is refused.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
course_duplicateDuplicate courseAInspect
Copy a course into a new hidden course named " (Copy)" on this site, the fastest way to start a new cohort or a variant of a template; use course_create for a blank course. The copy gets the source's settings, its current lessons as version 1 (graded blocks get fresh ids so learner records stay separate), SCORM/xAPI packages, discussion topics and prompts, tags, certificate template and instructors, plus authorId (default: the site's first admin), who is added to its instructors and recorded as the author of version 1. It does NOT copy enrollments or other learner data, the slug, or the certificate statement-code prefix and numbering, so give the copy a slug with course_update before learners can reach it. Large SCORM/xAPI packages make the copy slow; if the call times out, check course_list before retrying so you do not create a second copy (a copy that fails is rolled back). Returns the new course object.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Course to duplicate (must be on this site). | |
| authorId | No | User credited as the copy's author and added to its instructors; must belong to this site. Defaults to the site's first admin. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose that this is a non-read-only, non-destructive operation, but the description adds extensive behavioral detail: what is copied (settings, lessons as version 1, SCORM/xAPI, discussions, tags, certificate template, instructors), what is not copied (enrollments, slug, certificate numbering), timeout and rollback behavior, and the fact that a failed copy is rolled back.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured and front-loaded: it begins with the core purpose and alternative, then details copy behavior, exclusions, warnings, and return value. Most sentences carry useful, non-redundant information, though the density is high enough to be a slight readability tax.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description states the return value ('Returns the new course object') and covers side effects, exclusions, prerequisites, and failure behavior. It gives an agent everything needed to invoke the tool responsibly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning beyond the schema by explaining authorId's default, its side effect of adding the user to instructors, and its role as author of version 1. The id parameter is already well described in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Duplicate course') and explicitly distinguishes itself from course_create for a blank course. An agent can identify the operation and its scope without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear when-to-use guidance ('fastest way to start a new cohort or a variant of a template'), names the alternative (course_create), and adds operational prerequisites such as setting a slug via course_update and checking course_list before retrying a timeout.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
course_getGet courseARead-onlyInspect
Get one course's settings record by id: the same course object course_list returns (catalog fields, flags, subjects, topics, enrollmentCount). Pass includeConfig:true to also get its instructors, prerequisites and application form, which the course object leaves out; that needs the courses:write permission, and a read-only connection gets an error rather than silently missing fields. For the course's lessons use course_content_get; for a citable plain-text summary with its public page URL use fetch. Returns the course object, or {course, config} with includeConfig; a course that is not on this site is a not-found error.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Course id, as returned by course_list. | |
| includeConfig | No | true adds `config`: applicationFields, instructors [{userId, name}] and prerequisites [{courseId, minProgressPct, minAvgGradePct}]; certificateConfig is not included. Requires courses:write. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only annotation, the description discloses that includeConfig requires courses:write and that a read-only connection gets an error rather than silently missing fields. It also describes return shapes and not-found behavior, which are valuable behavioral details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded with the core purpose, then alternatives and return behavior. Every sentence adds useful routing or behavioral information without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description explains both possible return forms, including the includeConfig variant, and the not-found error case. It is complete enough for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are already documented clearly in the schema. The description reinforces includeConfig's effect and adds the read-only error behavior, but most parameter meaning is already present in the schema, making 3 the appropriate baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: retrieving one course's settings record by id, and explicitly says it returns the same course object as course_list with named fields. It also distinguishes this from course_content_get for lessons and fetch for a citable summary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit routing: use course_content_get for lessons and fetch for a plain-text summary with public URL. It also states when and why to pass includeConfig, including the permission requirement and read-only connection error.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
course_listList coursesARead-onlyInspect
List every course on this site with its settings, most recently updated first, including courses hidden from the public catalog and courses without a slug: the full inventory and the place to look up course ids. It has no keyword filter and returns no page URLs: to find courses by keyword, with their public page URLs, use search; for one course's record use course_get. Returns a JSON array of course objects: id, name, slug, description, price, discount, level, duration, dates, catalog flags such as isVisibleInCatalog, subjects, topics, and enrollmentCount (this site's enrollments, waitlisted included). To page, raise offset by limit until a page holds fewer than limit courses.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max courses to return (default 200; values above 500 are capped at 500). | |
| offset | No | Courses to skip, for paging (default 0). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a read-only, non-destructive operation; the description adds ordering, hidden-course inclusion, exact returned fields, enrollment counting semantics, and paging behavior. Nothing contradicts the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The scope is front-loaded, followed by alternatives, return shape, and paging. Despite being dense, every sentence carries decision-relevant information and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully explains the returned array and key fields. It also covers scope, exclusions, alternatives, and paging, leaving no major ambiguity for calling the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so `limit` and `offset` are already documented. The description still adds useful paging semantics by explaining how to advance `offset` and when to stop.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: list every course on the site, with scope clarified as full inventory including hidden and slugless courses. It also distinguishes itself from `search` and `course_get`, so an agent can select it without opening another schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says it has no keyword filter and returns no page URLs, then names `search` for keyword/public-URL lookup and `course_get` for one course record. Paging guidance is also given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
course_updateUpdate courseADestructiveInspect
Update a course's settings, from catalog text, slug, price, dates and visibility to tags, instructors, prerequisites, the application form and certificateConfig (completion and certificate rules), and return the updated course object (same shape as course_get). Scalar fields patch: only those you send change, and null clears a nullable one. Lists are replaced whole (subjects, topics, instructors, prerequisites, applicationFields): send the complete list; course_get with includeConfig:true returns the current ones. An invalid value rejects the call and leaves the course unchanged. Saves are recorded in the course's change log; they email no one and fire no webhook. Lessons are not settings: replace them with course_content_set. accessDurationDays applies only to new enrollments; change existing learners' expiry with enrollment_update.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Course id (required). | |
| xp | No | Gamification points awarded (integer). | |
| name | No | Course title shown in the catalog (max 191 chars); cannot be empty. | |
| slug | No | URL slug used in /course/<slug>/..., lowercased with other characters turned into hyphens. Must be unique across all Cubite sites (a taken slug is a 409 error). null clears it, which drops the course from the catalog and search. | |
| level | No | Difficulty label shown in the catalog, e.g. "Beginner". null clears. | |
| price | No | List price in US dollars. null or 0 = free. | |
| banner | No | Wide banner image for the course about page. | |
| topics | No | Topic tag names; created if new. REPLACES the full set (send the complete list, [] clears). | |
| credits | No | Credits/CEUs awarded on completion; feeds transcripts and the credits report. | |
| endDate | No | Course end, ISO 8601. null clears. | |
| discount | No | Sale price that REPLACES `price` when set (US dollars, NOT a percentage and NOT an amount off). Learners are charged `discount` if present, otherwise `price`. null clears the sale. | |
| duration | No | Informational content length in HOURS (integer). Not an access limit. | |
| featured | No | Highlight the course in featured catalog slots. | |
| subjects | No | Subject tag names; created if new. REPLACES the full set (send the complete list, [] clears). | |
| metaTitle | No | SEO meta title (<=60 chars recommended). | |
| startDate | No | Course start, ISO 8601 (e.g. "2026-09-01" or "2026-09-01T09:00:00Z"). null clears. | |
| coverImage | No | Catalog/card image: absolute URL or Cloudinary public id. | |
| introVideo | No | Intro video: a YouTube or Loom URL, or a direct video file URL. | |
| description | No | Catalog description of the course. This is the summary, NOT the lesson content (use course_content_set for that). | |
| instructors | No | Instructor user ids, REPLACING the full set ([] removes all). Each must already be on this site (a site role or site admin), or the call fails. | |
| prerequisites | No | Prerequisite courses whose thresholds a learner must meet before enrolling, REPLACING the full set ([] removes all). Each: {id, minProgressPct?, minAvgGradePct?}. | |
| metaDescription | No | SEO meta description (<=155 chars recommended). | |
| applicationFields | No | Application form questions, REPLACING the whole list: [{text, type, options?, required?}], where text is the question shown, type is "text" (default), "textarea" or "dropdown" (with options [{value, label}]), and required is a boolean. null clears it, leaving a single free-text message box. | |
| certificateConfig | No | Completion and certificate settings as ONE object that REPLACES the stored one: keys you leave out are deleted, and null clears it (no certificate, reading gate off). course_get and course_list do not return it, so send it only when you know every key to keep, as on a course you just created, which holds exactly {readingGate: {enabled: true}}. Keys include readingGate {enabled, wordsPerMinute (default 200), minSeconds (20), maxSeconds (600)}, the minimum reading time before a text unit counts as complete; completionRule {type: "all_content" (default), "quiz_passed" or "progress_pct" with minProgressPct (default 80)}, what completes the course; and the certificate, issued on completion only when statementPrefix is set (codes count up from nextSeq; templateKind "builtin" by default, or "pdf" with templateUrl; validityMonths; ceus). | |
| discussionEnabled | No | Enable the per-course discussion forum. | |
| enrollmentEndDate | No | Enrollment closes, ISO 8601. null clears. | |
| isSyllabusVisible | No | Show the syllabus/outline to visitors who are not enrolled. | |
| accessDurationDays | No | Days of access from enrollment (integer): each NEW enrollment gets expiresAt = enrolledAt + N days, while existing enrollments keep their current expiry. null = unlimited. Distinct from `duration`. | |
| isVisibleInCatalog | No | Show the course in the public catalog (it is listed only if it also has a slug). | |
| enrollmentStartDate | No | Enrollment opens, ISO 8601. null clears. | |
| requiresApplication | No | Require learners to apply and be approved instead of enrolling instantly. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the destructiveHint=true annotation: it states scalar fields patch while null clears nullable ones, lists are replaced whole, an invalid value rejects the call and leaves the course unchanged (atomicity), saves land in the change log, and no emails or webhooks fire. It also warns that certificateConfig replaces the stored object so omitted keys are deleted, which is exactly the kind of destructive nuance an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then semantics, then constraints, with zero filler sentences; each clause carries distinct information. It is a single dense run-on paragraph, though, which makes the individual rules harder to scan than a short bulleted structure would.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 31-parameter, deeply nested mutation tool this covers the essentials: patch semantics, replacement semantics, atomic failure behavior, side effects, change-log behavior, and the return shape ('same shape as course_get'). With no output schema, it still tells the agent what comes back and what the shared mutable prerequisites are.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the 31 parameters are already documented and this is the baseline-3 case. The description restates the patch-vs-replace rule and the accessDurationDays-to-new-enrollments caveat, but those points are also present in the schema, so it adds little parameter meaning beyond the structured fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb+resource (update a course's settings) and enumerates the field families covered, from catalog text and pricing to instructors, prerequisites, application form and certificateConfig. It also carves out what this tool is NOT (lessons belong to course_content_set), so an agent can separate it from siblings like course_content_set and enrollment_update.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes two adjacent tasks to the correct siblings ('replace them with course_content_set', 'change existing learners' expiry with enrollment_update') and points to course_get with includeConfig:true as the way to read current list values before replacing them. There is no explicit statement of when this tool should be chosen over course_create, but the update/create distinction is self-evident.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
course_version_listList course revisionsARead-onlyInspect
List a course's saved content versions, newest first, as metadata only: version number, createdAt, updatedAt and blockCount (plus authorName when the key also holds members:read). Use it to find an earlier version to inspect or restore, then read that version's blocks with course_content_get(version:N); to read the current lessons you do not need it, since course_content_get returns them by default. The first row is the current version, so limit:1 tells you its number and when it was saved. Every save adds a version and none are pruned: page back from the newest by raising offset in steps of limit. Returns {courseId, total, count, versions}. To restore a version, save its blocks with course_content_set; that adds a new version and keeps the history.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Course id. | |
| limit | No | Max versions to return (default 25; values above 50 are capped at 50). | |
| offset | No | Versions to skip, counting from the newest (default 0). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/not-destructive, and the description adds substantial behavior: authorName appears only with members:read, versions are never pruned, every save adds one, the first row is the current version, and paging works by raising offset in limit-sized steps. It also discloses the return shape, going beyond the safety profile the annotations carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded with the core purpose, and nearly every clause carries actionable detail (return fields, ordering, paging, restoration). Some sentences are long and packed, slightly straining readability but without wasted content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by stating the return object ({courseId, total, count, versions}) and the per-row fields, plus ordering and pagination semantics. An agent has everything needed to call and interpret it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3, but the description adds real meaning by explaining that limit:1 yields the current version number and save time, and that offset should be raised in steps of limit to page backward.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: lists a course's saved content versions, newest first, metadata only. It enumerates the returned fields and name-checks the sibling (course_content_get) used to read blocks, so an agent can distinguish it from related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes usage: use it to find an earlier version to inspect or restore, then call course_content_get(version:N); and it states when NOT to use it ('to read the current lessons you do not need it'). Restoration path via course_content_set is also named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enrollment_bulk_createBulk enroll learnersADestructiveInspect
Enroll up to 100 learners in one course in a single call, under the same rules as enrollment_create (accounts found or created, prerequisites checked unless skipped, no email unless sendInvite:true); use enrollment_create for one learner or to pass redirectTo or externalReference. Learners are processed one at a time: an invalid email or unmet prerequisites fails only that learner, so the call can partly succeed, but an unexpected server error stops the batch with no per-learner results (learners enrolled before it stay enrolled, so re-run the call). Already-enrolled learners keep their enrollment (created:false, status label reset to "completed"), so a retry duplicates nothing, though it re-sends invites when sendInvite is on and replaces earlier sign-in links. Returns "Enrolled N, failed M" and a result per learner (email, ok, created, emailSent, magicLinkUrl, enrollment; or error and missingPrerequisites); if every learner fails, the call errors with those results. Get course ids from course_list.
| Name | Required | Description | Default |
|---|---|---|---|
| emails | No | Learner emails, 1 to 100. Use this OR learners. | |
| courseId | Yes | Id of a course on this site (required). For a course linked to Open edX this creates only Cubite enrollments, not the learners' Open edX ones. | |
| learners | No | Learners with display names, 1 to 100. Use this OR emails; if both are sent, learners is used. | |
| sendInvite | No | Have Cubite email each learner a one-click sign-in invite (or the plain enrolment email when no link can be issued). Default false; each result carries emailSent. | |
| issueMagicLink | No | Return a single-use 24-hour sign-in link per learner as magicLinkUrl (default true; null for admins, password accounts and people on other Cubite sites). Each one cancels that learner's earlier link. Ignored when sendInvite is true. | |
| skipPrerequisiteCheck | No | Enroll even if the course has unmet prerequisites (default false); otherwise those learners fail with missingPrerequisites. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already flagging destructiveHint=true, the description adds rich behavior beyond them: per-learner partial-failure semantics, that an unexpected server error aborts the batch with no per-learner results but prior enrollments persist, that already-enrolled learners keep enrollment with created:false while invites are re-sent and sign-in links replaced, and that a full-failure batch errors. This is substantial disclosure well beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single dense paragraph but well front-loaded: purpose first, then the sibling alternative, then failure/retry behavior, then return shape. Every clause carries operational meaning, though the length pushes the limit of tightness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully explains the return value ('Enrolled N, failed M' plus per-learner fields and the all-failed error case), and it covers idempotency, retry safety, and prerequisite behavior. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds cross-parameter meaning not in the schema: that sendInvite suppresses email unless true, that it overrides issueMagicLink, and that emails/learners follow the same account-creation and prerequisite rules as enrollment_create. This is genuine added value on top of a fully documented schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource+scope ('Enroll up to 100 learners in one course in a single call') and explicitly contrasts itself with the sibling enrollment_create, naming the exact conditions that select the other tool (one learner, redirectTo, externalReference). An agent can differentiate it from enrollment_create without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use-this vs when-to-use-the-alternative guidance: 'use enrollment_create for one learner or to pass redirectTo or externalReference.' It also notes the cap of 100 and the course-id source (course_list), leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enrollment_createEnroll learnerADestructiveInspect
Enroll one learner in a course by email, finding or creating their account (new accounts are passwordless students on this site); use enrollment_bulk_create for many learners, and application_review to approve someone who applied. Price, the application requirement and enrollment dates are not checked; prerequisites are checked for a new enrollment unless skipPrerequisiteCheck:true, and an account is still created when they refuse it. Cubite emails no one unless sendInvite:true; by default you get magicLinkUrl, a single-use sign-in link for your own welcome email. A new enrollment gets the status label "completed" and the course's access period, and fires the site's enrollment.created webhook. Use it to add enrollments; to change an existing one, use enrollment_update. Calling it for a learner who is already enrolled creates nothing new (created:false) and keeps the expiry and waitlist flag, but resets the status label to "completed". Returns {enrollment, user, magicLinkUrl, created, emailSent, externalReference}. Get course ids from course_list.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Display name for a NEW account (default: the part of the email before @); an existing user's name is not changed. | |
| Yes | Learner email (required), matched case-insensitively to an existing account; a new email creates one. | ||
| courseId | Yes | Id of a course on this site (required). For a course linked to Open edX this creates only the Cubite enrollment, not the learner's Open edX one. | |
| redirectTo | No | Path on this site to open after sign-in, starting with "/" (e.g. "/course/<slug>/courseware", the lessons). Anything else is ignored and the learner lands on their dashboard. Use the courseware path for a paid course: this call records no payment, so the learner's dashboard card and the course page still show a checkout button. | |
| sendInvite | No | Have Cubite email the learner itself: a one-click sign-in invite (7-day link, lands on redirectTo, also returned as magicLinkUrl) when a link can be issued, otherwise the plain course-enrolment email. Default false. The site can turn these emails off; the response's emailSent says whether an email went out. It also emails a learner who is already enrolled, e.g. someone you just let in off the waitlist with enrollment_update. | |
| issueMagicLink | No | Return magicLinkUrl, a single-use sign-in link valid for 24 hours (default true). Minting it cancels any earlier link for this email. It is null when the person has a password, is an admin, or belongs to another Cubite site. Ignored when sendInvite is true. | |
| externalReference | No | Your own correlation value, echoed back unchanged in the response; not stored. | |
| skipPrerequisiteCheck | No | true enrolls even if the course's prerequisites are not met (default false); otherwise unmet prerequisites fail the call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses that an account is still created even if the user declines, that prerequisites are enforced unless skipPrerequisiteCheck:true, the exact default email behavior (nothing sent unless sendInvite:true), that magic links are single-use/24h and minting cancels earlier links, the duplicate-enrollment side effect (no new record, created:false, but status label reset to "completed"), and the enrollment.created webhook. This is unusually rich side-effect disclosure for a destructive write tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and zero filler sentences, but it is one dense run-on paragraph where semicolon-joined clauses blend usage guidance, side effects, and return values. It would read better split into use-when / behavior / returns groupings, though nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by enumerating the return shape ({enrollment, user, magicLinkUrl, created, emailSent, externalReference}) and explaining key values like created:false and emailSent. Combined with the side-effect coverage, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds cross-parameter behavior not in the schema: sendInvite overrides issueMagicLink, the magic link is what you use for your own welcome email, and no payment is recorded so checkout still shows. These interactions meaningfully extend the per-field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first clause states a specific verb+resource (enroll one learner in a course by email) and immediately scopes it against siblings: enrollment_bulk_create for many learners, application_review for approvals. An agent can distinguish this from enrollment_update and enrollment_bulk_create without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit alternatives are named with the condition that selects each: bulk create for many learners, application_review to approve an applicant, enrollment_update to change an existing enrollment. It also states what is NOT validated (price, application requirement, enrollment dates) and where to get course ids (course_list).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enrollment_listList enrollmentsARead-onlyInspect
List enrollment records on this site, newest enrollment first: who is enrolled or waitlisted in which course, and how far along they are. Narrow it to one learner by email or userId (every course they are in, or with courseId their single enrollment; an unknown email returns an empty list), by course, by exact status label, or to the waitlist queue (waitlisted:true) or everyone off it (waitlisted:false); status:"pending" with waitlisted:false finds enrolled learners who still see an enrollment step instead of Start/Continue (for example, ones unlocked from the waitlist in the dashboard). Course applications awaiting a decision are not enrollments: see application_list. Each row has courseId, userId, status, isWaitListed, enrolledAt, expiresAt, user {id, name, email, username}, progressPercentage (0 if not started) and completedAt (set when the learner first completes the course). Returns {total, enrollments}; page with offset until it reaches total. To change or revoke one learner's enrollment, pass their email straight to enrollment_update or enrollment_revoke.
| Name | Required | Description | Default |
|---|---|---|---|
| No | Only this learner's enrollments, by account email (case-insensitive). An email with no account or no enrollment on this site returns an empty list. | ||
| limit | No | Max rows (default 100; values above 500 are capped at 500). | |
| offset | No | Rows to skip (default 0); compare with total to page. | |
| status | No | Only rows with exactly this status label, e.g. "completed" (API enrollments, approved applications and payments; the only label that gives learners the Start/Continue button), "pending" (a learner who joined a waitlist, or one the dashboard added or unlocked) or "active" (learning-path enrollments). The label is about the enrollment, not course completion (see progressPercentage and completedAt). | |
| userId | No | Only this learner's enrollments, by user id (user.id in the rows). | |
| courseId | No | Only enrollments in this course (must be on this site). Combine with email or userId to get one learner's enrollment in it. | |
| waitlisted | No | true = only waitlisted learners; false = only learners off the waitlist; omit for both. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only safety profile, and the description adds substantial behavior beyond that: default sort order, the empty-list outcome for an unknown email, the pagination contract ({total, enrollments}, page with offset until total), the row field list, and the non-obvious semantics of the "pending" status label relative to waitlist unlocking.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and default ordering are front-loaded, and nearly every clause carries information. The middle section is a dense single paragraph of semicolon-chained filter cases, which is harder to scan than a short list would be, but nothing is truly wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries that burden and does so: it enumerates row fields, states the envelope shape and pagination method, and warns that an unmatched email returns an empty list rather than an error. Nothing needed to call this tool correctly appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the per-parameter baseline is 3; the description goes further by explaining cross-parameter behavior the schema cannot (email/userId + courseId yields the learner's single enrollment, status:"pending" with waitlisted:false isolates unlocked learners) and that status means the enrollment, not course completion.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("List enrollment records on this site"), names the default ordering (newest first), and characterizes the rows (who is enrolled or waitlisted in which course, and progress). It is immediately distinguishable from the sibling mutators enrollment_create/update/revoke and from application_list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: applications awaiting decision are not enrollments and should use application_list, and single-learner changes belong to enrollment_update or enrollment_revoke. It also spells out the when-to-use condition for each filter combination (email/userId with or without courseId, waitlisted true/false, status:"pending" + waitlisted:false).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enrollment_revokeRevoke enrollmentADestructiveInspect
Revoke one learner's enrollment in a course: the enrollment record is deleted and their access ends (a waitlisted learner leaves the waitlist); to change an expiry, waitlist place or status label instead, use enrollment_update. Revoking ends access without deleting the learner's history: their progress, graded work and any issued certificate are kept, so re-enrolling them later with enrollment_create restores access with that history. No email is sent, and the account and its site membership stay. Identify the learner by email or userId, as shown in enrollment_list rows; a learner who is not enrolled in that course is a not-found error. Returns the text "Enrollment revoked." Get course ids from course_list.
| Name | Required | Description | Default |
|---|---|---|---|
| No | Learner email; pass this or userId. | ||
| userId | No | Learner user id; pass this or email (userId wins if both are sent). | |
| courseId | Yes | Course id (required). For a course linked to Open edX this removes only the Cubite enrollment, not the learner's Open edX one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give destructiveHint=true; the description goes well beyond by disclosing exactly what is destroyed (the enrollment record, the waitlist place) and what is preserved (progress, graded work, issued certificates, the account and site membership). It also states the side-effect profile: no email is sent, and the exact return text.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action and its consequences before the routing alternatives and identifier guidance. It is one dense paragraph rather than scannable fragments, but nearly every clause carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still supplies the return value ('Enrollment revoked.'), the error case, and the full side-effect envelope. Nothing an agent needs to call this mutation safely is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds sourcing context the schema lacks: identify the learner by email or userId 'as shown in enrollment_list rows' and get course ids from course_list. It does not restate the userId-wins precedence beyond what the schema already covers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (revoke one learner's enrollment in a course) and immediately distinguishes itself from the two nearest siblings: enrollment_update for changing expiry/waitlist/status and enrollment_create for re-enrolling. An agent can route correctly without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names alternatives and the conditions selecting them ('to change an expiry, waitlist place or status label instead, use enrollment_update'; re-enrolling later with enrollment_create). It also states the not-found condition for a learner who is not enrolled, and points to enrollment_list and course_list for obtaining identifiers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enrollment_updateUpdate enrollmentADestructiveInspect
Change one existing enrollment in place, keeping it and the learner's progress: set or clear its access expiry, move the learner off or onto the waitlist, or relabel its status. Use it for every change to an enrollment that exists; to add one use enrollment_create, to remove one enrollment_revoke. Identify the learner by email or userId; a learner not enrolled in that course is a not-found error, and omitted fields stay unchanged. To let a waitlisted learner in, send isWaitListed:false with status:"completed": self-waitlisted learners hold "pending", and learner pages show Start/Continue only for "completed". No email is sent. Returns the updated enrollment {courseId, userId, status, isWaitListed, enrolledAt, expiresAt, user}.
| Name | Required | Description | Default |
|---|---|---|---|
| No | Learner's email; pass this or userId. | ||
| status | No | Free-text status label, stored as given (trimmed, cut to 64 chars); Cubite itself writes "completed", "pending" or, for learning-path enrollments, "active". Learner pages give the Start/Continue button only to "completed" (on a paid course, only once the learner has paid); with any other label the dashboard card and the course page show an enrollment step instead ("Start Now", "Complete Enrollment" or checkout). Omit it to keep the current label. | |
| userId | No | Learner's user id; pass this or email (userId wins if both are sent). | |
| courseId | Yes | Course id (required). For a course linked to Open edX this changes only the Cubite enrollment; to also enroll a waitlisted learner in Open edX, use the dashboard's Unlock button. | |
| expiresAt | No | New access expiry as an ISO 8601 date string (e.g. "2026-12-31"); null removes the expiry (never expires); omit to leave it unchanged. | |
| isWaitListed | No | false promotes the learner off the waitlist; true moves them back onto it. Either way the status label stays as it is unless you also send status. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnlyHint=false, and the description adds context the annotations cannot: mutations are in place and preserve learner progress, omitted fields stay unchanged, a non-enrolled learner yields a not-found error, and no email is sent. It also discloses the return payload shape, which is significant given there is no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then alternatives, then semantics, with no filler sentences. It is dense and long for a single tool, but each clause (waitlist mechanics, no-email behavior, return shape) carries information an agent needs, so the length is largely earned.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description compensates by listing the returned enrollment fields (courseId, userId, status, isWaitListed, enrolledAt, expiresAt, user). Combined with annotation-covered safety and explicit error behavior, nothing needed to invoke this mutation correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real value beyond the schema: it explains that identity is email or userId, that omitted fields are unchanged, and the non-obvious interaction of isWaitListed:false with status:"completed" to surface Start/Continue. It stops short of documenting any edge semantics the schema already owns.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Change one existing enrollment in place') and enumerates the three mutable aspects: access expiry, waitlist membership, and status label. It directly distinguishes itself from enrollment_create and enrollment_revoke by naming both siblings, so an agent can select it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing: 'Use it for every change to an enrollment that exists; to add one use enrollment_create, to remove one enrollment_revoke.' It also names the waitlist-promotion idiom (isWaitListed:false with status:"completed") and the prerequisite that the learner must be enrolled, covering when-not (not-found error) and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetchFetch a search resultARead-onlyInspect
Read one result found via search as plain text with its public page URL, for quoting or citing it in an answer; this is the fetch half of the search/fetch pair. Pass the result's id exactly as search returned it (e.g. "course:..."). Returns {id, title, text, url, metadata}. A course's text is its public catalog summary (name, description, level, duration in hours, price, subjects, topics), not its lessons. A missing document, another site's content, and a type this connection cannot read all return the same not-found error; an id without a type prefix is rejected as invalid. To work with a course rather than quote it, use course_get for its settings record (ids, flags, dates, enrollment count) and course_content_get for its lessons as EditorJS blocks.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | A document id exactly as `search` returned it, including its type prefix. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | The document id that was fetched. |
| url | Yes | Public URL (used for citations). |
| text | Yes | Full readable text of the document. |
| title | Yes | Document title. |
| metadata | No | Extra key/value details (entity type, dates). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, non-destructive, non-open-world), and the description adds behavior the annotations cannot: the exact return shape, the error-collapsing rule (missing doc, foreign site, unreadable type all yield the same not-found), the invalid-id rejection, and that a course's text is the catalog summary rather than its lessons.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose then progressively adding format, return, error, and alternative guidance — each sentence carries information. Slight redundancy in restating the return shape `{id, title, text, url, metadata}` when an output schema already exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, parameter format, return content, error semantics, and sibling routing. With an output schema present, no further explanation of return values is required, so nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents `id`. The description still adds real value: it must be passed exactly as search returned it, needs the type prefix, and a prefix-less id is rejected as invalid — format constraints beyond the schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (read one result) plus resource (a result previously found via `search`) and names the pair relationship with `search`. It also distinguishes itself from the course-oriented siblings by framing output as plain text with a public page URL for quoting/citing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly gives the when ('for quoting or citing it in an answer') and the when-not with named alternatives: 'To work with a course rather than quote it, use course_get ... and course_content_get for its lessons.' The agent has a clear routing rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchSearch site contentARead-onlyInspect
Search this Cubite site's courses by keyword and get each match's public page URL, for linking to or citing it. This is the search half of the search/fetch pair that ChatGPT connectors and deep research require. The whole query is matched as one case-insensitive phrase, so use one or two distinctive words. Courses match on name or description and are listed in name order; a course without a URL slug has no public page and is never returned, while courses hidden from the catalog are. Returns up to 10 results as {id, title, url}; pass a result's id to fetch for its citable text. It is not an inventory: to list, count or manage courses use course_list, which has no keyword filter but returns every course, with or without a slug, with its id, settings and enrollment count.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Word or short phrase to find in titles and descriptions, matched as one case-insensitive substring (max 200 characters; longer input is cut). |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavior beyond the read-only annotations: matching is a case-insensitive phrase against course names and descriptions, results are ordered by name, courses without slugs are omitted, catalog-hidden courses are included, and at most 10 results are returned. It also discloses the exact return shape and next-step handoff to `fetch`.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well structured, leading with purpose and then layering pairing, matching rules, result behavior, and sibling alternatives. Every sentence contributes actionable information for an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple one-parameter schema, available output schema, and read-only annotations, the description covers everything needed: purpose, matching rules, result limits, edge cases, return shape, and next steps. No critical calling context is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents the `query` parameter. The description still adds useful matching semantics and practical guidance about using one or two distinctive words, though it does not add new formal parameter constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: it searches this Cubite site's courses by keyword and returns public page URLs. It also explicitly distinguishes itself from the sibling `course_list` tool, which is for listing rather than keyword search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains exactly when to use this tool: for linking to or citing courses, as the search half of the search/fetch pair, and advises using one or two distinctive words. It also names the alternative `course_list` for inventory-style listing and `fetch` for retrieving citable text from a result.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
- Changed
enrollment_list3 fields changed- changed
Input schema / properties / courseId / descriptionPrevious value: -"Only enrollments in this course (must be on this site). Rows cannot be filtered by learner: to check one learner, pass their course and match user.email."New value: +"Only enrollments in this course (must be on this site). Combine with email or userId to get one learner's enrollment in it." - added
Input schema / properties / emailAdded value: +{ + "description": "Only this learner's enrollments, by account email (case-insensitive). An email with no account or no enrollment on this site returns an empty list.", + "type": "string" +} - added
Input schema / properties / userIdAdded value: +{ + "description": "Only this learner's enrollments, by user id (user.id in the rows).", + "type": "string" +}
24 tool updates
- Added
application_list - Added
application_review - Added
block_type_list - Removed
blog_list_blocks - Added
course_content_get - Added
course_content_set - Added
course_create - Added
course_delete - Added
course_duplicate - Added
course_get - Added
course_list - Added
course_update - Added
course_version_list - Removed
email_template_get - Removed
email_template_list - Added
enrollment_bulk_create - Added
enrollment_create - Added
enrollment_list - Added
enrollment_revoke - Added
enrollment_update - Added
fetch - Removed
homepage_get - Added
search - Removed
site_get
5 tool updates
- First observed
blog_list_blocks - First observed
email_template_get - First observed
email_template_list - First observed
homepage_get - First observed
site_get
Related MCP Connectors
Build, publish and track interactive micro-courses, quizzes and learner analytics.
Build, publish and track embedded training courses in your product: courses, learners, SCORM.
AI-powered LMS course builder: 89 tools, 17 skills, SCORM/xAPI export, agentic UI
Read Axis LMS users, courses, learning paths, certifications and reports; manage enrollments.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceBuilds SCORM 2004 compliant e-learning courses locally with automated packaging and data privacy.1MIT
- AlicenseNot gradedqualityAmaintenanceEnables users to manage courses, assignments, enrollments, grades, account administration, reports, and student/instructor workflows through the Canvas LMS API.21 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables students, instructors, and account administrators to interact with Canvas LMS through its API, supporting course and assignment management, submissions, grading, enrollments, discussions, quizzes, files, reports, and account administration.21 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables users to manage courses, assignments, enrollments, grades, users, reports, discussions, quizzes, and files through the Canvas LMS API, with support for student, instructor, and account-administrator workflows.21 npmMIT
Glama MCP Gateway
Add one secure layer between your agents and this server.