Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
CANVAS_BASE_URLYesCanvas instance URL (e.g., https://school.instructure.com)
CANVAS_API_TOKENYesCanvas personal access token
CANVAS_PSEUDONYM_DIRNoAbsolute path that overrides the default pseudonym map directory
CANVAS_ALLOWED_ORIGINNoCORS origin for HTTP mode (default: http://localhost:3000)
CANVAS_PSEUDONYM_AUDIT_LOGNoPath to an append-only file that mirrors resolve_pseudonym audit lines
CANVAS_PSEUDONYMIZE_STUDENTSNoSet to 'true' to enable FERPA mode student pseudonymization
CANVAS_PSEUDONYMIZE_REVERSE_LOOKUPNoSet to 'true' (with CANVAS_PSEUDONYMIZE_STUDENTS=true) to register the resolve_pseudonym audit tool

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}
prompts
{
  "listChanged": true
}
resources
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
health_checkA

Check if the Canvas API is reachable and the token is valid. Returns ok/error status.

list_coursesA

List courses for the authenticated user. Use fields="slim" when enumerating courses for selection; switch to "full" once you have identified the target. slim returns id, name, course_code, term name, and workflow_state only. "full" (default) includes all Canvas fields plus include extras (teachers, total_students, syllabus_body, etc.). state[] narrows by course workflow state; enrollment_state narrows by the caller's enrollment state.

get_courseA

Get details for a single course. Defaults to requesting term and total_students. Pass include to replace the default set with custom Canvas include[] fields (teachers, permissions, syllabus_body, sections, etc.).

get_syllabusA

Get just the syllabus HTML body for a course, returning { course_id, syllabus_body } where syllabus_body is null if the course has none set. Use get_course with include: ['syllabus_body'] instead when you also need other course fields in the same call, or update_course to change the syllabus body. If the course has public_syllabus or public_syllabus_to_auth enabled, the body may be readable even by callers without an enrollment in the course.

list_sectionsA

List the sections of a course, returning each section's id, name, course_id, start_at, end_at and restrict_enrollments_to_section_dates. Use it to resolve the section ID that create_assignment_override needs for a section-specific due date, that enroll_user takes as course_section_id, and that the needs_grading_count_by_section option on list_assignments reports against; use list_course_enrollments or list_course_users for the people in a section rather than the sections themselves, or get_course with include: ['sections'] when you also need other course fields in the same call. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. This tool never requests Canvas's student roster include, so no student names are returned. The SIS fields (sis_section_id, sis_course_id, integration_id) appear only for callers with SIS read permission, and Canvas silently drops the total_students and permissions extras — rather than erroring — unless the caller can read the course roster or grades. search_term must be at least 2 characters; Canvas ignores shorter ones. Requires read access to the course.

create_courseA

Create a new course in a Canvas account and return the created Canvas course object (id, name, course_code, workflow_state, and the fields passed in). Not idempotent: calling it again with the same name creates a second, separate course rather than reusing or updating the first — use update_course afterward to change it, or list_courses first to check whether a matching course already exists. Canvas silently drops start_at and end_at unless the course also restricts enrollment to course dates, which this tool does not expose, so the dates you pass may not take effect; set them with update_course if they don't. Requires the account-level permission to create courses.

update_courseA

Update an existing course and return the updated Canvas course object. Only the fields you pass are changed; omitted fields are left as-is, and calling it again with the same values leaves the course in the same state (idempotent). Requires permission to update course details; a caller who has only that lesser permission (not full course update rights) can still change syllabus_body through this same call, but every other field they pass is silently dropped rather than erroring. Use create_course for a new course, or get_course to see the current values before changing them.

list_assignmentsA

List all assignments in a course. Use fields="slim" when enumerating assignments for selection; switch to "full" once you've identified the target. slim returns id, name, due_at, points_possible, published, and course_id only. "full" (default) includes all Canvas fields plus include extras (submission, all_dates, overrides, score_statistics, etc.). Use bucket to filter by past/upcoming/overdue/etc. Other filters: search_term, assignment_ids, order_by.

get_assignmentA

Get the full assignment record for one assignment by ID, including every include extra requested. Get the assignment_id from list_assignments, which also supports fields="slim" for scanning many assignments before fetching one here in full. include adds submission (the current user's own), assignment_visibility, overrides, observed_users, can_edit, and score_statistics — each omitted from the response unless requested.

list_assignment_groupsA

List assignment groups (categories like Homework, Exams) in a course. Use include=assignments to nest assignments under each group; other includes add submission, overrides, score_statistics, etc.

create_assignment_groupA

Create a new assignment group (a gradebook category such as Homework or Exams) in a course and return the created Canvas assignment group object, including its id, name, position and group_weight. Not idempotent: each call makes another group even when the name matches an existing one, so read list_assignment_groups first and use update_assignment_group to change a group that already exists; the new group starts empty, and assignments move into it through create_assignment or update_assignment's assignment_group_id. group_weight is the group's percent of the final grade, and it changes nothing unless the course is set to weight its final grade by assignment group — a course setting update_course can turn on. Canvas coerces a missing or non-numeric group_weight to 0. Drop rules are deliberately not accepted here: Canvas validates them against the number of active assignments in the group, which is 0 for a group that does not exist yet, so set them with update_assignment_group once the group has assignments. Requires permission to manage assignments in the course.

update_assignment_groupA

Update an existing assignment group in a course and return the updated Canvas assignment group object. Only the fields passed are changed — anything omitted keeps its current value, so repeating the same call leaves the group in the same state, unlike create_assignment_group, which always makes a new group. Use it to repair a weighted gradebook: group_weight sets the group's percent of the final grade (which changes nothing unless the course is set to weight its final grade by assignment group — a course setting update_course can turn on), and rules drops the lowest or highest scores in the group, with never_drop exempting specific assignments. Canvas rejects a drop rule larger than the number of active assignments in the group, and refuses a group_weight or rules change with an authorization error — not a validation error — when any assignment in the group falls inside a closed grading period, unless the caller is an account admin. Read list_assignment_groups for the current values and the group ID first. Requires permission to manage assignments in the course.

create_assignmentA

Create a new assignment in a course and return the created assignment object. Each call creates another assignment — Canvas assigns a new ID every time, so check list_assignments with a search_term first to avoid duplicates. Use update_assignment to change an existing assignment instead of calling this again, and delete_assignment to remove one. due_at, lock_at, and unlock_at here apply to every student; to give a different date to a subset of students, a section, or a group, use create_assignment_override instead, or set_student_assignment_dates to fan a date change for one student across many assignments. Dates are ISO 8601 strings; lock_at must be after due_at and unlock_at before due_at when both are set. Requires instructor/TA permission to manage assignments and quizzes in the course.

update_assignmentA

Update an existing assignment in a course, changing only the fields you pass — anything omitted keeps its current value — and return the updated assignment object. Calling this again with the same arguments leaves the assignment in the same state, unlike create_assignment, which always makes a new one; use delete_assignment to remove this assignment instead. due_at, lock_at, and unlock_at set here apply to every student without an override; use create_assignment_override for a different date for one section, group, or set of students, or set_student_assignment_dates to fan one student's date change across many assignments at once. lock_at must stay after due_at and unlock_at before due_at when both are set. Requires instructor/TA permission to manage assignments and quizzes in the course.

delete_assignmentA

Permanently delete an assignment from a course; this cannot be undone. Returns no assignment object, only an acknowledgement that the deletion succeeded. Use update_assignment instead to change the assignment rather than remove it, or create_assignment afterward to make a new one — Canvas assigns it a new ID rather than reusing the deleted one. Requires instructor/TA permission to manage assignments and quizzes in the course.

list_submissionsA

List all submissions for an assignment. Use include to attach user, assignment, rubric_assessment, submission_history, or visibility. Filter with student_ids, workflow_state, or grading_period_id. Defaults to including submission_comments.

get_submissionA

Get one student's submission for an assignment by user_id, returning the Canvas submission object (score, grade, workflow_state, submitted_at, body/url, submission_comments). user_id can be any user in the course, not only the caller's own. Use list_submissions to fetch every student's submission for the assignment in a single call instead of one get_submission call per student, or get_my_submissions when the caller wants their own submissions across a whole course rather than one assignment. Defaults to including submission_comments; pass include to add submission_history, rubric_assessment, visibility, course, user, or read_status instead.

grade_submissionA

Post or update the grade for one student's submission on a regular assignment and return the updated Canvas submission object (score, grade, workflow_state, graded_at). Only grade is sent; nothing else on the submission changes. Idempotent: calling it again with the same grade string overwrites the previous posted_grade rather than creating a second grade. This sets only the top-level grade — for a rubric-based assignment use submit_rubric_assessment to score each criterion instead, and for a Classic Quiz use score_quiz_question to grade one question at a time rather than the assignment as a whole. Requires grading permission in the course.

comment_on_submissionA

Add a text comment to a submission and return the updated Canvas submission object, with the new entry appended to submission_comments. Not idempotent: each call posts another comment rather than editing or replacing a prior one, so a retried call leaves duplicate comments behind instead of one. This only adds a comment — it never changes grade or score; use grade_submission for that, on the same course_id/assignment_id/user_id. Use list_submission_comments_needing_attention to find submissions where the student's most recent comment has not yet been answered by staff. Permission is looser than grade_submission's: the submission's own student and any peer reviewer assigned to it can comment without grading rights; anyone who can grade can also comment.

list_course_submission_filesA

List every file attachment submitted by students across all assignments in a course. Returns a manifest — one entry per file — including the original filename, a file_id for re-fetching via download_file, content type, and size. Useful for bulk-archiving student work before a course expires or a Free-For-Teacher account is concluded. Outputs are bounded by max_files (default 500); when the limit is hit, truncated is true and truncation_note explains how to retrieve the rest. Download URLs are time-limited (typically 1 hour) — use the returned file_id with download_file to get a fresh URL at download time. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, user_name is a stable per-course pseudonym (e.g. "Student 1"); user_id (the raw numeric Canvas ID) is always returned and works as a stable per-student folder key.

list_submissions_awaiting_gradingA

Lists all submissions in a course that still need a human grade, sorted oldest-waiting first.

Surfaces two categories:

  • workflow_state=submitted: assignments submitted by students but not yet graded at all.

  • workflow_state=pending_review: Classic Quiz submissions where Canvas auto-graded the objective questions but left essays or manually-scored questions for the instructor.

Returns a triage list grouped by assignment or Classic Quiz, with per-submission details: student identity, workflow state, submitted_at, and whether the submission has pending manual-grading questions.

Parameters:

  • course_id (required): Canvas course ID to scan.

  • assignment_ids (optional): limit the scan to specific assignment IDs.

  • include_quizzes (default true): include Classic Quiz assignments in the scan.

  • include_assignments (default true): include non-quiz assignments.

  • only_pending_review (default false): when true, return only pending_review submissions (quiz essays awaiting manual scoring), omitting regular ungraded assignments.

Known limitations:

  • New Quizzes (Quizzes.Next) may not appear with 'pending_review' workflow state here; use SpeedGrader or the New Quizzes interface for their grading queue.

  • Fill-in-the-blank answers that Canvas auto-marked are not surfaced.

  • V1 returns submission-level state only; per-question detail is not included.

  • When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, student names are replaced with pseudonyms. Use resolve_pseudonym to look up the real identity.

list_rubricsA

List every rubric defined in a course, returning each rubric's title, points_possible, and criteria/ratings. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use get_rubric to fetch one rubric by ID once you have it, get_rubric_assessment for a specific student's completed assessment rather than the rubric definition, or create_rubric to add a new one. Requires the manage_rubrics permission in the course, so most students cannot call this.

get_rubricA

Get a single rubric's definition (title, points_possible, criteria, and rating levels) by ID. Use list_rubrics to find the rubric_id for a course first. Pass include=["assignment_associations"] to also retrieve the rubric association IDs that submit_rubric_assessment needs, or include=["assessments"|"graded_assessments"|"peer_assessments"] for assessor_id-only assessment summaries (no assessor name is returned). This returns the rubric's structure, not any one student's completed assessment — use get_rubric_assessment for that. Requires the manage_rubrics permission in the course, so most students cannot call this.

get_rubric_assessmentA

Get one student's submission for an assignment with the Canvas rubric_assessment attached, keyed by criterion_id (rating_id, comments, points per criterion) — this does not carry the assessor's name or any grader identity. This is the same full submission object (score, grade, workflow_state, submitted_at) that get_submission returns, requested here with include[]=rubric_assessment instead of get_submission's default submission_comments; use get_submission when you also need comments or the submitted text/URL. Use submit_rubric_assessment to post a rubric assessment for a student rather than read one back.

submit_rubric_assessmentC

Submit a rubric assessment with scores and comments for each criterion.

create_rubricA

Create a new rubric in a course with criteria and rating levels. Optionally link it to an assignment immediately. Returns { rubric, rubric_association? }; when an assignment association was requested, rubric_association.id is the association_id that submit_rubric_assessment takes.

attach_rubricA

Attach an existing course rubric to an assignment, so one rubric can be shared across many assignments instead of creating a duplicate per assignment with create_rubric. Returns the new rubric association.

delete_rubricA

Permanently delete a rubric from a course, removing it from every assignment it is attached to. Returns the deleted rubric.

list_quizzesA

List every quiz row in a course, including the New Quiz stub Canvas mixes into the same list (quiz_type: quizzes.next, with no question or submission detail of its own). Use quiz_type to tell Classic Quizzes (assignment, practice_quiz, graded_survey, survey) apart from New Quizzes, and list_new_quiz_items for a New Quiz's actual questions. Returns each quiz's title, quiz_type, points_possible, question_count, due_at and published state. Use get_quiz to fetch one quiz by ID, list_quiz_questions for its fixed questions, and list_quiz_submissions for student attempts. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating.

get_quizA

Get one quiz by ID, found with list_quizzes. If the ID belongs to a New Quiz, Canvas returns only its stub row (quiz_type: quizzes.next) — use list_new_quiz_items for the actual question content. Returns title, quiz_type, points_possible, question_count, due_at, published state, and assignment_id (the graded assignment Canvas created for this quiz; null for an ungraded survey or practice quiz). Use list_quiz_questions for a Classic quiz's fixed questions and list_quiz_submissions for student attempts.

list_quiz_submissionsA

List every submission (one row per student's attempt history) for a Classic quiz, including each submission's score, kept_score, workflow_state, and any extra_time / extra_attempts accommodation Canvas has recorded for that student. Find the quiz_id with list_quizzes or get_quiz. To see a submission's actual answers, use get_quiz_submission_answers for an in-progress attempt or get_quiz_question_responses for a submitted one; to change a score use score_quiz_question. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating.

list_quiz_questionsA

List the fixed questions defined on a Classic quiz — id, position, question_text, question_type, points_possible, and answers — in quiz order. This is the quiz's static question list only: it does not include the generated questions Canvas serves per attempt when a question-bank draw is configured, and it carries no student answer data. Find the quiz_id with list_quizzes or get_quiz. Use get_quiz_question_responses to see what each student was actually served and answered, including bank-drawn questions, and score_quiz_question to grade an answer. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating.

get_quiz_submission_answersA

Get a quiz submission's state for an IN-PROGRESS (untaken) attempt, including the student's live answer and flag per question. For a SUBMITTED attempt (complete or pending_review), Canvas never returns the answer value or a real flag state through this endpoint — only grading state (correct) is available here. To review a submitted attempt's actual answer text, use get_quiz_question_responses instead.

score_quiz_questionA

Set the score and an optional feedback comment for one question in one student's Classic quiz submission, overwriting any existing score for that question on the chosen attempt — it replaces the question's recorded score rather than adding to it, so calling again with the same score and comment leaves the submission unchanged. Omit attempt to score the latest attempt. Find submission_id with list_quiz_submissions and question_id with list_quiz_questions or get_quiz_question_responses. Returns { success: true }; Canvas does not hand back the updated submission to this endpoint. Requires grading permission in the course.

get_quiz_submission_eventsA

Get the event log for a Classic Quiz submission in chronological order. Events include session_started, question_answered, question_flagged, page_blurred, and page_focused. Use this to understand the timeline of a student's attempt. Classic Quizzes only — New Quizzes does not expose event logs via the Canvas REST API. Events are scoped to a single submission; Canvas enforces access permissions (instructors and the submitting student only). Do not use event logs as the sole basis for academic-integrity conclusions; present them with context.

delete_quizA

Permanently delete a Classic quiz from a course, including its questions and every student submission. Classic Quizzes only; use delete_new_quiz for a New Quiz (LTI).

delete_quiz_questionA

Permanently delete a single question from a Classic quiz. Classic Quizzes only; use delete_new_quiz_item for a New Quiz item.

create_new_quizA

Create a New Quiz (LTI) in a Canvas course. Returns the created quiz with its id, assignment_id, and current field values. New Quizzes is Canvas's current quiz engine; there is no tool here to create a Classic quiz — list_quizzes, get_quiz, and delete_quiz only read and delete that older type. After creating, add questions with create_new_quiz_item, change title, dates, or points with update_new_quiz, and remove the quiz with delete_new_quiz. Each call creates another quiz (not idempotent), so check list_quizzes before retrying. quiz_settings covers session behavior (calculator, shuffle, time limit, access code, one-at-a-time, and multiple_attempts); its multiple_attempts sub-object is replaced as a whole by Canvas, so a later update_new_quiz call must repeat every multiple_attempts sub-field you want to keep. IP-address access filtering and result_view_settings are not supported by this tool. Requires permission to manage quizzes in the course.

update_new_quizA

Update an existing New Quiz (LTI) in a Canvas course, found by its assignment_id (from list_assignments or get_assignment, filtered on is_quiz_lti_assignment, or from create_new_quiz — not a Classic Quiz ID). Only the fields you pass change; omitted fields keep their current value, so a repeated call with the same payload leaves the quiz unchanged. Pass null for due_at, unlock_at, or lock_at to clear that date. Returns the updated quiz (id, title, points_possible, due_at, unlock_at, lock_at, published, assignment_id). Use update_new_quiz_item to change an individual question instead of the quiz shell, and delete_new_quiz to remove the whole quiz. quiz_settings's flat fields (calculator, shuffle, time limit, access code, one-at-a-time) each change independently, same as the rest of this call, but its multiple_attempts sub-object is replaced as a whole by Canvas: passing { multiple_attempts: { max_attempts: 3 } } clears every other multiple_attempts sub-field (which score to keep, the cooling period, …) instead of leaving them as they were, so repeat every sub-field you want kept. IP-address access filtering and result_view_settings are not supported by this tool. Requires permission to manage quizzes in the course.

delete_new_quizA

Delete a New Quiz (LTI) from a Canvas course. This action is permanent. Use assignment_id (not quiz_id).

list_new_quiz_itemsA

List every item (question or stimulus) in a New Quiz (LTI), in quiz order, returning each item's id, position, points_possible, entry_type, and full entry body — including interaction_data and scoring_data, so the correct answer is visible in the result. Find the assignment_id with list_assignments or get_assignment, filtered on is_quiz_lti_assignment (not a Classic Quiz ID). Use get_new_quiz_item to refetch a single item by id, create_new_quiz_item to add one, update_new_quiz_item to change one, and delete_new_quiz_item to remove one. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating.

get_new_quiz_itemA

Get one item (question or stimulus) from a New Quiz (LTI) by its item_id, returning its position, points_possible, entry_type, and full entry body — including interaction_data and scoring_data, so the response reveals the correct answer. Find item_id with list_new_quiz_items, which also lists every item at once; use this tool only to refetch one item, such as right after create_new_quiz_item or update_new_quiz_item. assignment_id identifies the New Quiz (from list_assignments or get_assignment, filtered on is_quiz_lti_assignment), not a Classic Quiz ID.

create_new_quiz_itemA

Create one item (question) in a New Quiz (LTI). Returns the created item with its item_id, position, points_possible, and full entry body, including scoring_data. Supports 8 types: choice (one correct answer), multi-answer (select all that apply), true-false, essay, matching, numeric, rich-fill-blank (fill in the blank, with typed, dropdown, or word-bank blanks), and ordering (choices listed top-to-bottom in the correct sequence; Canvas shuffles their displayed order for the student). Each call adds another item (not idempotent), so check list_new_quiz_items before retrying a failed or uncertain create. Use update_new_quiz_item to change an existing item, delete_new_quiz_item to remove one, and create_new_quiz to make the quiz first. An item has no publish setting of its own; students see it when the quiz itself is published (update_new_quiz). assignment_id identifies the New Quiz (from list_assignments or get_assignment, filtered on is_quiz_lti_assignment), not a Classic Quiz ID. Canvas may rate-limit rapid creates, so call serially and pause between batches of about 50. Requires permission to manage quizzes in the course.

update_new_quiz_itemA

Update one existing item (question) in a New Quiz (LTI) by its item_id. Returns the updated item. Only the parts you pass are sent (position, points_possible, or item). When item is given, the whole item body (type, stem, choices, and answer) is rebuilt from it and sent, so pass the complete item, not only the changed field. It takes the same 8 types as create_new_quiz_item. Find item_id with list_new_quiz_items or get_new_quiz_item. Use create_new_quiz_item to add an item, delete_new_quiz_item to remove one, and update_new_quiz for quiz-level fields. assignment_id identifies the New Quiz (from list_assignments or get_assignment, filtered on is_quiz_lti_assignment), not a Classic Quiz ID. Canvas may rate-limit rapid updates, so call serially. Requires permission to manage quizzes in the course.

delete_new_quiz_itemA

Permanently delete one item (question or stimulus) from a New Quiz (LTI) by its item_id. This is irreversible — there is no undo and no tool to restore a deleted item. Returns { success: true }; Canvas does not hand back the deleted item. Find item_id with list_new_quiz_items or get_new_quiz_item. Use delete_new_quiz instead to remove the whole quiz, or update_new_quiz_item if you only need to change the item rather than remove it. assignment_id identifies the New Quiz (from list_assignments or get_assignment, filtered on is_quiz_lti_assignment), not a Classic Quiz ID. Requires permission to manage quizzes in the course.

get_quiz_question_responsesA

Review every student's answer to one or all questions in a Classic Quiz, pivoted by question instead of by student — for grading essay/short-answer/file-upload questions consistently across a class instead of paging through SpeedGrader one student at a time. Classic Quizzes only (quiz_type: assignment, practice_quiz, graded_survey, survey) — New Quizzes exposes responses through a different API. Omit question_id to get every question; provide it to scope to one. Each question reports needs_manual_grading (true for essay and file-upload questions) and points_possible. Questions drawn from a question bank are included: Canvas stores each draw as a generated question that the quiz's question list omits, so they are resolved from the students' own attempts, listed after the quiz's fixed questions, and report position: null. Each response reports the raw Canvas correctness value plus a derived scoring_state (correct / incorrect / partial / not_scored / awaiting_manual_grading / graded / unscored) so "undefined" is never read as an answer. Scans one Canvas API call per completed or pending-review submission, plus one per attempt needed to resolve bank-drawn questions, plus one paginated call to fetch every student's submitted answer text for the quiz (skipped, with answer_text_available: false and a reason, when the quiz has no assignment, is an anonymous survey, or the fetch fails). A failed per-submission answers fetch is recorded in submissions_failed, and a response whose question cannot be resolved is counted in unmatched_response_count and unmatched_question_ids, rather than aborting the whole call. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, student names are replaced with stable pseudonyms; essay/short-answer prose is student-authored text and may itself contain a real name, which pseudonymization of structured fields cannot strip.

list_filesA

List every file in a course's Files area, returning metadata only — name, size, content type, folder_id, and the Canvas-hosted download URL — not the file's content. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use download_file to fetch a file's actual content, get_file to refetch a single file's metadata by ID, list_folders for the folder tree these files sit in, and find_duplicate_files to spot same-name-and-size copies left over from course copies.

list_foldersA

List every folder in a course's Files area, including each folder's name, full path, parent_folder_id, and file/subfolder counts, but not the files or subfolders inside each one. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use list_files to see the files inside a folder, and upload_file's parent_folder_path to place a file in — and implicitly create — a folder path that doesn't exist yet; Canvas creates any missing segment along the way rather than requiring it to already exist.

get_fileA

Get metadata for a single file by ID, including download URL.

upload_fileA

Upload a new file to a course's Files area from base64-encoded content, and return the created file object (id, display_name, size, content_type, download url). Each call performs a new upload; check list_files first if you want to avoid creating a duplicate, and use delete_file to remove a file afterward. Canvas handles the upload as a multi-step hand-off to its storage backend (S3 or local Canvas storage), transparent to the caller. parent_folder_path places the file in that folder, creating any missing folder segment along the way; see list_folders for what already exists. Requires permission to manage files in the course.

delete_fileA

Permanently delete a file by ID, and return the deleted file object (its last known metadata) — the content is gone and there is no undelete. Use upload_file to put a replacement back afterward; Canvas assigns the new file a different ID rather than reusing the deleted one. Requires permission to manage files in the course.

download_fileA

Download the content of a Canvas file by ID. Text files (plain text, HTML, JSON, XML, JavaScript) are returned as readable text. Binary files (images, PDFs, etc.) are returned as base64-encoded data. Files larger than 10 MB are refused.

find_duplicate_filesA

Find duplicate files in a course's Files area — copies with the same name and size, typically left behind by repeated course copies. Each duplicate gets flagged separately by accessibility checkers, so this surfaces them for cleanup with the existing delete_file tool. Groups by display name + size (Canvas file listings carry no content hash), so same-name files of different sizes are not considered duplicates.

list_gradebook_history_daysB

List the dates in a course gradebook history that contain grading activity, grouped by grader and assignment.

get_gradebook_history_dayA

Get the graders and assignment IDs that had gradebook activity on a specific course date.

list_gradebook_history_submissionsA

List versioned submission history for one grader and assignment on a specific gradebook history date.

get_gradebook_history_feedA

Get the paginated gradebook history feed for a course, optionally filtered by assignment or user and optionally sorted oldest-first.

list_studentsA

List every student enrolled in a course (enrollment_type=student only), returning Canvas user objects (id, name, email, login_id) without grades or enrollment details. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use list_course_users for every role in the course (teachers, TAs, observers) or to filter users by enrollment_state, and list_course_enrollments when you need the enrollment/grade objects themselves (score, grade, enrollment workflow_state) rather than user profile fields. In pseudonymized mode every returned user's name and email are anonymized, since this endpoint carries no enrollment data for role classification to tell staff apart.

get_userA

Get a single Canvas user by numeric ID, returning the full Canvas user object (name, email, login_id, time_zone, bio, pronouns) when the caller is permitted to see it. Use get_profile instead when the target is the caller's own account, search_users to find a user when you only know their name, login, or email in an account, or list_course_users to see every user enrolled in a specific course. Because a bare ID lookup carries no enrollment data, pseudonymized mode cannot tell staff from students here and conservatively anonymizes the name and email on every call; list_course_users only keeps a real name when it is also called with include: ["enrollments"] and Canvas reports a teacher, TA, or designer enrollment for that user.

get_profileA

Get the profile of the currently authenticated user.

search_usersA

Search for users in a single Canvas account by name, login, or email, returning matching Canvas user objects. Use include to add email, last_login, avatar_url, time_zone, or uuid to each result, and sort/order to control the ordering. This is one account-scoped search — to check whether one student is enrolled anywhere across an educator's own active and concluded courses, use find_student_across_courses instead; to list every user in one course without a search term, use list_course_users; to list an entire account's users unfiltered, use list_account_users. Because results carry no enrollment data, pseudonymized mode cannot tell staff from students and anonymizes every returned user's name and email.

list_course_usersA

List users in a course with optional Canvas filters. Use include to request email, enrollments, avatar_url, bio, and other fields otherwise omitted from the default response. Use enrollment_type / enrollment_state to narrow by role or status, search_term to filter by name/login, user_ids to fetch a specific subset, and sort/order to control ordering.

list_groupsB

List all groups in a course.

list_group_membersC

List all members of a group.

list_group_categoriesA

List the group categories (group sets) in a course. A group assignment points at a category through its group_category_id, and create_group needs a category ID, so use this to find one.

create_group_categoryB

Create a new, empty group category (group set) in a course.

create_groupA

Create a group inside a group category. This is addressed by group_category_id, not by course ID: find the category with list_group_categories. The new group has no members; add them with add_group_member.

delete_groupA

Permanently delete a group and remove all of its members. The students stay enrolled in the course and the group category remains. Creating a group again does not restore the same group.

add_group_memberA

Add a user to a group. Returns the membership Canvas reports; if the user is already a member, Canvas returns the existing membership. remove_group_member removes this membership; it does not restore any other group membership Canvas changed.

remove_group_memberA

Remove a user from a group. The user stays enrolled in the course. Reverse with add_group_member.

list_enrollmentsA

List every enrollment the authenticated user holds across all of their Canvas courses — the caller's own enrollments only. Use list_course_enrollments for a single course's full roster, including a user_id filter to focus on one person. Optional type, state, and role filters and the include array mirror Canvas's own GET /users/self/enrollments endpoint. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. When pseudonymization is enabled, each enrollment classified as student or unknown has its nested user object replaced with that course's pseudonym and sis_user_id cleared before the result is returned; staff enrollments (TeacherEnrollment, TaEnrollment, DesignerEnrollment) are left as-is.

list_course_enrollmentsA

List enrollments within a specific course with Canvas filters. Use include=grades / include=current_points for richer grade data, type[] to limit to a role, and user_id to focus on a single user.

enroll_userA

Enroll a user in a course with a given role (StudentEnrollment, TeacherEnrollment, TaEnrollment, ObserverEnrollment, or DesignerEnrollment) and return the created enrollment object, including its id and enrollment_state. Use list_course_enrollments with a user_id filter to check a user's existing enrollments before enrolling them again, and remove_enrollment to conclude, deactivate, or permanently delete this enrollment afterward — enroll_user itself has no way to undo what it creates. Omitting enrollment_state leaves it at Canvas's documented default of "invited", so the user must accept a course invitation before the enrollment becomes active; pass enrollment_state: "active" to skip that step. Omitting course_section_id leaves Canvas to place the enrollment in the course's default section — read list_sections for the ID of a specific one. limit_privileges_to_course_section confines the user to that section: for teachers and TAs that includes grading privileges, and a section-limited student sees no user outside their own sections, teachers included. Both are left entirely unset when omitted, so the request is unchanged from a call that does not pass them. Requires permission to manage enrollments in the course; Canvas rejects the call otherwise.

remove_enrollmentA

Remove or conclude an enrollment from a course. The 'delete' task is permanent; 'conclude' and 'deactivate' are reversible.

list_discussionsA

List discussion topics in a course, returning id, title, message, posted_at, discussion_type, published, and is_announcement for each topic — replies are not included. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use get_discussion to fetch one topic in full detail including due/available dates, post_discussion_entry to reply, and list_announcements to see only announcements.

get_discussionA

Get a single discussion topic in a course by ID, returning its title, message, posted_at, discussion_type, published state, and is_announcement, plus due/available dates via Canvas's all_dates include. Find topic_id with list_discussions. Course-scoped only — use get_group_discussion for a topic that belongs to a group instead of a course.

list_group_discussionsA

List discussion topics in a group, returning id, title, message, posted_at, discussion_type, published, and is_announcement for each topic — replies are not included. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use get_group_discussion to fetch one topic in full detail including due/available dates, and list_discussions for the course-scoped equivalent; there is no group-scoped counterpart to post_discussion_entry or list_announcements.

get_group_discussionA

Get a single discussion topic in a group by ID, returning its title, message, posted_at, discussion_type, published state, and is_announcement, plus due/available dates via Canvas's all_dates include. Find topic_id with list_group_discussions. Group-scoped only — use get_discussion for a topic that belongs to a course instead of a group; there is no group-scoped counterpart to post_discussion_entry, so this server cannot post a reply to a group topic yet.

list_announcementsA

List announcements in a course, returning id, title, message, and posted_at for each one. Canvas serves this from the same discussion_topics index as list_discussions, filtered to topics marked is_announcement via the only_announcements query parameter. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use create_discussion with is_announcement: true to post a new announcement, and update_discussion to edit one afterward.

post_discussion_entryA

Post a new entry (reply) to a discussion topic in a course, and return the created entry (id, user_id, message, created_at). Not idempotent: each call adds another reply, Canvas does not deduplicate repeated calls. Works even on a topic Canvas has made anonymous, where get_discussion itself 404s — use list_discussions to confirm the topic exists and find its topic_id. Requires the caller to have an active enrollment in the course with permission to post to the forum, which Canvas grants to students, TAs and instructors by default unless an admin has restricted it.

create_discussionA

Create a new discussion topic in a course, and return the created topic (id, title, message, discussion_type, published, is_announcement, posted_at). Not idempotent: each call creates another topic — Canvas does not deduplicate by title, so check list_discussions first to avoid creating a duplicate. Setting is_announcement: true asks Canvas to create an announcement, but Canvas silently creates a plain discussion topic instead (HTTP 200, no error) if the caller lacks announcement-create permission in the course — this tool then throws instead of reporting success, naming the topic ID so you can check it with list_discussions or get_discussion. Use update_discussion to change an existing topic afterward, delete_discussion to remove one, and post_discussion_entry to reply to a topic instead of creating a new one. Requires instructor/TA permission to manage discussions in the course.

update_discussionA

Update an existing discussion topic in a course — title, message, published state, require_initial_post, delayed_post_at, or is_announcement — and return the updated topic; only the fields you pass are changed, the rest keep their current value. Course-scoped only: there is no update tool for group discussions, though list_group_discussions and get_group_discussion can still read them. Setting is_announcement: true asks Canvas to turn the topic into an announcement, but Canvas silently keeps it a plain discussion topic (HTTP 200, no error) if the caller lacks announcement-create permission in the course — this tool then throws instead of reporting success, naming the topic ID so you can check it with list_discussions or get_discussion. Use create_discussion to make a new topic, delete_discussion to remove one, list_announcements to see existing announcements, and post_discussion_entry to reply instead of editing the topic itself. Requires instructor/TA permission to manage discussions in the course.

delete_discussionA

Delete a discussion topic from a course. This action is permanent.

list_modulesA

List all modules in a course, including each module's name, position, publication state, unlock date and item count, but not the items inside. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use list_module_items or get_course_structure to see what is inside each module, and get_module to fetch one module by ID.

get_moduleA

Get a single module by its Canvas ID, including its name, position, publication state, unlock date and item count, but not the item list itself. Find the module_id via list_modules or get_course_structure. Use list_module_items to see what is inside, or view_course_structure for an interactive tree of every module in the course.

list_module_itemsA

List every item in one module — Assignment, Page, Quiz, File, Discussion, ExternalUrl, ExternalTool or SubHeader — in module order, including each item's published state and unpublished items. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use list_modules to find the module_id, get_course_structure for every module's items in one call, and create_module_item, update_module_item or delete_module_item to change what is inside.

get_course_structureA

Return the full module → items tree for a course in a single call, with summary stats. Avoids N+1 round-trips when an agent needs to reason over the whole course shape.

view_course_structureA

Interactive tree view of a course's modules and items. Returns the same payload as get_course_structure and additionally links to an MCP Apps UI resource that renders an explorable tree with type filters and search. Hosts that do not support MCP Apps fall back to the JSON payload (same as get_course_structure).

create_moduleA

Create a new module in a course. Returns the created module, including its new Canvas ID. Each call creates a separate module — calling it twice with the same name makes two modules, not one — so check list_modules first if you want to avoid duplicates. New modules are always created unpublished, regardless of any other field; use update_module with published: true to make one visible to students. prerequisite_module_ids silently drops any ID that is not an existing module positioned before this one in the course — Canvas does not error on an invalid ID, it just ignores it. Once created, add content with create_module_item. Requires instructor/TA permission to manage course content.

update_moduleA

Update an existing module's name, position or published state, and return the updated module object. Only the fields you pass are changed — anything you omit keeps its current value. Setting published: true publishes the module AND every item inside it (items Canvas couldn't publish come back as publish_warning_items); published: false unpublishes the module and every item inside it the same way — there is no way to change a module's published state without it cascading to its items. Use get_module to check the current state first, and list_modules to find the module_id. Requires instructor/TA permission to manage course content.

delete_moduleA

Permanently delete a module from a course, including its ordered list of module items. Assignments, pages, quizzes, files and discussions that the items link to are stored separately in the course and this call does not delete them, but ExternalUrl, ExternalTool and SubHeader items exist only inside the module and go with it. There is no single inverse: rebuilding the module means create_module plus create_module_item for each item.

create_module_itemA

Add an item to a module: Assignment, Page, Quiz, File, Discussion, ExternalUrl, ExternalTool or SubHeader. Returns the created module item, including its new Canvas ID. Each call adds a new item — calling it twice with the same title adds two items, not one. Which identifying field to pass depends on type: page_url for Page (addressed by slug, not ID), content_id for File, Discussion, Assignment or Quiz, external_url for ExternalUrl or ExternalTool, and neither for SubHeader. Use list_module_items to see what is already in the module, and update_module_item or delete_module_item to change or remove an item afterward. Requires instructor/TA permission to manage course content.

update_module_itemA

Edit an existing module item in place: rename it, repoint an ExternalUrl/ExternalTool item, reposition or re-indent it, publish/unpublish it, or move it to another module. ExternalUrl items exist only as module items, so a stale link carried in by a course copy can only be fixed here.

delete_module_itemA

Remove an item from a module. For ExternalUrl, ExternalTool and SubHeader items the item is the content, so this deletes it outright; for Assignment, Page, Quiz, File and Discussion items it only unlinks the item and the underlying content survives. Re-add with create_module_item.

list_pagesA

List every wiki page in a course, returning page stubs — title, url slug, published state and editing_roles — without the HTML body; the paginated list endpoint omits body entirely. Use get_page to fetch one page's full body by its url slug, or search_course_content to search page content across the whole course. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating.

get_pageA

Get one wiki page by its page_url slug — not a numeric ID — obtained from list_pages. Returns the page's title, published state, editing_roles and full HTML body, unlike the list endpoint's body-less stubs. Use list_pages to discover a course's pages and find a page_url, and update_page to edit this page's title, body, published state or editing_roles afterward.

create_pageA

Create a new wiki page in a course with a title and optional HTML body, published state and editing_roles, and return the created page — including its url slug, used as page_url by get_page, update_page and delete_page. Not idempotent: each call creates another page; Canvas does not deduplicate by title, so check list_pages first to avoid creating a duplicate. Use update_page to edit an existing page instead of creating a new one, and create_module_item's page_url parameter (with type Page) to place this page inside a module. Requires permission to manage wiki content in the course.

update_pageA

Update an existing wiki page's title, body, published state or editing_roles. Only the fields you pass are sent to Canvas; omitted fields are left unchanged. body is not merged — it replaces the entire HTML body, so read the current content with get_page first and send back the full edited body, not just the changed part. Returns the updated page. Idempotent: calling it again with the same fields produces the same resulting page. Use create_page to make a new page instead, delete_page to remove this one, and update_course's syllabus_body parameter to edit the course syllabus, which is not a wiki page editable here. Requires permission to manage wiki content in the course.

delete_pageA

Delete a wiki page from a course. This action is permanent.

list_calendar_eventsA

List calendar events for a course, unbounded by the ~1-week/20-item caps that get_upcoming_events and get_my_upcoming_assignments are stuck with. By default Canvas only returns type="event" items for today alone (end_date defaults to start_date) — pass both start_date and end_date to cover a range, and type="assignment" to list assignment due dates instead of plain events.

create_calendar_eventA

Create a new calendar event and return the created event object, including its id, start_at, end_at, and workflow_state. context_code can target any Canvas context the caller has permission to create events in — a course (course_123), group, user, or account context, not only courses, despite the course-shaped example. Each call creates a new event; calling it again with the same title and times does not update anything, it adds a duplicate, so check list_calendar_events for what already exists and use update_calendar_event with the returned id to change this event afterward. The event is saved and immediately part of that context's calendar — there is no separate draft or publish step. Requires permission to create events in the target context; Canvas rejects the call otherwise.

update_calendar_eventA

Update an existing calendar event. Only provided fields are changed.

list_conversationsA

List the authenticated user's inbox: every non-archived conversation, both read and unread, newest first, returning each one's id, subject, last_message, last_message_at, message_count, and participants (id, name) — no message bodies; use get_conversation for the full thread. There is no scope filter here, so starred-only, archived, sent-only, or unread-only views aren't available. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use get_conversation_unread_count for just the unread total instead of the whole inbox.

get_conversationA

Get one conversation's full message thread by id, returning its subject, participants, and every message (id, body, author_id, created_at) — not just the last_message summary list_conversations returns. Canvas marks any unread messages in this thread as read as a side effect of calling this, so re-reading a thread changes its unread state. Find the conversation_id with list_conversations. Use get_conversation_unread_count to check the inbox-wide unread total without marking anything read.

get_conversation_unread_countA

Get the number of unread conversations for the authenticated user as a single integer — not the conversations themselves, and not a count of unread messages within them. Use list_conversations to see which conversations are unread, or get_conversation to open one and mark its messages read.

send_conversationA

Send a new message and return the created conversation object(s) (id, subject, participants) — one per recipient. With more than one entry in recipients, this creates a separate private conversation with each recipient rather than one shared group thread: each recipient sees only their own copy, and nobody sees who else received it. Every call sends again — there is no dedup against an already-sent message with the same subject and body. recipients must be real Canvas user ids as strings; list_course_users or search_users can look those up first. Requires the authenticated user to have permission to message every recipient (course messaging rules and any inbox restrictions Canvas enforces). Use list_conversations and get_conversation to review what was sent.

list_peer_reviewsA

List every peer review assigned on an assignment, across every submission, returning each review's id, assessor_id (the reviewer), user_id (the reviewee whose submission is being reviewed), asset_id, and workflow_state ('assigned' or 'completed'). Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Pass submission_id to scope the results to the reviews assigned to that one submission instead of the whole assignment — the same result get_submission_peer_reviews returns, kept here as a shortcut. Omit it to see every review across the assignment. Use create_peer_review to assign a new reviewer, and delete_peer_review to remove one.

get_submission_peer_reviewsA

List the peer reviews assigned to one submission within an assignment — a single submission can have more than one assigned reviewer — returning each review's id, assessor_id (the reviewer), user_id (the reviewee), asset_id, and workflow_state ('assigned' or 'completed'). Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use list_peer_reviews instead to see every review assigned across the whole assignment rather than one submission, create_peer_review to assign another reviewer to this submission, and delete_peer_review to remove one.

create_peer_reviewA

Assign a Canvas user as a peer reviewer for one submission, and return the created peer review object (id, assessor_id, user_id, asset_id, workflow_state). The user_id parameter you pass is the reviewer being assigned; in the returned object assessor_id holds that same reviewer, while the response's own user_id field instead identifies the submission owner (the reviewee) — the two user_id values are not the same person. The new review starts in workflow_state "assigned". submission_id must already exist on this assignment. Use list_peer_reviews to see every review assigned on the whole assignment, or get_submission_peer_reviews to see only the reviews assigned to one submission, before assigning another reviewer; use delete_peer_review to unassign one. Requires instructor/TA permission in the course.

delete_peer_reviewA

Remove a peer-review assignment — identified by its assessor_id/user_id pairing — from one submission, unassigning that reviewer; the submission and the assignment itself are untouched, only the peer-review relationship goes away. Returns a confirmation message; Canvas's own response body is discarded. This is a reversible relationship removal, not an irreversible content delete: re-create the assignment with create_peer_review, though the new review gets a new id and workflow_state starts over at "assigned". Find the reviewer's user_id to remove with list_peer_reviews or get_submission_peer_reviews. Requires instructor/TA permission in the course.

get_accountA

Get a single Canvas account by ID, including its name, parent and root account IDs, UUID, default storage quotas, and workflow state. Find the account_id via list_accounts, or list_sub_accounts on a parent account to find one of its children. Requires an admin role on the account.

list_accountsA

List all accounts accessible to the authenticated user.

list_sub_accountsA

List the direct child accounts nested under a given Canvas account — one level deep, not grandchildren or deeper descendants. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use get_account to fetch one sub-account's full details by ID, or call this tool again with a child's ID as account_id to walk further down the tree. Requires an admin role on the account.

list_account_coursesA

List every course in a Canvas account, optionally filtered by search_term matching course name or course code. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use list_sub_accounts first if you want one sub-account's courses rather than this account's own, and list_courses instead for the courses the authenticated user is enrolled in or can access, rather than a full account inventory. Requires an admin role on the account.

list_account_usersA

List every user in a Canvas account — every role the account contains, not only students — optionally filtered by search_term matching name, email, or login. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use include to add email, last_login, avatar_url, time_zone, or uuid to each returned user, sort/order to control result ordering (sort: "id" is Canvas's recommended choice when paging through many results), and list_course_users to scope the roster to one course rather than the whole account. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, every returned user's name and contact info is replaced with a stable pseudonym — this tool has no enrollment data to tell students from staff, so every row is masked the same way; use resolve_pseudonym to map one back to a real user_id. Requires an admin role on the account.

get_account_reportsA

List the report types a Canvas account supports — csv/grade exports, SIS imports, and institution-specific types — each with its report key, title, expected parameters, and the most recent last_run status if one was ever generated. This only lists what can be run; it does not start, re-run, or download a report, and there is no report-running tool registered on this server. Use get_account to confirm the account first. Requires an admin role on the account.

list_account_notificationsA

List active global institution-wide announcements for the current user (maintenance windows, term deadlines, policy notices).

view_account_notificationsA

Interactive panel of active institution-wide announcements. Returns the same payload as list_account_notifications and additionally links to an MCP Apps UI resource that renders scannable announcement cards with type filters and search. Hosts that do not support MCP Apps fall back to the JSON payload (same as list_account_notifications).

search_course_contentA

Search for content within a course. Searches pages, assignments, discussions, and announcements by keyword.

get_course_analyticsA

Get course-level activity analytics. Returns daily page view and participation counts.

get_student_analyticsA

Get per-student activity analytics for a course. Returns page views, participations, and submission timeline for a specific student.

get_course_activity_streamA

Get a summary of recent activity in a course. Returns counts of recent events grouped by type (submissions, discussions, announcements, etc.).

get_assignment_analyticsA

Get score distribution analytics for assignments in a course. Returns statistical summary (min, max, median, first/third quartile), submission count, and tardiness breakdown (on_time, late, missing) for each assignment. Provide assignment_id to scope to one assignment; omit to return analytics for all assignments in the course.

get_root_outcome_groupA

Get the root outcome group for an account or course context, the entry point into the outcome tree. Returns the top-level outcome group (id, title, subgroups_url, outcomes_url); walk from there with list_outcome_group_subgroups for its child groups and list_outcome_group_outcomes for outcomes linked directly under a group, or use list_outcome_groups for a flat listing of every group in the context instead of walking the tree.

list_outcome_groupsA

List every outcome group in an account or course context as a flat array, not a tree. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use get_root_outcome_group plus list_outcome_group_subgroups to walk the hierarchy instead, or get_outcome_group to fetch one group's details by ID.

list_outcome_group_linksA

List every outcome link in an account or course context — the many-to-many join between outcome groups and the outcomes they contain, read from the context root, not one specific group. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Each link nests its outcome_group and outcome (full detail when outcome_style="full" / outcome_group_style="full", abbreviated otherwise); use list_outcome_group_outcomes instead to list only the outcomes linked directly under one specific outcome_group_id.

get_outcome_groupA

Get the full details for one outcome group by outcome_group_id within an account or course context, including its subgroups_url and outcomes_url. The ID comes from list_outcome_groups, list_outcome_group_subgroups, or get_root_outcome_group; use list_outcome_group_outcomes to list the outcomes linked under this group and list_outcome_group_subgroups to list this group's child groups.

list_outcome_group_outcomesA

List the outcomes linked directly under one outcome group (outcome_group_id), not its subgroups' outcomes. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Each link nests the outcome (full detail when outcome_style="full", abbreviated otherwise); use list_outcome_group_subgroups to descend into child groups first, or get_outcome for one outcome's full detail by outcome_id.

list_outcome_group_subgroupsA

List the immediate child outcome groups under one outcome group (outcome_group_id) — one level of the tree, not a recursive walk. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Call this again with each returned group's id to descend further, or use list_outcome_group_outcomes on the same outcome_group_id to list outcomes linked directly under it instead of its child groups.

get_outcomeA

Get the full details for one learning outcome by outcome_id, including its rating criteria, mastery_points, and calculation_method. The outcome_id comes from list_outcome_group_outcomes, list_outcome_group_links, or get_outcome_results' / get_outcome_rollups' linked.outcomes; get_outcome_alignments lists all alignments in the course (not scoped to one outcome) — cross-reference via get_outcome_results instead to tie an alignment to this outcome_id.

get_outcome_alignmentsA

Get the assignments aligned to outcomes in a course, optionally filtered to one student_id or assignment_id. Returns each alignment's assignment_id and title, but not the outcome_id it maps to. get_outcome_results nests the same alignment objects under linked.alignments, but ties an alignment to an outcome via each outcome_results[] entry's links.alignment and links.learning_outcome, not from linked.alignments alone. Use get_outcome_contributing_scores to see the assignment scores that produced an outcome's results instead of just the links.

get_outcome_resultsA

Get raw per-student, per-alignment outcome results for a course (one score per assessed alignment, not aggregated), optionally filtered by user_ids, outcome_ids, and include_hidden. Set include_alignments to nest the matching alignments under linked.alignments. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, linked.users entries are anonymized; use resolve_pseudonym to map one back to a real user. Use get_outcome_rollups instead for aggregated scores per student and outcome, or get_outcome_contributing_scores for the assignment or quiz scores behind one outcome.

get_outcome_rollupsA

Get aggregated outcome rollups for a course — one score per student per outcome, or, with aggregate="course", a single course-level mean or median — optionally filtered by user_ids and outcome_ids and sorted by student or by one outcome's score. Set include_courses to nest course details under linked.courses. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, linked.users entries are anonymized; use resolve_pseudonym to map one back to a real user. Use get_outcome_results instead for the raw per-alignment scores behind a rollup, or get_outcome_mastery_distribution for a mastery-level histogram across students.

get_outcome_contributing_scoresA

Get the assignment or quiz scores that contributed to one outcome_id's results for one or more students in a course, optionally restricted to assignment alignments only or including unpublished assignments. Use get_outcome_results instead for the final per-alignment outcome score rather than the scores that fed it, or get_outcome_alignments to list all alignments in the course (not scoped to this outcome) without their scores.

get_outcome_mastery_distributionA

Get a mastery-level histogram for outcomes in a course — how many students fall into each rating band — optionally filtered by outcome_ids and student_ids and excluding missing user rollups or missing outcome results. Set include_alignment_distributions to also break down scores by contributing alignment. Use get_outcome_rollups instead for each student's individual aggregated score, or get_outcome_results for the raw per-alignment scores.

get_my_coursesA

List active courses for the authenticated student.

get_my_gradesA

Get grade data for the authenticated student. If course_id is omitted, returns grades across all enrolled courses.

get_my_submissionsB

List all submissions for the authenticated student in a course.

get_my_upcoming_assignmentsA

List upcoming assignment events for the authenticated student. Canvas caps this endpoint at roughly the next 1 week and at most 20 events server-side — neither limit is adjustable, and results silently stop there even if more assignments fall later. For a longer or specific date range, use list_calendar_events with type="assignment" and explicit start_date/end_date instead.

get_my_submission_feedbackA

List the authenticated student's own submissions that carry feedback comments from an instructor or a peer reviewer — comments left by the student themselves do not count as feedback and submissions with no non-self comments are omitted. Omit course_id to scan every active course; a course that errors during a scan is skipped and reported in courses_failed rather than failing the whole call. Sorted most-recent-feedback-first. Comment author role is best-effort: 'teacher' is only identified when the author is the submission's recorded grader; other non-self authors are labeled 'peer', including any staff member who comments without being the recorded grader.

get_my_activity_stream_summaryA

Count unread and total items in the authenticated student's cross-course activity stream, grouped by Canvas item type (e.g. DiscussionTopic, Announcement, Submission, Conversation). No item content — counts only. A good first call in a daily workflow to check "is there anything to look at?" before fetching the full stream.

get_my_activity_streamA

The authenticated student's cross-course activity stream: new discussion posts, announcements, conversation messages, graded submissions, peer-review requests and conference invitations from every course at once, newest first. Four caveats, none of them visible in the response: (1) RECENT ACTIVITY ONLY — typically the last ~4 weeks; the retention window is a per-Canvas-instance setting and cannot be read through the API, so "nothing found" is not evidence that nothing happened. (2) Each item's message was truncated to 4096 characters when Canvas stored it, with no marker — follow the item's html_url object with get_discussion or get_conversation for the full text. (3) At most 3 root_discussion_entries per discussion item and 3 latest_messages per conversation item. (4) Exactly one of course_id / group_id is present on each item and the other key is ABSENT, not null — join on course_id, and read context_type to tell which you have.

list_my_planner_itemsA

The authenticated student's planner: assignments, ungraded quizzes, planner notes, wiki pages, ungraded discussions, calendar events, peer reviews, sub-assignments and peer-review sub-assignments — everything with a due or to-do date, across every course and group at once. Strictly richer than get_todo_items, which covers only assignments needing submitting or grading. Four caveats: (1) start_date and end_date must be given TOGETHER or OMITTED TOGETHER — supplying only one makes Canvas silently default the other side to a ten-year window, so a half-specified range is rejected outright; omitting both resolves to Canvas's own ~2-week default, echoed back as the response's start_date/end_date. (2) context_codes (e.g. "course_123", "group_7") restricts to those contexts; omit it for every context the student belongs to — an empty array is rejected rather than silently meaning "all". (3) submissions is false when the item has no gradable submission, or an object when it does — never null. (4) a planner note has no html_url (Canvas exposes none for individual planner notes).

get_my_course_requirementsA

What the authenticated student still has to DO in one course: a per-module requirement graph where every row names the Canvas endpoint and field its verdict came from. Richer than list_modules plus list_module_items, which return a raw completion_requirement without the cross-references that make it truthful; for grade outcomes use project_grade or explain_grade instead, and for cross-course context list_my_planner_items. Five things to read before acting on the output: (1) unknown is a real state and is NOT "unsatisfied" — Canvas attaches completion_requirement.completed only where it loaded a module progression, which happens only for a student caller, so an educator or admin token gets unknown on every row rather than a course full of incomplete work. (2) A module with requirement_type: "one" is COMPLETE as soon as any single requirement is met, so counting its unsatisfied rows invents work. (3) summary gives five counts and never one "things left to do" number: that number cannot be computed honestly across mixed requirement_type values and a non-zero unknown count. (4) Numeric threshold rows are re-evaluated by Canvas on every pass and can revert from met to unmet with no student action (a regrade, a posting-policy change); the other four requirement types latch. (5) canvas_state and derived_state are both reported and a mismatch is flagged in state_disagreement rather than resolved. Read-only and current-user-only: no student_id parameter, no attempt started, no LTI launch, nothing marked as viewed or done.

find_student_across_coursesA

Search the caller's teaching courses — active and, by default, concluded (past-term) ones — for a student by name, login, or email, and report every matching course with the student's enrollment state and last activity. Set include_concluded: false to only search current courses. max_courses bounds how many of the caller's courses are scanned (most recent term first); when exceeded, truncated: true is set rather than silently dropping courses. A course that errors during the scan is skipped and reported in courses_failed rather than failing the whole call.

get_dashboard_cardsA

Get the current user's dashboard course cards with position, color, and image.

get_todo_itemsA

Get the current user's to-do items, including upcoming assignments and grading tasks.

get_upcoming_eventsA

Get the current user's upcoming calendar events and assignments. Canvas caps this endpoint at roughly the next 1 week and at most 20 events server-side — neither limit is adjustable, and results silently stop there even if more events fall later. For a longer or specific date range, use list_calendar_events with explicit start_date/end_date instead. Canvas does not support filtering this endpoint server-side; type filters the returned items client-side by their own type field ("event", "assignment", or "sub_assignment") instead.

get_missing_submissionsA

Get assignments with missing submissions for the current user.

list_submission_comments_needing_attentionA

List submissions where the most recent comment is from the student and has not been addressed by grading or a reply — i.e. comments the instructor has likely not seen. Returns a triage list, oldest-unaddressed first. Requires instructor/TA permissions in the course.

list_students_needing_attentionA

Report students who may need instructor attention based on inactivity, missing or late submissions, and low current score. Each finding lists the exact signals that fired and the thresholds used — this is a factual report, not a prediction. Requires instructor/TA permissions in the course.

create_content_exportA

Start a Canvas course content export (Common Cartridge / QTI / zip). Exports are asynchronous — this tool returns immediately with an export ID and initial workflow_state ("created"). Call get_content_export to poll progress and retrieve the time-limited download link when the export finishes.

get_content_exportA

Get the status of a content export. When workflow_state is "exported", attachment.url contains a time-limited download link — download it promptly, as the URL expires (re-fetch to get a fresh one). Returns attachment: null while still "created"/"exporting" or on "failed".

list_content_exportsB

List all content exports for a course (most recent first).

list_content_migrationsB

List all content migrations for a course (most recent first).

get_content_migrationA

Get the status of a single content migration. When workflow_state is "running", poll progress_url for live updates. When "completed", the migration is done.

list_content_migration_typesA

List available migration types (migrators) for a course. Returns migrator type keys such as course_copy_importer, common_cartridge_importer, zip_file_importer, qti_converter, moodle_converter.

get_migration_selective_dataA

Get the selective import tree for a migration — the list of content items available to selectively import. Only meaningful for migrations in the "waiting_for_select" state.

get_migration_asset_id_mappingA

Get the old-to-new asset ID mapping for a completed migration. Useful for resolving references to content that existed in the source course.

list_migration_issuesA

List issues encountered during a content migration. Each issue has a type (todo, warning, or error) and a description.

create_content_migrationA

Start a content migration (course copy, Common Cartridge import, zip import, QTI conversion, or Moodle conversion). Migrations are asynchronous — this tool returns immediately with a migration ID and progress_url. Poll get_content_migration or progress_url to track completion.

list_grading_standardsA

List grading standards available in a course or account context. Provide either course_id (to see standards scoped to a course) or account_id (to see account-level standards, requires admin access). Returns an array of grading standard objects, each with an id, title, context, and grading_scheme array of { name, value } entries.

create_grading_standardA

Create a new grading standard (letter-to-percentage scheme) in a course or account context. Provide either course_id or account_id (account requires admin). scheme_entries is an array of { name, value } objects where value is the lower-bound percentage as a fraction 0–1 (e.g. { name: "A", value: 0.94 } means A ≥ 94%). Entries will be sorted descending by value before sending to Canvas. Canvas POST body key is grading_scheme_entry (singular); the returned object uses grading_scheme (plural). Returns the created grading standard object including its id — use that id with apply_grading_standard_to_course to activate it on a course.

apply_grading_standard_to_courseA

Apply an existing grading standard to a course so the gradebook uses it. Pass the grading_standard_id returned by create_grading_standard or list_grading_standards. Pass null for grading_standard_id to remove the current grading standard from the course. Returns the updated course object.

set_student_quiz_accommodationA

Apply extra time and/or extra attempts to a specific student across all Classic Quizzes in a course (or a specified subset). Fans out to the Canvas quiz extensions API for each quiz. New Quizzes (quiz_type quizzes.next) are skipped — use set_student_new_quiz_accommodation instead. Only applies to quizzes that exist at call time; re-run after creating new quizzes. Assignment due-date overrides are not handled here (separate fast-follow feature). Note: for courses with many quizzes this makes one Canvas API call per quiz. Partial failures are tolerated — a failure on one quiz does not abort the rest. Returns the standard fan-out envelope: separated applied[], skipped[] (each with a skip_reason), and failed[] (each with an error) arrays, a not_found list of any requested quiz_ids absent from the course, and a summary of counts. Provide user_id as the real Canvas user ID. If CANVAS_PSEUDONYMIZE_STUDENTS is enabled, call resolve_pseudonym first to obtain the real user_id from a pseudonym.

list_student_quiz_accommodationsA

List the current quiz accommodation (extra time and/or extra attempts) for a specific student across all Classic Quizzes in a course. Useful for auditing before or after calling set_student_quiz_accommodation. New Quizzes (quiz_type quizzes.next) are excluded. Reads extra_time / extra_attempts from each quiz's submission records (Canvas exposes no read endpoint for quiz extensions directly) — one Canvas API call per Classic Quiz, so it may be slow for courses with many quizzes. Errors from any quiz's read propagate immediately (no per-quiz error catching). Provide user_id as the real Canvas user ID. If CANVAS_PSEUDONYMIZE_STUDENTS is enabled, call resolve_pseudonym first.

set_student_new_quiz_accommodationA

Apply a time and/or attempts accommodation for a student across all New Quizzes in a course (course-level, single Canvas API call when no assignment_ids are given) or for a specified subset of New Quizzes (per-quiz fan-out when assignment_ids are given). New Quizzes use a time_multiplier (ratio, e.g. 1.5 for 1.5× time), not absolute minutes. For Classic Quizzes (quiz_type: assignment / practice_quiz / etc.) use set_student_quiz_accommodation instead. Partial per-quiz failures are tolerated — a failure on one quiz does not abort the rest. In per-quiz mode, fan-out is sequential (one Canvas API call per assignment ID, awaited in series). Canvas errors on the course-level path (no assignment_ids) propagate as a top-level error (no envelope). Returns a uniform envelope: scope ("course" or "per_quiz"), applied[], failed[], and summary. Provide user_id as the real Canvas user ID. If CANVAS_PSEUDONYMIZE_STUDENTS is enabled, call resolve_pseudonym first to obtain the real user_id from a pseudonym.

list_student_new_quiz_accommodationsA

Read the current course-level New Quizzes accommodation (time multiplier and/or extra attempts) for a specific student in a course. Useful for auditing before or after calling set_student_new_quiz_accommodation. Returns has_accommodation: false when no accommodation is set (Canvas 404 is treated as "no record", not an error). New Quizzes store a single course-level accommodation record per student; this is not per-quiz. For Classic Quizzes, use list_student_quiz_accommodations instead. Provide user_id as the real Canvas user ID. If CANVAS_PSEUDONYMIZE_STUDENTS is enabled, call resolve_pseudonym first.

list_assignment_overridesA

List all due-date / availability overrides for a specific assignment in a course. Returns overrides targeting individual students, sections, or groups. Useful for auditing before creating a new override — Canvas returns a 422 if a student-set override already exists for the same students on the same assignment.

create_assignment_overrideA

Create a due-date / availability override for a specific assignment, targeting a set of students, a course section, or a group. Exactly one of student_ids, course_section_id, or group_id must be provided. At least one date field (due_at, unlock_at, lock_at) should be provided; omit a date field to leave the corresponding date unchanged for the override target. Dates must be ISO 8601 strings (e.g. "2026-09-15T23:59:00Z"). Canvas returns a 422 if a student-set override already exists for the same students on this assignment — use list_assignment_overrides to audit first. Provide student_ids as real Canvas user IDs. If CANVAS_PSEUDONYMIZE_STUDENTS is enabled, call resolve_pseudonym first to resolve pseudonyms to real user IDs.

set_student_assignment_datesA

Fan a due-date / availability override for a specific student across all (or a filtered subset of) assignments in a course. Creates one student-set override per assignment via the Canvas assignment overrides API. Partial failures are tolerated — a failure on one assignment does not abort the rest. Note: for courses with many assignments this makes one Canvas API call per assignment. V1 is create-only: if an override for this student already exists on an assignment, Canvas returns a 422 and that assignment appears in the failed[] list. Use list_assignment_overrides to audit first. Dates must be ISO 8601 strings. To shift dates by a relative amount, first call list_assignments with include=overrides to retrieve current dates, compute absolute timestamps, then call this tool. Returns the standard fan-out envelope: separated applied[], skipped[] (unused in this create-only version, always empty), and failed[] (each with an error) arrays, a not_found list, and a summary of counts. Any assignment_ids that do not exist in the course are reported in not_found (they are neither applied nor failed). Provide user_id as the real Canvas user ID. If CANVAS_PSEUDONYMIZE_STUDENTS is enabled, call resolve_pseudonym first to obtain the real user_id from a pseudonym.

check_course_setupA

Run a factual course-readiness report that surfaces common configuration problems — assignments missing due dates, unpublished items students will not see, gradebook weighting gaps, graded assignments with no points, and published assignments still accepting submissions after their due date. Returns findings grouped by check with a plain-language detail per item. This is a config-health report only; it does not inspect student submissions or performance (see list_students_needing_attention / get_missing_submissions for those). Requires instructor permissions in the course.

explain_gradeA

Recomputes and explains the weighted course grade for a student, including assignment-group weights, drop_lowest / drop_highest / never_drop rules, per-group breakdowns (earned points, dropped assignments, weighted contributions), the mapped letter grade (via the course grading standard when present), and a reconciliation check against Canvas's posted current_score / final_score.

Use this when you need to verify that Canvas's displayed grade matches the rules, or to explain to a student or instructor how their grade was calculated.

Limitations:

  • V1 computes one student per call. Omit student_id to compute for the authenticated user.

  • Instructor-applied curves and fudge points are not exposed via the Canvas REST API and cannot be reflected in the computation; a caveat is added when the discrepancy exceeds 0.5 pp.

  • When the course uses grading periods, reconciliation is against the overall (cross-period) grade.

  • When CANVAS_PSEUDONYMIZE_STUDENTS is enabled and you are passing a student_id, first call resolve_pseudonym to obtain the real Canvas user_id.

explain_grading_policyA

Explains the grading automation rules configured for a Canvas course:

  • Missing-submission policy: whether blank/unsubmitted work is automatically scored 0 (or another deduction), or left unpenalised.

  • Late-submission policy: whether Canvas applies a per-day or per-hour percentage deduction to late submissions, and whether there is a floor below which the grade cannot fall.

  • Assignment-group weighting: whether the course uses weighted groups, and the weight of each group.

  • Grading scheme: whether a letter-grade scheme (A/B/C/F mapping) is applied to the final score.

Also returns a plain-language summary paragraph you can share with students or instructors.

Note: the late/missing policy section requires instructor or admin permissions. Students receive the group-weighting and grading-scheme sections only, with a caveat noting what is unavailable. Use explain_grade to compute the actual weighted grade for a specific student.

project_gradeA

Projects the minimum score needed on remaining assignments to reach a target course grade.

Given a target (as a percentage, e.g. 90, or a letter grade, e.g. "A") and the student's current scores, computes the minimum uniform percentage that must be earned on all remaining (not yet graded) assignments for the overall course grade to reach the target. Accounts for assignment-group weights, drop_lowest / drop_highest / never_drop rules, and the course grading scheme (for letter-grade targets and output letter mapping).

Returns:

  • minimum_pct_on_remaining: the uniform percentage needed on all remaining items.

  • feasibility: 'achievable' | 'already_secured' | 'impossible'.

  • Per-group breakdown of locked-in scores and remaining assignments.

  • A plain-language summary.

Limitations:

  • Uses a uniform-x model: the same percentage is assumed for every remaining item. This is the natural interpretation of "minimum average needed." Per-item optimization is not supported.

  • Drop rules are frozen at their current state (based on already-graded scores); which items are dropped may shift as remaining assignments are graded.

  • Late-submission penalties are not factored in.

  • V1 computes one student per call. Omit student_id to compute for the authenticated user. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, resolve the pseudonym first via resolve_pseudonym.

audit_course_linksA

Scan a course's content (pages, assignments, syllabus, announcements, and optionally quizzes) for broken or outdated links and images. Returns structured findings: cross-course references (links that still point at a previous copy of the course — the canonical stale-copy failure after a course import) and empty/malformed URLs. Pass "quizzes" in include to also scan Classic quiz descriptions/questions and New Quiz item stems — these break silently for students while still rendering in the instructor’s own preview. quizzes is opt-in (off by default). Structural checks only — no outbound HTTP requests. Requires instructor permissions in the course.

audit_course_accessibilityA

Scan a course's content (pages, assignments, syllabus, announcements, and optionally quizzes) for structurally-detectable WCAG 2.1 accessibility problems: images missing alt text or with low-quality (filename/generic) alt text, non-descriptive link text ("click here"), adjacent duplicate links, skipped/empty/overlong headings, and tables missing headers, header scope, or captions. Each finding carries a WCAG success criterion and a severity (error = unambiguous failure, advisory = needs human review). Structural checks only — no color-contrast checking (requires rendered theme CSS this tool cannot see) and no list-misuse detection in this version. Pass "quizzes" in include to also scan Classic quiz descriptions/questions and New Quiz item stems (opt-in, off by default). Complements — does not replace — Canvas's own in-app Accessibility Checker (course navigation → Accessibility → Scan Course), which covers the same WCAG areas plus rendered color contrast and offers in-UI remediation. Requires instructor permissions in the course.

list_appointment_groupsA

List appointment groups (Canvas Scheduler sign-up slots) visible to the current user, returning each group's id, title, context_codes, workflow_state, and location — time slots, per-slot reservations, and participant counts are each left out unless you pass the matching include value. scope defaults to "reservable" (groups the user is eligible to sign up for; reserving a slot itself happens in the Canvas UI, not through this server) and can be set to "manageable" for the groups the user administers. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use get_appointment_group for one group's full detail by id, and next_appointment to find the next open slot instead of browsing every group.

get_appointment_groupA

Get a single appointment group's core record — id, title, context_codes, workflow_state, and location — by id. None of its time slots, per-slot reservations, or participant counts come back unless you pass include with "appointments", "child_events", or "participant_count" respectively; omit include and you get only the core record. Find the id with list_appointment_groups. Use list_appointment_group_users or list_appointment_group_groups to see who has actually reserved a slot, and next_appointment to find the next slot still open to sign up for.

create_appointment_groupA

Create a new appointment group (Canvas Scheduler sign-up slots) in one or more contexts, e.g. ["course_123"], and return the created group object (id, title, workflow_state, context_codes). New groups start workflow_state "pending" (unpublished, invisible to participants) unless publish=true — once published, Canvas will not let it go back to unpublished, so confirm with get_appointment_group before setting it. participant_visibility defaults to "private"; set it to "protected" so signed-up participants can see each other's sign-ups. Add new_appointments as [start_at, end_at] ISO 8601 pairs to create the bookable time slots up front, or add more later with update_appointment_group. Each call creates another group — there is no dedup against an existing title. Requires permission to manage the Scheduler in every context listed.

update_appointment_groupA

Update an existing appointment group by id — only the fields you pass are changed — and return the updated group object. Set publish=true to make a draft group visible to participants; Canvas will not let you set it back to false once published. Add new_appointments as [start_at, end_at] ISO 8601 pairs to create additional time slots — existing slots are left alone and there is no removal here. This tool cannot change participant_type, participant_visibility, or the per-participant appointment limits set at create_appointment_group; those are fixed at creation. Find the id with list_appointment_groups. Requires permission to manage the Scheduler in the group's context.

delete_appointment_groupA

Delete an appointment group by id, canceling every time slot and reservation on it and emailing every signed-up participant, then return the deleted group object. This is permanent: the group and its slots cannot be recovered afterward. Pass cancel_reason to include why in that cancellation email. Find the id with list_appointment_groups, and check list_appointment_group_users or list_appointment_group_groups first if you need to know who will be notified. Requires permission to manage the Scheduler in the group's context.

list_appointment_group_usersA

List the individual Canvas users who have a reservation in this appointment group, returning each as a user object (id, name). Only meaningful when the group's participant_type is "User" — a Group-type group returns an empty list here; use list_appointment_group_groups instead for those. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Find the appointment_group_id with list_appointment_groups, or use get_appointment_group with include=["participant_count"] for just a count instead of the full list.

list_appointment_group_groupsA

List the student groups that have a reservation in this appointment group, returning each as a group object (id, name, group_category_id, members_count) — the same shape list_groups returns. Only meaningful when the group's participant_type is "Group" — a User-type group returns an empty list here; use list_appointment_group_users instead for those. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Find the appointment_group_id with list_appointment_groups.

next_appointmentA

Get the single next open time slot the current user is still eligible to sign up for, searched across every appointment group the user can reserve in (or only the appointment_group_ids you pass), and return it as a one-element array of calendar-event objects — or an empty array if nothing is open. This is about availability, not history: it excludes slots the user already reserved and slots that are full, but does not exclude a whole group just because the user holds a reservation in one of its other slots. Use list_appointment_groups with scope="reservable" to browse every open group instead of just the next slot, and list_appointment_group_users to see existing reservations.

Prompts

Interactive templates invoked by user choice

NameDescription
canvas-accessibility-sweepEducator and learning-designer skill for a pre-launch accessibility and broken-link sweep of a Canvas course. Walks the structural accessibility audit and the link audit over a course's pages, assignments, syllabus, announcements, and (optionally) quizzes, then produces a prioritised remediation list you can work through in the Canvas editor. Trigger phrases include "accessibility sweep", "accessibility audit", "check course accessibility", "a11y check", "WCAG scan", "alt text audit", "broken links", "check my course for broken links", "pre-launch course check", or "course QC for accessibility".
canvas-admin-rosterAdmin skill for walking the Canvas account hierarchy: list accounts and sub-accounts, see courses and users under each, look up which canned reports are available, and enroll or remove users from a specific course — one action at a time. Trigger phrases include "admin roster", "list accounts", "sub accounts", "account users", "users in this account", "enroll a user", "remove an enrollment", "account reports", or "what accounts can I see". Uses write tools: enroll_user, remove_enrollment. The workflow asks you to confirm before each write.
canvas-at-risk-studentsIdentify at-risk Canvas students and send targeted outreach. Surfaces students with missing assignments, low grades, or declining submission patterns — then lets you message them directly. Trigger phrases include "at-risk students", "struggling students", "who's falling behind", "students to check in with", or "missing submissions". Uses write tools: send_conversation. The workflow asks you to confirm before each write.
canvas-course-pulseEducator skill for tracking week-over-week course health trends in Canvas. Surfaces assignment performance trends, login activity, engagement gaps, and struggling students across a longer time horizon than a daily check. Trigger phrases include "course pulse", "course health", "course trends", "week-over-week performance", "how is the course going", "engagement trends", "who isn't logging in", or "course activity over time".
canvas-course-qcLearning designer quality-control checklist for Canvas courses. Walks modules, pages, assignments, and rubrics to surface structural issues — broken item sequences, missing rubrics, empty modules, unpublished content — before a course goes live. Trigger phrases include "course QC", "course quality check", "review course structure", "pre-launch audit", "check course content", or "canvas course review".
canvas-course-requirementsStudent plan for one Canvas course, built from the requirement graph instead of guessed from raw module flags. Shows what is genuinely left, what is blocked, and what Canvas cannot yet say either way, with the endpoint and field behind every verdict. Trigger phrases include "what do I still have to do in this course", "what's left in this course", "am I done with this module", "what's blocking me", "why is this item locked", "module requirements", or "course requirements".
canvas-discussion-facilitatorEducator skill for browsing, reading, replying to, and creating Canvas discussion topics. Surfaces active threads, unread entries, and announcement activity — then lets you post replies or create new topics without leaving your agent session. Trigger phrases include "discussion board", "course discussions", "reply to discussion", "create a discussion", "what's in the discussion forum", "check announcements", or "post to discussion". Uses write tools: create_discussion, post_discussion_entry, update_discussion. The workflow asks you to confirm before each write.
canvas-gradebook-auditAudit gradebook changes and grade edit history in Canvas. Surfaces who changed which grades, when, and by how much — across a date range or for a specific student. Unique to canvas-lms-mcp (no competitor exposes gradebook history). Trigger phrases include "grade audit", "who changed this grade", "gradebook history", "grade edits", "check for grade changes", or "grade integrity".
canvas-grading-passEducator grading workflow for Canvas. Walks through ungraded submissions one at a time, applying rubric assessments and score comments with explicit confirmation before each write. Trigger phrases include "grade submissions", "start grading", "grading pass", "mark submissions", "grade this assignment", or "rubric grading". Uses write tools: comment_on_submission, grade_submission, submit_rubric_assessment. The workflow asks you to confirm before each write.
canvas-morning-checkEducator morning briefing for Canvas. Surfaces ungraded submissions, participation gaps, upcoming deadlines, and flagged students across all active courses — in under a minute. Trigger phrases include "morning Canvas check", "what needs my attention today", "grading queue", "educator briefing", "what's pending", or "Canvas daily summary".
canvas-office-hoursEducator skill for running office hours through Canvas Scheduler appointment groups. Create and publish sign-up slots for a course, list existing groups and their time slots, and see which students (or student groups) have reserved — one confirmed action at a time. Trigger phrases include "office hours", "appointment group", "Canvas Scheduler", "sign-up slots", "create office hours", "who signed up for office hours", "manage appointment slots", "publish office hours", or "schedule office hours". Uses write tools: create_appointment_group, delete_appointment_group, update_appointment_group. The workflow asks you to confirm before each write.
canvas-outcome-trackerTrack student mastery of learning outcomes in Canvas. Shows outcome rollups by student, mastery distribution across the class, and which outcomes have the lowest proficiency rates. Built for accreditation reviews, program assessment, and advising. Trigger phrases include "outcome tracker", "learning outcomes", "mastery data", "accreditation report", "outcome mastery", or "who hasn't mastered".
canvas-peer-review-trackerEducator skill for tracking peer-review assignments in Canvas. Lists who has been asked to review whom, who has submitted versus who is still pending, and lets you assign new reviewers or send reminder messages — one student at a time. Trigger phrases include "peer reviews", "who hasn't done their peer review", "peer review status", "assign a peer reviewer", "remind students about peer reviews", or "peer review tracker". Uses write tools: create_peer_review, delete_peer_review, send_conversation. The workflow asks you to confirm before each write.
canvas-quiz-reviewEducator skill for reviewing Canvas quiz performance and regrading individual question scores. Surfaces struggling questions, low-scoring students, and per-student answer breakdowns — then lets you adjust scores for specific questions without leaving your agent session. Unique to canvas-lms-mcp (no other Canvas MCP server exposes quiz tools). Trigger phrases include "quiz review", "quiz results", "struggling quiz questions", "quiz scores", "regrade a quiz question", "quiz performance", or "student quiz answers". Uses write tools: score_quiz_question. The workflow asks you to confirm before each write.
canvas-student-todoStudent action list for Canvas. Surfaces every incomplete to-do item, missing submission, and upcoming deadline in one prioritised view — no calendar, no context switching. Trigger phrases include "what do I need to do", "my Canvas to-dos", "student to-do list", "what's missing", "catch me up", or "what should I work on".
canvas-syllabus-coachLearning designer skill for reviewing and improving Canvas course syllabi and front pages. Reads the syllabus and key pages, proposes clarity and completeness improvements, then optionally applies the edits with your confirmation. Trigger phrases include "syllabus review", "improve the syllabus", "syllabus coach", "course front page", "update course description", "review course pages", or "polish the syllabus". Uses write tools: create_page, update_course, update_page. The workflow asks you to confirm before each write.
canvas-week-planStudent weekly planner for Canvas. Pulls upcoming assignments, due dates, current grades, pending submissions, and peer review obligations into a single prioritised plan for the week ahead. Trigger phrases include "plan my week", "what's due this week", "weekly Canvas plan", "week ahead", or "upcoming assignments".

Resources

Contextual data attached and managed by the client

NameDescription
Course StructureInteractive course structure tree
Institution AnnouncementsInteractive institution announcements panel

TDQS

A3.6/5.0

Scored across 185 tools

Disambiguation3/5

Descriptions are unusually diligent about carving boundaries (e.g. list_quiz_questions vs get_quiz_question_responses vs list_new_quiz_items, or list_course_users vs list_students vs list_account_users), which rescues a lot. But the sheer number of near-pairs still creates real misselection risk: get_course_structure vs view_course_structure return the same payload, list_discussions vs list_group_discussions vs list_announcements share an index, and the eight get_outcome_* tools plus three gradebook-history tools are hard to tell apart at a glance. New Quiz vs Classic Quiz pairs are distinguished only by remembering which engine a given ID belongs to.

Naming Consistency4/5

The dominant pattern is a clean snake_case verb_noun convention (list_*, get_*, create_*, update_*, delete_*, search_*, set_*) applied consistently across ~150 tools. Outliers are few and purposeful — project_grade, explain_grade, explain_grading_policy, check_course_setup, audit_course_links, next_appointment, health_check — where the verb is descriptive rather than CRUD. No mixed casing.

Tool Count1/5

185 tools for one LMS integration is an extreme surface that no agent can select from reliably; the context cost alone is prohibitive. Whole clusters (8 outcome tools, 3 gradebook-history tools, 4 quiz-accommodation tools, 4 appointment-group membership tools, account admin tooling) sit far outside a typical instructor/student workflow. This needs aggressive grouping or profile-based subsetting.

Completeness4/5

Coverage is remarkably broad — courses, assignments, overrides, submissions, rubrics, both quiz engines, files, modules, pages, discussions, enrollments, groups, outcomes, analytics, accounts, calendar, conversations, peer reviews, migrations, Scheduler, and several cross-cutting audit/advisor tools. Gaps are minor and mostly life-cycle: no delete_course, no folder create/delete, no update_file, no Classic quiz creation, and no group-scoped discussion reply or edit.

Maintenance

ActivityActive
ResponsivenessSyncing