canvas-teacher-mcp
This server automates Canvas LMS instructor tasks: it reads courses, assignments, and quizzes; builds assignment pages and quizzes; posts announcements (with preview); runs a staged grading workflow (propose rubric → machine grading → post grades); and provides global skills for GitHub coding assignments, Google Docs, module overviews, and publisher quiz banks, all while never deleting or publishing content directly.
Setup & Configuration: Register schools and courses by URL, manage course configs, list registered courses, and retrieve course coordinates (Canvas ID, base URL, output paths).
Reading & Managing Content: Fetch and list pages, modules, assignments, quizzes, quiz questions, students, submissions, rubrics, assignment groups, and extract/classify links from Canvas HTML.
Creating & Updating Content: Create and update pages, assignments (due dates, points), modules, module items, quizzes (time limits, attempts), and quiz questions. Set due dates across multiple assignments. All new content is unpublished by default.
Specialized Content Generation: Build coding assignment pages (GitHub-backed specs), notebook assignment pages, weekly agendas, module overviews, formatted Google Docs, and quizzes from plain-text publisher test banks.
Announcements: Preview before sending; post only after explicit confirmation.
Grading Workflow: Identify assignments needing grading; list/submissions (with attachments, classification); read assignment instructions as students saw them; propose rubrics; run machine grading (Stage A, scores only); post grades and comments (dry-run default, explicit confirmation required). Fix mode for correcting errors. Supports grading of notebook and GitHub coding assignments.
GitHub & Google Workspace Integration: Create GitHub coding assignment repos (solution, tests, starter), format Google Docs and Slides, read/format Google Docs via CLI.
Direct API Access: Call any Canvas API endpoint (DELETE blocked) for uncovered functionality.
Safety Constraints: No content deletion; no publishing of created content by default; no arbitrary code execution; credentials stored locally; explicit confirmation for destructive or sensitive actions.
Allows reading and writing Canvas LMS course content: courses, modules, assignments, quizzes, pages, announcements, and submissions, with support for authentication and course setup.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@canvas-teacher-mcpCreate an assignment for next Tuesday in my Economics course."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
canvas-teacher-mcp
An MCP server for Canvas LMS, from the instructor's side. Ask your assistant to read a course, build an assignment page or a quiz, post an announcement, or run a grading pass — it calls Canvas for you.
v0.1.0. Everything is created unpublished and nothing is ever deleted.
Install
Point your MCP client at it. Nothing to install by hand — uvx fetches it on first run.
{
"mcpServers": {
"canvas-teacher": {
"command": "uvx",
"args": ["canvas-teacher-mcp"],
"env": { "CANVAS_LMS_ROOT": "/absolute/path/to/your/teaching/folder" }
}
}
}Claude Desktop — Settings → Developer → Edit Config opens the file. Add the entry inside the
existing mcpServers object rather than replacing it, then quit and reopen the app. A GUI app does
not inherit your shell PATH, so if the server does not appear, give the full path to uvx
(which uvx will tell you).
Claude Code — the same JSON in .mcp.json at your project root. Servers attach when a session
starts, so open a new one.
Codex — ~/.codex/config.toml, TOML rather than JSON, with the environment in a table of its
own:
[mcp_servers.canvas-teacher]
command = "uvx"
args = ["canvas-teacher-mcp"]
[mcp_servers.canvas-teacher.env]
CANVAS_LMS_ROOT = "/Users/you/Teaching"Use a plain chat or the codex CLI: inside a Codex Desktop project, no MCP tools appear at
all, while codex mcp list still shows the server — which makes it read as a setup mistake when
it is not (openai/codex #25843).
CANVAS_LMS_ROOT is the one thing you choose: the folder your courses live in. It is required
— the server keeps no root of its own, so this declaration is the only place it is written, and
you can always see what it is. Leave it out and the server says so on connect, telling your
assistant which file to add it to.
The folder need not exist yet; setup creates what it needs. An environment already exporting
CANVAS_LMS_ROOT works too — the server just reads the environment, and does not care how a
value got there.
Updating. uvx remembers which versions exist, not only the ones it downloaded, so a new
release can go unnoticed. To pick one up, either run it once with --refresh-package:
uvx --refresh-package canvas-teacher-mcp canvas-teacher-mcpor put those two arguments in front of the package name in the declaration above, and the check
happens every time your client starts it. (uv cache clean canvas-teacher-mcp does not do
this — it removes the downloaded package and keeps the stale list of versions.)
To try a change before it is released, point at the repository instead:
"args": ["--from", "git+https://github.com/Canvas-LMS-MCP/canvas-teacher-mcp", "canvas-teacher-mcp"]
Related MCP server: Canvas Agent
First run
Say "set up Canvas". Setup answers one step at a time; you relay what it asks for.
you set up Canvas
setup course root: /Users/you/Teaching
skills: read from this package
workflow: read from this package
schools: none registered
Next: what is your Canvas address? e.g. https://myschool.instructure.com
you https://myschool.instructure.com
setup Created /Users/you/Teaching/.claude/Canvas-Auth/myschool.json
Two ways to finish, and the first keeps the token out of this conversation:
1. Open that file and paste the token into its empty "token" field,
then ask me to run setup again — I will verify it.
2. Tell me the token and I will store it. It will then live in this
conversation's record as well as the file.
The token comes from Canvas: Account -> Settings -> + New Access Token.The file it made:
{
"base_url": "https://myschool.instructure.com/api/v1",
"token": ""
}Paste your token between those quotes, save, and say "run setup again":
setup schools: myschool
myschool: signed in as Your NameA token that Canvas rejects is never stored, and a token already stored is never overwritten.
No token at your school? Some run SSO only. Say so — the server opens a browser once, you log in as usual, and the session is saved and refreshed from then on.
Add a course
Give the assistant the course's Canvas URL.
you add this course: https://myschool.instructure.com/courses/12345
setup Registered Intro to Programming as slug 'cs101'.
Config: /Users/you/Teaching/CS101/.claude/course-config/cs101.json
School: myschool (guessed from the domain — say so if it is wrong)
Tools now take course='cs101'.It read the course's own name and code from Canvas; the slug and the folder are proposals. To put it somewhere else, say so: "add it under Fall2026/CS101".
The config is two lines, because the rest is derived:
{
"canvas_url": "https://myschool.instructure.com/courses/12345",
"school": "myschool"
}course_id, base_url, domain and the token variable all come from that URL. Add more only
when a feature needs it: github_org for GitHub assignments, db_path for grading records,
drive_folder for Google Docs, output_dir to write somewhere other than the default.
Registering is for convenience — it is what lets tools take course='cs101' instead of an id.
Authentication is per SCHOOL, so any course on that domain is reachable by id without registering.
Where things end up
<ROOT>/
├─ .claude/
│ ├─ Canvas-Auth/<school>.json your credentials — never leaves this machine
│ ├─ skills/ (optional) the methods, if you copy them to edit
│ └─ CourseGlobalWorkflow/ (optional) the working rules, same
└─ AVC/ one folder per school
└─ CS101/
└─ .claude/
├─ course-config/cs101.json the course's coordinates
├─ input/ material you bring in
└─ output/<kind>/ everything the server writesRegistering a course proposes <school>/<course>; pass course_dir for anything else, and any
depth works — a school whose departments are separate can put a level between them.
Credential files are written owner-only, and an existing world-readable one is corrected the next
time setup runs. Keep Canvas-Auth/ out of git: one token in a history is a token to revoke.
Skills and the working rules need no copying. They are read from inside the package and work as they are. Copy them into your tree only when you want to CHANGE them — grading policy, late grace, rubric splits, the tone of a comment. The packaged copies are replaced on every upgrade, so an edit there is lost; an edit in your tree survives.
What it does
Read — courses, modules and their items, assignments, quizzes and questions, pages, submissions with their attachments fetched and read (PDF, images, Office files, notebooks), students, and every link or embed inside a page, module or quiz.
Write — pages, modules, assignments, quizzes and their questions, due dates, module items. An announcement is previewed first and sent only when you say so.
Build — a coding assignment page from a spec, a notebook assignment page, a weekly agenda, a module overview, a formatted Google Doc, a quiz from a plain-text question bank, and a student starter repository from a solved assignment.
Grade — read the assignment as the student saw it, propose the rubric, run the machine pass, and post the result when you ask for that separately. A grading run stops at a report; posting is its own step, defaults to a dry run, and refuses to post evidence that was never read.
Anything else — canvas_api_request calls any Canvas endpoint the tools above do not cover.
What it will not do
Delete. No tool removes a page, an assignment, a submission or a course, and the direct API call refuses DELETE.
Publish. Everything is created unpublished. Publishing stays yours.
Run arbitrary code. There is no shell here, and no
run_python.
Notes that will save you a morning
The Canvas API answers 200 to several calls that change nothing. This server sends the forms Canvas actually accepts:
a grade must be form-encoded; as JSON it returns 200 and sets nothing
a quiz-question update needs the FULL payload, or it applies nothing
question_countstays cached until the quiz is touched againseconds_late_overrideis ignored when sent withlate_policy_statussubmission comments render HTML in SpeedGrader, but the API returns them flattened — the API response is not proof of what the student sees
Requirements
Python 3.10+, which uvx provides. A school without API tokens also needs Playwright's Chrome,
installed on the first browser login. GitHub assignment tools need git and gh; Google Docs
need the gws CLI.
License
MIT.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA local MCP server for Canvas LMS that enables querying courses, assignments, grades, modules, and more from any MCP-compatible AI client.19MIT
- AlicenseAqualityBmaintenanceMCP server that connects AI assistants to Instructure Canvas LMS, enabling teachers and administrators to manage courses, assignments, grades, and more through natural language.80291MIT
- FlicenseNot gradedqualityDmaintenanceMCP server for Canvas LMS that exposes courses, assignments, modules, pages, files, grades, and submissions as tools for AI agents.
- AlicenseNot gradedqualityDmaintenanceA teacher-facing MCP server that wraps the Canvas LMS REST API, enabling AI assistants to create and manage course content across multiple Canvas courses.19MIT
Related MCP Connectors
Educational MCP server with 17 math/stats tools, visualizations, and persistent workspace
MCP server for the Inistate platform: module discovery, entry management, and activity submission.
MCP server for generating rough-draft project plans from natural-language prompts.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Canvas-LMS-MCP/canvas-teacher-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server