Canvas LMS MCP Server
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 LMS MCP ServerShow my current grades and upcoming assignments"
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 LMS MCP Server
A Model Context Protocol server that gives an MCP client (Claude Desktop, Claude Code, or anything else that speaks MCP) read-only access to your Canvas LMS account.
It answers two questions:
"What am I taking and how am I doing?" — active courses with current grades.
"What do I still owe and when is it due?" — outstanding assignments with due dates.
Communication uses the standard stdio transport, so the client launches the server as a subprocess. Nothing is written to stdout except MCP traffic.
Requirements
Node.js 18.17 or newer (the server uses the built-in
fetch)A Canvas personal access token
Related MCP server: Canvas MCP Server
Install
cd canvas-mcp-server
npm installConfiguration
Both variables are required; the server exits with a clear message if either is missing.
Variable | Description | Example |
| Your Canvas instance root. A trailing |
|
| A Canvas personal access token. |
|
Getting a Canvas access token
Log in to Canvas.
Go to Account → Settings.
Under Approved Integrations, click + New Access Token.
Give it a purpose and (optionally) an expiry date, then click Generate Token.
Copy the token immediately — Canvas shows it only once.
The token carries your full Canvas privileges. Keep it out of version control, and revoke it from the same settings page if it ever leaks.
Connecting a client
Add the server to your MCP client config, pointing at the absolute path of
src/index.js:
{
"mcpServers": {
"canvas": {
"command": "node",
"args": ["/absolute/path/to/canvas-mcp-server/src/index.js"],
"env": {
"CANVAS_API_URL": "https://asu.instructure.com",
"CANVAS_ACCESS_TOKEN": "your-token-here"
}
}
}
}Claude Desktop —
claude_desktop_config.json(macOS:~/Library/Application Support/Claude/, Windows:%APPDATA%\Claude\).Claude Code —
claude mcp add canvas --env CANVAS_API_URL=... --env CANVAS_ACCESS_TOKEN=... -- node /absolute/path/to/canvas-mcp-server/src/index.js
Restart the client after editing the config.
Tools
list_courses_and_grades
Every course you are actively enrolled in as a student, with its current grade.
Parameter | Type | Default | Description |
| boolean |
| Also include active enrollments from terms that have already ended. |
Canvas reports grades twice when your institution uses grading periods: once for
the period in progress and once for the whole course. The grades.scope field
says which one you are looking at:
current_grading_period— the score covers the grading period in progress, andcourse_total_score/course_total_gradecarry the whole-course numbers.course_total— the institution does not use grading periods, so the score is the course total.unavailable— Canvas returned no enrollment with grade data.
Within either scope, current_* ignores work that has not been graded yet, while
final_* counts ungraded work as a zero.
{
"courses": [
{
"id": "101",
"name": "Full Stack Web Development",
"course_code": "GIT-411",
"term": "Fall 2026",
"term_start": "2026-08-20T00:00:00Z",
"term_end": "2026-12-18T00:00:00Z",
"enrollment_state": "active",
"grades": {
"current_score": 88.0,
"current_grade": "B+",
"final_score": 80.5,
"final_grade": "B-",
"scope": "current_grading_period",
"grading_period_title": "Fall Term",
"course_total_score": 91.4,
"course_total_grade": "A-"
},
"html_url": "https://asu.instructure.com/courses/101"
}
],
"course_count": 1,
"retrieved_at": "2026-09-01T12:00:00.000Z"
}list_upcoming_assignments
Assignments across your active courses that are still outstanding, sorted by due date, soonest first.
Parameter | Type | Default | Description |
| integer 1–365, or |
| How far ahead to look. |
| boolean |
| Include past-due work that was never turned in. |
| boolean |
| Include outstanding work with no due date. |
| string[] | all active courses | Restrict to specific Canvas course IDs. |
An assignment counts as outstanding when it is published, gradable, and not submitted, graded, or excused. Concretely, these are filtered out:
anything with a submission timestamp
submissions in
submitted,pending_review, orgradedstateexcused assignments
assignments that already carry a score or grade (manual or on-paper entry)
not_gradedassignments (attendance placeholders and the like)unpublished assignments
{
"assignments": [
{
"id": "9004",
"name": "Missed lab writeup",
"course_id": "101",
"course_name": "Full Stack Web Development",
"due_at": "2026-08-28T06:59:00.000Z",
"days_until_due": -4.2,
"overdue": true,
"points_possible": 25,
"submission_types": ["online_upload"],
"submission_state": "unsubmitted",
"missing": true,
"locked": false,
"unlock_at": null,
"lock_at": null,
"html_url": "https://asu.instructure.com/courses/101/assignments/9004"
}
],
"assignment_count": 1,
"courses_checked": 2,
"window": {
"from": "2026-09-01T12:00:00.000Z",
"to": "2026-09-15T12:00:00.000Z",
"include_overdue": true,
"include_undated": false
},
"errors": [],
"retrieved_at": "2026-09-01T12:00:00.000Z"
}If one course cannot be read — concluded, restricted, or otherwise erroring — it
is listed in errors and the remaining courses still return results.
Notes on behavior
Pagination. Canvas paginates every collection via the
Linkheader. The client followsrel="next"at 100 records per page, capped at 20 pages per endpoint so a bad response cannot loop forever.Concurrency. Assignments are fetched from at most 5 courses at a time to stay clear of Canvas rate limits.
Current term. By default only courses whose term has not ended are returned. Canvas's default term has no end date and is always included.
Errors. Canvas failures come back as MCP tool errors carrying the status code and Canvas's own message, with a hint for the common cases (401 → bad token, 404 → wrong URL).
Read-only. Both tools are annotated
readOnlyHint. The server issues onlyGETrequests and never modifies your Canvas data.
Development
npm test # 36 tests: API client, grade logic, filtering, and an end-to-end MCP round tripThe suite uses a fetch stand-in with recorded Canvas payloads, so no network or
real token is needed. All fixture dates are relative to the moment the tests run.
src/
index.js MCP server: tool definitions, schemas, stdio wiring
canvas.js Canvas REST client: auth, pagination, error mapping
courses.js Active-course and grade normalization
assignments.js Outstanding-assignment filtering and due-date windowsLicense
MIT
Available Tools
2 toolslist_courses_and_gradesList active courses and gradesARead-only
Fetch every course the user is actively enrolled in as a student, together with the current grade for each. When the institution uses grading periods, the score reported is for the grading period in progress and the whole-course total is included alongside it (see the 'scope' field). Defaults to the current term only.
| Name | Required | Description | Default |
|---|---|---|---|
| include_all_terms | No | Include active enrollments from terms that have already ended. |
Output Schema
| Name | Required | Description |
|---|---|---|
| courses | Yes | |
| course_count | Yes | |
| retrieved_at | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true. The description adds useful behavioral nuance beyond those: grading-period behavior, inclusion of the whole-course total alongside the in-progress score, and the 'scope' field for interpretation. This is valuable context for a read-only listing tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences. The first sentence front-loads the primary purpose, and the second adds an important grading-period nuance. There is no filler or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only listing tool with one optional parameter, an output schema, and high schema coverage, the description is complete. It explains active enrollment, grading-period behavior, and term defaulting, which is sufficient for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the only parameter, include_all_terms, is well documented in the schema with a clear description and default value. The main description restates the default behavior ('Defaults to the current term only') but adds no additional parameter-level meaning, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Fetch every course the user is actively enrolled in as a student') and a clear resource ('courses... together with the current grade for each'). It also adds meaningful scope distinctions like 'Defaults to the current term only' and grading-period behavior, which clearly separates it from the sibling assignment-listing tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: when you need active course enrollments and current grades, defaulting to the current term. It does not explicitly mention alternatives or exclusions relative to list_upcoming_assignments, but the course/grade vs. assignment subject matter implies the boundary clearly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_upcoming_assignmentsList upcoming unsubmitted assignmentsARead-only
Fetch assignments across the user's active courses that are still outstanding — not submitted, not graded, and not excused — with their due dates, sorted soonest first. Past-due work that was never turned in is included by default.
| Name | Required | Description | Default |
|---|---|---|---|
| course_ids | No | Restrict to these Canvas course IDs. Defaults to all active courses. | |
| days_ahead | No | How far ahead to look, in days. Pass null for no upper bound. | |
| include_overdue | No | Include past-due assignments that were never submitted. | |
| include_undated | No | Include outstanding assignments that have no due date. |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | Yes | Courses that could not be read; the rest of the results are still valid. |
| window | Yes | |
| assignments | Yes | |
| retrieved_at | Yes | |
| courses_checked | Yes | |
| assignment_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true and openWorldHint=true, so the description doesn't need to repeat those. It goes beyond the annotations by specifying the filtering logic (not submitted, not graded, not excused), sorting order (soonest first), and default inclusion of overdue items. This adds useful behavioral context without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core purpose, and every clause adds value. It efficiently conveys the tool's scope, filtering criteria, ordering, and default behavior without any fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists (as noted in the context), the description doesn't need to explain return values. The tool is relatively simple with 4 optional parameters, and the description plus schema fully cover the behavior. It could be a 5, but the absence of any prerequisites or error conditions keeps it at a solid 4.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers 100% of the parameters with descriptions. The tool description adds a bit more by explaining the filtering and sorting behavior, which relates to how the parameters interact (e.g., include_overdue default true). Since schema coverage is high, a baseline 3 is appropriate, but the description's mention of 'sorted soonest first' and 'Past-due work ... included by default' adds context beyond the schema, justifying a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Fetch') and identifies the resource ('assignments across the user's active courses') with clear criteria ('not submitted, not graded, not excused'). It also notes the sorting by due date and the inclusion of past-due unsubmitted work, which distinguishes it from the sibling tool (list_courses_and_grades) that focuses on grades and courses.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes it clear that the tool is for outstanding assignments, which implies using it when you need to see what's due or overdue. It does not explicitly state when NOT to use it or mention the sibling alternative, but the context is sufficiently clear for most use cases, and the default behavior (including overdue) is disclosed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
2 tool updates
v1.0.0- First observed
list_courses_and_grades - First observed
list_upcoming_assignments
TDQS
The two tools serve clearly distinct purposes: one retrieves course enrollments with grades, the other retrieves upcoming assignments. There is no ambiguity in selecting between them.
Both tools follow a consistent 'list_' prefix followed by a clear noun phrase ('courses_and_grades', 'upcoming_assignments'), making the naming pattern uniform and predictable.
With only two tools, the server feels minimal but not entirely unreasonable for a focused student dashboard scope. The count is at the borderline of being thin, as agents may expect additional related operations.
The tool surface covers the two primary student needs (grades and upcoming assignments) but lacks operations like retrieving individual course details, assignment submissions, or past assignmentscars. This leaves notable gaps for broader academic workflows, though it may suffice for a narrow use case.
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 Connectors
Manage your Canvas coursework with quick access to courses, assignments, and grades. Track upcomin…
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
- AgentioOAuthcom.agentio
Ask about your Agentio campaigns, Creator deals, and performance on YouTube and Meta. Read-only.
Read-only IELTS and CELPIP question banks, learner practice, progress, scores, and feedback.
1
Related MCP Servers
- FlicenseAqualityNot gradedmaintenanceEnables interaction with Canvas LMS courses and assignments directly from your LLM, allowing you to retrieve, search, and summarize course information, check due dates, and access assignment details without leaving your AI assistant.4159-
- FlicenseBqualityNot gradedmaintenanceProvides read-only access to Canvas LMS for students to retrieve courses, assignments, grades, files, discussions, and planner items. Includes optional NotebookLM integration for uploading course content to AI-powered study notebooks.45159-
- AlicenseAqualityBmaintenanceEnables AI systems to interact with Canvas Learning Management System data, allowing users to access courses, assignments, quizzes, planner items, files, and syllabi through natural language queries.227MIT
- FlicenseBqualityDmaintenanceEnables interaction with Canvas LMS to access courses, modules, files, pages, assignments, submissions, announcements, upcoming deadlines, and syllabus.15-
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/zwanner/canvas-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server