canvas-parent-mcp 0.1.0

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.
@@ -0,0 +1,38 @@
1
+ {
2
+ "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
3
+ "name": "canvas-parent-mcp",
4
+ "owner": {
5
+ "name": "Chris Hall",
6
+ "email": "chris.c.hall@gmail.com"
7
+ },
8
+ "metadata": {
9
+ "description": "MCP server for Canvas LMS (Instructure) — courses, grades, assignments, announcements, planner, conversations, files",
10
+ "version": "0.1.0"
11
+ },
12
+ "plugins": [
13
+ {
14
+ "name": "canvas-parent-mcp",
15
+ "displayName": "Canvas LMS",
16
+ "source": "./",
17
+ "description": "Canvas LMS (Instructure) MCP server for Claude — student/observer access via natural language",
18
+ "version": "0.1.0",
19
+ "author": {
20
+ "name": "Chris Hall"
21
+ },
22
+ "homepage": "https://github.com/chrischall/canvas-parent-mcp",
23
+ "repository": "https://github.com/chrischall/canvas-parent-mcp",
24
+ "license": "MIT",
25
+ "keywords": [
26
+ "canvas",
27
+ "canvas-lms",
28
+ "canvas-parent",
29
+ "instructure",
30
+ "observer",
31
+ "school",
32
+ "education",
33
+ "mcp"
34
+ ],
35
+ "category": "productivity"
36
+ }
37
+ ]
38
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "canvas-parent-mcp",
3
+ "displayName": "Canvas LMS",
4
+ "version": "0.1.0",
5
+ "description": "Canvas LMS (Instructure) MCP server for Claude — courses, grades, assignments, announcements, planner, conversations, files",
6
+ "author": {
7
+ "name": "Chris Hall",
8
+ "email": "chris.c.hall@gmail.com"
9
+ },
10
+ "homepage": "https://github.com/chrischall/canvas-parent-mcp",
11
+ "repository": "https://github.com/chrischall/canvas-parent-mcp",
12
+ "license": "MIT",
13
+ "keywords": [
14
+ "canvas",
15
+ "canvas-lms",
16
+ "canvas-parent",
17
+ "instructure",
18
+ "observer",
19
+ "school",
20
+ "education",
21
+ "mcp"
22
+ ],
23
+ "skills": "./SKILL.md",
24
+ "mcp": "./.mcp.json"
25
+ }
package/.mcp.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "mcpServers": {
3
+ "canvas": {
4
+ "command": "node",
5
+ "args": ["${CLAUDE_PLUGIN_ROOT}/dist/bundle.js"],
6
+ "env": {
7
+ "CANVAS_BASE_URL": "${CANVAS_BASE_URL}",
8
+ "CANVAS_TOKEN": "${CANVAS_TOKEN}",
9
+ "CANVAS_CLIENT_ID": "${CANVAS_CLIENT_ID}",
10
+ "CANVAS_CLIENT_SECRET": "${CANVAS_CLIENT_SECRET}",
11
+ "CANVAS_REFRESH_TOKEN": "${CANVAS_REFRESH_TOKEN}",
12
+ "CANVAS_NAME": "${CANVAS_NAME}"
13
+ }
14
+ }
15
+ }
16
+ }
package/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # canvas-parent-mcp
2
+
3
+ MCP server for Canvas LMS (Instructure), scoped for parent observers and student self-access. Targets `https://cms.instructure.com` by default but works against any Canvas instance.
4
+
5
+ Mirrors the read-only parent-portal scope of sibling [`infinitecampus-mcp`](https://github.com/chrischall/infinitecampus-mcp). Users interact via the `canvas_*` tool prefix.
6
+
7
+ ## Tools
8
+
9
+ 18 tools across profile, observees, courses, assignments, submissions, grades, calendar, planner, announcements, conversations, discussions, and files.
10
+
11
+ | Domain | Tools |
12
+ |---|---|
13
+ | Profile | `canvas_get_profile` |
14
+ | Observees | `canvas_list_observees` |
15
+ | Courses | `canvas_list_courses`, `canvas_get_course` |
16
+ | Assignments | `canvas_list_assignments`, `canvas_list_missing_submissions` |
17
+ | Submissions | `canvas_get_submission`, `canvas_list_recent_submissions` (default 14d window) |
18
+ | Grades | `canvas_list_enrollments` |
19
+ | Calendar | `canvas_list_calendar_events`, `canvas_list_upcoming_events` |
20
+ | Planner | `canvas_list_planner_items` |
21
+ | Announcements | `canvas_list_announcements` |
22
+ | Conversations | `canvas_list_conversations`, `canvas_get_conversation` |
23
+ | Discussions | `canvas_list_discussion_topics` |
24
+ | Files | `canvas_list_course_files`, `canvas_download_file` |
25
+
26
+ Tools that the harness will gate as write/IO operations: `canvas_download_file`.
27
+
28
+ ## Configuration
29
+
30
+ Set the base URL plus *one* auth mode:
31
+
32
+ **Personal access token (recommended):**
33
+
34
+ ```
35
+ CANVAS_BASE_URL=https://cms.instructure.com
36
+ CANVAS_TOKEN=your-personal-access-token
37
+ CANVAS_NAME=cms # optional, defaults to host portion of base URL
38
+ ```
39
+
40
+ **OAuth (advanced):**
41
+
42
+ ```
43
+ CANVAS_BASE_URL=https://cms.instructure.com
44
+ CANVAS_CLIENT_ID=...
45
+ CANVAS_CLIENT_SECRET=...
46
+ CANVAS_REFRESH_TOKEN=...
47
+ ```
48
+
49
+ If both modes are set, the token wins.
50
+
51
+ See `.env.example`.
52
+
53
+ ## Status
54
+
55
+ Unofficial — not affiliated with Instructure. AI-maintained.
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "canvas-parent-mcp",
3
+ "version": "0.1.0",
4
+ "mcpName": "io.github.chrischall/canvas-parent-mcp",
5
+ "description": "Canvas LMS (Instructure) MCP server — student/observer read access with optional file download",
6
+ "author": "Claude Code (AI) <https://www.anthropic.com/claude>",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/chrischall/canvas-parent-mcp.git"
10
+ },
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "mcp",
14
+ "model-context-protocol",
15
+ "claude",
16
+ "ai",
17
+ "canvas",
18
+ "canvas-lms",
19
+ "canvas-parent",
20
+ "instructure",
21
+ "observer",
22
+ "school",
23
+ "education",
24
+ "grades",
25
+ "assignments"
26
+ ],
27
+ "type": "module",
28
+ "bin": {
29
+ "canvas-parent-mcp": "dist/index.js"
30
+ },
31
+ "files": [
32
+ "dist",
33
+ ".claude-plugin",
34
+ "skills",
35
+ ".mcp.json",
36
+ "server.json"
37
+ ],
38
+ "scripts": {
39
+ "build": "tsc && npm run bundle",
40
+ "bundle": "esbuild src/index.ts --bundle --platform=node --format=esm --external:dotenv --outfile=dist/bundle.js",
41
+ "dev": "node --env-file=.env dist/index.js",
42
+ "test": "vitest run",
43
+ "test:watch": "vitest"
44
+ },
45
+ "dependencies": {
46
+ "@modelcontextprotocol/sdk": "^1.29.0",
47
+ "dotenv": "^17.4.0",
48
+ "zod": "^4.3.6"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^25.5.2",
52
+ "@vitest/coverage-v8": "^4.1.2",
53
+ "esbuild": "^0.28.0",
54
+ "typescript": "^6.0.2",
55
+ "vitest": "^4.1.2"
56
+ }
57
+ }
package/server.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.chrischall/canvas-parent-mcp",
4
+ "description": "Canvas LMS (Instructure) for Claude — courses, grades, assignments, announcements, planner, conversations",
5
+ "repository": {
6
+ "url": "https://github.com/chrischall/canvas-parent-mcp",
7
+ "source": "github"
8
+ },
9
+ "version": "0.1.0",
10
+ "packages": [
11
+ {
12
+ "registryType": "npm",
13
+ "identifier": "canvas-parent-mcp",
14
+ "version": "0.1.0",
15
+ "transport": {
16
+ "type": "stdio"
17
+ },
18
+ "environmentVariables": [
19
+ {
20
+ "name": "CANVAS_BASE_URL",
21
+ "description": "Canvas instance base URL, e.g. https://cms.instructure.com",
22
+ "isRequired": true,
23
+ "format": "string"
24
+ },
25
+ {
26
+ "name": "CANVAS_TOKEN",
27
+ "description": "Canvas personal access token (set this OR all three OAuth vars)",
28
+ "isRequired": false,
29
+ "format": "string",
30
+ "isSecret": true
31
+ },
32
+ {
33
+ "name": "CANVAS_CLIENT_ID",
34
+ "description": "Canvas OAuth client ID (required if not using CANVAS_TOKEN)",
35
+ "isRequired": false,
36
+ "format": "string"
37
+ },
38
+ {
39
+ "name": "CANVAS_CLIENT_SECRET",
40
+ "description": "Canvas OAuth client secret (required if not using CANVAS_TOKEN)",
41
+ "isRequired": false,
42
+ "format": "string",
43
+ "isSecret": true
44
+ },
45
+ {
46
+ "name": "CANVAS_REFRESH_TOKEN",
47
+ "description": "Canvas OAuth refresh token (required if not using CANVAS_TOKEN)",
48
+ "isRequired": false,
49
+ "format": "string",
50
+ "isSecret": true
51
+ },
52
+ {
53
+ "name": "CANVAS_NAME",
54
+ "description": "Friendly name for the Canvas instance (defaults to the host portion of the base URL)",
55
+ "isRequired": false,
56
+ "format": "string"
57
+ }
58
+ ]
59
+ }
60
+ ]
61
+ }
@@ -0,0 +1,193 @@
1
+ ---
2
+ name: canvas
3
+ description: This skill should be used when the user asks about Canvas LMS (Instructure) data for themselves or any student they observe. Triggers on phrases like "check Canvas", "what's my grade", "Canvas inbox", "what's due", "missing assignments", "Canvas LMS", "Instructure", "course announcements", "syllabus", or any request about courses, assignments, grades, conversations, announcements, planner items, or files.
4
+ ---
5
+
6
+ # canvas-parent-mcp
7
+
8
+ MCP server for Canvas LMS (Instructure) — 18 tools covering profile, observees, courses, assignments, submissions, grades, calendar, planner, announcements, conversations, discussions, and files. Read-only except for one file-download tool.
9
+
10
+ - **Source:** [github.com/chrischall/canvas-parent-mcp](https://github.com/chrischall/canvas-parent-mcp)
11
+ - **npm:** [npmjs.com/package/canvas-parent-mcp](https://www.npmjs.com/package/canvas-parent-mcp)
12
+
13
+ ## Setup
14
+
15
+ Two auth modes — set one. Personal access token is recommended.
16
+
17
+ ### Option A — Claude Code (direct MCP, no mcporter)
18
+
19
+ Add to `.mcp.json` in your project or `~/.claude/mcp.json`:
20
+
21
+ ```json
22
+ {
23
+ "mcpServers": {
24
+ "canvas": {
25
+ "command": "npx",
26
+ "args": ["-y", "canvas-parent-mcp"],
27
+ "env": {
28
+ "CANVAS_BASE_URL": "https://cms.instructure.com",
29
+ "CANVAS_TOKEN": "your-personal-access-token",
30
+ "CANVAS_NAME": "CMS"
31
+ }
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ For OAuth instead of a token:
38
+
39
+ ```json
40
+ {
41
+ "mcpServers": {
42
+ "canvas": {
43
+ "command": "npx",
44
+ "args": ["-y", "canvas-parent-mcp"],
45
+ "env": {
46
+ "CANVAS_BASE_URL": "https://cms.instructure.com",
47
+ "CANVAS_CLIENT_ID": "...",
48
+ "CANVAS_CLIENT_SECRET": "...",
49
+ "CANVAS_REFRESH_TOKEN": "..."
50
+ }
51
+ }
52
+ }
53
+ }
54
+ ```
55
+
56
+ ### Option B — mcporter
57
+
58
+ #### 1. Install
59
+
60
+ ```bash
61
+ npm install -g canvas-parent-mcp
62
+ ```
63
+
64
+ Or from source:
65
+ ```bash
66
+ git clone https://github.com/chrischall/canvas-parent-mcp
67
+ cd canvas-parent-mcp
68
+ npm install && npm run build
69
+ ```
70
+
71
+ #### 2. Configure credentials
72
+
73
+ ```bash
74
+ cp .env.example .env
75
+ # Edit .env: set CANVAS_BASE_URL and CANVAS_TOKEN (or the OAuth triple).
76
+ ```
77
+
78
+ #### 3. Register with mcporter
79
+
80
+ ```bash
81
+ mcporter config add canvas \
82
+ --command "canvas-parent-mcp" \
83
+ --env "CANVAS_BASE_URL=https://cms.instructure.com" \
84
+ --env "CANVAS_TOKEN=your-personal-access-token" \
85
+ --env "CANVAS_NAME=CMS" \
86
+ --config ~/.mcporter/mcporter.json
87
+ ```
88
+
89
+ #### 4. Verify
90
+
91
+ ```bash
92
+ mcporter list --config ~/.mcporter/mcporter.json
93
+ mcporter call canvas.canvas_get_profile --config ~/.mcporter/mcporter.json
94
+ ```
95
+
96
+ ## Calling tools (mcporter)
97
+
98
+ ```bash
99
+ mcporter call canvas.<tool_name> [key=value ...] --config ~/.mcporter/mcporter.json
100
+ ```
101
+
102
+ Always pass `--config ~/.mcporter/mcporter.json` unless a local `config/mcporter.json` exists.
103
+
104
+ Most tools accept an optional `observeeId` (defaults to `self`) — set it to a student's user ID when an observer is checking on a linked student. List the candidates with `canvas_list_observees`.
105
+
106
+ ## Tools
107
+
108
+ ### Profile & observees
109
+ | Tool | Notes |
110
+ |------|-------|
111
+ | `canvas_get_profile` | Your Canvas profile (id, name, email, login, locale, timezone). Call this first to confirm credentials work. |
112
+ | `canvas_list_observees` | Students linked to your observer account. Returns `[]` for plain student tokens. |
113
+
114
+ ### Courses
115
+ | Tool | Notes |
116
+ |------|-------|
117
+ | `canvas_list_courses(observeeId?)` | Active courses with course-level grades. Includes total scores + current grading period scores. |
118
+ | `canvas_get_course(courseId)` | Course detail: syllabus, teachers, term. |
119
+
120
+ ### Assignments & submissions
121
+ | Tool | Notes |
122
+ |------|-------|
123
+ | `canvas_list_assignments(courseId, bucket?)` | Assignments for a course. `bucket` can be `upcoming`, `overdue`, `past`, or `undated`. Includes the user's submission inline. |
124
+ | `canvas_list_missing_submissions(observeeId?, courseIds?)` | Past-due unsubmitted assignments. For an observee, `courseIds` is required. |
125
+ | `canvas_get_submission(courseId, assignmentId, userId?)` | A single submission with comments + rubric assessment. `userId` defaults to `self`. |
126
+ | `canvas_list_recent_submissions(courseId, since?)` | Recently graded submissions in a course. Defaults to a 14-day window. |
127
+
128
+ ### Grades
129
+ | Tool | Notes |
130
+ |------|-------|
131
+ | `canvas_list_enrollments(observeeId?)` | Active student enrollments with `grades` (current_score, final_score, current_grade, final_grade, current grading period). |
132
+
133
+ ### Calendar & planner
134
+ | Tool | Notes |
135
+ |------|-------|
136
+ | `canvas_list_calendar_events(contextCodes?, type?, startDate?, endDate?)` | Calendar events / assignments. `contextCodes` is an array like `["course_123", "user_456"]`. |
137
+ | `canvas_list_upcoming_events` | Canvas's curated next-7-days view. |
138
+ | `canvas_list_planner_items(observeeId?, startDate?, endDate?, contextCodes?)` | Unified planner: assignments + announcements + planner notes + calendar events. |
139
+
140
+ ### Communication
141
+ | Tool | Notes |
142
+ |------|-------|
143
+ | `canvas_list_announcements(contextCodes, startDate?, endDate?)` | Announcements across one or more courses. `contextCodes` is required (e.g. `["course_123"]`). Defaults to the last 14 days. |
144
+ | `canvas_list_conversations(scope?)` | Inbox conversation list. `scope` ∈ `unread` / `starred` / `archived`. |
145
+ | `canvas_get_conversation(id)` | Full conversation thread with messages. |
146
+ | `canvas_list_discussion_topics(courseId)` | Discussion topic list for a course (read-only). |
147
+
148
+ ### Files
149
+ | Tool | Notes |
150
+ |------|-------|
151
+ | `canvas_list_course_files(courseId, searchTerm?)` | File metadata: id, display_name, size, content-type, **`url`**. |
152
+ | `canvas_download_file(url, destinationPath, overwrite?)` | Writes the file to `destinationPath` on disk. **`destinationPath` is required** — confirm the path with the user before calling. |
153
+
154
+ ## Workflows
155
+
156
+ **Discovery (first time):**
157
+ 1. `canvas_get_profile` → confirm credentials
158
+ 2. `canvas_list_observees` → if empty, you're a student; otherwise capture observee IDs
159
+ 3. `canvas_list_courses` → capture course IDs
160
+
161
+ **Is everything OK at school?**
162
+ 1. `canvas_list_courses` (capture IDs)
163
+ 2. `canvas_list_recent_submissions(courseId)` for each — last 14 days of grading
164
+ 3. `canvas_list_missing_submissions` — past-due work
165
+ 4. `canvas_list_announcements(contextCodes=["course_<id>"])` — recent announcements
166
+
167
+ **What got graded this week?**
168
+ - `canvas_list_recent_submissions(courseId, since="YYYY-MM-DDTHH:MM:SSZ")`
169
+
170
+ **What's due soon?**
171
+ - `canvas_list_planner_items(startDate=..., endDate=...)` — unified planner
172
+ - Or `canvas_list_assignments(courseId, bucket="upcoming")` per course
173
+
174
+ **Today's calendar:**
175
+ - `canvas_list_upcoming_events`
176
+
177
+ **Read a syllabus:**
178
+ - `canvas_get_course(courseId)` — `syllabus_body` is included
179
+
180
+ **Inbox:**
181
+ 1. `canvas_list_conversations` — find a thread
182
+ 2. `canvas_get_conversation(id)` — read it
183
+
184
+ **Download a file:**
185
+ 1. `canvas_list_course_files(courseId)` → find the file's `url`
186
+ 2. Confirm destination path with the user
187
+ 3. `canvas_download_file(url, destinationPath="/Users/.../file.pdf")`
188
+
189
+ ## Caution
190
+
191
+ - `canvas_download_file` writes to disk at `destinationPath` — confirm the path with the user; pass `overwrite:true` to replace.
192
+ - Personal access tokens grant the same access as the user account they were issued for. Treat them as secrets.
193
+ - Endpoints that return paginated results follow Canvas's RFC 5988 `Link` headers automatically up to 50 pages (5,000 items at the default `per_page=100`).