canvas-lms-mcp 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +352 -0
  3. package/bin/canvas-lms-mcp.js +3 -0
  4. package/dist/canvas/index.cjs +11 -0
  5. package/dist/canvas/index.cjs.map +1 -0
  6. package/dist/canvas/index.js +11 -0
  7. package/dist/canvas/index.js.map +1 -0
  8. package/dist/chunk-4P7LR66V.cjs +947 -0
  9. package/dist/chunk-4P7LR66V.cjs.map +1 -0
  10. package/dist/chunk-7VYG7YHR.cjs +45 -0
  11. package/dist/chunk-7VYG7YHR.cjs.map +1 -0
  12. package/dist/chunk-GXZLOUHK.js +1951 -0
  13. package/dist/chunk-GXZLOUHK.js.map +1 -0
  14. package/dist/chunk-H4CEPP26.js +947 -0
  15. package/dist/chunk-H4CEPP26.js.map +1 -0
  16. package/dist/chunk-POJH4U3S.js +45 -0
  17. package/dist/chunk-POJH4U3S.js.map +1 -0
  18. package/dist/chunk-VOQ5A7CA.cjs +1951 -0
  19. package/dist/chunk-VOQ5A7CA.cjs.map +1 -0
  20. package/dist/cli.cjs +7 -0
  21. package/dist/cli.cjs.map +1 -0
  22. package/dist/cli.js +7 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/http.cjs +114 -0
  25. package/dist/http.cjs.map +1 -0
  26. package/dist/http.js +114 -0
  27. package/dist/http.js.map +1 -0
  28. package/dist/server.cjs +8 -0
  29. package/dist/server.cjs.map +1 -0
  30. package/dist/server.js +8 -0
  31. package/dist/server.js.map +1 -0
  32. package/dist/stdio.cjs +25 -0
  33. package/dist/stdio.cjs.map +1 -0
  34. package/dist/stdio.js +25 -0
  35. package/dist/stdio.js.map +1 -0
  36. package/package.json +80 -18
  37. package/build/canvas-client.js +0 -188
  38. package/build/index.js +0 -37
  39. package/build/tools/download-materials.js +0 -34
  40. package/build/tools/get-announcements.js +0 -38
  41. package/build/tools/get-assignments.js +0 -57
  42. package/build/tools/get-course-materials.js +0 -147
  43. package/build/tools/get-deadlines.js +0 -44
  44. package/build/tools/get-grades.js +0 -31
  45. package/build/tools/list-courses.js +0 -13
  46. package/build/tools/read-material.js +0 -51
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Christian Bru
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,352 @@
1
+ # Canvas LMS MCP Server
2
+
3
+ > The TypeScript MCP server for Canvas LMS.
4
+
5
+ [![CI](https://github.com/bruchris/canvas-lms-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/bruchris/canvas-lms-mcp/actions/workflows/ci.yml)
6
+ [![npm](https://img.shields.io/npm/v/canvas-lms-mcp)](https://www.npmjs.com/package/canvas-lms-mcp)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![Node](https://img.shields.io/badge/node-%3E%3D22-brightgreen)](https://nodejs.org)
9
+ [![npm downloads](https://img.shields.io/npm/dw/canvas-lms-mcp)](https://www.npmjs.com/package/canvas-lms-mcp)
10
+
11
+ MCP server for [Canvas LMS](https://www.instructure.com/canvas). Read courses, assignments, submissions, rubrics, quizzes; grade, comment, manage course content, and handle Canvas admin workflows from any AI agent.
12
+
13
+ 88 tools across Canvas courses, assignments, submissions, rubrics, quizzes, files, users, groups, enrollments, discussions, modules, pages, calendar, conversations, peer reviews, accounts, analytics, student workflows, dashboard, and health checks. Three deployment modes: stdio, HTTP, and library import.
14
+
15
+ ## Comparison
16
+
17
+ | | canvas-lms-mcp | [vishalsachdev/canvas-mcp](https://github.com/vishalsachdev/canvas-mcp) | [DMontgomery40/mcp-canvas-lms](https://github.com/DMontgomery40/mcp-canvas-lms) |
18
+ |---|---|---|---|
19
+ | Language | TypeScript | Python | TypeScript |
20
+ | Tools | 88 | 80+ | 54 |
21
+ | License | [![License: MIT](https://img.shields.io/github/license/bruchris/canvas-lms-mcp)](https://github.com/bruchris/canvas-lms-mcp/blob/main/LICENSE) | [![License](https://img.shields.io/github/license/vishalsachdev/canvas-mcp)](https://github.com/vishalsachdev/canvas-mcp/blob/main/LICENSE) | [![License](https://img.shields.io/github/license/DMontgomery40/mcp-canvas-lms)](https://github.com/DMontgomery40/mcp-canvas-lms/blob/main/LICENSE) |
22
+ | Last commit | [![Last commit](https://img.shields.io/github/last-commit/bruchris/canvas-lms-mcp)](https://github.com/bruchris/canvas-lms-mcp) | [![Last commit](https://img.shields.io/github/last-commit/vishalsachdev/canvas-mcp)](https://github.com/vishalsachdev/canvas-mcp) | [![Last commit](https://img.shields.io/github/last-commit/DMontgomery40/mcp-canvas-lms)](https://github.com/DMontgomery40/mcp-canvas-lms) |
23
+
24
+ ## Quick Start
25
+
26
+ ### 1. Get a Canvas API Token
27
+
28
+ 1. Log in to your Canvas instance
29
+ 2. Go to **Account > Settings**
30
+ 3. Scroll to **Approved Integrations** and click **+ New Access Token**
31
+ 4. Give it a name (e.g., "MCP Server") and click **Generate Token**
32
+ 5. Copy the token immediately -- you won't see it again
33
+
34
+ ### 2. One Command Setup
35
+
36
+ ```bash
37
+ npx add-mcp canvas-lms-mcp
38
+ ```
39
+
40
+ This auto-detects your installed AI clients (Claude Code, Cursor, VS Code, etc.) and configures them. You will be prompted for your Canvas API token and base URL.
41
+
42
+ ### Client-Specific Commands
43
+
44
+ **Claude Code**
45
+
46
+ ```bash
47
+ claude mcp add canvas-lms --env CANVAS_API_TOKEN=your-token --env CANVAS_BASE_URL=https://school.instructure.com -- npx -y canvas-lms-mcp
48
+ ```
49
+
50
+ **VS Code**
51
+
52
+ ```bash
53
+ code --add-mcp '{"name":"canvas-lms","command":"npx","args":["-y","canvas-lms-mcp"],"env":{"CANVAS_API_TOKEN":"your-token","CANVAS_BASE_URL":"https://school.instructure.com"}}'
54
+ ```
55
+
56
+ **Gemini CLI**
57
+
58
+ ```bash
59
+ gemini mcp add canvas-lms npx canvas-lms-mcp
60
+ ```
61
+
62
+ **Codex CLI**
63
+
64
+ ```bash
65
+ codex mcp add canvas-lms -- npx canvas-lms-mcp
66
+ ```
67
+
68
+ <details>
69
+ <summary>Manual Configuration</summary>
70
+
71
+ #### Claude Desktop
72
+
73
+ Add to your `claude_desktop_config.json`:
74
+
75
+ ```json
76
+ {
77
+ "mcpServers": {
78
+ "canvas-lms": {
79
+ "command": "npx",
80
+ "args": ["-y", "canvas-lms-mcp"],
81
+ "env": {
82
+ "CANVAS_API_TOKEN": "your-token-here",
83
+ "CANVAS_BASE_URL": "https://your-institution.instructure.com"
84
+ }
85
+ }
86
+ }
87
+ }
88
+ ```
89
+
90
+ #### Cursor
91
+
92
+ Add to `.cursor/mcp.json` in your project:
93
+
94
+ ```json
95
+ {
96
+ "mcpServers": {
97
+ "canvas-lms": {
98
+ "command": "npx",
99
+ "args": ["-y", "canvas-lms-mcp"],
100
+ "env": {
101
+ "CANVAS_API_TOKEN": "your-token-here",
102
+ "CANVAS_BASE_URL": "https://your-institution.instructure.com"
103
+ }
104
+ }
105
+ }
106
+ }
107
+ ```
108
+
109
+ #### VS Code
110
+
111
+ Add to your VS Code settings (`settings.json`):
112
+
113
+ ```json
114
+ {
115
+ "mcp.servers": {
116
+ "canvas-lms": {
117
+ "command": "npx",
118
+ "args": ["-y", "canvas-lms-mcp"],
119
+ "env": {
120
+ "CANVAS_API_TOKEN": "your-token-here",
121
+ "CANVAS_BASE_URL": "https://your-institution.instructure.com"
122
+ }
123
+ }
124
+ }
125
+ }
126
+ ```
127
+
128
+ #### Windsurf
129
+
130
+ Add to `~/.codeium/windsurf/mcp_config.json`:
131
+
132
+ ```json
133
+ {
134
+ "mcpServers": {
135
+ "canvas-lms": {
136
+ "command": "npx",
137
+ "args": ["-y", "canvas-lms-mcp"],
138
+ "env": {
139
+ "CANVAS_API_TOKEN": "your-token-here",
140
+ "CANVAS_BASE_URL": "https://your-institution.instructure.com"
141
+ }
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ #### ChatGPT / HTTP Clients
148
+
149
+ Run the server in HTTP mode, then point your client at the endpoint:
150
+
151
+ ```bash
152
+ npx canvas-lms-mcp serve --port 3001 \
153
+ --token your-token-here \
154
+ --base-url https://your-institution.instructure.com
155
+ ```
156
+
157
+ The MCP endpoint is `http://localhost:3001/mcp`. Per-request credentials can be passed via `X-Canvas-Token` and `X-Canvas-Base-URL` headers.
158
+
159
+ </details>
160
+
161
+ ## Example Prompts
162
+
163
+ Once configured, try these prompts with your AI client:
164
+
165
+ - "List all my active courses"
166
+ - "Show me the assignments for course 12345"
167
+ - "What's the average grade on the midterm exam?"
168
+ - "Grade Alice's essay submission with a B+ and add feedback"
169
+ - "Show me the rubric for the final project"
170
+ - "What discussions are happening in my Biology course?"
171
+ - "List all upcoming calendar events for course 12345"
172
+ - "Send a message to student 67890 about their missing assignment"
173
+
174
+ ## Tool Inventory
175
+
176
+ ### All Registered Tools (88)
177
+
178
+ | Category | Tools |
179
+ |----------|-------|
180
+ | Health | `health_check` |
181
+ | Courses | `list_courses`, `get_course`, `get_syllabus`, `create_course`, `update_course` |
182
+ | Assignments | `list_assignments`, `get_assignment`, `list_assignment_groups`, `create_assignment`, `update_assignment`, `delete_assignment` |
183
+ | Submissions | `list_submissions`, `get_submission`, `grade_submission`, `comment_on_submission` |
184
+ | Rubrics | `list_rubrics`, `get_rubric`, `get_rubric_assessment`, `submit_rubric_assessment` |
185
+ | Quizzes | `list_quizzes`, `get_quiz`, `list_quiz_submissions`, `list_quiz_questions`, `get_quiz_submission_answers`, `score_quiz_question` |
186
+ | Files | `list_files`, `list_folders`, `get_file`, `upload_file`, `delete_file` |
187
+ | Users | `list_students`, `get_user`, `get_profile`, `search_users`, `list_course_users` |
188
+ | Groups | `list_groups`, `list_group_members` |
189
+ | Enrollments | `list_enrollments`, `enroll_user`, `remove_enrollment` |
190
+ | Discussions | `list_discussions`, `get_discussion`, `list_announcements`, `post_discussion_entry`, `create_discussion`, `update_discussion`, `delete_discussion` |
191
+ | Modules | `list_modules`, `get_module`, `list_module_items`, `create_module`, `update_module`, `create_module_item` |
192
+ | Pages | `list_pages`, `get_page`, `create_page`, `update_page`, `delete_page` |
193
+ | Calendar | `list_calendar_events`, `create_calendar_event`, `update_calendar_event` |
194
+ | Conversations | `list_conversations`, `get_conversation`, `get_conversation_unread_count`, `send_conversation` |
195
+ | Peer Reviews | `list_peer_reviews`, `get_submission_peer_reviews`, `create_peer_review`, `delete_peer_review` |
196
+ | Accounts | `get_account`, `list_accounts`, `list_sub_accounts`, `list_account_courses`, `list_account_users`, `get_account_reports` |
197
+ | Analytics | `search_course_content`, `get_course_analytics`, `get_student_analytics`, `get_course_activity_stream` |
198
+ | Student | `get_my_courses`, `get_my_grades`, `get_my_submissions`, `get_my_upcoming_assignments` |
199
+ | Dashboard | `get_dashboard_cards`, `get_todo_items`, `get_upcoming_events`, `get_missing_submissions` |
200
+
201
+ 60 tools are read-only and 28 tools perform Canvas write operations.
202
+
203
+ All write tools require appropriate Canvas permissions. Canvas enforces its own permission model -- the MCP server does not bypass it.
204
+
205
+ ### MCP Resources (2)
206
+
207
+ | Resource | URI Template | Type |
208
+ |----------|-------------|------|
209
+ | Course Syllabus | `canvas://course/{courseId}/syllabus` | text/html |
210
+ | Assignment Description | `canvas://course/{courseId}/assignment/{assignmentId}/description` | text/html |
211
+
212
+ ## Deployment Modes
213
+
214
+ ### stdio (Default)
215
+
216
+ For local AI clients like Claude Desktop, Cursor, and VS Code. The server communicates over stdin/stdout.
217
+
218
+ ```bash
219
+ npx canvas-lms-mcp --token $CANVAS_API_TOKEN --base-url $CANVAS_BASE_URL
220
+ ```
221
+
222
+ ### HTTP
223
+
224
+ For web-based clients or hosted services. Starts an HTTP server with Streamable HTTP transport.
225
+
226
+ ```bash
227
+ npx canvas-lms-mcp serve \
228
+ --token $CANVAS_API_TOKEN \
229
+ --base-url $CANVAS_BASE_URL \
230
+ --port 3001 \
231
+ --allowed-origin https://your-app.example.com
232
+ ```
233
+
234
+ Endpoints:
235
+ - `POST /mcp` -- MCP protocol endpoint
236
+ - `GET /health` -- Health check (returns `{"status":"ok"}`)
237
+
238
+ ### Docker
239
+
240
+ ```bash
241
+ docker compose up -d
242
+ ```
243
+
244
+ Requires `CANVAS_API_TOKEN` and `CANVAS_BASE_URL` environment variables. See `docker-compose.yml`.
245
+
246
+ ```yaml
247
+ services:
248
+ canvas-lms-mcp:
249
+ build: .
250
+ ports:
251
+ - "3001:3001"
252
+ environment:
253
+ - CANVAS_API_TOKEN=${CANVAS_API_TOKEN}
254
+ - CANVAS_BASE_URL=${CANVAS_BASE_URL}
255
+ ```
256
+
257
+ ### Library Import
258
+
259
+ Use the server factory directly in your own Node.js application:
260
+
261
+ ```typescript
262
+ import { createCanvasMCPServer } from 'canvas-lms-mcp'
263
+
264
+ const { server, canvas } = createCanvasMCPServer({
265
+ token: userToken,
266
+ baseUrl: canvasBaseUrl,
267
+ })
268
+ ```
269
+
270
+ Or use the Canvas client standalone (no MCP dependency):
271
+
272
+ ```typescript
273
+ import { CanvasClient } from 'canvas-lms-mcp/canvas'
274
+
275
+ const canvas = new CanvasClient({
276
+ token: userToken,
277
+ baseUrl: canvasBaseUrl,
278
+ })
279
+
280
+ const courses = await canvas.courses.list()
281
+ ```
282
+
283
+ ## CLI Reference
284
+
285
+ | Flag | Env Variable | Default | Description |
286
+ |------|-------------|---------|-------------|
287
+ | `--token` | `CANVAS_API_TOKEN` | (required) | Canvas personal access token |
288
+ | `--base-url` | `CANVAS_BASE_URL` | (required) | Canvas instance URL |
289
+ | `serve` | -- | stdio mode | Switch to HTTP mode |
290
+ | `--port` | -- | `3001` | HTTP server port |
291
+ | `--allowed-origin` | `CANVAS_ALLOWED_ORIGIN` | `http://localhost:3000` | CORS allowed origin |
292
+
293
+ ## Environment Variables
294
+
295
+ | Variable | Required | Description |
296
+ |----------|----------|-------------|
297
+ | `CANVAS_API_TOKEN` | Yes | Canvas personal access token |
298
+ | `CANVAS_BASE_URL` | Yes | Canvas instance URL (e.g., `https://school.instructure.com`) |
299
+ | `CANVAS_ALLOWED_ORIGIN` | No | CORS origin for HTTP mode (default: `http://localhost:3000`) |
300
+
301
+
302
+ ## Development
303
+
304
+ ```bash
305
+ pnpm install # Install dependencies
306
+ pnpm dev # Watch mode build
307
+ pnpm build # Production build
308
+ pnpm test # Run tests (294 tests)
309
+ pnpm lint # ESLint + Prettier check
310
+ pnpm lint:fix # Auto-fix lint issues
311
+ pnpm typecheck # TypeScript strict type check
312
+ ```
313
+
314
+ ### Dependency audit
315
+
316
+ The `pnpm.overrides.hono` entry pins `hono` to `4.12.14` because
317
+ `@modelcontextprotocol/sdk@1.29.0` allows vulnerable `hono <4.12.14`
318
+ versions. Remove the override when the MCP SDK publishes a release that
319
+ depends on a patched `hono` range.
320
+
321
+ ### Architecture
322
+
323
+ ```
324
+ src/canvas/ Standalone Canvas REST API client (pure fetch, no MCP dependency)
325
+ src/tools/ MCP tool definitions with Zod input schemas
326
+ src/resources/ MCP resource templates (syllabus, assignment description)
327
+ src/server.ts Factory: createCanvasMCPServer(config)
328
+ src/stdio.ts stdio transport entry point
329
+ src/http.ts HTTP transport entry point
330
+ src/cli.ts CLI argument parser
331
+ ```
332
+
333
+ ### Contributing
334
+
335
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full contribution and validation workflow.
336
+
337
+ 1. Fork the repo
338
+ 2. Create a feature branch (`git checkout -b feat/my-feature`)
339
+ 3. Use conventional commits (`feat:`, `fix:`, `chore:`, `test:`, `docs:`)
340
+ 4. Ensure `pnpm lint && pnpm typecheck && pnpm test` pass
341
+ 5. Open a pull request
342
+
343
+ ## Guides
344
+
345
+ - [Getting Started](docs/getting-started.md) -- Step-by-step setup for non-developers: token, config, first query, troubleshooting
346
+ - [Student Guide](docs/student-guide.md) -- Token setup, AI client configuration, 10 example prompts
347
+ - [Educator Guide](docs/educator-guide.md) -- Grading workflows, write operations, privacy considerations
348
+ - [Integration Guide](docs/integration-guide.md) -- Three integration patterns with code examples
349
+
350
+ ## License
351
+
352
+ MIT
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import '../dist/stdio.js'
@@ -0,0 +1,11 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+ var _chunk4P7LR66Vcjs = require('../chunk-4P7LR66V.cjs');
6
+
7
+
8
+
9
+
10
+ exports.CanvasApiError = _chunk4P7LR66Vcjs.CanvasApiError; exports.CanvasClient = _chunk4P7LR66Vcjs.CanvasClient; exports.CanvasHttpClient = _chunk4P7LR66Vcjs.CanvasHttpClient;
11
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/canvas-lms-mcp/canvas-lms-mcp/dist/canvas/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACF,yDAA8B;AAC9B;AACE;AACA;AACA;AACF,gLAAC","file":"/home/runner/work/canvas-lms-mcp/canvas-lms-mcp/dist/canvas/index.cjs"}
@@ -0,0 +1,11 @@
1
+ import {
2
+ CanvasApiError,
3
+ CanvasClient,
4
+ CanvasHttpClient
5
+ } from "../chunk-H4CEPP26.js";
6
+ export {
7
+ CanvasApiError,
8
+ CanvasClient,
9
+ CanvasHttpClient
10
+ };
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}