Skip to main content
Glama

canvas-mcp

A read-only MCP server that gives Claude access to your Canvas LMS courses, so it can help you study from your teachers' actual materials: what's due, what a test covers, explanations of the slides, practice quizzes, and where you're losing points.

It can't submit, post, or change anything in Canvas. Every tool only reads.

Tools

Tool

What it's for

list_courses

Your courses, their ids, and current grades. Claude starts here.

get_upcoming

Everything due or scheduled across all classes, with submitted/missing status

list_assignments / get_assignment

Due dates, full instructions, rubric, your score, and teacher feedback

get_grades

Weighted grade breakdown (good for "what do I need on the final?")

get_syllabus

Syllabus text

list_modules

Units/weeks and their contents. Usually the best map of a course.

list_pages / get_page

Notes and pages the teacher wrote in Canvas

list_files / read_file

Reads PDF, DOCX, PPTX (with speaker notes), HTML, text/code. Long files come back in chunks.

list_announcements

Recent announcements ("test moved to Tuesday")

get_calendar

Course calendar for any date range: daily lesson topics, test days, and optionally due dates ("what did we do Tuesday?", "what's been covered since the last test?")

list_discussions / get_discussion

Discussion prompts and replies

list_quizzes

Quiz/test dates, number of questions, time limits

search_course

Finds modules, pages, files, and assignments matching a topic

Prompts (they show up as templates or slash commands in clients that support them): study_guide, quiz_me, weekly_plan.


Related MCP server: Canvas LMS MCP Server

Step 1: Build it

Needs Node 20+.

cd canvas-mcp
npm install
npm run build

Step 2: Check your token

Your Canvas URL is the address you log into, for example https://yourschool.instructure.com. Leave off any /api/v1.

macOS / Linux

CANVAS_BASE_URL=https://yourschool.instructure.com CANVAS_API_TOKEN=xxxx npm run check

Windows (PowerShell)

$env:CANVAS_BASE_URL="https://yourschool.instructure.com"; $env:CANVAS_API_TOKEN="xxxx"; npm run check

If the check passes, it prints your Canvas user id and your active courses. A 401 error means the token is wrong or expired. You can make a new one under Canvas → Account → Settings → Approved Integrations → + New Access Token.

Step 3: Connect it to Claude

Pick whichever option fits how you use Claude.

Option A: Claude Code (one command)

claude mcp add canvas --scope user \
  -e CANVAS_BASE_URL=https://yourschool.instructure.com \
  -e CANVAS_API_TOKEN=xxxx \
  -e CANVAS_TZ=America/Indianapolis \
  -- node /ABSOLUTE/PATH/TO/canvas-mcp/dist/index.js

Option B: Claude Desktop

Open the config file from Claude Desktop → Settings → Developer → Edit Config, and add this:

{
  "mcpServers": {
    "canvas": {
      "command": "node",
      "args": ["C:\\Users\\you\\canvas-mcp\\dist\\index.js"],
      "env": {
        "CANVAS_BASE_URL": "https://yourschool.instructure.com",
        "CANVAS_API_TOKEN": "xxxx",
        "CANVAS_TZ": "America/Indianapolis"
      }
    }
  }
}

On macOS, use a path like /Users/you/canvas-mcp/dist/index.js. Restart Claude Desktop fully after saving.

Option C: Self-host it and use it from claude.ai (any device, including a Chromebook)

HTTP mode serves MCP at https://your-host/mcp/<MCP_SECRET>. claude.ai's servers connect to that URL directly, so it has to be reachable from the public internet.

  1. Generate a secret: openssl rand -hex 24

  2. Deploy the included Dockerfile (Coolify: New Resource → Dockerfile, or any Docker host). Set these env vars: CANVAS_BASE_URL, CANVAS_API_TOKEN, CANVAS_TZ, MCP_SECRET. The container listens on port 7341 and has /health for health checks.

  3. Expose it on a subdomain, for example canvas-mcp.yourdomain.com, through your reverse proxy or Cloudflare Tunnel. Don't put it behind Cloudflare Access or Basic Auth. claude.ai can't log in through those, so the secret path is the protection instead.

  4. In claude.ai, go to Settings → Connectors, add a custom connector, and paste https://canvas-mcp.yourdomain.com/mcp/<MCP_SECRET>.

Without Docker: node dist/index.js --http (it reads the same env vars). It binds to 127.0.0.1 by default, so only this machine can reach it; add --host 0.0.0.0 when a proxy on another machine needs to reach it.

⚠️ Anyone who has the full URL can read your Canvas through it. Treat the URL like a password. If it leaks, change MCP_SECRET, and also revoke the token in Canvas if you're unsure.


Using it

Example requests:

  • "What's due this week across all my classes? Anything missing?"

  • "My AP Bio Unit 4 test is Tuesday. Make me a study guide from the actual slides and notes."

  • "Quiz me on the APUSH Period 5 material, one question at a time."

  • "Explain slide 12 of the cell respiration PowerPoint like I'm confused."

  • "What do I need on the final to keep an A in chemistry?"

  • "Where did I lose points on my last lab? Read the rubric feedback."

CLI reference

canvas-mcp [--url URL] [--token T] [--tz ZONE] [--max-chars N]   stdio mode (default)
canvas-mcp --http [--port 7341] [--host 127.0.0.1] [--secret S]    HTTP mode
canvas-mcp --check                                                  test credentials
canvas-mcp --help | --version

Env var

Flag

Default

CANVAS_BASE_URL

--url

(required)

CANVAS_API_TOKEN

--token

(required; prefer the env var over the flag so the token doesn't land in shell history)

CANVAS_TZ

--tz

system time zone

CANVAS_MAX_CHARS

--max-chars

20000 characters per response chunk

MCP_SECRET

--secret

(required for --http, minimum 24 chars)

CANVAS_MCP_PORT / CANVAS_MCP_HOST

--port / --host

7341 / 127.0.0.1 (Docker image uses 0.0.0.0)

Limitations

  • Scanned PDFs (images with no text layer) come back mostly empty, and the tool says so. Download the file and attach it to the chat so Claude can see the pages.

  • Quiz questions aren't visible to students through the API until results are released. That's Canvas's rule, not something this server can change.

  • Some schools hide tabs such as Files or Pages. Those tools return a 403/404, and Claude can work around it with list_modules.

  • Some schools disable personal access tokens entirely. If you can't make one, this approach won't work at your school.

Development

npm run dev     # tsc --watch
npm test        # runs every tool against a mock Canvas API (stdio + HTTP)

MIT licensed.

Related MCP Connectors

Related MCP Servers