canvas-lms-mcp 1.31.0 → 1.31.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/dist/canvas/index.cjs +3 -3
- package/dist/canvas/index.js +2 -2
- package/dist/canvas/new-quizzes.d.ts +5 -0
- package/dist/canvas/new-quizzes.d.ts.map +1 -1
- package/dist/{chunk-TOGA5SGP.js → chunk-A6OUWDRT.js} +2 -2
- package/dist/{chunk-TOGA5SGP.js.map → chunk-A6OUWDRT.js.map} +1 -1
- package/dist/{chunk-VBNIAVZQ.cjs → chunk-AT6C4S4M.cjs} +42 -42
- package/dist/{chunk-VBNIAVZQ.cjs.map → chunk-AT6C4S4M.cjs.map} +1 -1
- package/dist/{chunk-XD3BZK6F.js → chunk-E2RSL5I4.js} +15 -10
- package/dist/{chunk-XD3BZK6F.js.map → chunk-E2RSL5I4.js.map} +1 -1
- package/dist/{chunk-FUBSKWSI.js → chunk-T7NTLKGA.js} +3 -3
- package/dist/{chunk-DPPXJDSX.cjs → chunk-UP6NGBEG.cjs} +17 -12
- package/dist/chunk-UP6NGBEG.cjs.map +1 -0
- package/dist/{chunk-UMOWXSYV.cjs → chunk-ZJURO66M.cjs} +2 -2
- package/dist/{chunk-UMOWXSYV.cjs.map → chunk-ZJURO66M.cjs.map} +1 -1
- package/dist/http.cjs +6 -6
- package/dist/http.js +3 -3
- package/dist/init.cjs +3 -3
- package/dist/init.js +1 -1
- package/dist/server.cjs +4 -4
- package/dist/server.js +3 -3
- package/dist/stdio.cjs +4 -4
- package/dist/stdio.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-DPPXJDSX.cjs.map +0 -1
- /package/dist/{chunk-FUBSKWSI.js.map → chunk-T7NTLKGA.js.map} +0 -0
package/dist/canvas/index.cjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkUP6NGBEGcjs = require('../chunk-UP6NGBEG.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunkZJURO66Mcjs = require('../chunk-ZJURO66M.cjs');
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
exports.CanvasApiError =
|
|
16
|
+
exports.CanvasApiError = _chunkZJURO66Mcjs.CanvasApiError; exports.CanvasClient = _chunkUP6NGBEGcjs.CanvasClient; exports.CanvasHttpClient = _chunkZJURO66Mcjs.CanvasHttpClient; exports.appendCanvasQuery = _chunkZJURO66Mcjs.appendCanvasQuery; exports.toCanvasQuery = _chunkZJURO66Mcjs.toCanvasQuery;
|
|
17
17
|
//# sourceMappingURL=index.cjs.map
|
package/dist/canvas/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CanvasClient
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-E2RSL5I4.js";
|
|
4
4
|
import {
|
|
5
5
|
CanvasApiError,
|
|
6
6
|
CanvasHttpClient,
|
|
7
7
|
appendCanvasQuery,
|
|
8
8
|
toCanvasQuery
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-A6OUWDRT.js";
|
|
10
10
|
export {
|
|
11
11
|
CanvasApiError,
|
|
12
12
|
CanvasClient,
|
|
@@ -82,6 +82,11 @@ export declare class NewQuizzesModule {
|
|
|
82
82
|
delete(courseId: number, assignmentId: number): Promise<void>;
|
|
83
83
|
listItems(courseId: number, assignmentId: number): Promise<CanvasNewQuizItem[]>;
|
|
84
84
|
getItem(courseId: number, assignmentId: number, itemId: string): Promise<CanvasNewQuizItem>;
|
|
85
|
+
/**
|
|
86
|
+
* The New Quizzes Items API expects item fields nested under an `item` key
|
|
87
|
+
* (`item[entry_type]`, `item[points_possible]`, `item[entry][...]`). Flat
|
|
88
|
+
* fields would not be bound to the `item` parameter.
|
|
89
|
+
*/
|
|
85
90
|
createItem(courseId: number, assignmentId: number, input: NewQuizItemCreatePayload): Promise<CanvasNewQuizItem>;
|
|
86
91
|
updateItem(courseId: number, assignmentId: number, itemId: string, patch: NewQuizItemUpdatePayload): Promise<CanvasNewQuizItem>;
|
|
87
92
|
deleteItem(courseId: number, assignmentId: number, itemId: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new-quizzes.d.ts","sourceRoot":"","sources":["../../src/canvas/new-quizzes.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"new-quizzes.d.ts","sourceRoot":"","sources":["../../src/canvas/new-quizzes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// package.json
|
|
2
|
-
var version = "1.31.
|
|
2
|
+
var version = "1.31.2";
|
|
3
3
|
|
|
4
4
|
// src/canvas/query.ts
|
|
5
5
|
function appendCanvasQuery(target, params) {
|
|
@@ -176,4 +176,4 @@ export {
|
|
|
176
176
|
CanvasApiError,
|
|
177
177
|
CanvasHttpClient
|
|
178
178
|
};
|
|
179
|
-
//# sourceMappingURL=chunk-
|
|
179
|
+
//# sourceMappingURL=chunk-A6OUWDRT.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/canvas/query.ts","../src/canvas/client.ts"],"sourcesContent":["{\n \"name\": \"canvas-lms-mcp\",\n \"version\": \"1.31.0\",\n \"mcpName\": \"io.github.bruchris/canvas-lms-mcp\",\n \"description\": \"TypeScript MCP 1.x server for Canvas LMS — 167 tools across Canvas courses, assignments, grades, gradebook history, quizzes, New Quizzes (LTI), outcomes, discussions, admin workflows, and more.\",\n \"type\": \"module\",\n \"types\": \"./dist/server.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/server.d.ts\",\n \"import\": \"./dist/server.js\",\n \"require\": \"./dist/server.cjs\"\n },\n \"./stdio\": {\n \"types\": \"./dist/stdio.d.ts\",\n \"import\": \"./dist/stdio.js\",\n \"require\": \"./dist/stdio.cjs\"\n },\n \"./http\": {\n \"types\": \"./dist/http.d.ts\",\n \"import\": \"./dist/http.js\",\n \"require\": \"./dist/http.cjs\"\n },\n \"./canvas\": {\n \"types\": \"./dist/canvas/index.d.ts\",\n \"import\": \"./dist/canvas/index.js\",\n \"require\": \"./dist/canvas/index.cjs\"\n }\n },\n \"bin\": {\n \"canvas-lms-mcp\": \"bin/canvas-lms-mcp.js\"\n },\n \"files\": [\n \"bin/\",\n \"dist/\"\n ],\n \"scripts\": {\n \"dev\": \"tsup --watch\",\n \"build\": \"tsup && tsc -p tsconfig.build.json\",\n \"generate:manifests\": \"tsx scripts/generate-manifests.ts\",\n \"mcpb:pack\": \"node scripts/pack-mcpb.mjs\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"lint\": \"eslint src/ tests/ && prettier --check src/ tests/\",\n \"lint:fix\": \"eslint src/ tests/ --fix && prettier --write src/ tests/\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"keywords\": [\n \"canvas\",\n \"canvas-lms\",\n \"lms\",\n \"mcp\",\n \"model-context-protocol\",\n \"education\",\n \"grading\",\n \"ai-agent\",\n \"ai-tools\",\n \"claude-desktop\",\n \"cursor\",\n \"vscode\",\n \"instructure\",\n \"education-technology\",\n \"edtech\",\n \"teacher\",\n \"student\",\n \"grading-automation\",\n \"typescript\"\n ],\n \"author\": \"Christian Bru\",\n \"license\": \"MIT\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/bruchris/canvas-lms-mcp.git\"\n },\n \"engines\": {\n \"node\": \">=22\"\n },\n \"packageManager\": \"pnpm@10.11.0\",\n \"dependencies\": {\n \"@iarna/toml\": \"^2.2.5\",\n \"@modelcontextprotocol/sdk\": \"^1.30.0\",\n \"prompts\": \"^2.4.2\",\n \"zod\": \"^4.4.3\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^10.0.1\",\n \"@types/jsdom\": \"^30.0.0\",\n \"@types/node\": \"^26.4.0\",\n \"@types/prompts\": \"^2.4.9\",\n \"@typescript-eslint/eslint-plugin\": \"^8.65.0\",\n \"@typescript-eslint/parser\": \"^8.65.0\",\n \"@vitest/coverage-v8\": \"^4.1.10\",\n \"ajv\": \"^8.20.0\",\n \"eslint\": \"^10.7.0\",\n \"eslint-config-prettier\": \"^10.1.8\",\n \"eslint-plugin-prettier\": \"^5.5.6\",\n \"jsdom\": \"^30.0.1\",\n \"prettier\": \"^3.9.6\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.23.1\",\n \"typescript\": \"^6.0.3\",\n \"typescript-eslint\": \"^8.65.0\",\n \"vite\": \"^8.1.5\",\n \"vitest\": \"^4.1.10\",\n \"yaml\": \"^2.8.3\"\n }\n}\n","export type CanvasQueryPrimitive = string | number | boolean\n\nexport type CanvasQueryValue = CanvasQueryPrimitive | ReadonlyArray<CanvasQueryPrimitive>\n\nexport type CanvasQueryParams = Record<string, CanvasQueryValue | undefined | null>\n\nexport function appendCanvasQuery(target: URLSearchParams, params?: CanvasQueryParams): void {\n if (!params) return\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined || value === null) continue\n if (Array.isArray(value)) {\n if (value.length === 0) continue\n const arrayKey = key.endsWith('[]') ? key : `${key}[]`\n for (const item of value) {\n if (item === undefined || item === null) continue\n target.append(arrayKey, String(item))\n }\n } else {\n target.set(key, String(value))\n }\n }\n}\n\nexport function toCanvasQuery(params?: CanvasQueryParams): URLSearchParams {\n const search = new URLSearchParams()\n appendCanvasQuery(search, params)\n return search\n}\n","import { version } from '../../package.json'\nimport { appendCanvasQuery, type CanvasQueryParams } from './query'\nimport type { CanvasClientConfig, CanvasErrorResponse } from './types'\n\nexport class CanvasApiError extends Error {\n status: number\n endpoint: string\n\n constructor(message: string, status: number, endpoint: string) {\n super(message)\n this.name = 'CanvasApiError'\n this.status = status\n this.endpoint = endpoint\n }\n}\n\nconst DEFAULT_MAX_PAGINATION_PAGES = 1000\nconst USER_AGENT = `canvas-lms-mcp/${version}`\n\nexport interface CanvasRequestOptions extends RequestInit {\n /**\n * Query params to append to the endpoint URL. Arrays produce repeated\n * `key[]=v1&key[]=v2` entries (the convention Canvas uses for `include[]`).\n * Preserves any query string already present on the endpoint.\n */\n query?: CanvasQueryParams\n}\n\nexport class CanvasHttpClient {\n private token: string\n private _baseUrl: string\n private maxPaginationPages: number\n\n constructor(config: CanvasClientConfig) {\n this.token = config.token\n this._baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this.maxPaginationPages = config.maxPaginationPages ?? DEFAULT_MAX_PAGINATION_PAGES\n }\n\n get baseUrl(): string {\n return this._baseUrl\n }\n\n /**\n * Makes a single authenticated request to the Canvas API.\n * Returns `undefined` (typed as `T`) when Canvas responds with 204 No Content,\n * which is the expected response for DELETE operations.\n */\n async request<T>(endpoint: string, options: CanvasRequestOptions = {}): Promise<T> {\n const { query, ...init } = options\n let url = endpoint.startsWith('http') ? endpoint : `${this._baseUrl}${endpoint}`\n if (query) {\n const parsed = new URL(url)\n appendCanvasQuery(parsed.searchParams, query)\n url = parsed.toString()\n }\n\n const method = (init.method ?? 'GET').toUpperCase()\n if (init.body != null && (method === 'GET' || method === 'HEAD')) {\n throw new Error(\n `GET requests must not include a body (Canvas CloudFront CDN rejects them with 403): ${endpoint}`,\n )\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.token}`,\n 'User-Agent': USER_AGENT,\n }\n if (init.body) {\n headers['Content-Type'] = 'application/json'\n }\n\n const response = await fetch(url, {\n ...init,\n headers: {\n ...headers,\n ...init.headers,\n },\n })\n\n if (!response.ok) {\n const body = (await response.json().catch(() => ({}))) as CanvasErrorResponse\n const message =\n body.errors?.[0]?.message ?? body.message ?? `Canvas API error: ${response.status}`\n throw new CanvasApiError(message, response.status, endpoint)\n }\n\n if (response.status === 204) {\n return undefined as T\n }\n\n return response.json() as Promise<T>\n }\n\n async paginate<T>(endpoint: string, params?: CanvasQueryParams): Promise<T[]> {\n const url = new URL(`${this._baseUrl}${endpoint}`)\n if (!url.searchParams.has('per_page')) {\n url.searchParams.set('per_page', '100')\n }\n appendCanvasQuery(url.searchParams, params)\n\n const results: T[] = []\n let nextUrl: string | null = url.toString()\n let pages = 0\n\n while (nextUrl && pages < this.maxPaginationPages) {\n const response = await fetch(nextUrl, {\n headers: {\n Authorization: `Bearer ${this.token}`,\n 'User-Agent': USER_AGENT,\n },\n })\n\n if (!response.ok) {\n const body = (await response.json().catch(() => ({}))) as CanvasErrorResponse\n const message =\n body.errors?.[0]?.message ?? body.message ?? `Canvas API error: ${response.status}`\n throw new CanvasApiError(message, response.status, endpoint)\n }\n\n const data = (await response.json()) as T[]\n results.push(...data)\n pages++\n\n nextUrl = this.parseNextLink(response.headers.get('Link'))\n }\n\n this.assertNotTruncated(nextUrl, endpoint)\n return results\n }\n\n async paginateEnvelope<T>(\n endpoint: string,\n envelopeKey: string,\n params?: CanvasQueryParams,\n ): Promise<T[]> {\n const url = new URL(`${this._baseUrl}${endpoint}`)\n if (!url.searchParams.has('per_page')) {\n url.searchParams.set('per_page', '100')\n }\n appendCanvasQuery(url.searchParams, params)\n\n const results: T[] = []\n let nextUrl: string | null = url.toString()\n let pages = 0\n\n while (nextUrl && pages < this.maxPaginationPages) {\n const response = await fetch(nextUrl, {\n headers: {\n Authorization: `Bearer ${this.token}`,\n 'User-Agent': USER_AGENT,\n },\n })\n\n if (!response.ok) {\n const body = (await response.json().catch(() => ({}))) as CanvasErrorResponse\n const message =\n body.errors?.[0]?.message ?? body.message ?? `Canvas API error: ${response.status}`\n throw new CanvasApiError(message, response.status, endpoint)\n }\n\n const body = (await response.json()) as Record<string, T[]>\n const data = body[envelopeKey] ?? []\n results.push(...data)\n pages++\n\n nextUrl = this.parseNextLink(response.headers.get('Link'))\n }\n\n this.assertNotTruncated(nextUrl, endpoint)\n return results\n }\n\n /**\n * The pagination loops exit with a non-null `nextUrl` only when the page cap\n * was reached while Canvas still advertised another page. Surface that as an\n * error rather than returning a partial list that looks complete.\n */\n private assertNotTruncated(nextUrl: string | null, endpoint: string): void {\n if (!nextUrl) return\n throw new Error(\n `Results are incomplete: ${endpoint} has more pages beyond the configured limit of ${this.maxPaginationPages} pages, so the list was truncated. Narrow the query with filters or raise maxPaginationPages.`,\n )\n }\n\n private parseNextLink(linkHeader: string | null): string | null {\n if (!linkHeader) return null\n const match = linkHeader.match(/<([^>]+)>;\\s*rel=\"next\"/)\n return match?.[1] ?? null\n }\n}\n"],"mappings":"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","names":["body"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/canvas/query.ts","../src/canvas/client.ts"],"sourcesContent":["{\n \"name\": \"canvas-lms-mcp\",\n \"version\": \"1.31.2\",\n \"mcpName\": \"io.github.bruchris/canvas-lms-mcp\",\n \"description\": \"TypeScript MCP 1.x server for Canvas LMS — 167 tools across Canvas courses, assignments, grades, gradebook history, quizzes, New Quizzes (LTI), outcomes, discussions, admin workflows, and more.\",\n \"type\": \"module\",\n \"types\": \"./dist/server.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/server.d.ts\",\n \"import\": \"./dist/server.js\",\n \"require\": \"./dist/server.cjs\"\n },\n \"./stdio\": {\n \"types\": \"./dist/stdio.d.ts\",\n \"import\": \"./dist/stdio.js\",\n \"require\": \"./dist/stdio.cjs\"\n },\n \"./http\": {\n \"types\": \"./dist/http.d.ts\",\n \"import\": \"./dist/http.js\",\n \"require\": \"./dist/http.cjs\"\n },\n \"./canvas\": {\n \"types\": \"./dist/canvas/index.d.ts\",\n \"import\": \"./dist/canvas/index.js\",\n \"require\": \"./dist/canvas/index.cjs\"\n }\n },\n \"bin\": {\n \"canvas-lms-mcp\": \"bin/canvas-lms-mcp.js\"\n },\n \"files\": [\n \"bin/\",\n \"dist/\"\n ],\n \"scripts\": {\n \"dev\": \"tsup --watch\",\n \"build\": \"tsup && tsc -p tsconfig.build.json\",\n \"generate:manifests\": \"tsx scripts/generate-manifests.ts\",\n \"mcpb:pack\": \"node scripts/pack-mcpb.mjs\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"lint\": \"eslint src/ tests/ && prettier --check src/ tests/\",\n \"lint:fix\": \"eslint src/ tests/ --fix && prettier --write src/ tests/\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"keywords\": [\n \"canvas\",\n \"canvas-lms\",\n \"lms\",\n \"mcp\",\n \"model-context-protocol\",\n \"education\",\n \"grading\",\n \"ai-agent\",\n \"ai-tools\",\n \"claude-desktop\",\n \"cursor\",\n \"vscode\",\n \"instructure\",\n \"education-technology\",\n \"edtech\",\n \"teacher\",\n \"student\",\n \"grading-automation\",\n \"typescript\"\n ],\n \"author\": \"Christian Bru\",\n \"license\": \"MIT\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/bruchris/canvas-lms-mcp.git\"\n },\n \"engines\": {\n \"node\": \">=22\"\n },\n \"packageManager\": \"pnpm@10.11.0\",\n \"dependencies\": {\n \"@iarna/toml\": \"^2.2.5\",\n \"@modelcontextprotocol/sdk\": \"^1.30.0\",\n \"prompts\": \"^2.4.2\",\n \"zod\": \"^4.4.3\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^10.0.1\",\n \"@types/jsdom\": \"^30.0.0\",\n \"@types/node\": \"^26.4.0\",\n \"@types/prompts\": \"^2.4.9\",\n \"@typescript-eslint/eslint-plugin\": \"^8.65.0\",\n \"@typescript-eslint/parser\": \"^8.65.0\",\n \"@vitest/coverage-v8\": \"^4.1.10\",\n \"ajv\": \"^8.20.0\",\n \"eslint\": \"^10.7.0\",\n \"eslint-config-prettier\": \"^10.1.8\",\n \"eslint-plugin-prettier\": \"^5.5.6\",\n \"jsdom\": \"^30.0.1\",\n \"prettier\": \"^3.9.6\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.23.1\",\n \"typescript\": \"^6.0.3\",\n \"typescript-eslint\": \"^8.65.0\",\n \"vite\": \"^8.1.5\",\n \"vitest\": \"^4.1.10\",\n \"yaml\": \"^2.8.3\"\n }\n}\n","export type CanvasQueryPrimitive = string | number | boolean\n\nexport type CanvasQueryValue = CanvasQueryPrimitive | ReadonlyArray<CanvasQueryPrimitive>\n\nexport type CanvasQueryParams = Record<string, CanvasQueryValue | undefined | null>\n\nexport function appendCanvasQuery(target: URLSearchParams, params?: CanvasQueryParams): void {\n if (!params) return\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined || value === null) continue\n if (Array.isArray(value)) {\n if (value.length === 0) continue\n const arrayKey = key.endsWith('[]') ? key : `${key}[]`\n for (const item of value) {\n if (item === undefined || item === null) continue\n target.append(arrayKey, String(item))\n }\n } else {\n target.set(key, String(value))\n }\n }\n}\n\nexport function toCanvasQuery(params?: CanvasQueryParams): URLSearchParams {\n const search = new URLSearchParams()\n appendCanvasQuery(search, params)\n return search\n}\n","import { version } from '../../package.json'\nimport { appendCanvasQuery, type CanvasQueryParams } from './query'\nimport type { CanvasClientConfig, CanvasErrorResponse } from './types'\n\nexport class CanvasApiError extends Error {\n status: number\n endpoint: string\n\n constructor(message: string, status: number, endpoint: string) {\n super(message)\n this.name = 'CanvasApiError'\n this.status = status\n this.endpoint = endpoint\n }\n}\n\nconst DEFAULT_MAX_PAGINATION_PAGES = 1000\nconst USER_AGENT = `canvas-lms-mcp/${version}`\n\nexport interface CanvasRequestOptions extends RequestInit {\n /**\n * Query params to append to the endpoint URL. Arrays produce repeated\n * `key[]=v1&key[]=v2` entries (the convention Canvas uses for `include[]`).\n * Preserves any query string already present on the endpoint.\n */\n query?: CanvasQueryParams\n}\n\nexport class CanvasHttpClient {\n private token: string\n private _baseUrl: string\n private maxPaginationPages: number\n\n constructor(config: CanvasClientConfig) {\n this.token = config.token\n this._baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this.maxPaginationPages = config.maxPaginationPages ?? DEFAULT_MAX_PAGINATION_PAGES\n }\n\n get baseUrl(): string {\n return this._baseUrl\n }\n\n /**\n * Makes a single authenticated request to the Canvas API.\n * Returns `undefined` (typed as `T`) when Canvas responds with 204 No Content,\n * which is the expected response for DELETE operations.\n */\n async request<T>(endpoint: string, options: CanvasRequestOptions = {}): Promise<T> {\n const { query, ...init } = options\n let url = endpoint.startsWith('http') ? endpoint : `${this._baseUrl}${endpoint}`\n if (query) {\n const parsed = new URL(url)\n appendCanvasQuery(parsed.searchParams, query)\n url = parsed.toString()\n }\n\n const method = (init.method ?? 'GET').toUpperCase()\n if (init.body != null && (method === 'GET' || method === 'HEAD')) {\n throw new Error(\n `GET requests must not include a body (Canvas CloudFront CDN rejects them with 403): ${endpoint}`,\n )\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.token}`,\n 'User-Agent': USER_AGENT,\n }\n if (init.body) {\n headers['Content-Type'] = 'application/json'\n }\n\n const response = await fetch(url, {\n ...init,\n headers: {\n ...headers,\n ...init.headers,\n },\n })\n\n if (!response.ok) {\n const body = (await response.json().catch(() => ({}))) as CanvasErrorResponse\n const message =\n body.errors?.[0]?.message ?? body.message ?? `Canvas API error: ${response.status}`\n throw new CanvasApiError(message, response.status, endpoint)\n }\n\n if (response.status === 204) {\n return undefined as T\n }\n\n return response.json() as Promise<T>\n }\n\n async paginate<T>(endpoint: string, params?: CanvasQueryParams): Promise<T[]> {\n const url = new URL(`${this._baseUrl}${endpoint}`)\n if (!url.searchParams.has('per_page')) {\n url.searchParams.set('per_page', '100')\n }\n appendCanvasQuery(url.searchParams, params)\n\n const results: T[] = []\n let nextUrl: string | null = url.toString()\n let pages = 0\n\n while (nextUrl && pages < this.maxPaginationPages) {\n const response = await fetch(nextUrl, {\n headers: {\n Authorization: `Bearer ${this.token}`,\n 'User-Agent': USER_AGENT,\n },\n })\n\n if (!response.ok) {\n const body = (await response.json().catch(() => ({}))) as CanvasErrorResponse\n const message =\n body.errors?.[0]?.message ?? body.message ?? `Canvas API error: ${response.status}`\n throw new CanvasApiError(message, response.status, endpoint)\n }\n\n const data = (await response.json()) as T[]\n results.push(...data)\n pages++\n\n nextUrl = this.parseNextLink(response.headers.get('Link'))\n }\n\n this.assertNotTruncated(nextUrl, endpoint)\n return results\n }\n\n async paginateEnvelope<T>(\n endpoint: string,\n envelopeKey: string,\n params?: CanvasQueryParams,\n ): Promise<T[]> {\n const url = new URL(`${this._baseUrl}${endpoint}`)\n if (!url.searchParams.has('per_page')) {\n url.searchParams.set('per_page', '100')\n }\n appendCanvasQuery(url.searchParams, params)\n\n const results: T[] = []\n let nextUrl: string | null = url.toString()\n let pages = 0\n\n while (nextUrl && pages < this.maxPaginationPages) {\n const response = await fetch(nextUrl, {\n headers: {\n Authorization: `Bearer ${this.token}`,\n 'User-Agent': USER_AGENT,\n },\n })\n\n if (!response.ok) {\n const body = (await response.json().catch(() => ({}))) as CanvasErrorResponse\n const message =\n body.errors?.[0]?.message ?? body.message ?? `Canvas API error: ${response.status}`\n throw new CanvasApiError(message, response.status, endpoint)\n }\n\n const body = (await response.json()) as Record<string, T[]>\n const data = body[envelopeKey] ?? []\n results.push(...data)\n pages++\n\n nextUrl = this.parseNextLink(response.headers.get('Link'))\n }\n\n this.assertNotTruncated(nextUrl, endpoint)\n return results\n }\n\n /**\n * The pagination loops exit with a non-null `nextUrl` only when the page cap\n * was reached while Canvas still advertised another page. Surface that as an\n * error rather than returning a partial list that looks complete.\n */\n private assertNotTruncated(nextUrl: string | null, endpoint: string): void {\n if (!nextUrl) return\n throw new Error(\n `Results are incomplete: ${endpoint} has more pages beyond the configured limit of ${this.maxPaginationPages} pages, so the list was truncated. Narrow the query with filters or raise maxPaginationPages.`,\n )\n }\n\n private parseNextLink(linkHeader: string | null): string | null {\n if (!linkHeader) return null\n const match = linkHeader.match(/<([^>]+)>;\\s*rel=\"next\"/)\n return match?.[1] ?? null\n }\n}\n"],"mappings":"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","names":["body"]}
|
|
@@ -20,11 +20,11 @@ var _chunkQCEGMTXWcjs = require('./chunk-QCEGMTXW.cjs');
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
var
|
|
23
|
+
var _chunkUP6NGBEGcjs = require('./chunk-UP6NGBEG.cjs');
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
var
|
|
27
|
+
var _chunkZJURO66Mcjs = require('./chunk-ZJURO66M.cjs');
|
|
28
28
|
|
|
29
29
|
// src/server.ts
|
|
30
30
|
var _mcpjs = require('@modelcontextprotocol/sdk/server/mcp.js');
|
|
@@ -988,7 +988,7 @@ function assignmentSubmissionTools(canvas) {
|
|
|
988
988
|
|
|
989
989
|
// src/tools/errors.ts
|
|
990
990
|
function formatError(error) {
|
|
991
|
-
if (error instanceof
|
|
991
|
+
if (error instanceof _chunkZJURO66Mcjs.CanvasApiError) {
|
|
992
992
|
const status = error.status;
|
|
993
993
|
const message = error.message;
|
|
994
994
|
const ltiMarkers = ["Tool not configured", "tool is not configured"];
|
|
@@ -1042,7 +1042,7 @@ function analyticsTools(canvas) {
|
|
|
1042
1042
|
inputSchema: {
|
|
1043
1043
|
course_id: _zod.z.number().describe("The Canvas course ID"),
|
|
1044
1044
|
search_term: _zod.z.string().describe("The keyword or phrase to search for"),
|
|
1045
|
-
content_types: _zod.z.array(_zod.z.enum(
|
|
1045
|
+
content_types: _zod.z.array(_zod.z.enum(_chunkUP6NGBEGcjs.SEARCH_CONTENT_TYPES)).optional().describe(
|
|
1046
1046
|
"Content types to search. Defaults to all types: pages, discussions, assignments, announcements."
|
|
1047
1047
|
)
|
|
1048
1048
|
},
|
|
@@ -1054,7 +1054,7 @@ function analyticsTools(canvas) {
|
|
|
1054
1054
|
const courseId = params.course_id;
|
|
1055
1055
|
const searchTerm = params.search_term;
|
|
1056
1056
|
const types = _nullishCoalesce(params.content_types, () => ( [
|
|
1057
|
-
...
|
|
1057
|
+
..._chunkUP6NGBEGcjs.SEARCH_CONTENT_TYPES
|
|
1058
1058
|
]));
|
|
1059
1059
|
if (types.length === 0) return { results: [] };
|
|
1060
1060
|
const settled = await Promise.allSettled(
|
|
@@ -1307,7 +1307,7 @@ function attentionTools(canvas, pseudonymizer) {
|
|
|
1307
1307
|
summaryMap.set(s.id, s);
|
|
1308
1308
|
}
|
|
1309
1309
|
} catch (err) {
|
|
1310
|
-
if (err instanceof
|
|
1310
|
+
if (err instanceof _chunkZJURO66Mcjs.CanvasApiError && err.status === 404) {
|
|
1311
1311
|
analyticsAvailable = false;
|
|
1312
1312
|
} else {
|
|
1313
1313
|
throw err;
|
|
@@ -1661,7 +1661,7 @@ async function fanOut(config) {
|
|
|
1661
1661
|
skipped.push(outcome.result);
|
|
1662
1662
|
}
|
|
1663
1663
|
} catch (err) {
|
|
1664
|
-
if (!(err instanceof
|
|
1664
|
+
if (!(err instanceof _chunkZJURO66Mcjs.CanvasApiError)) {
|
|
1665
1665
|
console.error(`Unexpected error ${config.errorContext(item)}:`, err);
|
|
1666
1666
|
}
|
|
1667
1667
|
const message = err instanceof Error ? err.message : "Unknown error";
|
|
@@ -2653,7 +2653,7 @@ function discussionTools(canvas) {
|
|
|
2653
2653
|
try {
|
|
2654
2654
|
return await canvas.discussions.get(course_id, topic_id);
|
|
2655
2655
|
} catch (error) {
|
|
2656
|
-
if (!(error instanceof
|
|
2656
|
+
if (!(error instanceof _chunkZJURO66Mcjs.CanvasApiError) || error.status !== 404) throw error;
|
|
2657
2657
|
const description = await describeAnonymityFromList(canvas, course_id, topic_id);
|
|
2658
2658
|
if (description === void 0) throw error;
|
|
2659
2659
|
throw new Error(anonymousTopicMessage(course_id, topic_id, description), {
|
|
@@ -3996,9 +3996,9 @@ function gradingPolicyTools(canvas) {
|
|
|
3996
3996
|
latePolicySource = "api";
|
|
3997
3997
|
} else {
|
|
3998
3998
|
const err = latePolicyResult.reason;
|
|
3999
|
-
if (err instanceof
|
|
3999
|
+
if (err instanceof _chunkZJURO66Mcjs.CanvasApiError && err.status === 403) {
|
|
4000
4000
|
policyUnavailable = true;
|
|
4001
|
-
} else if (err instanceof
|
|
4001
|
+
} else if (err instanceof _chunkZJURO66Mcjs.CanvasApiError && err.status === 404) {
|
|
4002
4002
|
latePolicySource = "default";
|
|
4003
4003
|
} else {
|
|
4004
4004
|
throw err;
|
|
@@ -4028,7 +4028,7 @@ function gradingPolicyTools(canvas) {
|
|
|
4028
4028
|
}
|
|
4029
4029
|
}
|
|
4030
4030
|
} catch (err) {
|
|
4031
|
-
if (!(err instanceof
|
|
4031
|
+
if (!(err instanceof _chunkZJURO66Mcjs.CanvasApiError)) throw err;
|
|
4032
4032
|
if (err.status !== 403 && err.status !== 404) throw err;
|
|
4033
4033
|
}
|
|
4034
4034
|
if (standardTitle === null) {
|
|
@@ -4158,7 +4158,7 @@ function gradingStandardsTools(canvas) {
|
|
|
4158
4158
|
}
|
|
4159
4159
|
throw new Error("Provide either course_id or account_id.");
|
|
4160
4160
|
} catch (error) {
|
|
4161
|
-
if (error instanceof
|
|
4161
|
+
if (error instanceof _chunkZJURO66Mcjs.CanvasApiError && error.status === 403 && courseId === void 0 && accountId !== void 0 && !error.message.toLowerCase().includes("rate limit exceeded")) {
|
|
4162
4162
|
throw new Error(
|
|
4163
4163
|
"Creating grading standards at the account level requires Canvas admin permissions. Try creating the standard in a course context instead (use course_id).",
|
|
4164
4164
|
{ cause: error }
|
|
@@ -4518,7 +4518,7 @@ function outcomeTools(canvas, pseudonymizer) {
|
|
|
4518
4518
|
title: "Get Root Outcome Group",
|
|
4519
4519
|
description: "Get the root outcome group for an account or course context.",
|
|
4520
4520
|
inputSchema: {
|
|
4521
|
-
context_type: _zod.z.enum(
|
|
4521
|
+
context_type: _zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcomes from an account or course context."),
|
|
4522
4522
|
context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context.")
|
|
4523
4523
|
},
|
|
4524
4524
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
@@ -4532,7 +4532,7 @@ function outcomeTools(canvas, pseudonymizer) {
|
|
|
4532
4532
|
title: "List Outcome Groups",
|
|
4533
4533
|
description: "List all outcome groups for an account or course context.",
|
|
4534
4534
|
inputSchema: {
|
|
4535
|
-
context_type: _zod.z.enum(
|
|
4535
|
+
context_type: _zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcome groups from an account or course context."),
|
|
4536
4536
|
context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context.")
|
|
4537
4537
|
},
|
|
4538
4538
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
@@ -4546,10 +4546,10 @@ function outcomeTools(canvas, pseudonymizer) {
|
|
|
4546
4546
|
title: "List Outcome Group Links",
|
|
4547
4547
|
description: "List all outcome links in an account or course context.",
|
|
4548
4548
|
inputSchema: {
|
|
4549
|
-
context_type: _zod.z.enum(
|
|
4549
|
+
context_type: _zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcome links from an account or course context."),
|
|
4550
4550
|
context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context."),
|
|
4551
|
-
outcome_style: _zod.z.enum(
|
|
4552
|
-
outcome_group_style: _zod.z.enum(
|
|
4551
|
+
outcome_style: _zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_DETAIL_LEVELS).optional().describe('Outcome detail level. Use "full" to include expanded outcome fields.'),
|
|
4552
|
+
outcome_group_style: _zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_DETAIL_LEVELS).optional().describe(
|
|
4553
4553
|
'Outcome group detail level. Use "full" to include expanded outcome group fields.'
|
|
4554
4554
|
)
|
|
4555
4555
|
},
|
|
@@ -4568,7 +4568,7 @@ function outcomeTools(canvas, pseudonymizer) {
|
|
|
4568
4568
|
title: "Get Outcome Group",
|
|
4569
4569
|
description: "Get details for a specific outcome group in an account or course context.",
|
|
4570
4570
|
inputSchema: {
|
|
4571
|
-
context_type: _zod.z.enum(
|
|
4571
|
+
context_type: _zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
|
|
4572
4572
|
context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context."),
|
|
4573
4573
|
outcome_group_id: _zod.z.number().describe("The Canvas outcome group ID.")
|
|
4574
4574
|
},
|
|
@@ -4584,10 +4584,10 @@ function outcomeTools(canvas, pseudonymizer) {
|
|
|
4584
4584
|
title: "List Outcome Group Outcomes",
|
|
4585
4585
|
description: "List the linked outcomes directly under a specific outcome group.",
|
|
4586
4586
|
inputSchema: {
|
|
4587
|
-
context_type: _zod.z.enum(
|
|
4587
|
+
context_type: _zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
|
|
4588
4588
|
context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context."),
|
|
4589
4589
|
outcome_group_id: _zod.z.number().describe("The Canvas outcome group ID."),
|
|
4590
|
-
outcome_style: _zod.z.enum(
|
|
4590
|
+
outcome_style: _zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_DETAIL_LEVELS).optional().describe('Outcome detail level. Use "full" to include expanded outcome fields.')
|
|
4591
4591
|
},
|
|
4592
4592
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
4593
4593
|
handler: async (params) => canvas.outcomes.listGroupOutcomes(
|
|
@@ -4604,7 +4604,7 @@ function outcomeTools(canvas, pseudonymizer) {
|
|
|
4604
4604
|
title: "List Outcome Group Subgroups",
|
|
4605
4605
|
description: "List the immediate child outcome groups under a specific outcome group.",
|
|
4606
4606
|
inputSchema: {
|
|
4607
|
-
context_type: _zod.z.enum(
|
|
4607
|
+
context_type: _zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
|
|
4608
4608
|
context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context."),
|
|
4609
4609
|
outcome_group_id: _zod.z.number().describe("The Canvas outcome group ID.")
|
|
4610
4610
|
},
|
|
@@ -4674,14 +4674,14 @@ function outcomeTools(canvas, pseudonymizer) {
|
|
|
4674
4674
|
inputSchema: {
|
|
4675
4675
|
course_id: _zod.z.number().describe("The Canvas course ID."),
|
|
4676
4676
|
aggregate: _zod.z.enum(["course"]).optional().describe("Aggregate all student rollups into a single course-level rollup."),
|
|
4677
|
-
aggregate_stat: _zod.z.enum(
|
|
4677
|
+
aggregate_stat: _zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_ROLLUP_AGGREGATE_STATS).optional().describe('Statistic to use when aggregate="course".'),
|
|
4678
4678
|
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:".'),
|
|
4679
4679
|
outcome_ids: _zod.z.array(_zod.z.number()).optional().describe("Optional outcome IDs to restrict the rollups."),
|
|
4680
4680
|
include_courses: _zod.z.boolean().optional().describe("Include linked course details in the response payload."),
|
|
4681
|
-
exclude: _zod.z.array(_zod.z.enum(
|
|
4682
|
-
sort_by: _zod.z.enum(
|
|
4681
|
+
exclude: _zod.z.array(_zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_EXCLUDE_OPTIONS)).optional().describe("Optional rollup exclusions for missing users or missing outcome results."),
|
|
4682
|
+
sort_by: _zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_ROLLUP_SORT_BY).optional().describe("Sort rollups by student name or by a specific outcome score."),
|
|
4683
4683
|
sort_outcome_id: _zod.z.number().optional().describe('Outcome ID to sort by when sort_by="outcome".'),
|
|
4684
|
-
sort_order: _zod.z.enum(
|
|
4684
|
+
sort_order: _zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_SORT_ORDER).optional().describe("Sort order to apply when sorting rollups."),
|
|
4685
4685
|
add_defaults: _zod.z.boolean().optional().describe("Include default mastery colors and levels when Canvas supports it.")
|
|
4686
4686
|
},
|
|
4687
4687
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
@@ -4731,7 +4731,7 @@ function outcomeTools(canvas, pseudonymizer) {
|
|
|
4731
4731
|
description: "Get mastery distribution analytics for outcomes in a course, optionally filtered by students or outcomes.",
|
|
4732
4732
|
inputSchema: {
|
|
4733
4733
|
course_id: _zod.z.number().describe("The Canvas course ID."),
|
|
4734
|
-
exclude: _zod.z.array(_zod.z.enum(
|
|
4734
|
+
exclude: _zod.z.array(_zod.z.enum(_chunkUP6NGBEGcjs.OUTCOME_EXCLUDE_OPTIONS)).optional().describe("Optional exclusions for missing users or missing outcome results."),
|
|
4735
4735
|
outcome_ids: _zod.z.array(_zod.z.number()).optional().describe("Optional outcome IDs to restrict the distribution results."),
|
|
4736
4736
|
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:".'),
|
|
4737
4737
|
include_alignment_distributions: _zod.z.boolean().optional().describe("Include contributing score distributions for alignments."),
|
|
@@ -5581,7 +5581,7 @@ function newQuizAccommodationTools(canvas) {
|
|
|
5581
5581
|
extra_attempts: record.extra_attempts
|
|
5582
5582
|
});
|
|
5583
5583
|
} catch (err) {
|
|
5584
|
-
const message = err instanceof
|
|
5584
|
+
const message = err instanceof _chunkZJURO66Mcjs.CanvasApiError ? err.message : "Unknown error";
|
|
5585
5585
|
failed.push({
|
|
5586
5586
|
assignment_id: assignmentId,
|
|
5587
5587
|
time_multiplier: null,
|
|
@@ -6121,8 +6121,8 @@ function studentTools(canvas, pseudonymizer) {
|
|
|
6121
6121
|
} else {
|
|
6122
6122
|
coursesFailed.push({
|
|
6123
6123
|
course_id: result.courseId,
|
|
6124
|
-
status: result.err instanceof
|
|
6125
|
-
message: result.err instanceof
|
|
6124
|
+
status: result.err instanceof _chunkZJURO66Mcjs.CanvasApiError ? result.err.status : null,
|
|
6125
|
+
message: result.err instanceof _chunkZJURO66Mcjs.CanvasApiError ? result.err.message : String(result.err)
|
|
6126
6126
|
});
|
|
6127
6127
|
}
|
|
6128
6128
|
}
|
|
@@ -6262,7 +6262,7 @@ function studentSearchTools(canvas, pseudonymizer) {
|
|
|
6262
6262
|
const coursesToScan = truncated ? sorted.slice(0, maxCourses) : sorted;
|
|
6263
6263
|
const coursesFailed = [];
|
|
6264
6264
|
const perCourseMatches = [];
|
|
6265
|
-
const scanResults = await
|
|
6265
|
+
const scanResults = await _chunkUP6NGBEGcjs.mapWithConcurrency.call(void 0,
|
|
6266
6266
|
coursesToScan,
|
|
6267
6267
|
CONCURRENT_COURSE_LIMIT,
|
|
6268
6268
|
async (course) => {
|
|
@@ -6285,8 +6285,8 @@ function studentSearchTools(canvas, pseudonymizer) {
|
|
|
6285
6285
|
} else {
|
|
6286
6286
|
coursesFailed.push({
|
|
6287
6287
|
course_id: r.course.id,
|
|
6288
|
-
status: r.err instanceof
|
|
6289
|
-
message: r.err instanceof
|
|
6288
|
+
status: r.err instanceof _chunkZJURO66Mcjs.CanvasApiError ? r.err.status : null,
|
|
6289
|
+
message: r.err instanceof _chunkZJURO66Mcjs.CanvasApiError ? r.err.message : String(r.err)
|
|
6290
6290
|
});
|
|
6291
6291
|
}
|
|
6292
6292
|
}
|
|
@@ -6964,7 +6964,7 @@ async function scanQuizzes(canvas, courseId, warnings) {
|
|
|
6964
6964
|
canvas.assignments.list(courseId)
|
|
6965
6965
|
]);
|
|
6966
6966
|
const classicQuizzes = quizzes.filter((quiz) => CLASSIC_QUIZ_TYPES3.has(quiz.quiz_type));
|
|
6967
|
-
const classicFindings = await
|
|
6967
|
+
const classicFindings = await _chunkUP6NGBEGcjs.mapWithConcurrency.call(void 0,
|
|
6968
6968
|
classicQuizzes,
|
|
6969
6969
|
QUIZ_SCAN_CONCURRENCY_LIMIT,
|
|
6970
6970
|
async (quiz) => {
|
|
@@ -6990,7 +6990,7 @@ async function scanQuizzes(canvas, courseId, warnings) {
|
|
|
6990
6990
|
}
|
|
6991
6991
|
);
|
|
6992
6992
|
const newQuizAssignments = assignments.filter((a) => a.is_quiz_lti_assignment === true);
|
|
6993
|
-
const newQuizFindings = await
|
|
6993
|
+
const newQuizFindings = await _chunkUP6NGBEGcjs.mapWithConcurrency.call(void 0,
|
|
6994
6994
|
newQuizAssignments,
|
|
6995
6995
|
QUIZ_SCAN_CONCURRENCY_LIMIT,
|
|
6996
6996
|
async (assignment) => {
|
|
@@ -7340,7 +7340,7 @@ async function scanQuizzesAccessibility(canvas, courseId, warnings) {
|
|
|
7340
7340
|
canvas.assignments.list(courseId)
|
|
7341
7341
|
]);
|
|
7342
7342
|
const classicQuizzes = quizzes.filter((quiz) => CLASSIC_QUIZ_TYPES4.has(quiz.quiz_type));
|
|
7343
|
-
const classicFindings = await
|
|
7343
|
+
const classicFindings = await _chunkUP6NGBEGcjs.mapWithConcurrency.call(void 0,
|
|
7344
7344
|
classicQuizzes,
|
|
7345
7345
|
QUIZ_SCAN_CONCURRENCY_LIMIT2,
|
|
7346
7346
|
async (quiz) => {
|
|
@@ -7365,7 +7365,7 @@ async function scanQuizzesAccessibility(canvas, courseId, warnings) {
|
|
|
7365
7365
|
}
|
|
7366
7366
|
);
|
|
7367
7367
|
const newQuizAssignments = assignments.filter((a) => a.is_quiz_lti_assignment === true);
|
|
7368
|
-
const newQuizFindings = await
|
|
7368
|
+
const newQuizFindings = await _chunkUP6NGBEGcjs.mapWithConcurrency.call(void 0,
|
|
7369
7369
|
newQuizAssignments,
|
|
7370
7370
|
QUIZ_SCAN_CONCURRENCY_LIMIT2,
|
|
7371
7371
|
async (assignment) => {
|
|
@@ -7978,7 +7978,7 @@ function buildHandler(tool, pseudonymizer) {
|
|
|
7978
7978
|
}
|
|
7979
7979
|
return response;
|
|
7980
7980
|
} catch (error) {
|
|
7981
|
-
if (!(error instanceof
|
|
7981
|
+
if (!(error instanceof _chunkZJURO66Mcjs.CanvasApiError)) {
|
|
7982
7982
|
console.error(`Unexpected error in tool "${tool.name}":`, error);
|
|
7983
7983
|
}
|
|
7984
7984
|
return {
|
|
@@ -8066,7 +8066,7 @@ function registerSyllabusResource(server, canvas) {
|
|
|
8066
8066
|
]
|
|
8067
8067
|
};
|
|
8068
8068
|
} catch (error) {
|
|
8069
|
-
if (!(error instanceof
|
|
8069
|
+
if (!(error instanceof _chunkZJURO66Mcjs.CanvasApiError)) {
|
|
8070
8070
|
console.error("Unexpected error in syllabus resource:", error);
|
|
8071
8071
|
}
|
|
8072
8072
|
return {
|
|
@@ -8120,7 +8120,7 @@ function registerAssignmentDescriptionResource(server, canvas) {
|
|
|
8120
8120
|
]
|
|
8121
8121
|
};
|
|
8122
8122
|
} catch (error) {
|
|
8123
|
-
if (!(error instanceof
|
|
8123
|
+
if (!(error instanceof _chunkZJURO66Mcjs.CanvasApiError)) {
|
|
8124
8124
|
console.error("Unexpected error in assignment-description resource:", error);
|
|
8125
8125
|
}
|
|
8126
8126
|
return {
|
|
@@ -9198,14 +9198,14 @@ function resolvePseudonymizer(config) {
|
|
|
9198
9198
|
});
|
|
9199
9199
|
}
|
|
9200
9200
|
function createCanvasMCPServer(config) {
|
|
9201
|
-
const canvas = new (0,
|
|
9201
|
+
const canvas = new (0, _chunkUP6NGBEGcjs.CanvasClient)({
|
|
9202
9202
|
token: config.token,
|
|
9203
9203
|
baseUrl: config.baseUrl
|
|
9204
9204
|
});
|
|
9205
9205
|
const pseudonymizer = resolvePseudonymizer(config);
|
|
9206
9206
|
const server = new (0, _mcpjs.McpServer)({
|
|
9207
9207
|
name: "canvas-lms-mcp",
|
|
9208
|
-
version:
|
|
9208
|
+
version: _chunkZJURO66Mcjs.version
|
|
9209
9209
|
});
|
|
9210
9210
|
const features = {
|
|
9211
9211
|
assignmentSubmission: config.enableAssignmentSubmission,
|
|
@@ -9225,4 +9225,4 @@ function createCanvasMCPServer(config) {
|
|
|
9225
9225
|
|
|
9226
9226
|
|
|
9227
9227
|
exports.Pseudonymizer = Pseudonymizer; exports.createSharedPseudonymizer = createSharedPseudonymizer; exports.createCanvasMCPServer = createCanvasMCPServer;
|
|
9228
|
-
//# sourceMappingURL=chunk-
|
|
9228
|
+
//# sourceMappingURL=chunk-AT6C4S4M.cjs.map
|