Canvas LMS (read-only)

io.github.rbrtlol由 GitHub 账号 rbrtlol 发布v2.2.1更新于 Nov 12, 2026

Read-only Canvas LMS for students: what changed in your courses, search across slides and PDFs.

概览

AI 生成的概览

面向学生的只读 Canvas LMS 助手:查看课程有哪些变化,并检索页面、公告以及关联的 PDF 和幻灯片内容。

可以做什么
  • 跟踪变化与截止日期:某时间点以来的变更、带提交状态的日程事项、日历事件
  • 检索课程内容:对页面、作业、公告、讨论、教学大纲及关联文档正文做全文检索,并给出页码或幻灯片编号
  • 阅读课程材料:课程、模块、页面、教学大纲、公告、讨论、测验、作业与评分标准
  • 读取文件:按页读取 PDF、按幻灯片读取 PPTX、按章节读取 DOCX、文本或代码文件,以及 ZIP 列表
  • 查看成绩与身份:自己的分数、成绩与评语,令牌所属用户,以及快照健康状况
  • 备用入口:任意只读的 Canvas API GET 接口,可关闭
适用场景
适合希望每天获取课程变化摘要、查看哪些作业即将到期且尚未提交,或直接从讲义幻灯片和 PDF 中快速找答案而不必打开 Canvas 的学生。助教和教师也可用于阅读,包括待批改数量。
运行要求
npm 包需要本地 Node.js 运行时(22.13 或更高),或使用 Claude Desktop 安装一键扩展;HTTP 连接器模式需要 Docker 或 npx 搭建 HTTPS 服务器。需要 CANVAS_BASE_URL 中的 Canvas 地址和 CANVAS_TOKEN 中的 Canvas 个人访问令牌;HTTP 模式还需 MCP_SECRET。需要能访问你的 Canvas 实例的网络。
安装前请注意
该令牌可读取你在 Canvas 中能看到的一切,应像密码一样保管并设置有效期。部分学校禁用了个人访问令牌,且不支持 Canvas OAuth。HTTP 模式下连接器网址包含 MCP_SECRET,持有者可读取你的 Canvas 数据。他人编写的课程内容会作为工具输出进入模型,存在提示注入风险。快照和提取的文本会保存在本地数据目录中。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Canvas LMS (read-only),将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

canvas-readonly-mcp

Ask Claude what changed in your courses, and search every lecture slide. A read-only MCP server for Canvas LMS, built as a study assistant rather than a full Canvas API.

  • Knows what changed: daily snapshots of your courses, so "what's new since yesterday?" is one call: new announcements, moved deadlines, new grades, edited pages, even which slides in a lecture PDF changed.
  • Searches inside your files: full-text search over pages, assignments, announcements and the text of every linked PDF, slide deck and document, with the page or slide number. It finds files linked from pages and modules even when the Files tab is hidden.
  • Read-only by design: it only ever sends GET requests to Canvas. It can't submit, post, grade or change anything, and it doesn't even mark discussions as read.
  • Your token stays with you: one-click Claude Desktop extension (token in your system keychain), local stdio, or your own server for claude.ai. Nothing goes through a third party.

Works with any Canvas instance. Made for students; TAs and teachers can use it too (for reading, e.g. "needs grading" counts).

Not affiliated with or endorsed by Instructure. "Canvas" is a trademark of Instructure, Inc.

What you can ask

  • "What changed in my courses since yesterday?"
  • "What's due in the next two weeks, and what have I not submitted?"
  • "Summarize the lab 2 instructions" (the server finds the PDF linked from the course and returns its text)
  • "Which slides in lecture 5 changed since last week?"
  • "Where did we cover dynamic programming?" (searches pages, announcements and the text of every linked PDF and slide deck)
  • "How will lab 3 be graded, and what did I lose points on in lab 2?"

Tools

ToolWhat it's for
canvas_changes_sinceWhat changed since a time (default 26h): new/changed pages, assignments (due dates, grades), announcements, discussions, quizzes, events, files (which PDF pages changed). The daily-check tool.
canvas_searchFull-text search across your courses: pages, assignments, announcements, discussions, the syllabus, and the text of linked PDFs, slides and documents (with the page/slide number). From stored snapshots, so it's instant.
canvas_course_snapshotStored state of a course (optionally only some kinds, e.g. assignments). No Canvas calls.
canvas_snapshot_statusSnapshot health: courses and your role, last run, counts, errors, next run.
canvas_run_snapshotTake a snapshot now and return what changed.
canvas_whoamiThe Canvas user the token belongs to; checks that the connection works.
canvas_list_coursesYour courses, ids and your role in each.
canvas_whats_newCanvas's own activity stream since a time, including inbox messages. Live, but doesn't see edits, removals or file changes like canvas_changes_since does.
canvas_list_planner_itemsEverything dated in a window, with submission status.
canvas_list_assignments / canvas_get_assignmentAssignments, due dates, descriptions, rubrics; as a student also your submission, teacher comments and rubric scores. "Needs grading" counts for TAs/teachers.
canvas_list_quizzes / canvas_get_quizClassic quizzes and New Quizzes: time limit, attempts, lock window, instructions, your latest attempt.
canvas_list_announcementsAnnouncements across courses.
canvas_list_discussions / canvas_get_discussionDiscussion topics, and a whole thread with replies (without marking anything read).
canvas_get_syllabusThe syllabus page.
canvas_list_modulesModule structure with items.
canvas_list_pages / canvas_get_pageCourse pages as text, with their file links.
canvas_list_linked_filesEvery file linked from the course (front page, pages, modules, assignments, announcements). Works even when the files tab is hidden.
canvas_list_filesThe full Files area, including unlinked files (mostly for TAs/teachers); falls back to linked files when your role can't list it.
canvas_read_fileText of a PDF (per page), PPTX (per slide + notes), DOCX (per section), text/code file, or ZIP listing. Takes a file id or any Canvas file URL; supports page ranges.
canvas_list_calendar_eventsCalendar events.
canvas_get_gradesYour own scores, grades and comments (as a student).
canvas_api_getEscape hatch: any GET /api/v1/... endpoint (can be disabled).

Quick start

1. Get a Canvas access token

In Canvas: Account → Settings → + New access token. Give it a purpose ("Claude") and preferably an expiry date.

You also need your Canvas address, e.g. https://canvas.yourschool.edu or https://yourschool.instructure.com.

No "New access token" button? Your school may have turned personal tokens off.

Some institutions disable personal access tokens for students, or only allow short-lived ones. This server needs one: it doesn't support Canvas OAuth, because that requires your school's admins to register each app.

  • Button missing: ask your school's Canvas or IT support whether personal access tokens can be enabled for you. Mention that it's for a tool that only reads (it never sends anything but GET requests). Some schools say yes, many say no.
  • Token expires quickly: tools start failing with "the Canvas API token is invalid or expired". Create a new token and update it: in Claude Desktop under Settings → Extensions → Canvas LMS (read-only), or CANVAS_TOKEN in your config or .env.
  • Check your school's rules on connecting course data to AI tools before you start.

2a. Claude Desktop: one-click extension (easiest)

  1. Download canvas-readonly-mcp-<version>.mcpb from the latest release.
  2. Open it (double-click, or drag it into Claude Desktop → Settings → Extensions) and click Install.
  3. Enter your Canvas address and access token. The token is stored in your system keychain.

Nothing else to install: Claude Desktop runs the extension with its built-in Node.js.

2b. Local: Claude Code and other stdio clients

Requires Node.js 22.13 or newer.

Claude Code:

bash
claude mcp add canvas \  -e CANVAS_BASE_URL=https://canvas.yourschool.edu \  -e CANVAS_TOKEN=your-token \  -- npx -y canvas-readonly-mcp

Claude Desktop without the extension: add this to claude_desktop_config.json (Settings → Developer → Edit Config):

json
{  "mcpServers": {    "canvas": {      "command": "npx",      "args": ["-y", "canvas-readonly-mcp"],      "env": {        "CANVAS_BASE_URL": "https://canvas.yourschool.edu",        "CANVAS_TOKEN": "your-token"      }    }  }}

In stdio mode, snapshots refresh shortly after the client starts the server, and in the background whenever they're older than SNAPSHOT_MAX_AGE_H (default 20h). Data is stored in your user data directory (~/Library/Application Support/canvas-readonly-mcp on macOS, ~/.local/share/canvas-readonly-mcp on Linux, %APPDATA%\canvas-readonly-mcp on Windows).

2c. Server: claude.ai custom connectors (HTTP)

claude.ai connects from the internet, so this needs a server with HTTPS.

bash
mkdir canvas-mcp && cd canvas-mcpcurl -O https://raw.githubusercontent.com/rbrtlol/canvas-readonly-mcp/main/docker-compose.ymlcurl -o .env https://raw.githubusercontent.com/rbrtlol/canvas-readonly-mcp/main/.env.example# Fill in CANVAS_BASE_URL and CANVAS_TOKEN, then:sed -i "s/^MCP_SECRET=.*/MCP_SECRET=$(openssl rand -hex 32)/" .envchmod 600 .envdocker compose up -dcurl -s localhost:8787/healthz   # {"ok":true}

Put a reverse proxy with TLS in front of it: deploy/Caddyfile.example (automatic certificates) or deploy/nginx.conf.example. In claude.ai, add a custom connector with the URL

https://canvas-mcp.example.com/mcp/<MCP_SECRET>

and leave the OAuth fields empty. Clients that support headers can use https://…/mcp with Authorization: Bearer <MCP_SECRET> instead.

Without Docker: npx canvas-readonly-mcp --http --env-file .env.

Configuration

All settings are environment variables (or a file passed with --env-file).

VariableDefaultMeaning
CANVAS_BASE_URLrequiredYour Canvas address.
CANVAS_TOKENrequiredPersonal access token.
MCP_SECRETrequired for --httpAt least 32 characters; part of the connector URL.
CANVAS_HOST_ALIASESOther hostnames of the same Canvas, comma-separated (e.g. yourschool.instructure.com when you use a custom domain). Links to them are recognized.
DISPLAY_TZyour Canvas profile'sTime zone for displayed times (IANA name, e.g. Europe/Stockholm).
ENABLE_RAW_GETtrueSet false to remove canvas_api_get.
HOST / PORT127.0.0.1 / 8787HTTP listen address (0.0.0.0 in the Docker image).
DATA_DIROS user data dirWhere the database and cache live. DB_PATH / CACHE_DIR override each.
SNAPSHOT_ENABLEDtrueTurn the snapshot/change-log feature off entirely.
SNAPSHOT_COURSESOnly these course ids (overrides SNAPSHOT_SCOPE). id:label:role overrides the label and role.
SNAPSHOT_SCOPEdashboardWhich courses to snapshot: dashboard = the courses on your Canvas dashboard (your favorites, or Canvas's automatic pick if you haven't chosen any); active = every active enrollment. Courses whose end date has passed are skipped either way.
SNAPSHOT_EXCLUDECourse ids to skip.
SNAPSHOT_AT04:30Daily snapshot time in DISPLAY_TZ, or off.
SNAPSHOT_MAX_AGE_H20Refresh at startup / on demand when older than this.
SNAPSHOT_EXTRACTlinkedWhich files' text to hash for change detection: linked, all (also files only in the files index), none.
EVENT_RETENTION_DAYS120How long change events are kept.
CRAWL_MAX_PAGES / ANNOUNCEMENT_DAYS200 / 730Crawl limits per course.
MAX_FILE_MB / DOWNLOAD_TIMEOUT_S50 / 60Download limits.
EXTRACT_TIMEOUT_S / EXTRACT_MAX_PAGES60 / 500Text extraction limits.
CACHE_MAX_MB500Extracted-text cache size; least recently used entries are evicted.

How it works

Finding files. Many Canvas setups hide the files and pages lists from students. The server therefore uses those lists when your role may see them, and otherwise follows links from the front page, modules, syllabus, assignments and announcements. canvas_get_page shows file links inline as (file:<id>). Leftover $CANVAS_OBJECT_REFERENCE$ links from course copies are resolved where possible and otherwise marked as broken.

Reading files. canvas_read_file downloads the file (the token is only sent to Canvas itself, never to the storage host it redirects to) and extracts text in a separate worker thread with memory and time limits. Results are cached by file id and updated_at. Scanned PDFs without a text layer are reported as such (no OCR). Legacy .doc/.ppt aren't supported.

Snapshots and the change log. Once a day (and when stale), the server stores the state of each course on your Canvas dashboard in SQLite (star a course under Courses → All courses to add it, or set SNAPSHOT_COURSES): pages, modules, assignments (with your submission status and grade), announcements and discussions (with a teacher/TA flag), quizzes, calendar events, the syllabus, and file metadata with a per-page content hash for PDFs. Each item is normalized (HTML to text, volatile fields dropped) and hashed. Differences become change events with old → new values, short text diffs, and changed PDF page numbers. The first run is a silent baseline. Announcements with no posted_at (copied from an earlier course round) are flagged "unpublished/old". Items are only marked removed when every source that could link to them was read successfully, so a temporary error never produces false "removed" events.

Roles. Your role in each course comes from your enrollment. As a student, your submissions, grades and missing/late flags are tracked. As a TA or teacher, your own submissions are skipped, only staff discussion topics are tracked, and assignments show how many submissions need grading. Observer accounts work for course content, but the observed student's submissions aren't tracked.

Rate limits. The server watches Canvas's X-Rate-Limit-Remaining, backs off on 403 "Rate Limit Exceeded", 429 and 5xx responses, and limits how many requests run at once.

Security and privacy

  • Treat the token like a password: it can read everything you can see in Canvas. The server never sends it anywhere except your Canvas.
  • In HTTP mode the connector URL contains the secret: anyone with it can read your Canvas data (read-only). Wrong secrets get a plain 404. Rotate by changing MCP_SECRET.
  • Course content (pages, announcements, file text) is written by other people and goes to the model as tool output. See SECURITY.md about prompt injection.
  • Data stays on your machine/server: a SQLite database and an extracted-text cache. Delete DATA_DIR (or the Docker volumes) to remove it.
  • No telemetry and no hosted service: see PRIVACY.md for what is read, stored and sent where.

Development

bash
npm installnpm test             # unit + integration tests against a mock Canvasnpm run typechecknpm run buildCANVAS_BASE_URL=… CANVAS_TOKEN=… node dist/cli.js          # stdionode dist/cli.js --http --env-file .env                     # HTTPnpm run bundle       # build + pack the Claude Desktop extension (.mcpb)

The extension manifest is mcpb/manifest.json; its version is taken from package.json when packing. Update its tools list when adding or renaming a tool.

See CONTRIBUTING.md.

License

MIT

来源:README.md,提交 5aef78b

工具

0
SourceWeft 曾在隔离沙箱中以无凭据方式启动该软件包一次,以列出其工具,但未能完成:服务器未能启动。

版本历史

1
  1. v2.2.1最新Nov 12, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分