@charlie.act7/canvas-mcp-server 1.2.0 → 1.2.2

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.
package/README.md CHANGED
@@ -1,29 +1,48 @@
1
1
  # 🎓 Canvas LMS MCP Server
2
2
 
3
- [![CI](https://github.com/CharlieCardenasToledo/mcp-canvas-server/actions/workflows/ci.yml/badge.svg)](https://github.com/CharlieCardenasToledo/mcp-canvas-server/actions/workflows/ci.yml)
4
- [![npm version](https://img.shields.io/npm/v/@charlie.act7/canvas-mcp-server)](https://www.npmjs.com/package/@charlie.act7/canvas-mcp-server)
5
- [![npm downloads](https://img.shields.io/npm/dm/@charlie.act7/canvas-mcp-server)](https://www.npmjs.com/package/@charlie.act7/canvas-mcp-server)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
3
+ [![npm](https://img.shields.io/npm/v/@charlie.act7/canvas-mcp-server.svg)](https://www.npmjs.com/package/@charlie.act7/canvas-mcp-server)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@charlie.act7/canvas-mcp-server.svg)](https://www.npmjs.com/package/@charlie.act7/canvas-mcp-server)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue.svg)](https://www.typescriptlang.org/)
6
+ [![MCP](https://img.shields.io/badge/MCP-stdio%20%7C%20HTTP-green.svg)](https://modelcontextprotocol.io/)
7
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
7
8
 
8
- Bring AI to your Canvas Virtual Classroom! 🚀
9
+ Model Context Protocol (MCP) server for **Canvas LMS**. It acts as a bridge that allows AI assistants (Claude Code, Claude Desktop, Cursor, Codex CLI, n8n, OpenAI Custom GPTs, and generic MCP clients) to query, grade, audit, and manage Canvas courses, assignments, rubrics, submissions, quizzes, conversations, and analytics using natural language. Two transports are supported: `stdio` (default) and Streamable-HTTP with interactive Swagger API documentation.
9
10
 
10
- This project is a **Model Context Protocol (MCP)** server for **Canvas LMS**. It acts as a bridge that allows AI assistants (like Claude Desktop, Claude Code, Cursor, etc.) to query and manage your Canvas courses using natural language.
11
+ > **Versión en Español:** [README.es.md](README.es.md)
11
12
 
12
13
  ---
13
14
 
14
- ## Table of Contents
15
+ - [Requirements & Platform Support](#requirements--platform-support)
15
16
  - [How It Works](#how-it-works)
16
- - [Use Cases & Examples](#use-cases--examples)
17
- - [Setup Guide](#setup-guide)
18
- - [Step 1: Obtain Canvas Credentials](#step-1-obtain-canvas-credentials)
19
- - [Step 2: Connect to your AI Client](#step-2-connect-to-your-ai-client)
20
- - [CLI Configuration](#cli-configuration)
21
- - [Supported Tools & Resources](#supported-tools--resources)
22
- - [Local Development](#local-development)
17
+ - [Install](#install)
18
+ - [Connect to Claude Code](#connect-to-claude-code)
19
+ - [Connect to Other Clients](#connect-to-other-clients)
20
+ - [Claude Desktop](#claude-desktop)
21
+ - [Cursor](#cursor)
22
+ - [Codex CLI](#codex-cli)
23
+ - [Generic MCP Client (stdio)](#generic-mcp-client-stdio)
24
+ - [HTTP Server & OpenAI Custom GPTs](#http-server--openai-custom-gpts)
25
+ - [Authentication & Credentials](#authentication--credentials)
26
+ - [Transports](#transports)
27
+ - [Use Cases & Prompts](#use-cases--prompts)
28
+ - [Tools](#tools)
29
+ - [Resources](#resources)
30
+ - [Configuration Reference](#configuration-reference)
31
+ - [Development](#development)
32
+ - [Documentation](#documentation)
23
33
  - [License](#license)
24
34
 
25
35
  ---
26
36
 
37
+ ## Requirements & Platform Support
38
+
39
+ - **Node.js** ≥ 18.0.0 (Node.js ≥ 20.x recommended).
40
+ - **Canvas LMS Access**: An active account on your institution's Canvas LMS (e.g. `myschool.instructure.com`).
41
+ - **Canvas API Access Token**: Generated via your Canvas Account Settings page.
42
+ - **Linux / macOS / Windows / WSL2**.
43
+
44
+ ---
45
+
27
46
  ## How It Works
28
47
 
29
48
  When you interact with the server, communication flows as follows:
@@ -40,88 +59,112 @@ graph LR
40
59
 
41
60
  1. **You ask the AI** (e.g., *"Create an assignment due next Friday"*).
42
61
  2. **The AI detects your intent** and communicates with the **Canvas MCP Server**, sending the required parameters.
43
- 3. **The server makes a secure call** to the official Canvas API.
44
- 4. **Canvas processes the action** and returns the response.
62
+ 3. **The server makes a secure call** to the official Canvas LMS API over HTTPS.
63
+ 4. **Canvas LMS processes the action** and returns the response payload.
45
64
  5. **The AI confirms the success of the action** back to you in plain, natural language.
46
65
 
47
66
  ---
48
67
 
49
- ## Use Cases & Examples
68
+ ## Install
50
69
 
51
- Here are some realistic, everyday prompts you can use with your AI assistant:
70
+ ### Published package
52
71
 
53
- > [!TIP]
54
- > **Token Saving & Efficiency:** Whenever possible, specify the Canvas ID or the direct Canvas URL (e.g., `https://[your_institution].instructure.com/courses/[course_id]/assignments/[assignment_id]`) in your prompts. This prevents the AI from scanning all your courses/resources, leading to faster responses and substantial token savings.
55
-
56
- ### 📖 Course Auditing & Querying
57
- * 💬 *"What active courses do I have this semester? Check if there are multiple active sections/parallels."*
58
- * 💬 *"Show me all ungraded submissions for 'Essay 1: Introduction to Sociology' in Sociology 101."*
59
- * 💬 *"Who is in Student Group A for the Chemistry class?"*
60
- * 💬 *"Does the assignment 'Project Proposal' have an active rubric associated? If so, retrieve its criteria."*
61
- * 💬 *"Search for everything related to 'photosynthesis' across my Biology course — assignments, pages, and discussions."*
72
+ ```bash
73
+ npx @charlie.act7/canvas-mcp-server@latest
74
+ ```
62
75
 
63
- ### ✍️ Creating & Organizing Course Content
64
- * 💬 *"Create a new module named 'Week 1: Foundations' in my course."*
65
- * 💬 *"Add a SubHeader 'REQUIRED READINGS' inside the 'Week 1' module, and link the syllabus page to it."*
66
- * 💬 *"In my Business course, create an assignment called 'Case Study 1: Market Analysis'. Add an instructions table with columns for Criteria, Requirements, and Points."*
67
- * 💬 *"Create a threaded discussion topic in my course titled 'Weekly Reflection' and pin it to the top."*
76
+ This is the recommended path for end users. `npx` keeps the binary cached and self-updates on `@latest`.
68
77
 
69
- ### 💯 Grading & Absence Management
70
- * 💬 *"For assignment 'Case Study 1', find all students who haven't submitted their work. Assign them a grade of 0 and add the comment: 'Activity not submitted. Please contact the instructor if you have a valid excuse.'"*
71
- * 💬 *"Grade John's submission for 'Essay 1' with a 90 based on the rubric, and add a comment: 'Great job! The analysis is well-structured, though you could expand more on the conclusion. Keep it up!'"*
78
+ ### Interactive CLI Setup
72
79
 
73
- ### 📊 Student Engagement & Analytics
74
- * 💬 *"Show me the activity analytics for my Calculus course — how active have students been this week?"*
75
- * 💬 *"Which students haven't been active in course 12345 in the last few days? I want to reach out to them."*
76
- * 💬 *"Get the analytics for student [ID] in my Biology course — how many page views and participations do they have?"*
80
+ Configure your Canvas credentials interactively before running:
77
81
 
78
- ### 💬 Messaging & Communication
79
- * 💬 *"Send a private message to student [ID] reminding them their 'Project Proposal' is due tomorrow."*
80
- * 💬 *"How many unread messages do I have in my Canvas inbox?"*
81
- * 💬 *"Show me my last 10 inbox conversations."*
82
+ ```bash
83
+ npx @charlie.act7/canvas-mcp-server config
84
+ ```
82
85
 
83
- ### 👥 Enrollment & Student Management
84
- * 💬 *"Who is enrolled in my course? Show me students and TAs separately."*
85
- * 💬 *"Search for a student named 'Maria Gonzalez' in account 1."*
86
- * 💬 *"Enroll user [ID] as a TA in my Physics course."*
86
+ ### From source
87
87
 
88
- ### 🔄 Peer Reviews
89
- * 💬 *"List all peer review assignments for 'Research Paper' in course 12345."*
90
- * 💬 *"Manually assign student [ID] to review [other student ID]'s submission for 'Essay 2'."*
88
+ ```bash
89
+ git clone https://github.com/CharlieCardenasToledo/mcp-canvas-server.git
90
+ cd mcp-canvas-server
91
+ npm install
92
+ npm run build
93
+ node dist/index.js
94
+ ```
91
95
 
92
96
  ---
93
97
 
94
- ## Setup Guide
98
+ ## Connect to Claude Code
95
99
 
96
- To connect your AI assistant to Canvas, you need to configure **two things**: your Canvas credentials and your AI client (like Claude).
100
+ CLI form:
97
101
 
98
- ### Step 1: Obtain Canvas Credentials
99
- To let the server act on your behalf, it needs permission:
100
- 1. Log in to your **Canvas LMS** account.
101
- 2. Go to **Account** ➡️ **Settings** in the sidebar menu.
102
- 3. Scroll down to the **Approved Integrations** section and click **+ New Access Token**.
103
- 4. Enter a purpose (e.g., "Claude Assistant") and click **Generate Token**.
104
- 5. **Copy the generated token immediately** and store it somewhere safe (you won't be able to see it again after closing the page).
102
+ ```bash
103
+ claude mcp add canvas \
104
+ --env CANVAS_API_TOKEN=YOUR_ACCESS_TOKEN_HERE \
105
+ --env CANVAS_API_DOMAIN=myschool.instructure.com \
106
+ -- npx -y @charlie.act7/canvas-mcp-server@latest
107
+ ```
105
108
 
106
- > [!IMPORTANT]
107
- > You will also need your Canvas Domain. This is the web address of your school/university, for example: `myschool.instructure.com`.
109
+ Or from a local build:
110
+
111
+ ```bash
112
+ claude mcp add canvas \
113
+ --env CANVAS_API_TOKEN=YOUR_ACCESS_TOKEN_HERE \
114
+ --env CANVAS_API_DOMAIN=myschool.instructure.com \
115
+ -- node /absolute/path/to/mcp-canvas-server/dist/index.js
116
+ ```
117
+
118
+ Manual form — drop into `~/.claude.json`:
119
+
120
+ ```json
121
+ {
122
+ "mcpServers": {
123
+ "canvas": {
124
+ "command": "npx",
125
+ "args": ["-y", "@charlie.act7/canvas-mcp-server@latest"],
126
+ "env": {
127
+ "CANVAS_API_TOKEN": "YOUR_ACCESS_TOKEN_HERE",
128
+ "CANVAS_API_DOMAIN": "myschool.instructure.com"
129
+ }
130
+ }
131
+ }
132
+ }
133
+ ```
108
134
 
109
135
  ---
110
136
 
111
- ### Step 2: Connect to your AI Client
137
+ ## Connect to Other Clients
138
+
139
+ ### Claude Desktop
140
+
141
+ Edit your Claude Desktop configuration file:
142
+ - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
143
+ - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
144
+
145
+ ```json
146
+ {
147
+ "mcpServers": {
148
+ "canvas": {
149
+ "command": "npx",
150
+ "args": ["-y", "@charlie.act7/canvas-mcp-server@latest"],
151
+ "env": {
152
+ "CANVAS_API_TOKEN": "YOUR_ACCESS_TOKEN_HERE",
153
+ "CANVAS_API_DOMAIN": "myschool.instructure.com"
154
+ }
155
+ }
156
+ }
157
+ }
158
+ ```
112
159
 
113
- #### Option A: Claude Desktop (Desktop Application)
114
- 1. Open your Claude Desktop configuration file. On Windows, it is located at:
115
- `%APPDATA%\Claude\claude_desktop_config.json`
116
- *(On macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`)*
117
- 2. Add the Canvas server configuration under `mcpServers`:
160
+ ### Cursor `~/.cursor/mcp.json`
118
161
 
119
162
  ```json
120
163
  {
121
164
  "mcpServers": {
122
165
  "canvas": {
123
166
  "command": "npx",
124
- "args": ["-y", "@charlie.act7/canvas-mcp-server"],
167
+ "args": ["-y", "@charlie.act7/canvas-mcp-server@latest"],
125
168
  "env": {
126
169
  "CANVAS_API_TOKEN": "YOUR_ACCESS_TOKEN_HERE",
127
170
  "CANVAS_API_DOMAIN": "myschool.instructure.com"
@@ -130,47 +173,126 @@ To let the server act on your behalf, it needs permission:
130
173
  }
131
174
  }
132
175
  ```
133
- 3. Save the file and restart Claude Desktop. You will see a socket/plug icon indicating the server is successfully connected.
134
176
 
135
- #### Option B: Claude Code (Terminal CLI)
136
- If you are using the Claude Code terminal tool, install the plugin by running:
177
+ ### Codex CLI
178
+
137
179
  ```bash
138
- /plugin install canvas-lms@claude-community
180
+ codex mcp add canvas \
181
+ --env CANVAS_API_TOKEN=YOUR_ACCESS_TOKEN_HERE \
182
+ --env CANVAS_API_DOMAIN=myschool.instructure.com \
183
+ npx -y @charlie.act7/canvas-mcp-server@latest
139
184
  ```
140
- Then, configure your credentials interactively:
185
+
186
+ ### Generic MCP client (stdio)
187
+
188
+ Any client that can spawn an MCP server over stdio can use `npx -y @charlie.act7/canvas-mcp-server@latest`. The server speaks MCP 2025 (`tools`, `resources`, `prompts`).
189
+
190
+ ### HTTP Server & OpenAI Custom GPTs
191
+
192
+ Run the server in HTTP mode with Fastify and interactive Swagger documentation:
193
+
141
194
  ```bash
142
- /canvas-lms:config
195
+ npx @charlie.act7/canvas-mcp-server serve-http --port 3000 --host 0.0.0.0
196
+ # or from source:
197
+ npm run start:http
143
198
  ```
144
199
 
200
+ Visit `http://localhost:3000` to inspect interactive Swagger / OpenAPI definitions or hook into OpenAI Custom GPT Actions.
201
+
202
+ ---
203
+
204
+ ## Authentication & Credentials
205
+
206
+ ### Step 1: Obtain Canvas Credentials
207
+
208
+ 1. Log in to your **Canvas LMS** account.
209
+ 2. Go to **Account** ➡️ **Settings** in the sidebar navigation.
210
+ 3. Scroll to **Approved Integrations** and click **+ New Access Token**.
211
+ 4. Enter a purpose (e.g. "Claude Canvas MCP") and click **Generate Token**.
212
+ 5. Copy the generated token immediately and store it securely (it will not be shown again).
213
+
214
+ > [!IMPORTANT]
215
+ > Note down your **Canvas Domain**. This is the web address of your institution's Canvas platform, for example: `myschool.instructure.com`.
216
+
217
+ ### Token Auto-Renewal
218
+
219
+ If your institution enforces token expiration, the server checks the active token's expiry before each request and automatically regenerates and persists it once it is within 24 hours of expiring.
220
+
221
+ Toggles & Tuning:
222
+ - `CANVAS_TOKEN_AUTO_RENEW=false` — Disable automatic token regeneration.
223
+ - `CANVAS_TOKEN_RENEW_THRESHOLD_HOURS=48` — Change the renewal threshold window (default: `24` hours).
224
+
145
225
  ---
146
226
 
147
- ## CLI Configuration
148
- If you prefer to configure your credentials locally for development, run:
227
+ ## Transports
228
+
229
+ The server supports two transport modes:
230
+
231
+ ### stdio (default)
232
+
149
233
  ```bash
150
- npx @charlie.act7/canvas-mcp-server config
234
+ npx @charlie.act7/canvas-mcp-server@latest
151
235
  ```
152
- This will guide you step-by-step to input your domain and API token, storing them securely in a local configuration file.
236
+
237
+ Used by desktop applications and CLI tools (Claude Desktop, Claude Code, Cursor, Codex).
238
+
239
+ ### HTTP Server / Fastify REST API
240
+
241
+ ```bash
242
+ npx @charlie.act7/canvas-mcp-server serve-http --port 3000 --host 0.0.0.0
243
+ ```
244
+
245
+ Optionally pass `--port <port>` (default `3000`) and `--host <host>` (default `0.0.0.0` or `127.0.0.1`).
153
246
 
154
247
  ---
155
248
 
156
- ## Supported Tools & Resources
249
+ ## Use Cases & Prompts
157
250
 
158
- <details>
159
- <summary><b>View all 111 tools organized by category</b></summary>
251
+ > [!TIP]
252
+ > **Token Saving & Efficiency:** Whenever possible, specify the Canvas ID or the direct Canvas URL (e.g., `https://[your_institution].instructure.com/courses/[course_id]/assignments/[assignment_id]`) in your prompts. This prevents the AI from scanning all your courses/resources, leading to faster responses and substantial token savings.
160
253
 
161
- ### Tool Inventory
254
+ ### 📖 Course Auditing & Querying
255
+ - 💬 *"What active courses do I have this semester? Check if there are multiple active sections/parallels."*
256
+ - 💬 *"Show me all ungraded submissions for 'Essay 1: Introduction to Sociology' in Sociology 101."*
257
+ - 💬 *"Who is in Student Group A for the Chemistry class?"*
258
+ - 💬 *"Does the assignment 'Project Proposal' have an active rubric associated? If so, retrieve its criteria."*
259
+ - 💬 *"Search for everything related to 'photosynthesis' across my Biology course — assignments, pages, and discussions."*
260
+
261
+ ### ✍️ Creating & Organizing Course Content
262
+ - 💬 *"Create a new module named 'Week 1: Foundations' in my course."*
263
+ - 💬 *"Add a SubHeader 'REQUIRED READINGS' inside the 'Week 1' module, and link the syllabus page to it."*
264
+ - 💬 *"In my Business course, create an assignment called 'Case Study 1: Market Analysis'. Add an instructions table with columns for Criteria, Requirements, and Points."*
265
+ - 💬 *"Create a threaded discussion topic in my course titled 'Weekly Reflection' and pin it to the top."*
266
+
267
+ ### 💯 Grading & Absence Management
268
+ - 💬 *"For assignment 'Case Study 1', find all students who haven't submitted their work. Assign them a grade of 0 and add the comment: 'Activity not submitted.'"*
269
+ - 💬 *"Grade John's submission for 'Essay 1' with a 90 based on the rubric, and add feedback."*
270
+
271
+ ### 📊 Student Engagement & Analytics
272
+ - 💬 *"Show me the activity analytics for my Calculus course — how active have students been this week?"*
273
+ - 💬 *"Which students haven't been active in course 12345 in the last few days?"*
274
+
275
+ ### 💬 Messaging & Communication
276
+ - 💬 *"Send a private message to student [ID] reminding them their 'Project Proposal' is due tomorrow."*
277
+ - 💬 *"How many unread messages do I have in my Canvas inbox?"*
278
+
279
+ ---
280
+
281
+ ## Tools
282
+
283
+ The Canvas MCP Server exposes **117 tools** organized into 21 functional categories:
162
284
 
163
285
  | Category | Tools | Description |
164
286
  |---|---|---|
165
287
  | **Courses** | `list_courses` · `create_course` · `update_course` · `get_syllabus` | Manage and configure courses |
166
288
  | **Modules** | `list_modules` · `create_module` · `update_module` · `delete_module` · `create_module_item` · `update_module_item` · `delete_module_item` | Full CRUD for modules and their items |
167
- | **Pages** | `list_pages` · `get_page_content` · `create_page` · `update_page` · `delete_page` | Manage wiki pages |
289
+ | **Pages** | `list_pages` · `get_page_content` · `create_page` · `update_page` · `delete_page` | Wiki page publishing & editing |
168
290
  | **Files & Folders** | `list_files` · `upload_file` · `update_file` · `delete_file` · `list_folders` · `create_folder` · `update_folder` · `delete_folder` | File management with folder support |
169
291
  | **Assignments** | `get_assignments` · `get_assignment` · `create_assignment` · `update_assignment` · `delete_assignment` · `update_assignment_dates` · `bulk_update_due_dates` · `list_assignment_groups` | Full assignment lifecycle |
170
292
  | **Submissions** | `get_submissions` · `get_submission` · `get_submission_comments` · `delete_submission_comment` · `submit_assignment` | View and manage student submissions |
171
293
  | **Grading** | `grade_submission` · `grade_multiple_submissions` · `audit_course` | Grade individually or in bulk |
172
294
  | **Rubrics** | `list_rubrics` · `get_rubric` · `create_rubric` · `update_rubric` · `create_rubric_association` | Build and attach grading rubrics |
173
- | **Quizzes (Classic)** | `list_quizzes` · `get_quiz` · `create_quiz` · `update_quiz` · `update_quiz_dates` · `list_quiz_questions` · `get_quiz_question` · `create_quiz_question` · `update_quiz_question` · `delete_quiz_question` · `create_quiz_group` | Classic Canvas quiz engine |
295
+ | **Classic Quizzes** | `list_quizzes` · `get_quiz` · `create_quiz` · `update_quiz` · `update_quiz_dates` · `list_quiz_questions` · `get_quiz_question` · `create_quiz_question` · `update_quiz_question` · `delete_quiz_question` · `create_quiz_group` | Classic Canvas quiz engine |
174
296
  | **New Quizzes (LTI)** | `create_new_quiz` · `update_new_quiz` · `delete_new_quiz` · `list_new_quiz_items` · `get_new_quiz_item` · `create_new_quiz_item` · `update_new_quiz_item` · `delete_new_quiz_item` | Modern LTI quiz engine (`/api/quiz/v1`) |
175
297
  | **Students** | `list_students` · `list_students_with_grades` · `get_student_grades` · `get_student_assignments` · `list_assignment_due_dates` | Roster and progress tracking |
176
298
  | **Enrollments** | `list_course_enrollments` · `enroll_user` · `remove_enrollment` · `get_user` · `get_profile` · `search_users` | Manage who is in your course |
@@ -181,40 +303,67 @@ This will guide you step-by-step to input your domain and API token, storing the
181
303
  | **Calendar** | `list_appointment_groups` · `get_appointment_group` · `create_appointment_group` · `update_appointment_group` · `delete_appointment_group` · `list_appointment_group_users` · `list_appointment_group_groups` · `get_next_appointment` | Scheduling and appointments |
182
304
  | **Analytics** | `get_course_analytics` · `get_student_analytics` · `get_course_activity_stream` · `search_course_content` | Engagement data and content search |
183
305
  | **Peer Reviews** | `list_peer_reviews` · `get_submission_peer_reviews` · `create_peer_review` · `delete_peer_review` | Configure and manage peer assessments |
184
- | **Health & Config** | `health_check` · `set_canvas_config` | Verify connection and update credentials at runtime |
306
+ | **Access Tokens** | `list_access_tokens` · `get_access_token` · `create_access_token` · `update_access_token` · `regenerate_access_token` · `delete_access_token` | Manage Canvas API tokens with auto-renewal |
307
+ | **Health & Config** | `health_check` · `set_canvas_config` | Connection checks & runtime configuration updates |
308
+
309
+ ---
310
+
311
+ ## Resources
312
+
313
+ Supported native MCP resources:
314
+
315
+ | Resource URI | Description |
316
+ |---|---|
317
+ | `canvas://courses/{id}/readme` | Formatted Markdown course summary |
318
+ | `canvas://courses/{id}/pages/{slug}` | Direct HTML content of Canvas pages |
185
319
 
186
- ### Supported MCP Resources
187
- For clients supporting direct resources:
188
- * `canvas://courses/{id}/readme` — Formatted course summary.
189
- * `canvas://courses/{id}/pages/{slug}` — Direct HTML content of Canvas pages.
190
- </details>
320
+ ---
321
+
322
+ ## Configuration Reference
323
+
324
+ All configuration parameters can be passed as environment variables or stored via CLI configuration (`npx @charlie.act7/canvas-mcp-server config`).
325
+
326
+ | Env Var | Default | Purpose |
327
+ |---|---|---|
328
+ | `CANVAS_API_TOKEN` | _(unset)_ | Canvas LMS API access token. |
329
+ | `CANVAS_API_DOMAIN` | _(unset)_ | Domain of your Canvas LMS instance (e.g. `myschool.instructure.com`). |
330
+ | `CANVAS_TOKEN_AUTO_RENEW` | `true` | Automatically regenerate expiring access tokens before expiration. |
331
+ | `CANVAS_TOKEN_RENEW_THRESHOLD_HOURS` | `24` | Threshold in hours before token expiry to trigger auto-renewal. |
332
+ | `PORT` / `HTTP_PORT` | `3000` | HTTP port when running `serve-http`. |
333
+ | `HTTP_HOST` | `0.0.0.0` | Host interface binding for HTTP server mode. |
334
+ | `GEMINI_API_KEY` | _(unset)_ | (Optional) Gemini API key for local LLM bridge / script utilities. |
335
+ | `OLLAMA_HOST` | `http://localhost:11434` | (Optional) Local Ollama host address for local model bridge. |
191
336
 
192
337
  ---
193
338
 
194
- ## Local Development
195
-
196
- To clone this repository and modify the code:
197
-
198
- 1. **Install Dependencies:**
199
- ```bash
200
- npm install
201
- ```
202
- 2. **Build the Project (TypeScript to JavaScript):**
203
- ```bash
204
- npm run build
205
- ```
206
- 3. **Start Server in Stdio Mode (MCP):**
207
- ```bash
208
- npm start
209
- ```
210
- 4. **Start HTTP Server with Swagger Documentation:**
211
- If you want to use this as an OpenAI GPT Custom Action, spin up the web server with:
212
- ```bash
213
- npm run start:http
214
- ```
215
- Then visit `http://localhost:3000` to view the interactive Swagger interface.
339
+ ## Development
340
+
341
+ ```bash
342
+ npm run build # Compile TypeScript source code (tsc)
343
+ npm run dev # Watch mode compilation (tsc --watch)
344
+ npm start # Run MCP server in stdio mode
345
+ npm run start:http # Run HTTP server with Swagger UI at http://localhost:3000
346
+ npm run chat # Launch interactive Ollama bridge test CLI
347
+ ```
348
+
349
+ ### Source Layout
350
+
351
+ - `src/index.ts` CLI entry point (Commander), stdio MCP server bootstrap
352
+ - `src/http-server.ts` — Fastify HTTP server, Swagger / OpenAPI route definitions
353
+ - `src/common/` — `canvas-client.ts` (API client & token auto-renewal), `config.ts` (`conf` manager), `types.ts`
354
+ - `src/tools/` — 117+ tool implementations divided by functional module
355
+ - `src/resources/` MCP resource providers (`canvas://`)
356
+ - `src/prompts/` MCP prompt templates
357
+
358
+ ---
359
+
360
+ ## Documentation
361
+
362
+ - [`README.es.md`](./README.es.md) — Versión en Español del README.
363
+ - [`llms-install.md`](./llms-install.md) — Detailed guide for client integration (Cursor, Copilot, Custom GPTs).
216
364
 
217
365
  ---
218
366
 
219
367
  ## License
220
- This project is licensed under the MIT License. Created by [Charlie Cárdenas Toledo](https://github.com/charlie-act7).
368
+
369
+ This project is licensed under the **MIT License**. Created by [Charlie Cárdenas Toledo](https://github.com/CharlieCardenasToledo).
package/dist/index.js CHANGED
@@ -28,6 +28,7 @@ import { conversationTools } from "./tools/conversation-tools.js";
28
28
  import { newQuizTools } from "./tools/new-quiz-tools.js";
29
29
  import { analyticsTools } from "./tools/analytics-tools.js";
30
30
  import { peerReviewTools } from "./tools/peer-review-tools.js";
31
+ import { accessTokenTools } from "./tools/access-token-tools.js";
31
32
  import { canvasResources } from "./resources/canvas-resources.js";
32
33
  import { canvasPrompts } from "./prompts/canvas-prompts.js";
33
34
  import { startHttpServer } from "./http-server.js";
@@ -35,6 +36,16 @@ import { startHttpServer } from "./http-server.js";
35
36
  dotenv.config();
36
37
  const configManager = new ConfigManager();
37
38
  const program = new Command();
39
+ function uniqueTools(tools) {
40
+ const seen = new Set();
41
+ return tools.filter((tool) => {
42
+ if (seen.has(tool.name)) {
43
+ return false;
44
+ }
45
+ seen.add(tool.name);
46
+ return true;
47
+ });
48
+ }
38
49
  program
39
50
  .name("canvas-mcp")
40
51
  .description("MCP Server for Canvas LMS (Refactored)")
@@ -75,7 +86,16 @@ function getClient() {
75
86
  console.error(`Please run ${chalk.cyan("canvas-mcp config")} or set env vars.`);
76
87
  process.exit(1);
77
88
  }
78
- return new CanvasClient(token, domain);
89
+ return new CanvasClient(token, domain, {
90
+ autoRenewToken: process.env.CANVAS_TOKEN_AUTO_RENEW !== "false",
91
+ renewThresholdHours: process.env.CANVAS_TOKEN_RENEW_THRESHOLD_HOURS
92
+ ? Number.parseFloat(process.env.CANVAS_TOKEN_RENEW_THRESHOLD_HOURS)
93
+ : undefined,
94
+ onTokenRenewed: (newToken) => {
95
+ configManager.set("CANVAS_API_TOKEN", newToken);
96
+ console.error(chalk.green("Canvas access token auto-renewed and persisted."));
97
+ }
98
+ });
79
99
  }
80
100
  // NOTE: We could keep CLI commands for grading/auditing here calling the client directly,
81
101
  // but for the sake of the MCP Server refactor, we are focusing on the 'start' command.
@@ -96,7 +116,7 @@ program
96
116
  },
97
117
  });
98
118
  // --- Aggregation ---
99
- const allTools = [
119
+ const allTools = uniqueTools([
100
120
  ...courseTools,
101
121
  ...assignmentTools,
102
122
  ...quizTools,
@@ -115,8 +135,9 @@ program
115
135
  ...conversationTools,
116
136
  ...newQuizTools,
117
137
  ...analyticsTools,
118
- ...peerReviewTools
119
- ];
138
+ ...peerReviewTools,
139
+ ...accessTokenTools
140
+ ]);
120
141
  // --- Tool Handlers ---
121
142
  server.setRequestHandler(ListToolsRequestSchema, async () => {
122
143
  return {
@@ -173,7 +194,7 @@ program
173
194
  .action(async (options) => {
174
195
  const client = getClient();
175
196
  const port = Number.parseInt(options.port, 10);
176
- const allTools = [
197
+ const allTools = uniqueTools([
177
198
  ...courseTools,
178
199
  ...assignmentTools,
179
200
  ...quizTools,
@@ -192,8 +213,9 @@ program
192
213
  ...conversationTools,
193
214
  ...newQuizTools,
194
215
  ...analyticsTools,
195
- ...peerReviewTools
196
- ];
216
+ ...peerReviewTools,
217
+ ...accessTokenTools
218
+ ]);
197
219
  await startHttpServer(client, options.host, port, allTools);
198
220
  });
199
221
  program.parse(process.argv);