Canvas LMS MCP Server
MCP serverDev toolsYour AI can work directly in Canvas LMS once this integration is added, taking on tasks across the learning platform. It brings 165 tools covering 42 areas of Canvas, so a broad range of coursework can be handled with a simple request. Everyday tasks can then be done without opening Canvas itself.
Unavailable. This server has no hosted endpoint yet, so ahel can't serve it.
Once it is added, tell your AI what you want done in Canvas in everyday language. It will choose from the 165 available tools to carry out the task.
What your AI can do with it
- Connect your AI to Canvas LMS
- Carry out Canvas tasks from your conversation
- Use 165 ready-made tools for Canvas work
- Work across 42 areas of the platform
- Get coursework done without opening Canvas itself
From the project's README
As published by bruchris/canvas-lms-mcp in README.md.
The TypeScript MCP server for Canvas LMS.
MCP server for Canvas LMS. Read courses, assignments, submissions, rubrics, quizzes; grade, comment, manage course content, and handle Canvas admin workflows from any AI agent.
165 tools across Canvas courses, assignments, submissions, gradebook history, rubrics, quizzes, New Quizzes (LTI), files, users, groups, enrollments, discussions, modules, pages, calendar, conversations, peer reviews, accounts, analytics, outcomes, grading standards, grade projection, link audit, accessibility audit, content exports, content migrations, quiz accommodations, appointment groups, student workflows, student search, dashboard, instructor attention workflows, and health checks. Three deployment modes: stdio, HTTP, and library import.
One-click install (Claude Desktop)
- Download
canvas-lms-mcp.mcpbfrom the latest release. - Double-click the file (or drag it into Claude Desktop's Extensions settings).
- When prompted, paste your Canvas API token and Canvas base URL — your institution's origin only, e.g.
https://school.instructure.com(do not append/api/v1). Teachers and staff handling student data can also flip FERPA mode — pseudonymize students on in the same dialog (what it does).
No terminal, no Node.js install, no config-file editing — Claude Desktop bundles the runtime and handles config for you. The same .mcpb works in Claude Code and MCP for Windows.
Prefer the terminal? Use the Quick Start below.
One-click install (Cursor / VS Code)
Click a badge to open Cursor or VS Code with canvas-lms-mcp pre-configured (placeholder credentials filled in — replace with your actual Canvas API token and base URL after install). For manual config-file setup, see docs/manual-setup.md.
One-click install (Claude Code plugin)
/plugin marketplace add bruchris/canvas-lms-mcp
/plugin install canvas-lms-mcp
Installs the MCP server (via npx canvas-lms-mcp) and all 16 Agent Skills in a single step, versioned and updatable through Claude Code's plugin manager. On enable, Claude Code prompts for your Canvas API token and base URL (and the optional FERPA pseudonymization settings). See the Claude Code plugins reference for how marketplaces and plugin manifests work.
Comparison
| canvas-lms-mcp | vishalsachdev/canvas-mcp | DMontgomery40/mcp-canvas-lms | |
|---|---|---|---|
| Language | TypeScript | Python | TypeScript |
| Tools | 165 | 80+ | 54 |
| License | |||
| Last commit |
Quick Start
1. Get a Canvas API Token
- Log in to your Canvas instance
- Go to Account > Settings
- Scroll to Approved Integrations and click + New Access Token
- Give it a name (e.g., "MCP Server") and click Generate Token
- Copy the token immediately -- you won't see it again
2. Run the Setup Wizard
npx canvas-lms-mcp init
The wizard detects your installed AI clients (Claude Desktop, Cursor, VS Code, Windsurf, Codex, Continue, Claude Code), prompts for your Canvas token and base URL, validates the credentials against your Canvas instance, and writes the config for every client you select.
add-mcp is also supported as a generic alternative: npx add-mcp canvas-lms-mcp.
For clients not yet supported by the wizard, or if you prefer editing config files by hand, see docs/manual-setup.md.
Agent Skills
Install reusable Canvas workflows into Claude Code, Cursor, GitHub Copilot, Cline, and 40+ other AI agents:
npx skills add bruchris/canvas-lms-mcp
| Skill | Description |
|---|---|
canvas-at-risk-students | Surface students with missing assignments or declining grades and send targeted outreach |
canvas-gradebook-audit | Inspect the full grade-change audit trail — who changed what grade, when, and by how much |
canvas-outcome-tracker | Track learning outcome mastery and class-wide proficiency for accreditation and program review |
canvas-accessibility-sweep | Pre-launch WCAG accessibility and broken-link sweep of a course, with a prioritised remediation list |
canvas-office-hours | Create, publish, and manage Canvas Scheduler office-hour sign-up slots and see who reserved |
Skills are markdown workflow files (no extra dependencies). They work with the MCP server you already have installed. See the skills/ directory for the full list.
Example Prompts
Once configured, try these prompts with your AI client:
- "List all my active courses"
- "Show me the assignments for course 12345"
- "What's the average grade on the midterm exam?"
- "Grade Alice's essay submission with a B+ and add feedback"
- "Show me the rubric for the final project"
- "What discussions are happening in my Biology course?"
- "List all upcoming calendar events for course 12345"
- "Send a message to student 67890 about their missing assignment"
Tool Inventory
All Registered Tools (165)
| Category | Tools |
|---|---|
| Health | health_check |
| Courses | list_courses, get_course, get_syllabus, create_course, update_course |
| Assignments | list_assignments, get_assignment, list_assignment_groups, create_assignment, update_assignment, delete_assignment |
| Assignment Overrides | list_assignment_overrides, create_assignment_override, set_student_assignment_dates |
| Submissions | list_submissions, get_submission, grade_submission, comment_on_submission |
| Submissions Awaiting Grading | list_submissions_awaiting_grading |
| Submission Files | list_course_submission_files |
| Rubrics | list_rubrics, get_rubric, get_rubric_assessment, submit_rubric_assessment, create_rubric |
| Quizzes | list_quizzes, get_quiz, list_quiz_submissions, list_quiz_questions, get_quiz_submission_answers, score_quiz_question, get_quiz_submission_events |
| Quiz Question Responses | get_quiz_question_responses |
| Quiz Accommodations | list_student_quiz_accommodations, set_student_quiz_accommodation |
| New Quizzes (LTI) | create_new_quiz, update_new_quiz, delete_new_quiz, list_new_quiz_items, get_new_quiz_item, create_new_quiz_item, update_new_quiz_item, delete_new_quiz_item |
| New Quiz Accommodations | list_student_new_quiz_accommodations, set_student_new_quiz_accommodation |
| Files | list_files, list_folders, get_file, upload_file, download_file, delete_file, find_duplicate_files |
| Gradebook History | list_gradebook_history_days, get_gradebook_history_day, list_gradebook_history_submissions, get_gradebook_history_feed |
| Grade Explanation | explain_grade |
| Grading Policy | explain_grading_policy |
| Grade Projection | project_grade |
| Grading Standards | list_grading_standards, create_grading_standard, apply_grading_standard_to_course |
| Users | list_students, get_user, get_profile, search_users, list_course_users |
| Groups | list_groups, list_group_members |
| Enrollments | list_enrollments, list_course_enrollments, enroll_user, remove_enrollment |
| Discussions | list_discussions, get_discussion, list_announcements, post_discussion_entry, create_discussion, update_discussion, delete_discussion |
| Modules | list_modules, get_module, list_module_items, get_course_structure, view_course_structure, create_module, update_module, create_module_item |
| Pages | list_pages, get_page, create_page, update_page, delete_page |
| Calendar | list_calendar_events, create_calendar_event, update_calendar_event |
| Conversations | list_conversations, get_conversation, get_conversation_unread_count, send_conversation |
| Peer Reviews | list_peer_reviews, get_submission_peer_reviews, create_peer_review, delete_peer_review |
| Accounts | get_account, list_accounts, list_sub_accounts, list_account_courses, list_account_users, get_account_reports, list_account_notifications, view_account_notifications |
| Analytics | search_course_content, get_course_analytics, get_student_analytics, get_course_activity_stream, get_assignment_analytics |
| Outcomes | get_root_outcome_group, list_outcome_groups, list_outcome_group_links, get_outcome_group, list_outcome_group_outcomes, list_outcome_group_subgroups, get_outcome, get_outcome_alignments, get_outcome_results, get_outcome_rollups, get_outcome_contributing_scores, get_outcome_mastery_distribution |
| Content Exports | list_content_exports, get_content_export, create_content_export |
| Course Setup | check_course_setup |
| Link Audit | audit_course_links |
| Accessibility Audit | audit_course_accessibility |
| Appointment Groups | list_appointment_groups, get_appointment_group, create_appointment_group, update_appointment_group, delete_appointment_group, list_appointment_group_users, list_appointment_group_groups, next_appointment |
| Student | get_my_courses, get_my_grades, get_my_submissions, get_my_upcoming_assignments, get_my_submission_feedback |
| Student Search | find_student_across_courses |
| Dashboard | get_dashboard_cards, get_todo_items, get_upcoming_events, get_missing_submissions |
| Attention | list_submission_comments_needing_attention, list_students_needing_attention |
| FERPA (conditional) | resolve_pseudonym — stdio only, registered when CANVAS_PSEUDONYMIZE_STUDENTS=true and CANVAS_PSEUDONYMIZE_REVERSE_LOOKUP=true |
117 tools are read-only and 48 tools perform Canvas write operations. When FERPA mode is enabled on the stdio transport, resolve_pseudonym is registered as the 166th tool overall (118th read tool). The HTTP transport never registers it — see FERPA mode.
All write tools require appropriate Canvas permissions. Canvas enforces its own permission model -- the MCP server does not bypass it.
Bulk operations
Canvas applies rate limits per-user. When creating many New Quizzes items (e.g., RAG-generated quizzes), call the tools serially rather than in parallel. For >50 items, chunk and pause between batches. If you hit a rate-limit error, wait a few seconds and retry.
MCP Resources (2)
| Resource | URI Template | Type |
|---|---|---|
| Course Syllabus | canvas://course/{courseId}/syllabus | text/html |
| Assignment Description | canvas://course/{courseId}/assignment/{assignmentId}/description | text/html |
Structured output
Some tools return machine-readable structuredContent alongside their text content, validated against an outputSchema the server advertises in tools/list. Migration is per tool, so the two surfaces coexist:
| Client behaviour | Migrated tool | Unmigrated tool |
|---|---|---|
Reads content[0].text | Works, byte-identical to before | Works |
Reads structuredContent | Works | Field is absent |
Validates against outputSchema | Works | No schema advertised |
Three guarantees hold for every migrated tool:
- The text content is unchanged.
content[0].textcarries exactly the bytes it did before migration.structuredContentis added alongside it, never in place of it, so text-only clients and the interactive widgets are unaffected. - Canvas fields we do not declare are passed through, not stripped or rejected. Entity schemas are open, because Canvas ships new fields continuously and a closed schema would turn each one into a failed tool call. Only the envelopes this server authors itself are closed.
- Errors are never structured. A tool failure returns
isError: truewith plain text, exactly as before.
A tool returning a list wraps it under a single plural key, since MCP requires an output schema to be an object:
{
"content": [{ "type": "text", "text": "[ ... unchanged JSON ... ]" }],
"structuredContent": { "pages": [ /* the same value */ ] }
}
Which tools are migrated is recorded per tool as structuredOutput in docs/generated/tool-manifest.json (manifest schema 1.1). Currently: the five pages tools.
JSON Schema dialect
Every advertised inputSchema and outputSchema declares JSON Schema 2020-12 ("$schema": "https://json-schema.org/draft/2020-12/schema").
@modelcontextprotocol/sdk v1 converts Zod with a fixed draft-07 target and registerTool accepts no override, so the server re-declares the dialect on the tools/list response. That is a declaration change only: CI asks the SDK's own converter for both dialects and requires the emitted bodies to be byte-identical for every registered schema, with a tuple schema as the control for a case where the two genuinely differ. A 2020-12-only validator (Ajv's 2020 entry point, the same family Claude Desktop uses) compiles all 168 schemas in the guard suite.
Clients that support 2020-12 only rejected the five tools advertising an outputSchema before this — see #341. The rewrite is installed during tool registration rather than in a transport, so stdio, HTTP and the library factory are all covered.
Interactive widgets
view_course_structure is an MCP Apps tool: hosts that support the spec render an interactive tree explorer (collapsible modules, type-filter chips, title search, published/unpublished badges, links open in a new tab); hosts that don't fall back transparently to the same JSON payload that get_course_structure returns. The widget is self-contained — no external scripts, fonts, or network calls — and is shipped inline with the tool definition.
| Tool | UI resource URI | Fallback |
|---|---|---|
view_course_structure | ui://canvas-lms-mcp/course-structure.html | Same JSON payload as get_course_structure |
Host verification (Claude Desktop, ChatGPT, Codex fallback) is performed manually after each release, since it requires real Canvas credentials. A screenshot will be added once the first verified host pass lands.
Deployment Modes
stdio (Default)
For local AI clients like Claude Desktop, Cursor, and VS Code. The server communicates over stdin/stdout.
npx canvas-lms-mcp --token $CANVAS_API_TOKEN --base-url $CANVAS_BASE_URL
HTTP
For web-based clients or hosted services. Starts an HTTP server with Streamable HTTP transport.
npx canvas-lms-mcp serve \
--token $CANVAS_API_TOKEN \
--base-url $CANVAS_BASE_URL \
--port 3001 \
--allowed-origin https://your-app.example.com
Endpoints:
POST /mcp-- MCP protocol endpointGET /health-- Health check (returns{"status":"ok"})
Docker
docker compose up -d
Requires CANVAS_API_TOKEN and CANVAS_BASE_URL environment variables. See docker-compose.yml.
services:
canvas-lms-mcp:
build: .
ports:
- "3001:3001"
environment:
- CANVAS_API_TOKEN=${CANVAS_API_TOKEN}
- CANVAS_BASE_URL=${CANVAS_BASE_URL}
Library Import
Use the server factory directly in your own Node.js application:
import { createCanvasMCPServer } from 'canvas-lms-mcp'
const { server, canvas } = createCanvasMCPServer({
token: userToken,
baseUrl: canvasBaseUrl,
})
Or use the Canvas client standalone (no MCP dependency):
import { CanvasClient } from 'canvas-lms-mcp/canvas'
const canvas = new CanvasClient({
token: userToken,
baseUrl: canvasBaseUrl,
})
const courses = await canvas.courses.list()
CLI Reference
| Flag | Env Variable | Default | Description |
|---|---|---|---|
--token | CANVAS_API_TOKEN | (required) | Canvas personal access token |
--base-url | CANVAS_BASE_URL | (required) | Canvas instance URL |
serve | -- | stdio mode | Switch to HTTP mode |
--port | -- | 3001 | HTTP server port |
--allowed-origin | CANVAS_ALLOWED_ORIGIN | http://localhost:3000 | CORS allowed origin |
--role | CANVAS_ROLE | (all tools) | Filter tools by Canvas role: student, teacher, or admin (see Role-based tool filtering) |
--destructive-tools=<mode> | CANVAS_DESTRUCTIVE_TOOLS | allow | allow or block. block unregisters the seven irreversible delete tools (see Destructive tool policy) |
Environment Variables
| Variable | Required | Description |
|---|---|---|
CANVAS_API_TOKEN | Yes | Canvas personal access token |
CANVAS_BASE_URL | Yes | Canvas instance URL (e.g., https://school.instructure.com) |
CANVAS_ALLOWED_ORIGIN | No | CORS origin for HTTP mode (default: http://localhost:3000) |
CANVAS_ROLE | No | Filter the tool list by role: student, teacher, or admin (see Role-based tool filtering) |
CANVAS_ENABLE_ASSIGNMENT_SUBMISSION | No | Set to true to register the opt-in assignment submission tools |
CANVAS_PSEUDONYMIZE_STUDENTS | No | Set to true to enable FERPA mode |
CANVAS_PSEUDONYMIZE_REVERSE_LOOKUP | No | stdio only. Set to true (with CANVAS_PSEUDONYMIZE_STUDENTS=true) to register the resolve_pseudonym audit tool. Ignored on the HTTP transport, with a warning |
CANVAS_PSEUDONYM_DIR | No | Absolute path that overrides the default pseudonym map directory |
CANVAS_PSEUDONYM_AUDIT_LOG | No | Path to an append-only file that mirrors resolve_pseudonym audit lines (stderr is always written) |
CANVAS_PROVENANCE_FENCING | No | On by default. Set to exactly false to disable provenance fencing |
CANVAS_DESTRUCTIVE_TOOLS | No | allow (default) or block. Set to exactly block to unregister the seven irreversible delete tools (see Destructive tool policy) |
Destructive tool policy
Canvas has no undo. This server cannot restore anything it deletes -- every recovery
story for a mistaken delete is something you do outside this tooling, in Canvas or
with your institution's admin. CANVAS_DESTRUCTIVE_TOOLS=block removes the seven
irreversible delete tools from the server entirely, so no amount of model confusion
or prompt injection can reach them.
CANVAS_DESTRUCTIVE_TOOLS=block canvas-lms-mcp --base-url https://school.instructure.com
# or
canvas-lms-mcp --destructive-tools=block --base-url https://school.instructure.com
| Mode | Behaviour |
|---|---|
allow | Default. Every tool is registered -- unchanged from previous releases. |
block | The seven tools below are not registered at all. They are absent from tools/list, and a call naming one is refused by the MCP protocol layer before any Canvas request is made. |
Blocked by block:
| Tool | What is lost |
|---|---|
delete_assignment | The assignment plus its submissions and gradebook column |
delete_new_quiz | The quiz, all its items, and all student results |
delete_new_quiz_item | One question and its responses; re-authoring is manual |
delete_discussion | The whole reply thread, including student-authored posts |
delete_page | Page body and revision history (keyed by URL slug, not a numeric ID) |
delete_file | A file, addressed by a global ID with no course scoping in the call |
delete_appointment_group | Every reservation -- and it emails every signed-up student |
Not blocked: delete_peer_review. It is the only delete this server can itself
undo (create_peer_review recreates the row) and it destroys no authored content.
Notes:
Shortened here. Read the whole README on GitHub.
Signals
- GitHub stars
- 7
- Forks
- 4
- Last commit
- Sep 2026
- Weekly downloads
- 2k
- Weekly_downloads
- 2k weekly_downloads
Advanced
- Delivery
- canvas-lms-mcp MCP server → your ahel connector (mcp.ahel.ai) → your AI.
- Item type
- mcp-server
- Key
io-github-bruchris-canvas-lms-mcp- Source
- github.com/bruchris/canvas-lms-mcp