canvas-lms-mcp 1.18.0 → 1.19.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.
package/README.md CHANGED
@@ -13,6 +13,16 @@ MCP server for [Canvas LMS](https://www.instructure.com/canvas). Read courses, a
13
13
 
14
14
  116 tools across Canvas courses, assignments, submissions, gradebook history, rubrics, quizzes, New Quizzes (LTI), files, users, groups, enrollments, discussions, modules, pages, calendar, conversations, peer reviews, accounts, analytics, outcomes, student workflows, dashboard, and health checks. Three deployment modes: stdio, HTTP, and library import.
15
15
 
16
+ ## One-click install (Claude Desktop)
17
+
18
+ 1. **[Download `canvas-lms-mcp.mcpb`](https://github.com/bruchris/canvas-lms-mcp/releases/latest/download/canvas-lms-mcp.mcpb)** from the latest release.
19
+ 2. Double-click the file (or drag it into Claude Desktop's Extensions settings).
20
+ 3. When prompted, paste your Canvas API token and Canvas API base URL (e.g. `https://school.instructure.com/api/v1`).
21
+
22
+ No terminal, no Node.js install, no config-file editing — Claude Desktop bundles the runtime and handles config for you. The same `.mcpb` works in Claude Code and MCP for Windows.
23
+
24
+ Prefer the terminal? Use the [Quick Start](#quick-start) below.
25
+
16
26
  ## Comparison
17
27
 
18
28
  | | canvas-lms-mcp | [vishalsachdev/canvas-mcp](https://github.com/vishalsachdev/canvas-mcp) | [DMontgomery40/mcp-canvas-lms](https://github.com/DMontgomery40/mcp-canvas-lms) |
@@ -1,17 +1,17 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkTKK4IOCLcjs = require('../chunk-TKK4IOCL.cjs');
3
+ var _chunkLTBTS6YAcjs = require('../chunk-LTBTS6YA.cjs');
4
4
 
5
5
 
6
6
 
7
7
 
8
8
 
9
- var _chunkXPJXO3NJcjs = require('../chunk-XPJXO3NJ.cjs');
9
+ var _chunkEXAIZYJYcjs = require('../chunk-EXAIZYJY.cjs');
10
10
 
11
11
 
12
12
 
13
13
 
14
14
 
15
15
 
16
- exports.CanvasApiError = _chunkXPJXO3NJcjs.CanvasApiError; exports.CanvasClient = _chunkTKK4IOCLcjs.CanvasClient; exports.CanvasHttpClient = _chunkXPJXO3NJcjs.CanvasHttpClient; exports.appendCanvasQuery = _chunkXPJXO3NJcjs.appendCanvasQuery; exports.toCanvasQuery = _chunkXPJXO3NJcjs.toCanvasQuery;
16
+ exports.CanvasApiError = _chunkEXAIZYJYcjs.CanvasApiError; exports.CanvasClient = _chunkLTBTS6YAcjs.CanvasClient; exports.CanvasHttpClient = _chunkEXAIZYJYcjs.CanvasHttpClient; exports.appendCanvasQuery = _chunkEXAIZYJYcjs.appendCanvasQuery; exports.toCanvasQuery = _chunkEXAIZYJYcjs.toCanvasQuery;
17
17
  //# sourceMappingURL=index.cjs.map
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  CanvasClient
3
- } from "../chunk-5WXEIIJS.js";
3
+ } from "../chunk-5P4FUG7Q.js";
4
4
  import {
5
5
  CanvasApiError,
6
6
  CanvasHttpClient,
7
7
  appendCanvasQuery,
8
8
  toCanvasQuery
9
- } from "../chunk-TYV6ENOV.js";
9
+ } from "../chunk-Z5EZRC5F.js";
10
10
  export {
11
11
  CanvasApiError,
12
12
  CanvasClient,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  CanvasHttpClient
3
- } from "./chunk-TYV6ENOV.js";
3
+ } from "./chunk-Z5EZRC5F.js";
4
4
 
5
5
  // src/canvas/courses.ts
6
6
  var DEFAULT_LIST_INCLUDE = ["term"];
@@ -1395,4 +1395,4 @@ export {
1395
1395
  OUTCOME_EXCLUDE_OPTIONS,
1396
1396
  CanvasClient
1397
1397
  };
1398
- //# sourceMappingURL=chunk-5WXEIIJS.js.map
1398
+ //# sourceMappingURL=chunk-5P4FUG7Q.js.map
@@ -7,11 +7,11 @@
7
7
 
8
8
 
9
9
 
10
- var _chunkTKK4IOCLcjs = require('./chunk-TKK4IOCL.cjs');
10
+ var _chunkLTBTS6YAcjs = require('./chunk-LTBTS6YA.cjs');
11
11
 
12
12
 
13
13
 
14
- var _chunkXPJXO3NJcjs = require('./chunk-XPJXO3NJ.cjs');
14
+ var _chunkEXAIZYJYcjs = require('./chunk-EXAIZYJY.cjs');
15
15
 
16
16
  // src/server.ts
17
17
  var _mcpjs = require('@modelcontextprotocol/sdk/server/mcp.js');
@@ -547,7 +547,7 @@ function accountTools(canvas, pseudonymizer) {
547
547
 
548
548
  // src/tools/errors.ts
549
549
  function formatError(error) {
550
- if (error instanceof _chunkXPJXO3NJcjs.CanvasApiError) {
550
+ if (error instanceof _chunkEXAIZYJYcjs.CanvasApiError) {
551
551
  const status = error.status;
552
552
  const message = error.message;
553
553
  const ltiMarkers = ["Tool not configured", "tool is not configured"];
@@ -599,7 +599,7 @@ function analyticsTools(canvas) {
599
599
  inputSchema: {
600
600
  course_id: _zod.z.number().describe("The Canvas course ID"),
601
601
  search_term: _zod.z.string().describe("The keyword or phrase to search for"),
602
- content_types: _zod.z.array(_zod.z.enum(_chunkTKK4IOCLcjs.SEARCH_CONTENT_TYPES)).optional().describe(
602
+ content_types: _zod.z.array(_zod.z.enum(_chunkLTBTS6YAcjs.SEARCH_CONTENT_TYPES)).optional().describe(
603
603
  "Content types to search. Defaults to all types: pages, discussions, assignments, announcements."
604
604
  )
605
605
  },
@@ -611,7 +611,7 @@ function analyticsTools(canvas) {
611
611
  const courseId = params.course_id;
612
612
  const searchTerm = params.search_term;
613
613
  const types = _nullishCoalesce(params.content_types, () => ( [
614
- ..._chunkTKK4IOCLcjs.SEARCH_CONTENT_TYPES
614
+ ..._chunkLTBTS6YAcjs.SEARCH_CONTENT_TYPES
615
615
  ]));
616
616
  if (types.length === 0) return { results: [] };
617
617
  const settled = await Promise.allSettled(
@@ -1983,7 +1983,7 @@ function outcomeTools(canvas, pseudonymizer) {
1983
1983
  name: "get_root_outcome_group",
1984
1984
  description: "Get the root outcome group for an account or course context.",
1985
1985
  inputSchema: {
1986
- context_type: _zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcomes from an account or course context."),
1986
+ context_type: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcomes from an account or course context."),
1987
1987
  context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context.")
1988
1988
  },
1989
1989
  annotations: { readOnlyHint: true, openWorldHint: true },
@@ -1996,7 +1996,7 @@ function outcomeTools(canvas, pseudonymizer) {
1996
1996
  name: "list_outcome_groups",
1997
1997
  description: "List all outcome groups for an account or course context.",
1998
1998
  inputSchema: {
1999
- context_type: _zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcome groups from an account or course context."),
1999
+ context_type: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcome groups from an account or course context."),
2000
2000
  context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context.")
2001
2001
  },
2002
2002
  annotations: { readOnlyHint: true, openWorldHint: true },
@@ -2009,10 +2009,10 @@ function outcomeTools(canvas, pseudonymizer) {
2009
2009
  name: "list_outcome_group_links",
2010
2010
  description: "List all outcome links in an account or course context.",
2011
2011
  inputSchema: {
2012
- context_type: _zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcome links from an account or course context."),
2012
+ context_type: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcome links from an account or course context."),
2013
2013
  context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context."),
2014
- outcome_style: _zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_DETAIL_LEVELS).optional().describe('Outcome detail level. Use "full" to include expanded outcome fields.'),
2015
- outcome_group_style: _zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_DETAIL_LEVELS).optional().describe(
2014
+ outcome_style: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_DETAIL_LEVELS).optional().describe('Outcome detail level. Use "full" to include expanded outcome fields.'),
2015
+ outcome_group_style: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_DETAIL_LEVELS).optional().describe(
2016
2016
  'Outcome group detail level. Use "full" to include expanded outcome group fields.'
2017
2017
  )
2018
2018
  },
@@ -2030,7 +2030,7 @@ function outcomeTools(canvas, pseudonymizer) {
2030
2030
  name: "get_outcome_group",
2031
2031
  description: "Get details for a specific outcome group in an account or course context.",
2032
2032
  inputSchema: {
2033
- context_type: _zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
2033
+ context_type: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
2034
2034
  context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context."),
2035
2035
  outcome_group_id: _zod.z.number().describe("The Canvas outcome group ID.")
2036
2036
  },
@@ -2045,10 +2045,10 @@ function outcomeTools(canvas, pseudonymizer) {
2045
2045
  name: "list_outcome_group_outcomes",
2046
2046
  description: "List the linked outcomes directly under a specific outcome group.",
2047
2047
  inputSchema: {
2048
- context_type: _zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
2048
+ context_type: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
2049
2049
  context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context."),
2050
2050
  outcome_group_id: _zod.z.number().describe("The Canvas outcome group ID."),
2051
- outcome_style: _zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_DETAIL_LEVELS).optional().describe('Outcome detail level. Use "full" to include expanded outcome fields.')
2051
+ outcome_style: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_DETAIL_LEVELS).optional().describe('Outcome detail level. Use "full" to include expanded outcome fields.')
2052
2052
  },
2053
2053
  annotations: { readOnlyHint: true, openWorldHint: true },
2054
2054
  handler: async (params) => canvas.outcomes.listGroupOutcomes(
@@ -2064,7 +2064,7 @@ function outcomeTools(canvas, pseudonymizer) {
2064
2064
  name: "list_outcome_group_subgroups",
2065
2065
  description: "List the immediate child outcome groups under a specific outcome group.",
2066
2066
  inputSchema: {
2067
- context_type: _zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
2067
+ context_type: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
2068
2068
  context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context."),
2069
2069
  outcome_group_id: _zod.z.number().describe("The Canvas outcome group ID.")
2070
2070
  },
@@ -2130,14 +2130,14 @@ function outcomeTools(canvas, pseudonymizer) {
2130
2130
  inputSchema: {
2131
2131
  course_id: _zod.z.number().describe("The Canvas course ID."),
2132
2132
  aggregate: _zod.z.enum(["course"]).optional().describe("Aggregate all student rollups into a single course-level rollup."),
2133
- aggregate_stat: _zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_ROLLUP_AGGREGATE_STATS).optional().describe('Statistic to use when aggregate="course".'),
2133
+ aggregate_stat: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_ROLLUP_AGGREGATE_STATS).optional().describe('Statistic to use when aggregate="course".'),
2134
2134
  user_ids: _zod.z.array(_zod.z.union([_zod.z.number(), _zod.z.string()])).optional().describe('Optional Canvas user IDs or SIS user IDs prefixed with "sis_user_id:".'),
2135
2135
  outcome_ids: _zod.z.array(_zod.z.number()).optional().describe("Optional outcome IDs to restrict the rollups."),
2136
2136
  include_courses: _zod.z.boolean().optional().describe("Include linked course details in the response payload."),
2137
- exclude: _zod.z.array(_zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_EXCLUDE_OPTIONS)).optional().describe("Optional rollup exclusions for missing users or missing outcome results."),
2138
- sort_by: _zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_ROLLUP_SORT_BY).optional().describe("Sort rollups by student name or by a specific outcome score."),
2137
+ exclude: _zod.z.array(_zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_EXCLUDE_OPTIONS)).optional().describe("Optional rollup exclusions for missing users or missing outcome results."),
2138
+ sort_by: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_ROLLUP_SORT_BY).optional().describe("Sort rollups by student name or by a specific outcome score."),
2139
2139
  sort_outcome_id: _zod.z.number().optional().describe('Outcome ID to sort by when sort_by="outcome".'),
2140
- sort_order: _zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_SORT_ORDER).optional().describe("Sort order to apply when sorting rollups."),
2140
+ sort_order: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_SORT_ORDER).optional().describe("Sort order to apply when sorting rollups."),
2141
2141
  add_defaults: _zod.z.boolean().optional().describe("Include default mastery colors and levels when Canvas supports it.")
2142
2142
  },
2143
2143
  annotations: { readOnlyHint: true, openWorldHint: true },
@@ -2185,7 +2185,7 @@ function outcomeTools(canvas, pseudonymizer) {
2185
2185
  description: "Get mastery distribution analytics for outcomes in a course, optionally filtered by students or outcomes.",
2186
2186
  inputSchema: {
2187
2187
  course_id: _zod.z.number().describe("The Canvas course ID."),
2188
- exclude: _zod.z.array(_zod.z.enum(_chunkTKK4IOCLcjs.OUTCOME_EXCLUDE_OPTIONS)).optional().describe("Optional exclusions for missing users or missing outcome results."),
2188
+ exclude: _zod.z.array(_zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_EXCLUDE_OPTIONS)).optional().describe("Optional exclusions for missing users or missing outcome results."),
2189
2189
  outcome_ids: _zod.z.array(_zod.z.number()).optional().describe("Optional outcome IDs to restrict the distribution results."),
2190
2190
  student_ids: _zod.z.array(_zod.z.union([_zod.z.number(), _zod.z.string()])).optional().describe('Optional Canvas student IDs or SIS user IDs prefixed with "sis_user_id:".'),
2191
2191
  include_alignment_distributions: _zod.z.boolean().optional().describe("Include contributing score distributions for alignments."),
@@ -3395,7 +3395,7 @@ function registerAllTools(server, canvas, pseudonymizer) {
3395
3395
  }
3396
3396
  return response;
3397
3397
  } catch (error) {
3398
- if (error instanceof _chunkXPJXO3NJcjs.CanvasApiError) {
3398
+ if (error instanceof _chunkEXAIZYJYcjs.CanvasApiError) {
3399
3399
  } else {
3400
3400
  console.error(`Unexpected error in tool "${tool.name}":`, error);
3401
3401
  }
@@ -3443,7 +3443,7 @@ function registerSyllabusResource(server, canvas) {
3443
3443
  ]
3444
3444
  };
3445
3445
  } catch (error) {
3446
- if (!(error instanceof _chunkXPJXO3NJcjs.CanvasApiError)) {
3446
+ if (!(error instanceof _chunkEXAIZYJYcjs.CanvasApiError)) {
3447
3447
  console.error("Unexpected error in syllabus resource:", error);
3448
3448
  }
3449
3449
  return {
@@ -3492,7 +3492,7 @@ function registerAssignmentDescriptionResource(server, canvas) {
3492
3492
  ]
3493
3493
  };
3494
3494
  } catch (error) {
3495
- if (!(error instanceof _chunkXPJXO3NJcjs.CanvasApiError)) {
3495
+ if (!(error instanceof _chunkEXAIZYJYcjs.CanvasApiError)) {
3496
3496
  console.error("Unexpected error in assignment-description resource:", error);
3497
3497
  }
3498
3498
  return {
@@ -3511,14 +3511,14 @@ function registerAllResources(server, canvas) {
3511
3511
 
3512
3512
  // src/server.ts
3513
3513
  function createCanvasMCPServer(config) {
3514
- const canvas = new (0, _chunkTKK4IOCLcjs.CanvasClient)({
3514
+ const canvas = new (0, _chunkLTBTS6YAcjs.CanvasClient)({
3515
3515
  token: config.token,
3516
3516
  baseUrl: config.baseUrl
3517
3517
  });
3518
3518
  const pseudonymizer = _nullishCoalesce(config.pseudonymizer, () => ( new Pseudonymizer({ baseUrl: config.baseUrl })));
3519
3519
  const server = new (0, _mcpjs.McpServer)({
3520
3520
  name: "canvas-lms-mcp",
3521
- version: _chunkXPJXO3NJcjs.version
3521
+ version: _chunkEXAIZYJYcjs.version
3522
3522
  });
3523
3523
  registerAllTools(server, canvas, pseudonymizer);
3524
3524
  registerAllResources(server, canvas);
@@ -3529,4 +3529,4 @@ function createCanvasMCPServer(config) {
3529
3529
 
3530
3530
 
3531
3531
  exports.Pseudonymizer = Pseudonymizer; exports.createCanvasMCPServer = createCanvasMCPServer;
3532
- //# sourceMappingURL=chunk-PMDK4WZA.cjs.map
3532
+ //# sourceMappingURL=chunk-CDWLOZQ2.cjs.map