# canvas-lms-mcp [Health: Active]

**Category:** 🎓 Education  
**Repository:** https://github.com/bruchris/canvas-lms-mcp  
**GitHub Stars:** 10  
**npm Downloads (last month):** 9212  
**Views:** 2  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/canvas-lms-mcp

## Description
TypeScript MCP server for Canvas LMS — 115 read+write tools across 17 domains.

## Tools
Capabilities this server exposes over MCP:

- **health_check** — Check if the Canvas API is reachable and the token is valid. Returns ok/error status.
- **list_courses** — 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_course** — 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_syllabus** — Get the syllabus HTML body for a course.
- **create_course** — Create a new course in a Canvas account. Returns the created course object.
- **update_course** — Update an existing course. Only provided fields are changed; omitted fields are left as-is.
- **list_assignments** — 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_assignment** — Get details for a single assignment by ID. Use `include` to request submission, overrides, all_dates, score_statistics, and other optional fields.
- **list_assignment_groups** — 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** — Create a new assignment in a course.
- **update_assignment** — Update an existing assignment in a course.
- **delete_assignment** — Delete an assignment from a course. This action is permanent.
- **list_submissions** — 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_submission** — Get a single submission for a specific user on an assignment. Defaults to including submission_comments. Pass `include` to add rubric_assessment, submission_history, visibility, course, user, or read_status.
- **grade_submission** — Post or update a grade for a submission. Requires grading permissions.
- **comment_on_submission** — Add a text comment to a submission.
- **list_course_submission_files** — 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_grading** — 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_rubrics** — List all rubrics in a course.
- **get_rubric** — Get details for a single rubric by ID, including criteria. Use include=["assignment_associations"] to retrieve the rubric association IDs needed for rubric assessment writes.
- **get_rubric_assessment** — Get the rubric assessment for a specific student submission on an assignment.
- **submit_rubric_assessment** — Submit a rubric assessment with scores and comments for each criterion.
- **create_rubric** — 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_rubric** — 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_rubric** — Permanently delete a rubric from a course, removing it from every assignment it is attached to. Returns the deleted rubric.
- **list_quizzes** — List all quizzes in a course.
- **get_quiz** — Get details for a single quiz by ID.
- **list_quiz_submissions** — List all submissions for a quiz.
- **list_quiz_questions** — List all questions in a quiz.
- **get_quiz_submission_answers** — Get a student's answers for a quiz submission.
- **score_quiz_question** — Score a specific question in a quiz submission. Specify attempt to score a particular attempt (omit for latest). Requires grading permissions.
- **get_quiz_submission_events** — 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_quiz** — 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_question** — Permanently delete a single question from a Classic quiz. Classic Quizzes only; use delete_new_quiz_item for a New Quiz item.
- **create_new_quiz** — Create a New Quiz (LTI) in a Canvas course. New Quizzes is the modern quiz engine; for Classic quizzes use create_quiz.
- **update_new_quiz** — Update an existing New Quiz (LTI) in a Canvas course.
- **delete_new_quiz** — Delete a New Quiz (LTI) from a Canvas course. This action is permanent. Use assignment_id (not quiz_id).
- **list_new_quiz_items** — List all items (questions) in a New Quiz (LTI).
- **get_new_quiz_item** — Get a single item (question) from a New Quiz (LTI) by item ID.
- **create_new_quiz_item** — Create an item (question) in a New Quiz (LTI). Supports 5 types: choice (MCQ), true-false, essay, matching, numeric. Canvas may rate-limit rapid sequential creates. Call serially (not in parallel). For >50 items, chunk and pause between batches.
- **update_new_quiz_item** — Update an existing item (question) in a New Quiz (LTI). All fields are optional; supply only what changes. Canvas may rate-limit rapid sequential updates. Call serially (not in parallel). For >50 items, chunk and pause between batches.
- **delete_new_quiz_item** — Delete an item (question) from a New Quiz (LTI). This action is permanent.
- **get_quiz_question_responses** — 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. Scans one Canvas API call per completed or pending-review submission, plus one per attempt needed to resolve such questions. A failed per-submission 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.
- **list_files** — List all files in a course.
- **list_folders** — List all folders in a course.
- **get_file** — Get metadata for a single file by ID, including download URL.
- **upload_file** — Upload a file to a course. Content must be base64-encoded. Canvas performs a multi-step upload internally.
- **delete_file** — Delete a file by ID. This action is permanent.
- **download_file** — 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_files** — 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_days** — List the dates in a course gradebook history that contain grading activity, grouped by grader and assignment.
- **get_gradebook_history_day** — Get the graders and assignment IDs that had gradebook activity on a specific course date.
- **list_gradebook_history_submissions** — List versioned submission history for one grader and assignment on a specific gradebook history date.
- **get_gradebook_history_feed** — Get the paginated gradebook history feed for a course, optionally filtered by assignment or user and optionally sorted oldest-first.
- **list_students** — List all students enrolled in a course.
- **get_user** — Get details for a single user by ID.
- **get_profile** — Get the profile of the currently authenticated user.
- **search_users** — Search for users in a Canvas account by name, login, or email. Use `include` to request email, last_login, avatar_url, time_zone, or uuid in the response.
- **list_course_users** — 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_groups** — List all groups in a course.
- **list_group_members** — List all members of a group.
- **list_enrollments** — List all enrollments for the authenticated user across courses. Optional filters and includes mirror Canvas `GET /users/self/enrollments`.
- **list_course_enrollments** — 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_user** — Enroll a user in a course with a specified role.
- **remove_enrollment** — Remove or conclude an enrollment from a course. The 'delete' task is permanent; 'conclude' and 'deactivate' are reversible.
- **list_discussions** — List all discussion topics in a course.
- **get_discussion** — Get details for a single discussion topic by ID.
- **list_group_discussions** — List all discussion topics in a group.
- **get_group_discussion** — Get details for a single discussion topic in a group by ID.
- **list_announcements** — List all announcements in a course.
- **post_discussion_entry** — Post a new entry (reply) to a discussion topic.
- **create_discussion** — Create a new discussion topic in a course.
- **update_discussion** — Update an existing discussion topic.
- **delete_discussion** — Delete a discussion topic from a course. This action is permanent.
- **list_modules** — List all modules in a course.
- **get_module** — Get details for a single module by ID.
- **list_module_items** — List all items within a module.
- **get_course_structure** — 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_structure** — 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_module** — Create a new module in a course.
- **update_module** — Update an existing module (rename, reposition, publish/unpublish).
- **create_module_item** — Add an item (Assignment, Page, Quiz, File, Discussion, ExternalUrl, ExternalTool, SubHeader) to a module.
- **update_module_item** — 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_item** — 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_pages** — List all wiki pages in a course.
- **get_page** — Get a single wiki page by its URL slug.
- **create_page** — Create a new wiki page in a course.
- **update_page** — Update an existing wiki page.
- **delete_page** — Delete a wiki page from a course. This action is permanent.
- **list_calendar_events** — 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_event** — Create a new calendar event in Canvas.
- **update_calendar_event** — Update an existing calendar event. Only provided fields are changed.
- **list_conversations** — List conversations (inbox messages) for the authenticated user.
- **get_conversation** — Get a single conversation with its full message thread.
- **get_conversation_unread_count** — Get the number of unread conversations for the authenticated user.
- **send_conversation** — Send a new conversation message to one or more recipients.
- **list_peer_reviews** — List all peer reviews for an assignment in a course.
- **get_submission_peer_reviews** — List peer reviews assigned to a specific submission.
- **create_peer_review** — Assign a user to peer-review a submission.
- **delete_peer_review** — Remove a peer review assignment from a submission. This action is permanent.
- **get_account** — Get details for a Canvas account by ID.
- **list_accounts** — List all accounts accessible to the authenticated user.
- **list_sub_accounts** — List sub-accounts under a given Canvas account.
- **list_account_courses** — List courses under a given Canvas account.
- **list_account_users** — List users in a Canvas account.
- **get_account_reports** — List available report types for a Canvas account.
- **list_account_notifications** — List active global institution-wide announcements for the current user (maintenance windows, term deadlines, policy notices).
- **view_account_notifications** — 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_content** — Search for content within a course. Searches pages, assignments, discussions, and announcements by keyword.
- **get_course_analytics** — Get course-level activity analytics. Returns daily page view and participation counts.
- **get_student_analytics** — Get per-student activity analytics for a course. Returns page views, participations, and submission timeline for a specific student.
- **get_course_activity_stream** — Get a summary of recent activity in a course. Returns counts of recent events grouped by type (submissions, discussions, announcements, etc.).
- **get_assignment_analytics** — 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_group** — Get the root outcome group for an account or course context.
- **list_outcome_groups** — List all outcome groups for an account or course context.
- **list_outcome_group_links** — List all outcome links in an account or course context.
- **get_outcome_group** — Get details for a specific outcome group in an account or course context.
- **list_outcome_group_outcomes** — List the linked outcomes directly under a specific outcome group.
- **list_outcome_group_subgroups** — List the immediate child outcome groups under a specific outcome group.
- **get_outcome** — Get the full details for a specific learning outcome by ID.
- **get_outcome_alignments** — Get outcome alignments for a course, optionally filtered to a specific student or assignment.
- **get_outcome_results** — Get per-student outcome results for a course, with optional outcome, student, and alignment filters.
- **get_outcome_rollups** — Get outcome rollups for a course, optionally aggregated or filtered by students, outcomes, and sort options.
- **get_outcome_contributing_scores** — Get assignment or quiz scores that contributed to a specific outcome for one or more students in a course.
- **get_outcome_mastery_distribution** — Get mastery distribution analytics for outcomes in a course, optionally filtered by students or outcomes.
- **get_my_courses** — List active courses for the authenticated student.
- **get_my_grades** — Get grade data for the authenticated student. If course_id is omitted, returns grades across all enrolled courses.
- **get_my_submissions** — List all submissions for the authenticated student in a course.
- **get_my_upcoming_assignments** — 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_feedback** — 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_summary** — 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_stream** — 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_items** — 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).
- **find_student_across_courses** — 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_cards** — Get the current user's dashboard course cards with position, color, and image.
- **get_todo_items** — Get the current user's to-do items, including upcoming assignments and grading tasks.
- **get_upcoming_events** — 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.
- **get_missing_submissions** — Get assignments with missing submissions for the current user.
- **list_submission_comments_needing_attention** — 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_attention** — 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_export** — 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_export** — 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_exports** — List all content exports for a course (most recent first).
- **list_content_migrations** — List all content migrations for a course (most recent first).
- **get_content_migration** — 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_types** — 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_data** — 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_mapping** — 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_issues** — List issues encountered during a content migration. Each issue has a type (todo, warning, or error) and a description.
- **create_content_migration** — 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_standards** — 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_standard** — 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_course** — 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_accommodation** — 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_accommodations** — 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_accommodation** — 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_accommodations** — 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_overrides** — 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_override** — 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_dates** — 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_setup** — 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_grade** — 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_policy** — 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_grade** — 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_links** — 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_accessibility** — 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_groups** — List appointment groups (Canvas Scheduler sign-up slots). Use scope=reservable to find groups students can reserve, or scope=manageable for groups the current user manages.
- **get_appointment_group** — Get a single appointment group by ID, including its time slots and participant counts.
- **create_appointment_group** — Create a new appointment group (sign-up slots) in Canvas Scheduler. Provide at least one context_code (e.g. "course_123") and a title. Add new_appointments as [start_at, end_at] pairs to define time slots.
- **update_appointment_group** — Update an existing appointment group. Use publish=true to make a draft group visible to participants, or add new time slots via new_appointments.
- **delete_appointment_group** — Delete an appointment group and cancel any existing reservations. Provide cancel_reason to notify participants.
- **list_appointment_group_users** — List participants (users) who have reserved a slot in an appointment group.
- **list_appointment_group_groups** — List student groups that have reserved a slot in an appointment group (when participant_type=Group).
- **next_appointment** — Get the current user's next upcoming appointment across all (or specified) appointment groups.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "canvas-lms-mcp": {
    "command": "npx",
    "args": ["-y","canvas-lms-mcp"],
    "env": {
      "CANVAS_API_TOKEN": "",
      "CANVAS_BASE_URL": "",
      "CANVAS_PSEUDONYMIZE_STUDENTS": ""
    }
  }
}
```

**Requires environment variables:** `CANVAS_API_TOKEN`, `CANVAS_BASE_URL`, `CANVAS_PSEUDONYMIZE_STUDENTS` — the values above are empty placeholders; fill in real credentials before running (see the repository for what each one is for).

## Documentation

## What canvas-lms-mcp does

The canvas-lms-mcp MCP server connects AI clients to Canvas LMS through the Canvas REST API. It is intended for instructors, staff, and other authorized users who need to inspect or modify Canvas data from an MCP-compatible agent. The repository is written in TypeScript and supports stdio, HTTP, and library-import deployment modes.

The listed capabilities cover core academic administration. Agents can check API connectivity, enumerate courses and assignments, retrieve syllabus content, inspect submissions, review quizzes, and work with rubrics. Write operations include creating and updating courses and assignments, deleting assignments, grading submissions, adding submission comments, creating rubrics, attaching rubrics, and submitting rubric assessments. The broader project also documents workflows involving files, users, groups, enrollments, discussions, modules, pages, calendars, conversations, analytics, outcomes, and other Canvas areas.

## How it works

An MCP host launches or connects to the server, which uses the configured Canvas credentials to make API requests. Course and assignment listing tools offer slim responses for selection and fuller responses after an agent identifies a target. Optional Canvas include fields can add related data such as teachers, syllabus content, submissions, overrides, score statistics, or rubric associations.

Submission tools support filtering by student, workflow state, and grading period. The awaiting-grading workflow groups ungraded assignment and Classic Quiz submissions for triage, including submissions in submitted or pending_review states. New Quizzes may not expose pending review items through this workflow, and the tool does not provide per-question detail.

## Setup and configuration

The canvas-lms-mcp MCP server requires a Canvas API token and the base URL of the institution’s Canvas instance. The base URL should identify the institution origin, such as `https://school.instructure.com`, without appending `/api/v1`.

A terminal setup can be started with `npx canvas-lms-mcp init`. The wizard detects supported clients, asks for the token and base URL, validates the credentials, and writes configuration for selected clients. The package can also be installed through `npx add-mcp canvas-lms-mcp`. Claude Desktop users can install the provided `.mcpb` package, while Cursor, VS Code, and Claude Code have documented installation paths.

The optional FERPA setting `CANVAS_PSEUDONYMIZE_STUDENTS` replaces displayed student names with stable per-course pseudonyms. Raw Canvas user IDs remain available for stable identification, and `resolve_pseudonym` can be used where supported to recover an identity.

## Tools and capabilities

Core tools include:

- `health_check` for validating Canvas reachability and token validity.
- Course and syllabus discovery with `list_courses`, `get_course`, and `get_syllabus`.
- Assignment browsing and management through listing, retrieval, creation, updates, and deletion.
- Submission retrieval, grading, commenting, file manifests, and awaiting-grading triage.
- Rubric listing, creation, attachment, assessment retrieval, and assessment submission.
- Quiz listing, retrieval, question inspection, submission listing, and answer retrieval.

## Limitations and notes

Write actions depend on the Canvas permissions granted to the authenticated user. Deleting assignments and deleting rubrics are permanent operations. Submission download URLs are temporary; use the returned file ID to obtain a fresh URL when needed. File manifests are bounded by `max_files`, which defaults to 500.

The awaiting-grading workflow does not reliably surface New Quizzes pending review, does not show auto-marked fill-in-the-blank answers, and returns submission-level rather than question-level state. Student pseudonymization changes displayed names, so agents handling FERPA-sensitive data should account for that behavior.

_Full upstream README: https://allmcps.com/mcp/canvas-lms-mcp/readme_

