canvas-lms-mcp 2.8.2 → 2.8.3

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.
@@ -25,11 +25,11 @@ var _chunkQCEGMTXWcjs = require('./chunk-QCEGMTXW.cjs');
25
25
 
26
26
 
27
27
 
28
- var _chunkDEFB5PL2cjs = require('./chunk-DEFB5PL2.cjs');
28
+ var _chunk3X2VLRJJcjs = require('./chunk-3X2VLRJJ.cjs');
29
29
 
30
30
 
31
31
 
32
- var _chunkZT2BWA2Jcjs = require('./chunk-ZT2BWA2J.cjs');
32
+ var _chunk2RKEK44Ecjs = require('./chunk-2RKEK44E.cjs');
33
33
 
34
34
 
35
35
 
@@ -1038,7 +1038,7 @@ function accountTools(canvas, pseudonymizer) {
1038
1038
  title: "Get Account",
1039
1039
  description: "Get details for a Canvas account by ID.",
1040
1040
  inputSchema: {
1041
- account_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID")
1041
+ account_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID")
1042
1042
  },
1043
1043
  annotations: {
1044
1044
  readOnlyHint: true,
@@ -1066,7 +1066,7 @@ function accountTools(canvas, pseudonymizer) {
1066
1066
  title: "List Sub-Accounts",
1067
1067
  description: "List sub-accounts under a given Canvas account.",
1068
1068
  inputSchema: {
1069
- account_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The parent Canvas account ID")
1069
+ account_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The parent Canvas account ID")
1070
1070
  },
1071
1071
  annotations: {
1072
1072
  readOnlyHint: true,
@@ -1081,7 +1081,7 @@ function accountTools(canvas, pseudonymizer) {
1081
1081
  title: "List Account Courses",
1082
1082
  description: "List courses under a given Canvas account.",
1083
1083
  inputSchema: {
1084
- account_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID"),
1084
+ account_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID"),
1085
1085
  search_term: _zod.z.string().optional().describe("Search courses by name or course code")
1086
1086
  },
1087
1087
  annotations: {
@@ -1099,7 +1099,7 @@ function accountTools(canvas, pseudonymizer) {
1099
1099
  title: "List Account Users",
1100
1100
  description: "List users in a Canvas account.",
1101
1101
  inputSchema: {
1102
- account_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID"),
1102
+ account_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID"),
1103
1103
  search_term: _zod.z.string().optional().describe("Search users by name, email, or login")
1104
1104
  },
1105
1105
  annotations: {
@@ -1120,7 +1120,7 @@ function accountTools(canvas, pseudonymizer) {
1120
1120
  title: "Get Account Reports",
1121
1121
  description: "List available report types for a Canvas account.",
1122
1122
  inputSchema: {
1123
- account_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID")
1123
+ account_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID")
1124
1124
  },
1125
1125
  annotations: {
1126
1126
  readOnlyHint: true,
@@ -1184,8 +1184,8 @@ function assignmentSubmissionTools(canvas) {
1184
1184
  name: "upload_submission_file",
1185
1185
  description: "Upload a file to the authenticated student's own submission area for one assignment, as step 1 of an online_upload submission (step 2: pass the returned file id to submit_assignment). Opt-in tool: only available when the server was started with CANVAS_ENABLE_ASSIGNMENT_SUBMISSION. Content must be base64-encoded. This uploads only \u2014 nothing is submitted until submit_assignment is called.",
1186
1186
  inputSchema: {
1187
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1188
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
1187
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1188
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
1189
1189
  name: _zod.z.string().describe("The filename, including extension"),
1190
1190
  content_base64: _zod.z.string().describe("The file content, base64-encoded"),
1191
1191
  content_type: _zod.z.string().describe("The MIME type, e.g. application/pdf")
@@ -1205,12 +1205,12 @@ function assignmentSubmissionTools(canvas) {
1205
1205
  name: "submit_assignment",
1206
1206
  description: "Submit the authenticated student's own work to an assignment. Opt-in tool: only available when the server was started with CANVAS_ENABLE_ASSIGNMENT_SUBMISSION. IMPORTANT: before calling, show the user exactly what will be submitted (assignment name, submission type, and full content/URL/file list) and get their explicit confirmation \u2014 submissions cannot be retracted and may consume a limited attempt. Submits as the token holder only; submitting on behalf of another user is not supported. For online_upload, first upload each file with upload_submission_file and pass the returned file ids.",
1207
1207
  inputSchema: {
1208
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1209
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
1208
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1209
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
1210
1210
  submission_type: _zod.z.enum(["online_text_entry", "online_url", "online_upload"]).describe("Must be one of the assignment's allowed submission_types"),
1211
1211
  body: _zod.z.string().optional().describe("The submission text/HTML. Required iff submission_type is online_text_entry"),
1212
1212
  url: _zod.z.string().optional().describe("The submission URL (http/https). Required iff submission_type is online_url"),
1213
- file_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe(
1213
+ file_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe(
1214
1214
  "File IDs from prior upload_submission_file calls. Required (non-empty) iff submission_type is online_upload"
1215
1215
  ),
1216
1216
  comment: _zod.z.string().optional().describe("Optional text comment to attach alongside the submission")
@@ -1290,7 +1290,7 @@ function assignmentSubmissionTools(canvas) {
1290
1290
 
1291
1291
  // src/tools/errors.ts
1292
1292
  function formatError(error) {
1293
- if (error instanceof _chunkZT2BWA2Jcjs.CanvasApiError) {
1293
+ if (error instanceof _chunk2RKEK44Ecjs.CanvasApiError) {
1294
1294
  const status = error.status;
1295
1295
  const message = error.message;
1296
1296
  const ltiMarkers = ["Tool not configured", "tool is not configured"];
@@ -1342,9 +1342,9 @@ function analyticsTools(canvas) {
1342
1342
  audience: "shared",
1343
1343
  description: "Search for content within a course. Searches pages, assignments, discussions, and announcements by keyword.",
1344
1344
  inputSchema: {
1345
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1345
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1346
1346
  search_term: _zod.z.string().describe("The keyword or phrase to search for"),
1347
- content_types: _zod.z.array(_zod.z.enum(_chunkDEFB5PL2cjs.SEARCH_CONTENT_TYPES)).optional().describe(
1347
+ content_types: _zod.z.array(_zod.z.enum(_chunk3X2VLRJJcjs.SEARCH_CONTENT_TYPES)).optional().describe(
1348
1348
  "Content types to search. Defaults to all types: pages, discussions, assignments, announcements."
1349
1349
  )
1350
1350
  },
@@ -1356,7 +1356,7 @@ function analyticsTools(canvas) {
1356
1356
  const courseId = params.course_id;
1357
1357
  const searchTerm = params.search_term;
1358
1358
  const types = _nullishCoalesce(params.content_types, () => ( [
1359
- ..._chunkDEFB5PL2cjs.SEARCH_CONTENT_TYPES
1359
+ ..._chunk3X2VLRJJcjs.SEARCH_CONTENT_TYPES
1360
1360
  ]));
1361
1361
  if (types.length === 0) return { results: [] };
1362
1362
  const settled = await Promise.allSettled(
@@ -1384,7 +1384,7 @@ ${allErrors.join("\n")}`);
1384
1384
  title: "Get Course Analytics",
1385
1385
  description: "Get course-level activity analytics. Returns daily page view and participation counts.",
1386
1386
  inputSchema: {
1387
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
1387
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
1388
1388
  },
1389
1389
  annotations: {
1390
1390
  readOnlyHint: true,
@@ -1400,8 +1400,8 @@ ${allErrors.join("\n")}`);
1400
1400
  title: "Get Student Analytics",
1401
1401
  description: "Get per-student activity analytics for a course. Returns page views, participations, and submission timeline for a specific student.",
1402
1402
  inputSchema: {
1403
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1404
- student_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID of the student")
1403
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1404
+ student_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID of the student")
1405
1405
  },
1406
1406
  annotations: {
1407
1407
  readOnlyHint: true,
@@ -1419,7 +1419,7 @@ ${allErrors.join("\n")}`);
1419
1419
  audience: "shared",
1420
1420
  description: "Get a summary of recent activity in a course. Returns counts of recent events grouped by type (submissions, discussions, announcements, etc.).",
1421
1421
  inputSchema: {
1422
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
1422
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
1423
1423
  },
1424
1424
  annotations: {
1425
1425
  readOnlyHint: true,
@@ -1436,8 +1436,8 @@ ${allErrors.join("\n")}`);
1436
1436
  audience: "shared",
1437
1437
  description: "Get score distribution analytics for assignments in a course. Returns statistical summary (min, max, median, first/third quartile), submission count, and tardiness breakdown (on_time, late, missing) for each assignment. Provide assignment_id to scope to one assignment; omit to return analytics for all assignments in the course.",
1438
1438
  inputSchema: {
1439
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1440
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe(
1439
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1440
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe(
1441
1441
  "Scope the result to a single assignment ID. Omit to return analytics for all assignments."
1442
1442
  )
1443
1443
  },
@@ -1498,8 +1498,8 @@ function attentionTools(canvas, pseudonymizer) {
1498
1498
  title: "List Submission Comments Needing Attention",
1499
1499
  description: "List submissions where the most recent comment is from the student and has not been addressed by grading or a reply \u2014 i.e. comments the instructor has likely not seen. Returns a triage list, oldest-unaddressed first. Requires instructor/TA permissions in the course.",
1500
1500
  inputSchema: {
1501
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1502
- assignment_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe(
1501
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1502
+ assignment_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe(
1503
1503
  "Scope the scan to specific assignment IDs (fetches all assignments when omitted)"
1504
1504
  ),
1505
1505
  unread_only: _zod.z.boolean().optional().describe(
@@ -1571,7 +1571,7 @@ function attentionTools(canvas, pseudonymizer) {
1571
1571
  title: "List Students Needing Attention",
1572
1572
  description: "Report students who may need instructor attention based on inactivity, missing or late submissions, and low current score. Each finding lists the exact signals that fired and the thresholds used \u2014 this is a factual report, not a prediction. Requires instructor/TA permissions in the course.",
1573
1573
  inputSchema: {
1574
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1574
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1575
1575
  inactive_days: _zod.z.number().optional().describe("Flag students with no activity in the last N days (default 7)"),
1576
1576
  min_missing: _zod.z.number().optional().describe("Flag students with at least N missing submissions (default 1)"),
1577
1577
  min_late: _zod.z.number().optional().describe("Flag students with at least N late submissions (default 3)"),
@@ -1609,7 +1609,7 @@ function attentionTools(canvas, pseudonymizer) {
1609
1609
  summaryMap.set(s.id, s);
1610
1610
  }
1611
1611
  } catch (err) {
1612
- if (err instanceof _chunkZT2BWA2Jcjs.CanvasApiError && err.status === 404) {
1612
+ if (err instanceof _chunk2RKEK44Ecjs.CanvasApiError && err.status === 404) {
1613
1613
  analyticsAvailable = false;
1614
1614
  } else {
1615
1615
  throw err;
@@ -1748,7 +1748,7 @@ function assignmentTools(canvas) {
1748
1748
  audience: "shared",
1749
1749
  description: 'List all assignments in a course. Use fields="slim" when enumerating assignments for selection; switch to "full" once you\'ve identified the target. slim returns id, name, due_at, points_possible, published, and course_id only. "full" (default) includes all Canvas fields plus `include` extras (submission, all_dates, overrides, score_statistics, etc.). Use `bucket` to filter by past/upcoming/overdue/etc. Other filters: `search_term`, `assignment_ids`, `order_by`.',
1750
1750
  inputSchema: {
1751
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1751
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1752
1752
  fields: _zod.z.enum(["slim", "full"]).optional().describe(
1753
1753
  'Projection mode: "slim" returns id/name/due_at/points_possible/published/course_id only; "full" (default) returns all fields'
1754
1754
  ),
@@ -1757,7 +1757,7 @@ function assignmentTools(canvas) {
1757
1757
  ),
1758
1758
  search_term: _zod.z.string().optional().describe("Partial name substring to filter assignments by"),
1759
1759
  bucket: _zod.z.enum(ASSIGNMENT_BUCKET).optional().describe("Only include assignments in the given bucket"),
1760
- assignment_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe("Restrict to the given list of assignment IDs"),
1760
+ assignment_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe("Restrict to the given list of assignment IDs"),
1761
1761
  order_by: _zod.z.enum(ASSIGNMENT_ORDER_BY).optional().describe("Field to sort the result by"),
1762
1762
  override_assignment_dates: _zod.z.boolean().optional().describe(
1763
1763
  "Apply assignment overrides to due/unlock/lock dates (default Canvas behavior: true)"
@@ -1802,8 +1802,8 @@ function assignmentTools(canvas) {
1802
1802
  audience: "shared",
1803
1803
  description: "Get details for a single assignment by ID. Use `include` to request submission, overrides, all_dates, score_statistics, and other optional fields.",
1804
1804
  inputSchema: {
1805
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1806
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
1805
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1806
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
1807
1807
  include: _zod.z.array(_zod.z.enum(ASSIGNMENT_GET_INCLUDE)).optional().describe("Extra fields to include on the assignment (Canvas include[] param)"),
1808
1808
  override_assignment_dates: _zod.z.boolean().optional().describe("Apply assignment overrides to due/unlock/lock dates"),
1809
1809
  needs_grading_count_by_section: _zod.z.boolean().optional().describe("Break needs_grading_count down by section"),
@@ -1835,14 +1835,14 @@ function assignmentTools(canvas) {
1835
1835
  audience: "shared",
1836
1836
  description: "List assignment groups (categories like Homework, Exams) in a course. Use `include=assignments` to nest assignments under each group; other includes add submission, overrides, score_statistics, etc.",
1837
1837
  inputSchema: {
1838
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1838
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1839
1839
  include: _zod.z.array(_zod.z.enum(ASSIGNMENT_GROUP_INCLUDE)).optional().describe("Extra fields to include (Canvas include[] param)"),
1840
- assignment_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe(
1840
+ assignment_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe(
1841
1841
  "When combined with include=assignments, restrict nested assignments to these IDs"
1842
1842
  ),
1843
1843
  exclude_assignment_submission_types: _zod.z.array(_zod.z.string()).optional().describe("Exclude assignments whose submission_types match any of these values"),
1844
1844
  override_assignment_dates: _zod.z.boolean().optional().describe("Apply assignment overrides to due/unlock/lock dates"),
1845
- grading_period_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Scope to a specific grading period"),
1845
+ grading_period_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Scope to a specific grading period"),
1846
1846
  scope_assignments_to_student: _zod.z.boolean().optional().describe("Limit assignments to what the current student can see")
1847
1847
  },
1848
1848
  annotations: {
@@ -1871,7 +1871,7 @@ function assignmentTools(canvas) {
1871
1871
  title: "Create Assignment",
1872
1872
  description: "Create a new assignment in a course and return the created assignment object. Each call creates another assignment \u2014 Canvas assigns a new ID every time, so check list_assignments with a search_term first to avoid duplicates. Use update_assignment to change an existing assignment instead of calling this again, and delete_assignment to remove one. due_at, lock_at, and unlock_at here apply to every student; to give a different date to a subset of students, a section, or a group, use create_assignment_override instead, or set_student_assignment_dates to fan a date change for one student across many assignments. Dates are ISO 8601 strings; lock_at must be after due_at and unlock_at before due_at when both are set. Requires instructor/TA permission to manage assignments and quizzes in the course.",
1873
1873
  inputSchema: {
1874
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1874
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1875
1875
  name: _zod.z.string().describe("Assignment name"),
1876
1876
  description: _zod.z.string().optional().describe("Assignment description (HTML supported)"),
1877
1877
  points_possible: _zod.z.number().optional().describe("Maximum points for this assignment"),
@@ -1885,7 +1885,7 @@ function assignmentTools(canvas) {
1885
1885
  submission_types: _zod.z.array(_zod.z.string()).optional().describe(
1886
1886
  'Allowed submission types (e.g. ["online_upload", "online_text_entry", "none"])'
1887
1887
  ),
1888
- assignment_group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("ID of the assignment group to place this assignment in"),
1888
+ assignment_group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("ID of the assignment group to place this assignment in"),
1889
1889
  published: _zod.z.boolean().optional().describe("Whether the assignment is published and visible to students"),
1890
1890
  omit_from_final_grade: _zod.z.boolean().optional().describe("Whether to leave this assignment out of the final grade calculation"),
1891
1891
  grade_group_students_individually: _zod.z.boolean().optional().describe(
@@ -1906,8 +1906,8 @@ function assignmentTools(canvas) {
1906
1906
  title: "Update Assignment",
1907
1907
  description: "Update an existing assignment in a course.",
1908
1908
  inputSchema: {
1909
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1910
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
1909
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1910
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
1911
1911
  name: _zod.z.string().optional().describe("New assignment name"),
1912
1912
  description: _zod.z.string().optional().describe("New assignment description (HTML supported)"),
1913
1913
  points_possible: _zod.z.number().optional().describe("New maximum points"),
@@ -1919,7 +1919,7 @@ function assignmentTools(canvas) {
1919
1919
  "New date the assignment becomes available to students, in ISO 8601 format. Must be before due_at when there is one"
1920
1920
  ),
1921
1921
  submission_types: _zod.z.array(_zod.z.string()).optional().describe("New allowed submission types"),
1922
- assignment_group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("New assignment group ID"),
1922
+ assignment_group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("New assignment group ID"),
1923
1923
  published: _zod.z.boolean().optional().describe("Whether the assignment is published and visible to students"),
1924
1924
  omit_from_final_grade: _zod.z.boolean().optional().describe("Whether to leave this assignment out of the final grade calculation"),
1925
1925
  grade_group_students_individually: _zod.z.boolean().optional().describe(
@@ -1941,8 +1941,8 @@ function assignmentTools(canvas) {
1941
1941
  title: "Delete Assignment",
1942
1942
  description: "Delete an assignment from a course. This action is permanent.",
1943
1943
  inputSchema: {
1944
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1945
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID to delete")
1944
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
1945
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID to delete")
1946
1946
  },
1947
1947
  annotations: {
1948
1948
  destructiveHint: true,
@@ -1975,7 +1975,7 @@ async function fanOut(config) {
1975
1975
  skipped.push(outcome.result);
1976
1976
  }
1977
1977
  } catch (err) {
1978
- if (!(err instanceof _chunkZT2BWA2Jcjs.CanvasApiError)) {
1978
+ if (!(err instanceof _chunk2RKEK44Ecjs.CanvasApiError)) {
1979
1979
  console.error(`Unexpected error ${config.errorContext(item)}:`, err);
1980
1980
  }
1981
1981
  const message = err instanceof Error ? err.message : "Unknown error";
@@ -2008,8 +2008,8 @@ function assignmentOverrideTools(canvas) {
2008
2008
  title: "List Assignment Overrides",
2009
2009
  description: "List all due-date / availability overrides for a specific assignment in a course. Returns overrides targeting individual students, sections, or groups. Useful for auditing before creating a new override \u2014 Canvas returns a 422 if a student-set override already exists for the same students on the same assignment.",
2010
2010
  inputSchema: {
2011
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
2012
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas assignment ID")
2011
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
2012
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas assignment ID")
2013
2013
  },
2014
2014
  annotations: {
2015
2015
  readOnlyHint: true,
@@ -2026,15 +2026,15 @@ function assignmentOverrideTools(canvas) {
2026
2026
  title: "Create Assignment Override",
2027
2027
  description: 'Create a due-date / availability override for a specific assignment, targeting a set of students, a course section, or a group. Exactly one of student_ids, course_section_id, or group_id must be provided. At least one date field (due_at, unlock_at, lock_at) should be provided; omit a date field to leave the corresponding date unchanged for the override target. Dates must be ISO 8601 strings (e.g. "2026-09-15T23:59:00Z"). Canvas returns a 422 if a student-set override already exists for the same students on this assignment \u2014 use list_assignment_overrides to audit first. Provide student_ids as real Canvas user IDs. If CANVAS_PSEUDONYMIZE_STUDENTS is enabled, call resolve_pseudonym first to resolve pseudonyms to real user IDs.',
2028
2028
  inputSchema: {
2029
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
2030
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas assignment ID"),
2031
- student_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).min(1).optional().describe(
2029
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
2030
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas assignment ID"),
2031
+ student_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).min(1).optional().describe(
2032
2032
  "Real Canvas user IDs to grant the override to. Mutually exclusive with course_section_id and group_id."
2033
2033
  ),
2034
- course_section_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe(
2034
+ course_section_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe(
2035
2035
  "ID of the course section to override. Mutually exclusive with student_ids and group_id."
2036
2036
  ),
2037
- group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe(
2037
+ group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe(
2038
2038
  "ID of the group to override. Mutually exclusive with student_ids and course_section_id."
2039
2039
  ),
2040
2040
  title: _zod.z.string().optional().describe(
@@ -2082,9 +2082,9 @@ function assignmentOverrideTools(canvas) {
2082
2082
  title: "Set Student Assignment Dates",
2083
2083
  description: "Fan a due-date / availability override for a specific student across all (or a filtered subset of) assignments in a course. Creates one student-set override per assignment via the Canvas assignment overrides API. Partial failures are tolerated \u2014 a failure on one assignment does not abort the rest. Note: for courses with many assignments this makes one Canvas API call per assignment. V1 is create-only: if an override for this student already exists on an assignment, Canvas returns a 422 and that assignment appears in the failed[] list. Use list_assignment_overrides to audit first. Dates must be ISO 8601 strings. To shift dates by a relative amount, first call list_assignments with include=overrides to retrieve current dates, compute absolute timestamps, then call this tool. Returns the standard fan-out envelope: separated applied[], skipped[] (unused in this create-only version, always empty), and failed[] (each with an error) arrays, a not_found list, and a summary of counts. Any assignment_ids that do not exist in the course are reported in not_found (they are neither applied nor failed). Provide user_id as the real Canvas user ID. If CANVAS_PSEUDONYMIZE_STUDENTS is enabled, call resolve_pseudonym first to obtain the real user_id from a pseudonym.",
2084
2084
  inputSchema: {
2085
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
2086
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Real Canvas user ID of the student to accommodate"),
2087
- assignment_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).min(1).optional().describe(
2085
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
2086
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Real Canvas user ID of the student to accommodate"),
2087
+ assignment_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).min(1).optional().describe(
2088
2088
  "Limit the fan-out to these specific assignment IDs (provide at least one). Omit entirely to target all assignments in the course. IDs not present in the course are returned in not_found, not applied/failed."
2089
2089
  ),
2090
2090
  title: _zod.z.string().optional().describe(
@@ -2165,7 +2165,7 @@ function calendarTools(canvas) {
2165
2165
  title: "List Calendar Events",
2166
2166
  description: 'List calendar events for a course, unbounded by the ~1-week/20-item caps that `get_upcoming_events` and `get_my_upcoming_assignments` are stuck with. By default Canvas only returns `type="event"` items for today alone (end_date defaults to start_date) \u2014 pass both start_date and end_date to cover a range, and type="assignment" to list assignment due dates instead of plain events.',
2167
2167
  inputSchema: {
2168
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2168
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2169
2169
  type: _zod.z.enum(["event", "assignment", "sub_assignment"]).optional().describe('Kind of calendar item to return. Defaults to "event" if omitted.'),
2170
2170
  start_date: _zod.z.string().optional().describe(
2171
2171
  "Inclusive range start (YYYY-MM-DD or ISO 8601 datetime). Defaults to today if omitted."
@@ -2219,7 +2219,7 @@ function calendarTools(canvas) {
2219
2219
  title: "Update Calendar Event",
2220
2220
  description: "Update an existing calendar event. Only provided fields are changed.",
2221
2221
  inputSchema: {
2222
- event_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas calendar event ID"),
2222
+ event_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas calendar event ID"),
2223
2223
  title: _zod.z.string().optional().describe("New event title"),
2224
2224
  start_at: _zod.z.string().optional().describe("New start time in ISO 8601 format"),
2225
2225
  end_at: _zod.z.string().optional().describe("New end time in ISO 8601 format"),
@@ -2253,7 +2253,7 @@ function contentExportsTools(canvas) {
2253
2253
  title: "Create Content Export",
2254
2254
  description: 'Start a Canvas course content export (Common Cartridge / QTI / zip). Exports are asynchronous \u2014 this tool returns immediately with an export ID and initial workflow_state ("created"). Call get_content_export to poll progress and retrieve the time-limited download link when the export finishes.',
2255
2255
  inputSchema: {
2256
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2256
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2257
2257
  export_type: _zod.z.enum(["common_cartridge", "qti", "zip"]).describe(
2258
2258
  "Export format: common_cartridge (IMS CC, widely portable for migration/backup), qti (assessments only), zip (Canvas-native files archive)"
2259
2259
  )
@@ -2269,8 +2269,8 @@ function contentExportsTools(canvas) {
2269
2269
  title: "Get Content Export",
2270
2270
  description: 'Get the status of a content export. When workflow_state is "exported", attachment.url contains a time-limited download link \u2014 download it promptly, as the URL expires (re-fetch to get a fresh one). Returns attachment: null while still "created"/"exporting" or on "failed".',
2271
2271
  inputSchema: {
2272
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2273
- export_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The export ID returned by create_content_export")
2272
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2273
+ export_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The export ID returned by create_content_export")
2274
2274
  },
2275
2275
  annotations: { readOnlyHint: true, openWorldHint: true },
2276
2276
  handler: async (params) => canvas.contentExports.get(params.course_id, params.export_id)
@@ -2280,7 +2280,7 @@ function contentExportsTools(canvas) {
2280
2280
  title: "List Content Exports",
2281
2281
  description: "List all content exports for a course (most recent first).",
2282
2282
  inputSchema: {
2283
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
2283
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
2284
2284
  },
2285
2285
  annotations: { readOnlyHint: true, openWorldHint: true },
2286
2286
  handler: async (params) => canvas.contentExports.list(params.course_id)
@@ -2297,7 +2297,7 @@ function contentMigrationsTools(canvas) {
2297
2297
  title: "List Content Migrations",
2298
2298
  description: "List all content migrations for a course (most recent first).",
2299
2299
  inputSchema: {
2300
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
2300
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
2301
2301
  },
2302
2302
  annotations: { readOnlyHint: true, openWorldHint: true },
2303
2303
  handler: async (params) => canvas.contentMigrations.list(params.course_id)
@@ -2307,8 +2307,8 @@ function contentMigrationsTools(canvas) {
2307
2307
  title: "Get Content Migration",
2308
2308
  description: 'Get the status of a single content migration. When workflow_state is "running", poll progress_url for live updates. When "completed", the migration is done.',
2309
2309
  inputSchema: {
2310
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2311
- migration_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The content migration ID")
2310
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2311
+ migration_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The content migration ID")
2312
2312
  },
2313
2313
  annotations: { readOnlyHint: true, openWorldHint: true },
2314
2314
  handler: async (params) => canvas.contentMigrations.get(params.course_id, params.migration_id)
@@ -2318,7 +2318,7 @@ function contentMigrationsTools(canvas) {
2318
2318
  title: "List Content Migration Types",
2319
2319
  description: "List available migration types (migrators) for a course. Returns migrator type keys such as course_copy_importer, common_cartridge_importer, zip_file_importer, qti_converter, moodle_converter.",
2320
2320
  inputSchema: {
2321
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
2321
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
2322
2322
  },
2323
2323
  annotations: { readOnlyHint: true, openWorldHint: true },
2324
2324
  handler: async (params) => canvas.contentMigrations.listMigrators(params.course_id)
@@ -2328,8 +2328,8 @@ function contentMigrationsTools(canvas) {
2328
2328
  title: "Get Migration Selective Data",
2329
2329
  description: 'Get the selective import tree for a migration \u2014 the list of content items available to selectively import. Only meaningful for migrations in the "waiting_for_select" state.',
2330
2330
  inputSchema: {
2331
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2332
- migration_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The content migration ID"),
2331
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2332
+ migration_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The content migration ID"),
2333
2333
  type: _zod.z.string().optional().describe(
2334
2334
  'Filter to a specific content type (e.g. "course_settings", "syllabus_body", "context_modules", "assignments")'
2335
2335
  )
@@ -2346,8 +2346,8 @@ function contentMigrationsTools(canvas) {
2346
2346
  title: "Get Migration Asset ID Mapping",
2347
2347
  description: "Get the old-to-new asset ID mapping for a completed migration. Useful for resolving references to content that existed in the source course.",
2348
2348
  inputSchema: {
2349
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2350
- migration_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The content migration ID")
2349
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2350
+ migration_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The content migration ID")
2351
2351
  },
2352
2352
  annotations: { readOnlyHint: true, openWorldHint: true },
2353
2353
  handler: async (params) => canvas.contentMigrations.getAssetIdMapping(
@@ -2360,8 +2360,8 @@ function contentMigrationsTools(canvas) {
2360
2360
  title: "List Migration Issues",
2361
2361
  description: "List issues encountered during a content migration. Each issue has a type (todo, warning, or error) and a description.",
2362
2362
  inputSchema: {
2363
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2364
- migration_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The content migration ID")
2363
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2364
+ migration_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The content migration ID")
2365
2365
  },
2366
2366
  annotations: { readOnlyHint: true, openWorldHint: true },
2367
2367
  handler: async (params) => canvas.contentMigrations.listMigrationIssues(
@@ -2374,7 +2374,7 @@ function contentMigrationsTools(canvas) {
2374
2374
  title: "Create Content Migration",
2375
2375
  description: "Start a content migration (course copy, Common Cartridge import, zip import, QTI conversion, or Moodle conversion). Migrations are asynchronous \u2014 this tool returns immediately with a migration ID and progress_url. Poll get_content_migration or progress_url to track completion.",
2376
2376
  inputSchema: {
2377
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The destination Canvas course ID"),
2377
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The destination Canvas course ID"),
2378
2378
  migration_type: _zod.z.enum([
2379
2379
  "course_copy_importer",
2380
2380
  "common_cartridge_importer",
@@ -2427,7 +2427,7 @@ function conversationTools(canvas, pseudonymizer) {
2427
2427
  title: "Get Conversation",
2428
2428
  description: "Get a single conversation with its full message thread.",
2429
2429
  inputSchema: {
2430
- conversation_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The conversation ID")
2430
+ conversation_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The conversation ID")
2431
2431
  },
2432
2432
  annotations: {
2433
2433
  readOnlyHint: true,
@@ -2532,7 +2532,7 @@ function courseSetupTools(canvas) {
2532
2532
  title: "Check Course Setup",
2533
2533
  description: "Run a factual course-readiness report that surfaces common configuration problems \u2014 assignments missing due dates, unpublished items students will not see, gradebook weighting gaps, graded assignments with no points, and published assignments still accepting submissions after their due date. Returns findings grouped by check with a plain-language detail per item. This is a config-health report only; it does not inspect student submissions or performance (see list_students_needing_attention / get_missing_submissions for those). Requires instructor permissions in the course.",
2534
2534
  inputSchema: {
2535
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
2535
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
2536
2536
  checks: _zod.z.array(
2537
2537
  _zod.z.enum([
2538
2538
  "missing_due_dates",
@@ -2756,7 +2756,7 @@ function courseTools(canvas) {
2756
2756
  title: "Get Course",
2757
2757
  description: "Get details for a single course. Defaults to requesting `term` and `total_students`. Pass `include` to replace the default set with custom Canvas include[] fields (teachers, permissions, syllabus_body, sections, etc.).",
2758
2758
  inputSchema: {
2759
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2759
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2760
2760
  include: _zod.z.array(_zod.z.enum(COURSE_GET_INCLUDE)).optional().describe("Extra fields to include on the course (Canvas include[] param)"),
2761
2761
  teacher_limit: _zod.z.number().int().optional().describe("Limit on the number of teachers returned when include=teachers")
2762
2762
  },
@@ -2777,7 +2777,7 @@ function courseTools(canvas) {
2777
2777
  title: "Get Syllabus",
2778
2778
  description: "Get the syllabus HTML body for a course.",
2779
2779
  inputSchema: {
2780
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
2780
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
2781
2781
  },
2782
2782
  annotations: {
2783
2783
  readOnlyHint: true,
@@ -2795,7 +2795,7 @@ function courseTools(canvas) {
2795
2795
  audience: "admin",
2796
2796
  description: "Create a new course in a Canvas account. Returns the created course object.",
2797
2797
  inputSchema: {
2798
- account_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID to create the course in"),
2798
+ account_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID to create the course in"),
2799
2799
  name: _zod.z.string().describe("The name of the course"),
2800
2800
  course_code: _zod.z.string().optional().describe("The course code (e.g. CS101)"),
2801
2801
  start_at: _zod.z.string().datetime().optional().describe("Course start date in ISO 8601 format (e.g. 2026-01-15T00:00:00Z)"),
@@ -2816,7 +2816,7 @@ function courseTools(canvas) {
2816
2816
  audience: "educator",
2817
2817
  description: "Update an existing course. Only provided fields are changed; omitted fields are left as-is.",
2818
2818
  inputSchema: {
2819
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID to update"),
2819
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID to update"),
2820
2820
  name: _zod.z.string().optional().describe("New course name"),
2821
2821
  course_code: _zod.z.string().optional().describe("New course code"),
2822
2822
  start_at: _zod.z.string().datetime().optional().describe("New start date in ISO 8601 format (e.g. 2026-01-15T00:00:00Z)"),
@@ -2948,9 +2948,9 @@ function discussionTools(canvas) {
2948
2948
  {
2949
2949
  name: "list_discussions",
2950
2950
  title: "List Discussions",
2951
- description: "List all discussion topics in a course.",
2951
+ description: "List discussion topics in a course, returning id, title, message, posted_at, discussion_type, published, and is_announcement for each topic \u2014 replies are not included. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use get_discussion to fetch one topic in full detail including due/available dates, post_discussion_entry to reply, and list_announcements to see only announcements.",
2952
2952
  inputSchema: {
2953
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
2953
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
2954
2954
  },
2955
2955
  annotations: {
2956
2956
  readOnlyHint: true,
@@ -2967,10 +2967,10 @@ function discussionTools(canvas) {
2967
2967
  // The anonymous-topic case is reported by the handler's error below rather than
2968
2968
  // advertised here: `docs/generated/tool-manifest.json` embeds this string, so any
2969
2969
  // edit also requires `pnpm generate:manifests`.
2970
- description: "Get details for a single discussion topic by ID.",
2970
+ description: "Get a single discussion topic in a course by ID, returning its title, message, posted_at, discussion_type, published state, and is_announcement, plus due/available dates via Canvas's all_dates include. Find topic_id with list_discussions. Course-scoped only \u2014 use get_group_discussion for a topic that belongs to a group instead of a course.",
2971
2971
  inputSchema: {
2972
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2973
- topic_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas discussion topic ID")
2972
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
2973
+ topic_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas discussion topic ID")
2974
2974
  },
2975
2975
  annotations: {
2976
2976
  readOnlyHint: true,
@@ -2982,7 +2982,7 @@ function discussionTools(canvas) {
2982
2982
  try {
2983
2983
  return await canvas.discussions.get(course_id, topic_id);
2984
2984
  } catch (error) {
2985
- if (!(error instanceof _chunkZT2BWA2Jcjs.CanvasApiError) || error.status !== 404) throw error;
2985
+ if (!(error instanceof _chunk2RKEK44Ecjs.CanvasApiError) || error.status !== 404) throw error;
2986
2986
  const description = await describeAnonymityFromList(canvas, course_id, topic_id);
2987
2987
  if (description === void 0) throw error;
2988
2988
  throw new Error(anonymousTopicMessage(course_id, topic_id, description), {
@@ -2994,9 +2994,9 @@ function discussionTools(canvas) {
2994
2994
  {
2995
2995
  name: "list_group_discussions",
2996
2996
  title: "List Group Discussions",
2997
- description: "List all discussion topics in a group.",
2997
+ description: "List discussion topics in a group, returning id, title, message, posted_at, discussion_type, published, and is_announcement for each topic \u2014 replies are not included. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use get_group_discussion to fetch one topic in full detail including due/available dates, and list_discussions for the course-scoped equivalent; there is no group-scoped counterpart to post_discussion_entry or list_announcements.",
2998
2998
  inputSchema: {
2999
- group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas group ID")
2999
+ group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas group ID")
3000
3000
  },
3001
3001
  annotations: {
3002
3002
  readOnlyHint: true,
@@ -3013,10 +3013,10 @@ function discussionTools(canvas) {
3013
3013
  // As with get_discussion, the anonymous-topic case is reported by the handler's
3014
3014
  // error below rather than advertised here — `docs/generated/tool-manifest.json`
3015
3015
  // embeds this string, so any edit also requires `pnpm generate:manifests`.
3016
- description: "Get details for a single discussion topic in a group by ID.",
3016
+ description: "Get a single discussion topic in a group by ID, returning its title, message, posted_at, discussion_type, published state, and is_announcement, plus due/available dates via Canvas's all_dates include. Find topic_id with list_group_discussions. Group-scoped only \u2014 use get_discussion for a topic that belongs to a course instead of a group; there is no group-scoped counterpart to post_discussion_entry, so this server cannot post a reply to a group topic yet.",
3017
3017
  inputSchema: {
3018
- group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas group ID"),
3019
- topic_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas discussion topic ID")
3018
+ group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas group ID"),
3019
+ topic_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas discussion topic ID")
3020
3020
  },
3021
3021
  annotations: {
3022
3022
  readOnlyHint: true,
@@ -3028,7 +3028,7 @@ function discussionTools(canvas) {
3028
3028
  try {
3029
3029
  return await canvas.discussions.getForGroup(group_id, topic_id);
3030
3030
  } catch (error) {
3031
- if (!(error instanceof _chunkZT2BWA2Jcjs.CanvasApiError) || error.status !== 404) throw error;
3031
+ if (!(error instanceof _chunk2RKEK44Ecjs.CanvasApiError) || error.status !== 404) throw error;
3032
3032
  const description = await describeGroupAnonymityFromList(canvas, group_id, topic_id);
3033
3033
  if (description === void 0) throw error;
3034
3034
  throw new Error(anonymousGroupTopicMessage(group_id, topic_id, description), {
@@ -3040,9 +3040,9 @@ function discussionTools(canvas) {
3040
3040
  {
3041
3041
  name: "list_announcements",
3042
3042
  title: "List Announcements",
3043
- description: "List all announcements in a course.",
3043
+ description: "List announcements in a course, returning id, title, message, and posted_at for each one. Canvas serves this from the same discussion_topics index as list_discussions, filtered to topics marked is_announcement via the only_announcements query parameter. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use create_discussion with is_announcement: true to post a new announcement, and update_discussion to edit one afterward.",
3044
3044
  inputSchema: {
3045
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
3045
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
3046
3046
  },
3047
3047
  annotations: {
3048
3048
  readOnlyHint: true,
@@ -3056,10 +3056,10 @@ function discussionTools(canvas) {
3056
3056
  {
3057
3057
  name: "post_discussion_entry",
3058
3058
  title: "Post Discussion Entry",
3059
- description: "Post a new entry (reply) to a discussion topic.",
3059
+ description: "Post a new entry (reply) to a discussion topic in a course, and return the created entry (id, user_id, message, created_at). Not idempotent: each call adds another reply, Canvas does not deduplicate repeated calls. Works even on a topic Canvas has made anonymous, where get_discussion itself 404s \u2014 use list_discussions to confirm the topic exists and find its topic_id. Requires the caller to have an active enrollment in the course with permission to post to the forum, which Canvas grants to students, TAs and instructors by default unless an admin has restricted it.",
3060
3060
  inputSchema: {
3061
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3062
- topic_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas discussion topic ID"),
3061
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3062
+ topic_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas discussion topic ID"),
3063
3063
  message: _zod.z.string().describe("The message body (supports HTML)")
3064
3064
  },
3065
3065
  annotations: {
@@ -3077,9 +3077,9 @@ function discussionTools(canvas) {
3077
3077
  name: "create_discussion",
3078
3078
  title: "Create Discussion",
3079
3079
  audience: "educator",
3080
- description: "Create a new discussion topic in a course.",
3080
+ description: "Create a new discussion topic in a course, and return the created topic (id, title, message, discussion_type, published, is_announcement, posted_at). Not idempotent: each call creates another topic \u2014 Canvas does not deduplicate by title, so check list_discussions first to avoid creating a duplicate. Setting is_announcement: true asks Canvas to create an announcement, but Canvas silently creates a plain discussion topic instead (HTTP 200, no error) if the caller lacks announcement-create permission in the course \u2014 this tool then throws instead of reporting success, naming the topic ID so you can check it with list_discussions or get_discussion. Use update_discussion to change an existing topic afterward, delete_discussion to remove one, and post_discussion_entry to reply to a topic instead of creating a new one. Requires instructor/TA permission to manage discussions in the course.",
3081
3081
  inputSchema: {
3082
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3082
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3083
3083
  title: _zod.z.string().min(1).describe("Title of the discussion topic"),
3084
3084
  message: _zod.z.string().optional().describe("Body text of the discussion (supports HTML)"),
3085
3085
  discussion_type: _zod.z.enum(["side_comment", "threaded"]).optional().describe("Discussion type: side_comment (flat) or threaded"),
@@ -3116,8 +3116,8 @@ function discussionTools(canvas) {
3116
3116
  audience: "educator",
3117
3117
  description: "Update an existing discussion topic in a course \u2014 title, message, published state, require_initial_post, delayed_post_at, or is_announcement \u2014 and return the updated topic; only the fields you pass are changed, the rest keep their current value. Course-scoped only: there is no update tool for group discussions, though list_group_discussions and get_group_discussion can still read them. Setting is_announcement: true asks Canvas to turn the topic into an announcement, but Canvas silently keeps it a plain discussion topic (HTTP 200, no error) if the caller lacks announcement-create permission in the course \u2014 this tool then throws instead of reporting success, naming the topic ID so you can check it with list_discussions or get_discussion. Use create_discussion to make a new topic, delete_discussion to remove one, list_announcements to see existing announcements, and post_discussion_entry to reply instead of editing the topic itself. Requires instructor/TA permission to manage discussions in the course.",
3118
3118
  inputSchema: {
3119
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3120
- topic_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas discussion topic ID"),
3119
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3120
+ topic_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas discussion topic ID"),
3121
3121
  title: _zod.z.string().optional().describe("New title for the discussion topic"),
3122
3122
  message: _zod.z.string().optional().describe("New body text (supports HTML)"),
3123
3123
  published: _zod.z.boolean().optional().describe("Publish or unpublish the topic"),
@@ -3157,8 +3157,8 @@ function discussionTools(canvas) {
3157
3157
  audience: "educator",
3158
3158
  description: "Delete a discussion topic from a course. This action is permanent.",
3159
3159
  inputSchema: {
3160
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3161
- topic_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas discussion topic ID to delete")
3160
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3161
+ topic_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas discussion topic ID to delete")
3162
3162
  },
3163
3163
  annotations: {
3164
3164
  destructiveHint: true,
@@ -3216,8 +3216,8 @@ function enrollmentTools(canvas, pseudonymizer) {
3216
3216
  state: _zod.z.array(_zod.z.enum(ENROLLMENT_STATE)).optional().describe("Filter by one or more enrollment states"),
3217
3217
  role: _zod.z.array(_zod.z.string()).optional().describe("Filter by enrollment role names (as defined in the Canvas account)"),
3218
3218
  include: _zod.z.array(_zod.z.enum(ENROLLMENT_INCLUDE)).optional().describe("Extra fields to include on each enrollment (Canvas include[] param)"),
3219
- grading_period_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Return enrollments scoped to this grading period"),
3220
- enrollment_term_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Limit to enrollments in the given term")
3219
+ grading_period_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Return enrollments scoped to this grading period"),
3220
+ enrollment_term_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Limit to enrollments in the given term")
3221
3221
  },
3222
3222
  annotations: {
3223
3223
  readOnlyHint: true,
@@ -3247,14 +3247,14 @@ function enrollmentTools(canvas, pseudonymizer) {
3247
3247
  audience: "educator",
3248
3248
  description: "List enrollments within a specific course with Canvas filters. Use `include=grades` / `include=current_points` for richer grade data, `type[]` to limit to a role, and `user_id` to focus on a single user.",
3249
3249
  inputSchema: {
3250
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3250
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3251
3251
  type: _zod.z.array(_zod.z.enum(ENROLLMENT_TYPE)).optional().describe("Filter by one or more enrollment types"),
3252
3252
  state: _zod.z.array(_zod.z.enum(ENROLLMENT_STATE)).optional().describe("Filter by enrollment states"),
3253
3253
  role: _zod.z.array(_zod.z.string()).optional().describe("Filter by custom role names"),
3254
3254
  include: _zod.z.array(_zod.z.enum(ENROLLMENT_INCLUDE)).optional().describe("Extra fields to include (Canvas include[] param)"),
3255
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, { sentinels: ["self"] }).optional().describe('Filter to a specific user. Canvas ID (pass large IDs as a string) or "self".'),
3256
- grading_period_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Scope grade-related includes to this grading period"),
3257
- enrollment_term_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Limit to enrollments in the given term")
3255
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, { sentinels: ["self"] }).optional().describe('Filter to a specific user. Canvas ID (pass large IDs as a string) or "self".'),
3256
+ grading_period_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Scope grade-related includes to this grading period"),
3257
+ enrollment_term_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Limit to enrollments in the given term")
3258
3258
  },
3259
3259
  annotations: {
3260
3260
  readOnlyHint: true,
@@ -3283,8 +3283,8 @@ function enrollmentTools(canvas, pseudonymizer) {
3283
3283
  title: "Enroll User",
3284
3284
  description: "Enroll a user in a course with a specified role.",
3285
3285
  inputSchema: {
3286
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3287
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID to enroll"),
3286
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3287
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID to enroll"),
3288
3288
  type: _zod.z.enum([
3289
3289
  "StudentEnrollment",
3290
3290
  "TeacherEnrollment",
@@ -3312,8 +3312,8 @@ function enrollmentTools(canvas, pseudonymizer) {
3312
3312
  title: "Remove Enrollment",
3313
3313
  description: "Remove or conclude an enrollment from a course. The 'delete' task is permanent; 'conclude' and 'deactivate' are reversible.",
3314
3314
  inputSchema: {
3315
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3316
- enrollment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The enrollment ID to remove"),
3315
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3316
+ enrollment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The enrollment ID to remove"),
3317
3317
  task: _zod.z.enum(["conclude", "delete", "deactivate"]).describe("The action to perform on the enrollment")
3318
3318
  },
3319
3319
  annotations: {
@@ -3391,7 +3391,7 @@ function fileTools(canvas) {
3391
3391
  title: "List Files",
3392
3392
  description: "List all files in a course.",
3393
3393
  inputSchema: {
3394
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
3394
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
3395
3395
  },
3396
3396
  annotations: {
3397
3397
  readOnlyHint: true,
@@ -3407,7 +3407,7 @@ function fileTools(canvas) {
3407
3407
  title: "List Folders",
3408
3408
  description: "List all folders in a course.",
3409
3409
  inputSchema: {
3410
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
3410
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
3411
3411
  },
3412
3412
  annotations: {
3413
3413
  readOnlyHint: true,
@@ -3423,8 +3423,8 @@ function fileTools(canvas) {
3423
3423
  title: "Get File",
3424
3424
  description: "Get metadata for a single file by ID, including download URL.",
3425
3425
  inputSchema: {
3426
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3427
- file_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas file ID")
3426
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3427
+ file_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas file ID")
3428
3428
  },
3429
3429
  annotations: {
3430
3430
  readOnlyHint: true,
@@ -3442,7 +3442,7 @@ function fileTools(canvas) {
3442
3442
  audience: "educator",
3443
3443
  description: "Upload a file to a course. Content must be base64-encoded. Canvas performs a multi-step upload internally.",
3444
3444
  inputSchema: {
3445
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3445
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3446
3446
  name: _zod.z.string().describe("File name including extension"),
3447
3447
  content: _zod.z.string().describe("Base64-encoded file content"),
3448
3448
  content_type: _zod.z.string().describe('MIME type, e.g. "application/pdf" or "image/png"'),
@@ -3467,7 +3467,7 @@ function fileTools(canvas) {
3467
3467
  audience: "educator",
3468
3468
  description: "Delete a file by ID. This action is permanent.",
3469
3469
  inputSchema: {
3470
- file_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas file ID")
3470
+ file_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas file ID")
3471
3471
  },
3472
3472
  annotations: {
3473
3473
  destructiveHint: true,
@@ -3483,8 +3483,8 @@ function fileTools(canvas) {
3483
3483
  title: "Download File",
3484
3484
  description: "Download the content of a Canvas file by ID. Text files (plain text, HTML, JSON, XML, JavaScript) are returned as readable text. Binary files (images, PDFs, etc.) are returned as base64-encoded data. Files larger than 10 MB are refused.",
3485
3485
  inputSchema: {
3486
- file_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas file ID"),
3487
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Optional Canvas course ID to scope the file lookup")
3486
+ file_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas file ID"),
3487
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Optional Canvas course ID to scope the file lookup")
3488
3488
  },
3489
3489
  annotations: {
3490
3490
  readOnlyHint: true,
@@ -3501,8 +3501,8 @@ function fileTools(canvas) {
3501
3501
  title: "Find Duplicate Files",
3502
3502
  description: "Find duplicate files in a course's Files area \u2014 copies with the same name and size, typically left behind by repeated course copies. Each duplicate gets flagged separately by accessibility checkers, so this surfaces them for cleanup with the existing delete_file tool. Groups by display name + size (Canvas file listings carry no content hash), so same-name files of different sizes are not considered duplicates.",
3503
3503
  inputSchema: {
3504
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3505
- folder_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe(
3504
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3505
+ folder_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe(
3506
3506
  "Optional Canvas folder ID to scope the search to that folder and its subfolders"
3507
3507
  )
3508
3508
  },
@@ -3543,7 +3543,7 @@ function gradebookHistoryTools(canvas, pseudonymizer) {
3543
3543
  title: "List Gradebook History Days",
3544
3544
  description: "List the dates in a course gradebook history that contain grading activity, grouped by grader and assignment.",
3545
3545
  inputSchema: {
3546
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
3546
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
3547
3547
  },
3548
3548
  annotations: {
3549
3549
  readOnlyHint: true,
@@ -3559,7 +3559,7 @@ function gradebookHistoryTools(canvas, pseudonymizer) {
3559
3559
  title: "Get Gradebook History Day",
3560
3560
  description: "Get the graders and assignment IDs that had gradebook activity on a specific course date.",
3561
3561
  inputSchema: {
3562
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3562
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3563
3563
  date: _zod.z.string().describe("The gradebook history date to inspect, in YYYY-MM-DD format")
3564
3564
  },
3565
3565
  annotations: {
@@ -3577,10 +3577,10 @@ function gradebookHistoryTools(canvas, pseudonymizer) {
3577
3577
  title: "List Gradebook History Submissions",
3578
3578
  description: "List versioned submission history for one grader and assignment on a specific gradebook history date.",
3579
3579
  inputSchema: {
3580
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3580
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3581
3581
  date: _zod.z.string().describe("The gradebook history date to inspect, in YYYY-MM-DD format"),
3582
- grader_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID of the grader"),
3583
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID")
3582
+ grader_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID of the grader"),
3583
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID")
3584
3584
  },
3585
3585
  annotations: {
3586
3586
  readOnlyHint: true,
@@ -3613,9 +3613,9 @@ function gradebookHistoryTools(canvas, pseudonymizer) {
3613
3613
  title: "Get Gradebook History Feed",
3614
3614
  description: "Get the paginated gradebook history feed for a course, optionally filtered by assignment or user and optionally sorted oldest-first.",
3615
3615
  inputSchema: {
3616
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3617
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Optional Canvas assignment ID to filter the feed"),
3618
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Optional Canvas user ID to filter the feed"),
3616
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
3617
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Optional Canvas assignment ID to filter the feed"),
3618
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Optional Canvas user ID to filter the feed"),
3619
3619
  ascending: _zod.z.boolean().optional().describe("Set true to return the oldest gradebook history entries first")
3620
3620
  },
3621
3621
  annotations: {
@@ -3890,11 +3890,11 @@ function gradeExplanationTools(canvas, pseudonymizer) {
3890
3890
  title: "Explain Grade",
3891
3891
  description: "Recomputes and explains the weighted course grade for a student, including assignment-group weights, drop_lowest / drop_highest / never_drop rules, per-group breakdowns (earned points, dropped assignments, weighted contributions), the mapped letter grade (via the course grading standard when present), and a reconciliation check against Canvas's posted current_score / final_score.\n\nUse this when you need to verify that Canvas's displayed grade matches the rules, or to explain to a student or instructor how their grade was calculated.\n\nLimitations:\n- V1 computes one student per call. Omit student_id to compute for the authenticated user.\n- Instructor-applied curves and fudge points are not exposed via the Canvas REST API and cannot be reflected in the computation; a caveat is added when the discrepancy exceeds 0.5 pp.\n- When the course uses grading periods, reconciliation is against the overall (cross-period) grade.\n- When CANVAS_PSEUDONYMIZE_STUDENTS is enabled and you are passing a student_id, first call resolve_pseudonym to obtain the real Canvas user_id.",
3892
3892
  inputSchema: {
3893
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID to compute the grade for."),
3894
- student_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe(
3893
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID to compute the grade for."),
3894
+ student_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe(
3895
3895
  "Canvas user_id of the student to compute the grade for. Omit to compute for the currently authenticated user. Instructors may pass any enrolled student's user_id. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, pass the numeric Canvas user_id after resolving the pseudonym via resolve_pseudonym."
3896
3896
  ),
3897
- assignment_group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe(
3897
+ assignment_group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe(
3898
3898
  "Narrow the output to a single assignment group. When omitted all groups are included and the overall course grade is computed."
3899
3899
  )
3900
3900
  },
@@ -4130,7 +4130,7 @@ Limitations:
4130
4130
  - Late-submission penalties are not factored in.
4131
4131
  - V1 computes one student per call. Omit student_id to compute for the authenticated user. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, resolve the pseudonym first via resolve_pseudonym.`,
4132
4132
  inputSchema: {
4133
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe(
4133
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe(
4134
4134
  "Canvas course ID to compute the grade projection for."
4135
4135
  ),
4136
4136
  target_percentage: _zod.z.number().min(0).max(100).optional().describe(
@@ -4139,7 +4139,7 @@ Limitations:
4139
4139
  target_letter: _zod.z.string().optional().describe(
4140
4140
  'Target course grade as a letter (e.g. "A", "B+"). Requires the course to have a grading standard configured. Exactly one of target_percentage or target_letter must be provided. Case-insensitive.'
4141
4141
  ),
4142
- student_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe(
4142
+ student_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe(
4143
4143
  "Canvas user_id of the student to compute for. Omit to compute for the authenticated user. Instructors may pass any enrolled student's user_id. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, pass the numeric Canvas user_id after resolving the pseudonym via resolve_pseudonym."
4144
4144
  )
4145
4145
  },
@@ -4343,7 +4343,7 @@ function gradingPolicyTools(canvas) {
4343
4343
  title: "Explain Grading Policy",
4344
4344
  description: "Explains the grading automation rules configured for a Canvas course:\n- Missing-submission policy: whether blank/unsubmitted work is automatically scored 0 (or another deduction), or left unpenalised.\n- Late-submission policy: whether Canvas applies a per-day or per-hour percentage deduction to late submissions, and whether there is a floor below which the grade cannot fall.\n- Assignment-group weighting: whether the course uses weighted groups, and the weight of each group.\n- Grading scheme: whether a letter-grade scheme (A/B/C/F mapping) is applied to the final score.\n\nAlso returns a plain-language summary paragraph you can share with students or instructors.\n\nNote: the late/missing policy section requires instructor or admin permissions. Students receive the group-weighting and grading-scheme sections only, with a caveat noting what is unavailable. Use explain_grade to compute the actual weighted grade for a specific student.",
4345
4345
  inputSchema: {
4346
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID to explain the grading policy for.")
4346
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID to explain the grading policy for.")
4347
4347
  },
4348
4348
  annotations: {
4349
4349
  readOnlyHint: true,
@@ -4370,9 +4370,9 @@ function gradingPolicyTools(canvas) {
4370
4370
  latePolicySource = "api";
4371
4371
  } else {
4372
4372
  const err = latePolicyResult.reason;
4373
- if (err instanceof _chunkZT2BWA2Jcjs.CanvasApiError && err.status === 403) {
4373
+ if (err instanceof _chunk2RKEK44Ecjs.CanvasApiError && err.status === 403) {
4374
4374
  policyUnavailable = true;
4375
- } else if (err instanceof _chunkZT2BWA2Jcjs.CanvasApiError && err.status === 404) {
4375
+ } else if (err instanceof _chunk2RKEK44Ecjs.CanvasApiError && err.status === 404) {
4376
4376
  latePolicySource = "default";
4377
4377
  } else {
4378
4378
  throw err;
@@ -4402,7 +4402,7 @@ function gradingPolicyTools(canvas) {
4402
4402
  }
4403
4403
  }
4404
4404
  } catch (err) {
4405
- if (!(err instanceof _chunkZT2BWA2Jcjs.CanvasApiError)) throw err;
4405
+ if (!(err instanceof _chunk2RKEK44Ecjs.CanvasApiError)) throw err;
4406
4406
  if (err.status !== 403 && err.status !== 404) throw err;
4407
4407
  }
4408
4408
  if (standardTitle === null) {
@@ -4473,8 +4473,8 @@ function gradingStandardsTools(canvas) {
4473
4473
  title: "List Grading Standards",
4474
4474
  description: "List grading standards available in a course or account context. Provide either course_id (to see standards scoped to a course) or account_id (to see account-level standards, requires admin access). Returns an array of grading standard objects, each with an id, title, context, and grading_scheme array of { name, value } entries.",
4475
4475
  inputSchema: {
4476
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Course ID to list standards for (mutually exclusive with account_id)"),
4477
- account_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe(
4476
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Course ID to list standards for (mutually exclusive with account_id)"),
4477
+ account_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe(
4478
4478
  "Account ID to list standards for (mutually exclusive with course_id; requires admin)"
4479
4479
  )
4480
4480
  },
@@ -4502,8 +4502,8 @@ function gradingStandardsTools(canvas) {
4502
4502
  title: "Create Grading Standard",
4503
4503
  description: 'Create a new grading standard (letter-to-percentage scheme) in a course or account context. Provide either course_id or account_id (account requires admin). scheme_entries is an array of { name, value } objects where value is the lower-bound percentage as a fraction 0\u20131 (e.g. { name: "A", value: 0.94 } means A \u2265 94%). Entries will be sorted descending by value before sending to Canvas. Canvas POST body key is grading_scheme_entry (singular); the returned object uses grading_scheme (plural). Returns the created grading standard object including its id \u2014 use that id with apply_grading_standard_to_course to activate it on a course.',
4504
4504
  inputSchema: {
4505
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Course ID to create the standard in (mutually exclusive with account_id)"),
4506
- account_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe(
4505
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Course ID to create the standard in (mutually exclusive with account_id)"),
4506
+ account_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe(
4507
4507
  "Account ID to create the standard in (requires admin; mutually exclusive with course_id)"
4508
4508
  ),
4509
4509
  title: _zod.z.string().min(1).describe('Display name for this grading standard (e.g. "GPA 4.0 Scale")'),
@@ -4532,7 +4532,7 @@ function gradingStandardsTools(canvas) {
4532
4532
  }
4533
4533
  throw new Error("Provide either course_id or account_id.");
4534
4534
  } catch (error) {
4535
- if (error instanceof _chunkZT2BWA2Jcjs.CanvasApiError && error.status === 403 && courseId === void 0 && accountId !== void 0 && !error.message.toLowerCase().includes("rate limit exceeded")) {
4535
+ if (error instanceof _chunk2RKEK44Ecjs.CanvasApiError && error.status === 403 && courseId === void 0 && accountId !== void 0 && !error.message.toLowerCase().includes("rate limit exceeded")) {
4536
4536
  throw new Error(
4537
4537
  "Creating grading standards at the account level requires Canvas admin permissions. Try creating the standard in a course context instead (use course_id).",
4538
4538
  { cause: error }
@@ -4547,8 +4547,8 @@ function gradingStandardsTools(canvas) {
4547
4547
  title: "Apply Grading Standard to Course",
4548
4548
  description: "Apply an existing grading standard to a course so the gradebook uses it. Pass the grading_standard_id returned by create_grading_standard or list_grading_standards. Pass null for grading_standard_id to remove the current grading standard from the course. Returns the updated course object.",
4549
4549
  inputSchema: {
4550
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID to update"),
4551
- grading_standard_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).nullable().describe("The grading standard ID to apply, or null to remove the current standard")
4550
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID to update"),
4551
+ grading_standard_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).nullable().describe("The grading standard ID to apply, or null to remove the current standard")
4552
4552
  },
4553
4553
  annotations: {
4554
4554
  destructiveHint: true,
@@ -4575,7 +4575,7 @@ function groupTools(canvas, pseudonymizer) {
4575
4575
  title: "List Groups",
4576
4576
  description: "List all groups in a course.",
4577
4577
  inputSchema: {
4578
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
4578
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
4579
4579
  },
4580
4580
  annotations: {
4581
4581
  readOnlyHint: true,
@@ -4593,7 +4593,7 @@ function groupTools(canvas, pseudonymizer) {
4593
4593
  title: "List Group Members",
4594
4594
  description: "List all members of a group.",
4595
4595
  inputSchema: {
4596
- group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas group ID")
4596
+ group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas group ID")
4597
4597
  },
4598
4598
  annotations: {
4599
4599
  readOnlyHint: true,
@@ -4612,7 +4612,7 @@ function groupTools(canvas, pseudonymizer) {
4612
4612
  audience: "educator",
4613
4613
  description: "List the group categories (group sets) in a course. A group assignment points at a category through its group_category_id, and create_group needs a category ID, so use this to find one.",
4614
4614
  inputSchema: {
4615
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
4615
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
4616
4616
  },
4617
4617
  annotations: {
4618
4618
  readOnlyHint: true,
@@ -4629,7 +4629,7 @@ function groupTools(canvas, pseudonymizer) {
4629
4629
  audience: "educator",
4630
4630
  description: "Create a new, empty group category (group set) in a course.",
4631
4631
  inputSchema: {
4632
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4632
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4633
4633
  name: _zod.z.string().describe("Name of the group category")
4634
4634
  },
4635
4635
  annotations: {
@@ -4647,7 +4647,7 @@ function groupTools(canvas, pseudonymizer) {
4647
4647
  audience: "educator",
4648
4648
  description: "Create a group inside a group category. This is addressed by group_category_id, not by course ID: find the category with list_group_categories. The new group has no members; add them with add_group_member.",
4649
4649
  inputSchema: {
4650
- group_category_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe(
4650
+ group_category_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe(
4651
4651
  "The Canvas group category ID to create the group in (not a course ID)"
4652
4652
  ),
4653
4653
  name: _zod.z.string().describe("Name of the group"),
@@ -4676,7 +4676,7 @@ function groupTools(canvas, pseudonymizer) {
4676
4676
  audience: "educator",
4677
4677
  description: "Permanently delete a group and remove all of its members. The students stay enrolled in the course and the group category remains. Creating a group again does not restore the same group.",
4678
4678
  inputSchema: {
4679
- group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas group ID to delete")
4679
+ group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas group ID to delete")
4680
4680
  },
4681
4681
  annotations: {
4682
4682
  destructiveHint: true,
@@ -4694,8 +4694,8 @@ function groupTools(canvas, pseudonymizer) {
4694
4694
  audience: "educator",
4695
4695
  description: "Add a user to a group. Returns the membership Canvas reports; if the user is already a member, Canvas returns the existing membership. remove_group_member removes this membership; it does not restore any other group membership Canvas changed.",
4696
4696
  inputSchema: {
4697
- group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas group ID"),
4698
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID to add")
4697
+ group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas group ID"),
4698
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID to add")
4699
4699
  },
4700
4700
  annotations: {
4701
4701
  destructiveHint: true,
@@ -4714,8 +4714,8 @@ function groupTools(canvas, pseudonymizer) {
4714
4714
  audience: "educator",
4715
4715
  description: "Remove a user from a group. The user stays enrolled in the course. Reverse with add_group_member.",
4716
4716
  inputSchema: {
4717
- group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas group ID"),
4718
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID to remove")
4717
+ group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas group ID"),
4718
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID to remove")
4719
4719
  },
4720
4720
  annotations: {
4721
4721
  destructiveHint: true,
@@ -4761,7 +4761,7 @@ function moduleTools(canvas) {
4761
4761
  audience: "shared",
4762
4762
  description: "List all modules in a course.",
4763
4763
  inputSchema: {
4764
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
4764
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
4765
4765
  },
4766
4766
  annotations: {
4767
4767
  readOnlyHint: true,
@@ -4778,8 +4778,8 @@ function moduleTools(canvas) {
4778
4778
  audience: "shared",
4779
4779
  description: "Get details for a single module by ID.",
4780
4780
  inputSchema: {
4781
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4782
- module_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID")
4781
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4782
+ module_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID")
4783
4783
  },
4784
4784
  annotations: {
4785
4785
  readOnlyHint: true,
@@ -4797,8 +4797,8 @@ function moduleTools(canvas) {
4797
4797
  audience: "shared",
4798
4798
  description: "List all items within a module.",
4799
4799
  inputSchema: {
4800
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4801
- module_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID")
4800
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4801
+ module_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID")
4802
4802
  },
4803
4803
  annotations: {
4804
4804
  readOnlyHint: true,
@@ -4816,7 +4816,7 @@ function moduleTools(canvas) {
4816
4816
  audience: "shared",
4817
4817
  description: "Return the full module \u2192 items tree for a course in a single call, with summary stats. Avoids N+1 round-trips when an agent needs to reason over the whole course shape.",
4818
4818
  inputSchema: {
4819
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4819
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4820
4820
  include_published_only: _zod.z.boolean().optional().describe("When true, exclude unpublished items from each module (default: false)"),
4821
4821
  include_content_details: _zod.z.boolean().optional().describe(
4822
4822
  "When true, fetch content_details for each item (adds extra Canvas API data; default: false)"
@@ -4844,7 +4844,7 @@ function moduleTools(canvas) {
4844
4844
  audience: "shared",
4845
4845
  description: "Interactive tree view of a course's modules and items. Returns the same payload as `get_course_structure` and additionally links to an MCP Apps UI resource that renders an explorable tree with type filters and search. Hosts that do not support MCP Apps fall back to the JSON payload (same as `get_course_structure`).",
4846
4846
  inputSchema: {
4847
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4847
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4848
4848
  include_published_only: _zod.z.boolean().optional().describe("When true, exclude unpublished items (default: false)"),
4849
4849
  include_content_details: _zod.z.boolean().optional().describe("When true, fetch content_details for each item (default: false)")
4850
4850
  },
@@ -4873,11 +4873,11 @@ function moduleTools(canvas) {
4873
4873
  title: "Create Module",
4874
4874
  description: "Create a new module in a course.",
4875
4875
  inputSchema: {
4876
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4876
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4877
4877
  name: _zod.z.string().describe("Name of the module"),
4878
4878
  position: _zod.z.number().optional().describe("Position of the module in the list"),
4879
4879
  unlock_at: _zod.z.string().optional().describe("Date/time the module unlocks (ISO 8601)"),
4880
- prerequisite_module_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe("IDs of modules that must be completed before this one")
4880
+ prerequisite_module_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe("IDs of modules that must be completed before this one")
4881
4881
  },
4882
4882
  annotations: {
4883
4883
  destructiveHint: true,
@@ -4898,8 +4898,8 @@ function moduleTools(canvas) {
4898
4898
  title: "Update Module",
4899
4899
  description: "Update an existing module (rename, reposition, publish/unpublish).",
4900
4900
  inputSchema: {
4901
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4902
- module_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID"),
4901
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4902
+ module_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID"),
4903
4903
  name: _zod.z.string().optional().describe("New name for the module"),
4904
4904
  position: _zod.z.number().optional().describe("New position in the module list"),
4905
4905
  published: _zod.z.boolean().optional().describe("Whether the module is published")
@@ -4923,8 +4923,8 @@ function moduleTools(canvas) {
4923
4923
  title: "Delete Module",
4924
4924
  description: "Permanently delete a module from a course, including its ordered list of module items. Assignments, pages, quizzes, files and discussions that the items link to are stored separately in the course and this call does not delete them, but ExternalUrl, ExternalTool and SubHeader items exist only inside the module and go with it. There is no single inverse: rebuilding the module means create_module plus create_module_item for each item.",
4925
4925
  inputSchema: {
4926
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4927
- module_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID to delete")
4926
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4927
+ module_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID to delete")
4928
4928
  },
4929
4929
  annotations: {
4930
4930
  destructiveHint: true,
@@ -4942,8 +4942,8 @@ function moduleTools(canvas) {
4942
4942
  title: "Create Module Item",
4943
4943
  description: "Add an item (Assignment, Page, Quiz, File, Discussion, ExternalUrl, ExternalTool, SubHeader) to a module.",
4944
4944
  inputSchema: {
4945
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4946
- module_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID"),
4945
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4946
+ module_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID"),
4947
4947
  title: _zod.z.string().describe("Title of the module item"),
4948
4948
  type: _zod.z.enum([
4949
4949
  "File",
@@ -4955,7 +4955,7 @@ function moduleTools(canvas) {
4955
4955
  "ExternalTool",
4956
4956
  "SubHeader"
4957
4957
  ]).describe("Type of content to add"),
4958
- content_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Canvas ID of the content (required for File, Discussion, Assignment, Quiz)"),
4958
+ content_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Canvas ID of the content (required for File, Discussion, Assignment, Quiz)"),
4959
4959
  page_url: _zod.z.string().optional().describe("Page URL slug (required for Page items, which are addressed by slug, not ID)"),
4960
4960
  external_url: _zod.z.string().optional().describe("URL for ExternalUrl or ExternalTool items"),
4961
4961
  position: _zod.z.number().optional().describe("Position within the module")
@@ -4982,16 +4982,16 @@ function moduleTools(canvas) {
4982
4982
  title: "Update Module Item",
4983
4983
  description: "Edit an existing module item in place: rename it, repoint an ExternalUrl/ExternalTool item, reposition or re-indent it, publish/unpublish it, or move it to another module. ExternalUrl items exist only as module items, so a stale link carried in by a course copy can only be fixed here.",
4984
4984
  inputSchema: {
4985
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4986
- module_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID the item currently belongs to"),
4987
- item_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas module item ID"),
4985
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
4986
+ module_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID the item currently belongs to"),
4987
+ item_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas module item ID"),
4988
4988
  title: _zod.z.string().optional().describe("New title for the module item"),
4989
4989
  external_url: _zod.z.string().optional().describe("New URL for an ExternalUrl or ExternalTool item"),
4990
4990
  position: _zod.z.number().optional().describe("New 1-based position within the module"),
4991
4991
  indent: _zod.z.number().optional().describe("New indent level (0 = flush left)"),
4992
4992
  new_tab: _zod.z.boolean().optional().describe("Whether an external item opens in a new tab"),
4993
4993
  published: _zod.z.boolean().optional().describe("Whether the item is published"),
4994
- target_module_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Move the item to this module ID (omit to leave it where it is)")
4994
+ target_module_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Move the item to this module ID (omit to leave it where it is)")
4995
4995
  },
4996
4996
  annotations: {
4997
4997
  destructiveHint: true,
@@ -5010,9 +5010,9 @@ function moduleTools(canvas) {
5010
5010
  title: "Delete Module Item",
5011
5011
  description: "Remove an item from a module. For ExternalUrl, ExternalTool and SubHeader items the item is the content, so this deletes it outright; for Assignment, Page, Quiz, File and Discussion items it only unlinks the item and the underlying content survives. Re-add with create_module_item.",
5012
5012
  inputSchema: {
5013
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5014
- module_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID"),
5015
- item_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas module item ID to remove")
5013
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5014
+ module_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas module ID"),
5015
+ item_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas module item ID to remove")
5016
5016
  },
5017
5017
  annotations: {
5018
5018
  destructiveHint: true,
@@ -5038,8 +5038,8 @@ function outcomeTools(canvas, pseudonymizer) {
5038
5038
  title: "Get Root Outcome Group",
5039
5039
  description: "Get the root outcome group for an account or course context, the entry point into the outcome tree. Returns the top-level outcome group (id, title, subgroups_url, outcomes_url); walk from there with list_outcome_group_subgroups for its child groups and list_outcome_group_outcomes for outcomes linked directly under a group, or use list_outcome_groups for a flat listing of every group in the context instead of walking the tree.",
5040
5040
  inputSchema: {
5041
- context_type: _zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcomes from an account or course context."),
5042
- context_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID or course ID for the context.")
5041
+ context_type: _zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcomes from an account or course context."),
5042
+ context_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID or course ID for the context.")
5043
5043
  },
5044
5044
  annotations: { readOnlyHint: true, openWorldHint: true },
5045
5045
  handler: async (params) => canvas.outcomes.getRootOutcomeGroup(
@@ -5052,8 +5052,8 @@ function outcomeTools(canvas, pseudonymizer) {
5052
5052
  title: "List Outcome Groups",
5053
5053
  description: "List every outcome group in an account or course context as a flat array, not a tree. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Use get_root_outcome_group plus list_outcome_group_subgroups to walk the hierarchy instead, or get_outcome_group to fetch one group's details by ID.",
5054
5054
  inputSchema: {
5055
- context_type: _zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcome groups from an account or course context."),
5056
- context_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID or course ID for the context.")
5055
+ context_type: _zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcome groups from an account or course context."),
5056
+ context_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID or course ID for the context.")
5057
5057
  },
5058
5058
  annotations: { readOnlyHint: true, openWorldHint: true },
5059
5059
  handler: async (params) => canvas.outcomes.listOutcomeGroups(
@@ -5066,10 +5066,10 @@ function outcomeTools(canvas, pseudonymizer) {
5066
5066
  title: "List Outcome Group Links",
5067
5067
  description: `List every outcome link in an account or course context \u2014 the many-to-many join between outcome groups and the outcomes they contain, read from the context root, not one specific group. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Each link nests its outcome_group and outcome (full detail when outcome_style="full" / outcome_group_style="full", abbreviated otherwise); use list_outcome_group_outcomes instead to list only the outcomes linked directly under one specific outcome_group_id.`,
5068
5068
  inputSchema: {
5069
- context_type: _zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcome links from an account or course context."),
5070
- context_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID or course ID for the context."),
5071
- outcome_style: _zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_DETAIL_LEVELS).optional().describe('Outcome detail level. Use "full" to include expanded outcome fields.'),
5072
- outcome_group_style: _zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_DETAIL_LEVELS).optional().describe(
5069
+ context_type: _zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcome links from an account or course context."),
5070
+ context_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID or course ID for the context."),
5071
+ outcome_style: _zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_DETAIL_LEVELS).optional().describe('Outcome detail level. Use "full" to include expanded outcome fields.'),
5072
+ outcome_group_style: _zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_DETAIL_LEVELS).optional().describe(
5073
5073
  'Outcome group detail level. Use "full" to include expanded outcome group fields.'
5074
5074
  )
5075
5075
  },
@@ -5088,9 +5088,9 @@ function outcomeTools(canvas, pseudonymizer) {
5088
5088
  title: "Get Outcome Group",
5089
5089
  description: "Get the full details for one outcome group by outcome_group_id within an account or course context, including its subgroups_url and outcomes_url. The ID comes from list_outcome_groups, list_outcome_group_subgroups, or get_root_outcome_group; use list_outcome_group_outcomes to list the outcomes linked under this group and list_outcome_group_subgroups to list this group's child groups.",
5090
5090
  inputSchema: {
5091
- context_type: _zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
5092
- context_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID or course ID for the context."),
5093
- outcome_group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas outcome group ID.")
5091
+ context_type: _zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
5092
+ context_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID or course ID for the context."),
5093
+ outcome_group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas outcome group ID.")
5094
5094
  },
5095
5095
  annotations: { readOnlyHint: true, openWorldHint: true },
5096
5096
  handler: async (params) => canvas.outcomes.getOutcomeGroup(
@@ -5104,10 +5104,10 @@ function outcomeTools(canvas, pseudonymizer) {
5104
5104
  title: "List Outcome Group Outcomes",
5105
5105
  description: `List the outcomes linked directly under one outcome group (outcome_group_id), not its subgroups' outcomes. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Each link nests the outcome (full detail when outcome_style="full", abbreviated otherwise); use list_outcome_group_subgroups to descend into child groups first, or get_outcome for one outcome's full detail by outcome_id.`,
5106
5106
  inputSchema: {
5107
- context_type: _zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
5108
- context_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID or course ID for the context."),
5109
- outcome_group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas outcome group ID."),
5110
- outcome_style: _zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_DETAIL_LEVELS).optional().describe('Outcome detail level. Use "full" to include expanded outcome fields.')
5107
+ context_type: _zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
5108
+ context_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID or course ID for the context."),
5109
+ outcome_group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas outcome group ID."),
5110
+ outcome_style: _zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_DETAIL_LEVELS).optional().describe('Outcome detail level. Use "full" to include expanded outcome fields.')
5111
5111
  },
5112
5112
  annotations: { readOnlyHint: true, openWorldHint: true },
5113
5113
  handler: async (params) => canvas.outcomes.listGroupOutcomes(
@@ -5124,9 +5124,9 @@ function outcomeTools(canvas, pseudonymizer) {
5124
5124
  title: "List Outcome Group Subgroups",
5125
5125
  description: "List the immediate child outcome groups under one outcome group (outcome_group_id) \u2014 one level of the tree, not a recursive walk. Fetches every page (100 per request) and fails with a 'Results are incomplete' error instead of silently truncating. Call this again with each returned group's id to descend further, or use list_outcome_group_outcomes on the same outcome_group_id to list outcomes linked directly under it instead of its child groups.",
5126
5126
  inputSchema: {
5127
- context_type: _zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
5128
- context_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID or course ID for the context."),
5129
- outcome_group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas outcome group ID.")
5127
+ context_type: _zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
5128
+ context_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID or course ID for the context."),
5129
+ outcome_group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas outcome group ID.")
5130
5130
  },
5131
5131
  annotations: { readOnlyHint: true, openWorldHint: true },
5132
5132
  handler: async (params) => canvas.outcomes.listGroupSubgroups(
@@ -5140,7 +5140,7 @@ function outcomeTools(canvas, pseudonymizer) {
5140
5140
  title: "Get Outcome",
5141
5141
  description: "Get the full details for one learning outcome by outcome_id, including its rating criteria, mastery_points, and calculation_method. The outcome_id comes from list_outcome_group_outcomes, list_outcome_group_links, or get_outcome_results' / get_outcome_rollups' linked.outcomes; get_outcome_alignments lists all alignments in the course (not scoped to one outcome) \u2014 cross-reference via get_outcome_results instead to tie an alignment to this outcome_id.",
5142
5142
  inputSchema: {
5143
- outcome_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas outcome ID."),
5143
+ outcome_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas outcome ID."),
5144
5144
  add_defaults: _zod.z.boolean().optional().describe("Include default mastery colors and levels when Canvas supports it.")
5145
5145
  },
5146
5146
  annotations: { readOnlyHint: true, openWorldHint: true },
@@ -5153,9 +5153,9 @@ function outcomeTools(canvas, pseudonymizer) {
5153
5153
  title: "Get Outcome Alignments",
5154
5154
  description: "Get the assignments aligned to outcomes in a course, optionally filtered to one student_id or assignment_id. Returns each alignment's assignment_id and title, but not the outcome_id it maps to. get_outcome_results nests the same alignment objects under linked.alignments, but ties an alignment to an outcome via each outcome_results[] entry's links.alignment and links.learning_outcome, not from linked.alignments alone. Use get_outcome_contributing_scores to see the assignment scores that produced an outcome's results instead of just the links.",
5155
5155
  inputSchema: {
5156
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID."),
5157
- student_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Optional Canvas user ID of the student to filter alignments by."),
5158
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Optional Canvas assignment ID to filter alignments by.")
5156
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID."),
5157
+ student_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Optional Canvas user ID of the student to filter alignments by."),
5158
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Optional Canvas assignment ID to filter alignments by.")
5159
5159
  },
5160
5160
  annotations: { readOnlyHint: true, openWorldHint: true },
5161
5161
  handler: async (params) => canvas.outcomes.getOutcomeAlignments(params.course_id, {
@@ -5168,11 +5168,11 @@ function outcomeTools(canvas, pseudonymizer) {
5168
5168
  title: "Get Outcome Results",
5169
5169
  description: "Get raw per-student, per-alignment outcome results for a course (one score per assessed alignment, not aggregated), optionally filtered by user_ids, outcome_ids, and include_hidden. Set include_alignments to nest the matching alignments under linked.alignments. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, linked.users entries are anonymized; use resolve_pseudonym to map one back to a real user. Use get_outcome_rollups instead for aggregated scores per student and outcome, or get_outcome_contributing_scores for the assignment or quiz scores behind one outcome.",
5170
5170
  inputSchema: {
5171
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID."),
5172
- user_ids: _chunkDEFB5PL2cjs.canvasIdList.call(void 0, { prefixes: ["sis_user_id"] }).optional().describe(
5171
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID."),
5172
+ user_ids: _chunk3X2VLRJJcjs.canvasIdList.call(void 0, { prefixes: ["sis_user_id"] }).optional().describe(
5173
5173
  'Optional Canvas user IDs (pass large IDs as strings) or SIS user IDs prefixed with "sis_user_id:".'
5174
5174
  ),
5175
- outcome_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe("Optional outcome IDs to restrict the results."),
5175
+ outcome_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe("Optional outcome IDs to restrict the results."),
5176
5176
  include_alignments: _zod.z.boolean().optional().describe("Include linked alignment details in the response."),
5177
5177
  include_hidden: _zod.z.boolean().optional().describe("Include hidden outcomes when Canvas supports it.")
5178
5178
  },
@@ -5194,18 +5194,18 @@ function outcomeTools(canvas, pseudonymizer) {
5194
5194
  title: "Get Outcome Rollups",
5195
5195
  description: `Get aggregated outcome rollups for a course \u2014 one score per student per outcome, or, with aggregate="course", a single course-level mean or median \u2014 optionally filtered by user_ids and outcome_ids and sorted by student or by one outcome's score. Set include_courses to nest course details under linked.courses. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, linked.users entries are anonymized; use resolve_pseudonym to map one back to a real user. Use get_outcome_results instead for the raw per-alignment scores behind a rollup, or get_outcome_mastery_distribution for a mastery-level histogram across students.`,
5196
5196
  inputSchema: {
5197
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID."),
5197
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID."),
5198
5198
  aggregate: _zod.z.enum(["course"]).optional().describe("Aggregate all student rollups into a single course-level rollup."),
5199
- aggregate_stat: _zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_ROLLUP_AGGREGATE_STATS).optional().describe('Statistic to use when aggregate="course".'),
5200
- user_ids: _chunkDEFB5PL2cjs.canvasIdList.call(void 0, { prefixes: ["sis_user_id"] }).optional().describe(
5199
+ aggregate_stat: _zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_ROLLUP_AGGREGATE_STATS).optional().describe('Statistic to use when aggregate="course".'),
5200
+ user_ids: _chunk3X2VLRJJcjs.canvasIdList.call(void 0, { prefixes: ["sis_user_id"] }).optional().describe(
5201
5201
  'Optional Canvas user IDs (pass large IDs as strings) or SIS user IDs prefixed with "sis_user_id:".'
5202
5202
  ),
5203
- outcome_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe("Optional outcome IDs to restrict the rollups."),
5203
+ outcome_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe("Optional outcome IDs to restrict the rollups."),
5204
5204
  include_courses: _zod.z.boolean().optional().describe("Include linked course details in the response payload."),
5205
- exclude: _zod.z.array(_zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_EXCLUDE_OPTIONS)).optional().describe("Optional rollup exclusions for missing users or missing outcome results."),
5206
- sort_by: _zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_ROLLUP_SORT_BY).optional().describe("Sort rollups by student name or by a specific outcome score."),
5207
- sort_outcome_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe('Outcome ID to sort by when sort_by="outcome".'),
5208
- sort_order: _zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_SORT_ORDER).optional().describe("Sort order to apply when sorting rollups."),
5205
+ exclude: _zod.z.array(_zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_EXCLUDE_OPTIONS)).optional().describe("Optional rollup exclusions for missing users or missing outcome results."),
5206
+ sort_by: _zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_ROLLUP_SORT_BY).optional().describe("Sort rollups by student name or by a specific outcome score."),
5207
+ sort_outcome_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe('Outcome ID to sort by when sort_by="outcome".'),
5208
+ sort_order: _zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_SORT_ORDER).optional().describe("Sort order to apply when sorting rollups."),
5209
5209
  add_defaults: _zod.z.boolean().optional().describe("Include default mastery colors and levels when Canvas supports it.")
5210
5210
  },
5211
5211
  annotations: { readOnlyHint: true, openWorldHint: true },
@@ -5232,9 +5232,9 @@ function outcomeTools(canvas, pseudonymizer) {
5232
5232
  title: "Get Outcome Contributing Scores",
5233
5233
  description: "Get the assignment or quiz scores that contributed to one outcome_id's results for one or more students in a course, optionally restricted to assignment alignments only or including unpublished assignments. Use get_outcome_results instead for the final per-alignment outcome score rather than the scores that fed it, or get_outcome_alignments to list all alignments in the course (not scoped to this outcome) without their scores.",
5234
5234
  inputSchema: {
5235
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID."),
5236
- outcome_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas outcome ID."),
5237
- user_ids: _chunkDEFB5PL2cjs.canvasIdList.call(void 0, { prefixes: ["sis_user_id"] }).optional().describe(
5235
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID."),
5236
+ outcome_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas outcome ID."),
5237
+ user_ids: _chunk3X2VLRJJcjs.canvasIdList.call(void 0, { prefixes: ["sis_user_id"] }).optional().describe(
5238
5238
  'Optional Canvas user IDs (pass large IDs as strings) or SIS user IDs prefixed with "sis_user_id:".'
5239
5239
  ),
5240
5240
  only_assignment_alignments: _zod.z.boolean().optional().describe("Limit results to assignment alignments only."),
@@ -5256,10 +5256,10 @@ function outcomeTools(canvas, pseudonymizer) {
5256
5256
  title: "Get Outcome Mastery Distribution",
5257
5257
  description: "Get a mastery-level histogram for outcomes in a course \u2014 how many students fall into each rating band \u2014 optionally filtered by outcome_ids and student_ids and excluding missing user rollups or missing outcome results. Set include_alignment_distributions to also break down scores by contributing alignment. Use get_outcome_rollups instead for each student's individual aggregated score, or get_outcome_results for the raw per-alignment scores.",
5258
5258
  inputSchema: {
5259
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID."),
5260
- exclude: _zod.z.array(_zod.z.enum(_chunkDEFB5PL2cjs.OUTCOME_EXCLUDE_OPTIONS)).optional().describe("Optional exclusions for missing users or missing outcome results."),
5261
- outcome_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe("Optional outcome IDs to restrict the distribution results."),
5262
- student_ids: _chunkDEFB5PL2cjs.canvasIdList.call(void 0, { prefixes: ["sis_user_id"] }).optional().describe(
5259
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID."),
5260
+ exclude: _zod.z.array(_zod.z.enum(_chunk3X2VLRJJcjs.OUTCOME_EXCLUDE_OPTIONS)).optional().describe("Optional exclusions for missing users or missing outcome results."),
5261
+ outcome_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe("Optional outcome IDs to restrict the distribution results."),
5262
+ student_ids: _chunk3X2VLRJJcjs.canvasIdList.call(void 0, { prefixes: ["sis_user_id"] }).optional().describe(
5263
5263
  'Optional Canvas student IDs (pass large IDs as strings) or SIS user IDs prefixed with "sis_user_id:".'
5264
5264
  ),
5265
5265
  include_alignment_distributions: _zod.z.boolean().optional().describe("Include contributing score distributions for alignments."),
@@ -5353,7 +5353,7 @@ function pageTools(canvas) {
5353
5353
  audience: "shared",
5354
5354
  description: "List all wiki pages in a course.",
5355
5355
  inputSchema: {
5356
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
5356
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
5357
5357
  },
5358
5358
  output: listOutput("pages", canvasPageSchema),
5359
5359
  annotations: {
@@ -5371,7 +5371,7 @@ function pageTools(canvas) {
5371
5371
  audience: "shared",
5372
5372
  description: "Get a single wiki page by its URL slug.",
5373
5373
  inputSchema: {
5374
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5374
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5375
5375
  page_url: _zod.z.string().describe('The page URL slug (e.g. "welcome-page")')
5376
5376
  },
5377
5377
  output: objectOutput(canvasPageSchema),
@@ -5390,7 +5390,7 @@ function pageTools(canvas) {
5390
5390
  title: "Create Page",
5391
5391
  description: "Create a new wiki page in a course.",
5392
5392
  inputSchema: {
5393
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5393
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5394
5394
  title: _zod.z.string().describe("Title of the page"),
5395
5395
  body: _zod.z.string().optional().describe("HTML body content of the page"),
5396
5396
  published: _zod.z.boolean().optional().describe("Whether the page is published"),
@@ -5416,7 +5416,7 @@ function pageTools(canvas) {
5416
5416
  title: "Update Page",
5417
5417
  description: "Update an existing wiki page.",
5418
5418
  inputSchema: {
5419
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5419
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5420
5420
  page_url: _zod.z.string().describe("The page URL slug"),
5421
5421
  title: _zod.z.string().optional().describe("New title for the page"),
5422
5422
  body: _zod.z.string().optional().describe("New HTML body content"),
@@ -5444,7 +5444,7 @@ function pageTools(canvas) {
5444
5444
  title: "Delete Page",
5445
5445
  description: "Delete a wiki page from a course. This action is permanent.",
5446
5446
  inputSchema: {
5447
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5447
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5448
5448
  page_url: _zod.z.string().describe("The page URL slug to delete")
5449
5449
  },
5450
5450
  output: objectOutput(pageDeletionSchema),
@@ -5470,8 +5470,8 @@ function peerReviewTools(canvas) {
5470
5470
  title: "List Peer Reviews",
5471
5471
  description: "List all peer reviews for an assignment in a course.",
5472
5472
  inputSchema: {
5473
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5474
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID")
5473
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5474
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID")
5475
5475
  },
5476
5476
  annotations: {
5477
5477
  readOnlyHint: true,
@@ -5488,9 +5488,9 @@ function peerReviewTools(canvas) {
5488
5488
  title: "Get Submission Peer Reviews",
5489
5489
  description: "List peer reviews assigned to a specific submission.",
5490
5490
  inputSchema: {
5491
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5492
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
5493
- submission_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas submission ID")
5491
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5492
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
5493
+ submission_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas submission ID")
5494
5494
  },
5495
5495
  annotations: {
5496
5496
  readOnlyHint: true,
@@ -5509,10 +5509,10 @@ function peerReviewTools(canvas) {
5509
5509
  audience: "educator",
5510
5510
  description: `Assign a Canvas user as a peer reviewer for one submission, and return the created peer review object (id, assessor_id, user_id, asset_id, workflow_state). The user_id parameter you pass is the reviewer being assigned; in the returned object assessor_id holds that same reviewer, while the response's own user_id field instead identifies the submission owner (the reviewee) \u2014 the two user_id values are not the same person. The new review starts in workflow_state "assigned". submission_id must already exist on this assignment. Use list_peer_reviews to see every review assigned on the whole assignment, or get_submission_peer_reviews to see only the reviews assigned to one submission, before assigning another reviewer; use delete_peer_review to unassign one. Requires instructor/TA permission in the course.`,
5511
5511
  inputSchema: {
5512
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5513
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
5514
- submission_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas submission ID"),
5515
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID of the reviewer to assign")
5512
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5513
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
5514
+ submission_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas submission ID"),
5515
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID of the reviewer to assign")
5516
5516
  },
5517
5517
  annotations: {
5518
5518
  destructiveHint: true,
@@ -5532,10 +5532,10 @@ function peerReviewTools(canvas) {
5532
5532
  audience: "educator",
5533
5533
  description: "Remove a peer review assignment from a submission. This action is permanent.",
5534
5534
  inputSchema: {
5535
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5536
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
5537
- submission_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas submission ID"),
5538
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID of the reviewer to remove")
5535
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5536
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
5537
+ submission_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas submission ID"),
5538
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID of the reviewer to remove")
5539
5539
  },
5540
5540
  annotations: {
5541
5541
  destructiveHint: true,
@@ -5562,7 +5562,7 @@ function quizTools(canvas) {
5562
5562
  audience: "shared",
5563
5563
  description: "List all quizzes in a course.",
5564
5564
  inputSchema: {
5565
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
5565
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
5566
5566
  },
5567
5567
  annotations: {
5568
5568
  readOnlyHint: true,
@@ -5579,8 +5579,8 @@ function quizTools(canvas) {
5579
5579
  audience: "shared",
5580
5580
  description: "Get details for a single quiz by ID.",
5581
5581
  inputSchema: {
5582
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5583
- quiz_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID")
5582
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5583
+ quiz_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID")
5584
5584
  },
5585
5585
  annotations: {
5586
5586
  readOnlyHint: true,
@@ -5597,8 +5597,8 @@ function quizTools(canvas) {
5597
5597
  title: "List Quiz Submissions",
5598
5598
  description: "List all submissions for a quiz.",
5599
5599
  inputSchema: {
5600
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5601
- quiz_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID")
5600
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5601
+ quiz_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID")
5602
5602
  },
5603
5603
  annotations: {
5604
5604
  readOnlyHint: true,
@@ -5615,8 +5615,8 @@ function quizTools(canvas) {
5615
5615
  title: "List Quiz Questions",
5616
5616
  description: "List all questions in a quiz.",
5617
5617
  inputSchema: {
5618
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5619
- quiz_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID")
5618
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5619
+ quiz_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID")
5620
5620
  },
5621
5621
  annotations: {
5622
5622
  readOnlyHint: true,
@@ -5633,7 +5633,7 @@ function quizTools(canvas) {
5633
5633
  title: "Get Quiz Submission Answers",
5634
5634
  description: "Get a quiz submission's state for an IN-PROGRESS (untaken) attempt, including the student's live answer and flag per question. For a SUBMITTED attempt (complete or pending_review), Canvas never returns the answer value or a real flag state through this endpoint \u2014 only grading state (correct) is available here. To review a submitted attempt's actual answer text, use get_quiz_question_responses instead.",
5635
5635
  inputSchema: {
5636
- quiz_submission_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz submission ID")
5636
+ quiz_submission_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz submission ID")
5637
5637
  },
5638
5638
  annotations: {
5639
5639
  readOnlyHint: true,
@@ -5649,10 +5649,10 @@ function quizTools(canvas) {
5649
5649
  title: "Score Quiz Question",
5650
5650
  description: "Score a specific question in a quiz submission. Specify attempt to score a particular attempt (omit for latest). Requires grading permissions.",
5651
5651
  inputSchema: {
5652
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5653
- quiz_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID"),
5654
- submission_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz submission ID"),
5655
- question_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz question ID"),
5652
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5653
+ quiz_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID"),
5654
+ submission_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz submission ID"),
5655
+ question_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz question ID"),
5656
5656
  score: _zod.z.number().describe("The score to assign"),
5657
5657
  comment: _zod.z.string().optional().describe("Optional feedback comment"),
5658
5658
  attempt: _zod.z.number().optional().describe("Quiz attempt number to score (omit for latest)")
@@ -5692,9 +5692,9 @@ function quizTools(canvas) {
5692
5692
  audience: "shared",
5693
5693
  description: `Get the event log for a Classic Quiz submission in chronological order. Events include session_started, question_answered, question_flagged, page_blurred, and page_focused. Use this to understand the timeline of a student's attempt. Classic Quizzes only \u2014 New Quizzes does not expose event logs via the Canvas REST API. Events are scoped to a single submission; Canvas enforces access permissions (instructors and the submitting student only). Do not use event logs as the sole basis for academic-integrity conclusions; present them with context.`,
5694
5694
  inputSchema: {
5695
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5696
- quiz_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID (Classic Quizzes only)"),
5697
- submission_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The quiz submission ID"),
5695
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5696
+ quiz_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID (Classic Quizzes only)"),
5697
+ submission_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The quiz submission ID"),
5698
5698
  attempt: _zod.z.number().int().positive().optional().describe("Attempt number (1-based). Omit for the most recent attempt.")
5699
5699
  },
5700
5700
  annotations: {
@@ -5714,8 +5714,8 @@ function quizTools(canvas) {
5714
5714
  title: "Delete Quiz",
5715
5715
  description: "Permanently delete a Classic quiz from a course, including its questions and every student submission. Classic Quizzes only; use delete_new_quiz for a New Quiz (LTI).",
5716
5716
  inputSchema: {
5717
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5718
- quiz_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID to delete (Classic Quizzes only)")
5717
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5718
+ quiz_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID to delete (Classic Quizzes only)")
5719
5719
  },
5720
5720
  annotations: { destructiveHint: true, idempotentHint: true, openWorldHint: true },
5721
5721
  handler: async (params) => {
@@ -5729,9 +5729,9 @@ function quizTools(canvas) {
5729
5729
  title: "Delete Quiz Question",
5730
5730
  description: "Permanently delete a single question from a Classic quiz. Classic Quizzes only; use delete_new_quiz_item for a New Quiz item.",
5731
5731
  inputSchema: {
5732
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5733
- quiz_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID (Classic Quizzes only)"),
5734
- question_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz question ID to delete")
5732
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5733
+ quiz_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID (Classic Quizzes only)"),
5734
+ question_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz question ID to delete")
5735
5735
  },
5736
5736
  annotations: { destructiveHint: true, idempotentHint: true, openWorldHint: true },
5737
5737
  handler: async (params) => {
@@ -5865,9 +5865,9 @@ function quizQuestionResponseTools(canvas, pseudonymizer) {
5865
5865
  title: "Get Quiz Question Responses",
5866
5866
  description: `Review every student's answer to one or all questions in a Classic Quiz, pivoted by question instead of by student \u2014 for grading essay/short-answer/file-upload questions consistently across a class instead of paging through SpeedGrader one student at a time. Classic Quizzes only (quiz_type: assignment, practice_quiz, graded_survey, survey) \u2014 New Quizzes exposes responses through a different API. Omit question_id to get every question; provide it to scope to one. Each question reports needs_manual_grading (true for essay and file-upload questions) and points_possible. Questions drawn from a question bank are included: Canvas stores each draw as a generated question that the quiz's question list omits, so they are resolved from the students' own attempts, listed after the quiz's fixed questions, and report position: null. Each response reports the raw Canvas correctness value plus a derived scoring_state (correct / incorrect / partial / not_scored / awaiting_manual_grading / graded / unscored) so "undefined" is never read as an answer. Scans one Canvas API call per completed or pending-review submission, plus one per attempt needed to resolve bank-drawn questions, plus one paginated call to fetch every student's submitted answer text for the quiz (skipped, with answer_text_available: false and a reason, when the quiz has no assignment, is an anonymous survey, or the fetch fails). A failed per-submission answers fetch is recorded in submissions_failed, and a response whose question cannot be resolved is counted in unmatched_response_count and unmatched_question_ids, rather than aborting the whole call. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, student names are replaced with stable pseudonyms; essay/short-answer prose is student-authored text and may itself contain a real name, which pseudonymization of structured fields cannot strip.`,
5867
5867
  inputSchema: {
5868
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5869
- quiz_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID (Classic Quizzes only)"),
5870
- question_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe(
5868
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
5869
+ quiz_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas quiz ID (Classic Quizzes only)"),
5870
+ question_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe(
5871
5871
  "Scope the result to a single question ID (from list_quiz_questions, or a bank-drawn question_id returned by this tool). Omit to return every question with every student's response."
5872
5872
  )
5873
5873
  },
@@ -5936,7 +5936,7 @@ function quizQuestionResponseTools(canvas, pseudonymizer) {
5936
5936
  answersBySubmission,
5937
5937
  missing
5938
5938
  );
5939
- for (const question of resolved.sort((a, b) => _chunkDEFB5PL2cjs.compareCanvasIds.call(void 0, a.id, b.id))) {
5939
+ for (const question of resolved.sort((a, b) => _chunk3X2VLRJJcjs.compareCanvasIds.call(void 0, a.id, b.id))) {
5940
5940
  groups.set(question.id, toGroup(question, null));
5941
5941
  }
5942
5942
  }
@@ -5979,7 +5979,7 @@ function quizQuestionResponseTools(canvas, pseudonymizer) {
5979
5979
  unmatched_response_count: unmatchedResponseCount,
5980
5980
  // `a - b` would round both operands above 2**53 and can report two
5981
5981
  // distinct ids as equal (BRU-2730 §4.4).
5982
- unmatched_question_ids: [...unmatchedQuestionIds].sort(_chunkDEFB5PL2cjs.compareCanvasIds),
5982
+ unmatched_question_ids: [...unmatchedQuestionIds].sort(_chunk3X2VLRJJcjs.compareCanvasIds),
5983
5983
  answer_text_available: answerTextUnavailableReason === null,
5984
5984
  answer_text_unavailable_reason: answerTextUnavailableReason
5985
5985
  };
@@ -5998,8 +5998,8 @@ function quizAccommodationTools(canvas) {
5998
5998
  title: "Set Student Quiz Accommodation",
5999
5999
  description: "Apply extra time and/or extra attempts to a specific student across all Classic Quizzes in a course (or a specified subset). Fans out to the Canvas quiz extensions API for each quiz. New Quizzes (quiz_type quizzes.next) are skipped \u2014 use set_student_new_quiz_accommodation instead. Only applies to quizzes that exist at call time; re-run after creating new quizzes. Assignment due-date overrides are not handled here (separate fast-follow feature). Note: for courses with many quizzes this makes one Canvas API call per quiz. Partial failures are tolerated \u2014 a failure on one quiz does not abort the rest. Returns the standard fan-out envelope: separated applied[], skipped[] (each with a skip_reason), and failed[] (each with an error) arrays, a not_found list of any requested quiz_ids absent from the course, and a summary of counts. Provide user_id as the real Canvas user ID. If CANVAS_PSEUDONYMIZE_STUDENTS is enabled, call resolve_pseudonym first to obtain the real user_id from a pseudonym.",
6000
6000
  inputSchema: {
6001
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
6002
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Real Canvas user ID of the student to accommodate"),
6001
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
6002
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Real Canvas user ID of the student to accommodate"),
6003
6003
  extra_time_minutes: _zod.z.number().int().positive().optional().describe(
6004
6004
  "Absolute extra time in minutes to add to each quiz. Mutually exclusive with time_multiplier."
6005
6005
  ),
@@ -6007,7 +6007,7 @@ function quizAccommodationTools(canvas) {
6007
6007
  "Relative time multiplier (e.g. 1.5 for 1.5\xD7 time). extra_minutes = round(quiz.time_limit * (multiplier - 1)), minimum 1 minute. Quizzes with no time limit are skipped for extra_time (extra_attempts is still applied if provided). Mutually exclusive with extra_time_minutes."
6008
6008
  ),
6009
6009
  extra_attempts: _zod.z.number().int().min(1).optional().describe("Additional attempts to grant beyond the quiz default."),
6010
- quiz_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe(
6010
+ quiz_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe(
6011
6011
  "Limit accommodation to these specific quiz IDs. Omit to target all Classic Quizzes in the course."
6012
6012
  )
6013
6013
  },
@@ -6103,8 +6103,8 @@ function quizAccommodationTools(canvas) {
6103
6103
  title: "List Student Quiz Accommodations",
6104
6104
  description: "List the current quiz accommodation (extra time and/or extra attempts) for a specific student across all Classic Quizzes in a course. Useful for auditing before or after calling set_student_quiz_accommodation. New Quizzes (quiz_type quizzes.next) are excluded. Reads extra_time / extra_attempts from each quiz's submission records (Canvas exposes no read endpoint for quiz extensions directly) \u2014 one Canvas API call per Classic Quiz, so it may be slow for courses with many quizzes. Errors from any quiz's read propagate immediately (no per-quiz error catching). Provide user_id as the real Canvas user ID. If CANVAS_PSEUDONYMIZE_STUDENTS is enabled, call resolve_pseudonym first.",
6105
6105
  inputSchema: {
6106
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
6107
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Real Canvas user ID of the student")
6106
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
6107
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Real Canvas user ID of the student")
6108
6108
  },
6109
6109
  annotations: {
6110
6110
  readOnlyHint: true,
@@ -6154,13 +6154,13 @@ function newQuizAccommodationTools(canvas) {
6154
6154
  title: "Set Student New Quiz Accommodation",
6155
6155
  description: 'Apply a time and/or attempts accommodation for a student across all New Quizzes in a course (course-level, single Canvas API call when no assignment_ids are given) or for a specified subset of New Quizzes (per-quiz fan-out when assignment_ids are given). New Quizzes use a time_multiplier (ratio, e.g. 1.5 for 1.5\xD7 time), not absolute minutes. For Classic Quizzes (quiz_type: assignment / practice_quiz / etc.) use set_student_quiz_accommodation instead. Partial per-quiz failures are tolerated \u2014 a failure on one quiz does not abort the rest. In per-quiz mode, fan-out is sequential (one Canvas API call per assignment ID, awaited in series). Canvas errors on the course-level path (no assignment_ids) propagate as a top-level error (no envelope). Returns a uniform envelope: scope ("course" or "per_quiz"), applied[], failed[], and summary. Provide user_id as the real Canvas user ID. If CANVAS_PSEUDONYMIZE_STUDENTS is enabled, call resolve_pseudonym first to obtain the real user_id from a pseudonym.',
6156
6156
  inputSchema: {
6157
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
6158
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Real Canvas user ID of the student to accommodate"),
6157
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
6158
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Real Canvas user ID of the student to accommodate"),
6159
6159
  time_multiplier: _zod.z.number().min(1.01).optional().describe(
6160
6160
  "Time multiplier for New Quizzes (e.g. 1.5 for 1.5\xD7 time, 2.0 for double time). This is the native New Quizzes field; Canvas applies it to each quiz's time limit. Must be > 1.0. Mutually exclusive with nothing \u2014 can be combined with extra_attempts."
6161
6161
  ),
6162
6162
  extra_attempts: _zod.z.number().int().min(1).optional().describe("Additional attempts to grant beyond each quiz's default attempt limit."),
6163
- assignment_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe(
6163
+ assignment_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe(
6164
6164
  "Limit accommodation to these specific New Quiz assignment IDs. Omit to apply a course-level accommodation (covers all New Quizzes in the course with a single Canvas API call). When provided, fans out one call per assignment ID."
6165
6165
  )
6166
6166
  },
@@ -6213,7 +6213,7 @@ function newQuizAccommodationTools(canvas) {
6213
6213
  extra_attempts: record.extra_attempts
6214
6214
  });
6215
6215
  } catch (err) {
6216
- const message = err instanceof _chunkZT2BWA2Jcjs.CanvasApiError ? err.message : "Unknown error";
6216
+ const message = err instanceof _chunk2RKEK44Ecjs.CanvasApiError ? err.message : "Unknown error";
6217
6217
  failed.push({
6218
6218
  assignment_id: assignmentId,
6219
6219
  time_multiplier: null,
@@ -6235,8 +6235,8 @@ function newQuizAccommodationTools(canvas) {
6235
6235
  title: "List Student New Quiz Accommodations",
6236
6236
  description: 'Read the current course-level New Quizzes accommodation (time multiplier and/or extra attempts) for a specific student in a course. Useful for auditing before or after calling set_student_new_quiz_accommodation. Returns has_accommodation: false when no accommodation is set (Canvas 404 is treated as "no record", not an error). New Quizzes store a single course-level accommodation record per student; this is not per-quiz. For Classic Quizzes, use list_student_quiz_accommodations instead. Provide user_id as the real Canvas user ID. If CANVAS_PSEUDONYMIZE_STUDENTS is enabled, call resolve_pseudonym first.',
6237
6237
  inputSchema: {
6238
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
6239
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Real Canvas user ID of the student")
6238
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
6239
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Real Canvas user ID of the student")
6240
6240
  },
6241
6241
  annotations: {
6242
6242
  readOnlyHint: true,
@@ -6329,7 +6329,7 @@ function newQuizTools(canvas) {
6329
6329
  title: "Create New Quiz",
6330
6330
  description: "Create a New Quiz (LTI) in a Canvas course. New Quizzes is the modern quiz engine; for Classic quizzes use create_quiz.",
6331
6331
  inputSchema: {
6332
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6332
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6333
6333
  title: _zod.z.string().describe("Title of the quiz"),
6334
6334
  instructions: _zod.z.string().nullable().optional().describe("HTML instructions shown before the quiz starts"),
6335
6335
  points_possible: _zod.z.number().optional().describe("Total points; defaults to sum of item points"),
@@ -6357,8 +6357,8 @@ function newQuizTools(canvas) {
6357
6357
  title: "Update New Quiz",
6358
6358
  description: "Update an existing New Quiz (LTI) in a Canvas course.",
6359
6359
  inputSchema: {
6360
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6361
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz"),
6360
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6361
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz"),
6362
6362
  title: _zod.z.string().optional().describe("Title of the quiz"),
6363
6363
  instructions: _zod.z.string().nullable().optional().describe("HTML instructions shown before the quiz starts"),
6364
6364
  points_possible: _zod.z.number().optional().describe("Total points"),
@@ -6387,8 +6387,8 @@ function newQuizTools(canvas) {
6387
6387
  title: "Delete New Quiz",
6388
6388
  description: "Delete a New Quiz (LTI) from a Canvas course. This action is permanent. Use assignment_id (not quiz_id).",
6389
6389
  inputSchema: {
6390
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6391
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz")
6390
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6391
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz")
6392
6392
  },
6393
6393
  annotations: { destructiveHint: true, idempotentHint: true, openWorldHint: true },
6394
6394
  handler: async (params) => {
@@ -6403,8 +6403,8 @@ function newQuizTools(canvas) {
6403
6403
  title: "List New Quiz Items",
6404
6404
  description: "List all items (questions) in a New Quiz (LTI).",
6405
6405
  inputSchema: {
6406
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6407
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz")
6406
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6407
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz")
6408
6408
  },
6409
6409
  annotations: { readOnlyHint: true, openWorldHint: true },
6410
6410
  handler: async (params) => {
@@ -6418,8 +6418,8 @@ function newQuizTools(canvas) {
6418
6418
  title: "Get New Quiz Item",
6419
6419
  description: "Get a single item (question) from a New Quiz (LTI) by item ID.",
6420
6420
  inputSchema: {
6421
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6422
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz"),
6421
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6422
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz"),
6423
6423
  item_id: _zod.z.string().describe("The New Quiz item ID (string, not numeric)")
6424
6424
  },
6425
6425
  annotations: { readOnlyHint: true, openWorldHint: true },
@@ -6435,8 +6435,8 @@ function newQuizTools(canvas) {
6435
6435
  title: "Create New Quiz Item",
6436
6436
  description: "Create an item (question) in a New Quiz (LTI). Supports 5 types: choice (MCQ), true-false, essay, matching, numeric. Canvas may rate-limit rapid sequential creates. Call serially (not in parallel). For >50 items, chunk and pause between batches.",
6437
6437
  inputSchema: {
6438
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6439
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz"),
6438
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6439
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz"),
6440
6440
  points_possible: _zod.z.number().describe("Points awarded for a fully correct answer"),
6441
6441
  position: _zod.z.number().int().optional().describe("1-based position in the quiz; appended if omitted"),
6442
6442
  item: itemDiscriminatedUnion
@@ -6457,8 +6457,8 @@ function newQuizTools(canvas) {
6457
6457
  title: "Update New Quiz Item",
6458
6458
  description: "Update an existing item (question) in a New Quiz (LTI). All fields are optional; supply only what changes. Canvas may rate-limit rapid sequential updates. Call serially (not in parallel). For >50 items, chunk and pause between batches.",
6459
6459
  inputSchema: {
6460
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6461
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz"),
6460
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6461
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz"),
6462
6462
  item_id: _zod.z.string().describe("The New Quiz item ID (string, not numeric)"),
6463
6463
  points_possible: _zod.z.number().optional().describe("Updated point value"),
6464
6464
  position: _zod.z.number().int().optional().describe("Updated 1-based position"),
@@ -6481,8 +6481,8 @@ function newQuizTools(canvas) {
6481
6481
  title: "Delete New Quiz Item",
6482
6482
  description: "Delete an item (question) from a New Quiz (LTI). This action is permanent.",
6483
6483
  inputSchema: {
6484
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6485
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz"),
6484
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6485
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The assignment ID of the New Quiz"),
6486
6486
  item_id: _zod.z.string().describe("The New Quiz item ID (string, not numeric)")
6487
6487
  },
6488
6488
  annotations: { destructiveHint: true, idempotentHint: true, openWorldHint: true },
@@ -6515,7 +6515,7 @@ function rubricTools(canvas) {
6515
6515
  title: "List Rubrics",
6516
6516
  description: "List all rubrics in a course.",
6517
6517
  inputSchema: {
6518
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
6518
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
6519
6519
  },
6520
6520
  annotations: {
6521
6521
  readOnlyHint: true,
@@ -6531,8 +6531,8 @@ function rubricTools(canvas) {
6531
6531
  title: "Get Rubric",
6532
6532
  description: 'Get details for a single rubric by ID, including criteria. Use include=["assignment_associations"] to retrieve the rubric association IDs needed for rubric assessment writes.',
6533
6533
  inputSchema: {
6534
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6535
- rubric_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas rubric ID"),
6534
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6535
+ rubric_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas rubric ID"),
6536
6536
  include: _zod.z.array(_zod.z.enum(RUBRIC_INCLUDE)).optional().describe(
6537
6537
  "Related Canvas records to include. Use assignment_associations to retrieve association IDs for linked assignments. Canvas honours only one association scope per request; extra association values are ignored."
6538
6538
  )
@@ -6555,9 +6555,9 @@ function rubricTools(canvas) {
6555
6555
  title: "Get Rubric Assessment",
6556
6556
  description: "Get the rubric assessment for a specific student submission on an assignment.",
6557
6557
  inputSchema: {
6558
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6559
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
6560
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID")
6558
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6559
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
6560
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID")
6561
6561
  },
6562
6562
  annotations: {
6563
6563
  readOnlyHint: true,
@@ -6575,8 +6575,8 @@ function rubricTools(canvas) {
6575
6575
  title: "Submit Rubric Assessment",
6576
6576
  description: "Submit a rubric assessment with scores and comments for each criterion.",
6577
6577
  inputSchema: {
6578
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6579
- association_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The rubric association ID"),
6578
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6579
+ association_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The rubric association ID"),
6580
6580
  data: _zod.z.array(
6581
6581
  _zod.z.object({
6582
6582
  criterion_id: _zod.z.string().describe("The rubric criterion ID"),
@@ -6602,7 +6602,7 @@ function rubricTools(canvas) {
6602
6602
  title: "Create Rubric",
6603
6603
  description: "Create a new rubric in a course with criteria and rating levels. Optionally link it to an assignment immediately. Returns { rubric, rubric_association? }; when an assignment association was requested, rubric_association.id is the association_id that submit_rubric_assessment takes.",
6604
6604
  inputSchema: {
6605
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6605
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6606
6606
  title: _zod.z.string().describe("The rubric title"),
6607
6607
  criteria: _zod.z.array(
6608
6608
  _zod.z.object({
@@ -6617,7 +6617,7 @@ function rubricTools(canvas) {
6617
6617
  })
6618
6618
  ).min(1, "At least one criterion is required").describe("Rubric criteria"),
6619
6619
  association: _zod.z.object({
6620
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Assignment ID to link this rubric to"),
6620
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Assignment ID to link this rubric to"),
6621
6621
  use_for_grading: _zod.z.boolean().optional().describe("Whether to use this rubric for grading"),
6622
6622
  purpose: _zod.z.string().optional().describe('Purpose of the association (e.g., "grading")')
6623
6623
  }).optional().describe("Optional assignment association")
@@ -6641,9 +6641,9 @@ function rubricTools(canvas) {
6641
6641
  title: "Attach Rubric",
6642
6642
  description: "Attach an existing course rubric to an assignment, so one rubric can be shared across many assignments instead of creating a duplicate per assignment with create_rubric. Returns the new rubric association.",
6643
6643
  inputSchema: {
6644
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6645
- rubric_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The ID of the existing rubric to attach"),
6646
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID to attach the rubric to"),
6644
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6645
+ rubric_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The ID of the existing rubric to attach"),
6646
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID to attach the rubric to"),
6647
6647
  use_for_grading: _zod.z.boolean().optional().describe("Whether the rubric drives the assignment grade"),
6648
6648
  hide_score_total: _zod.z.boolean().optional().describe("Whether to hide the rubric score total from students"),
6649
6649
  purpose: _zod.z.string().optional().describe('Association purpose, e.g. "grading" (the default) or "bookmark"')
@@ -6669,8 +6669,8 @@ function rubricTools(canvas) {
6669
6669
  title: "Delete Rubric",
6670
6670
  description: "Permanently delete a rubric from a course, removing it from every assignment it is attached to. Returns the deleted rubric.",
6671
6671
  inputSchema: {
6672
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6673
- rubric_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas rubric ID to delete")
6672
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
6673
+ rubric_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas rubric ID to delete")
6674
6674
  },
6675
6675
  annotations: {
6676
6676
  destructiveHint: true,
@@ -6740,7 +6740,7 @@ function studentTools(canvas, pseudonymizer) {
6740
6740
  title: "Get My Grades",
6741
6741
  description: "Get grade data for the authenticated student. If course_id is omitted, returns grades across all enrolled courses.",
6742
6742
  inputSchema: {
6743
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("The Canvas course ID (omit for all courses)")
6743
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("The Canvas course ID (omit for all courses)")
6744
6744
  },
6745
6745
  annotations: {
6746
6746
  readOnlyHint: true,
@@ -6756,7 +6756,7 @@ function studentTools(canvas, pseudonymizer) {
6756
6756
  title: "Get My Submissions",
6757
6757
  description: "List all submissions for the authenticated student in a course.",
6758
6758
  inputSchema: {
6759
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
6759
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
6760
6760
  },
6761
6761
  annotations: {
6762
6762
  readOnlyHint: true,
@@ -6785,7 +6785,7 @@ function studentTools(canvas, pseudonymizer) {
6785
6785
  title: "Get My Submission Feedback",
6786
6786
  description: "List the authenticated student's own submissions that carry feedback comments from an instructor or a peer reviewer \u2014 comments left by the student themselves do not count as feedback and submissions with no non-self comments are omitted. Omit `course_id` to scan every active course; a course that errors during a scan is skipped and reported in `courses_failed` rather than failing the whole call. Sorted most-recent-feedback-first. Comment author role is best-effort: 'teacher' is only identified when the author is the submission's recorded grader; other non-self authors are labeled 'peer', including any staff member who comments without being the recorded grader.",
6787
6787
  inputSchema: {
6788
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("The Canvas course ID. Omit to scan all of the student's active courses."),
6788
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("The Canvas course ID. Omit to scan all of the student's active courses."),
6789
6789
  unread_only: _zod.z.boolean().optional().describe(
6790
6790
  "Only include submissions the student hasn't opened yet (Canvas read_status). Defaults to false."
6791
6791
  )
@@ -6826,8 +6826,8 @@ function studentTools(canvas, pseudonymizer) {
6826
6826
  } else {
6827
6827
  coursesFailed.push({
6828
6828
  course_id: result.courseId,
6829
- status: result.err instanceof _chunkZT2BWA2Jcjs.CanvasApiError ? result.err.status : null,
6830
- message: result.err instanceof _chunkZT2BWA2Jcjs.CanvasApiError ? result.err.message : String(result.err)
6829
+ status: result.err instanceof _chunk2RKEK44Ecjs.CanvasApiError ? result.err.status : null,
6830
+ message: result.err instanceof _chunk2RKEK44Ecjs.CanvasApiError ? result.err.message : String(result.err)
6831
6831
  });
6832
6832
  }
6833
6833
  }
@@ -7097,7 +7097,7 @@ function studentSearchTools(canvas, pseudonymizer) {
7097
7097
  const coursesToScan = truncated ? sorted.slice(0, maxCourses) : sorted;
7098
7098
  const coursesFailed = [];
7099
7099
  const perCourseMatches = [];
7100
- const scanResults = await _chunkDEFB5PL2cjs.mapWithConcurrency.call(void 0,
7100
+ const scanResults = await _chunk3X2VLRJJcjs.mapWithConcurrency.call(void 0,
7101
7101
  coursesToScan,
7102
7102
  CONCURRENT_COURSE_LIMIT,
7103
7103
  async (course) => {
@@ -7120,8 +7120,8 @@ function studentSearchTools(canvas, pseudonymizer) {
7120
7120
  } else {
7121
7121
  coursesFailed.push({
7122
7122
  course_id: r.course.id,
7123
- status: r.err instanceof _chunkZT2BWA2Jcjs.CanvasApiError ? r.err.status : null,
7124
- message: r.err instanceof _chunkZT2BWA2Jcjs.CanvasApiError ? r.err.message : String(r.err)
7123
+ status: r.err instanceof _chunk2RKEK44Ecjs.CanvasApiError ? r.err.status : null,
7124
+ message: r.err instanceof _chunk2RKEK44Ecjs.CanvasApiError ? r.err.message : String(r.err)
7125
7125
  });
7126
7126
  }
7127
7127
  }
@@ -7199,18 +7199,18 @@ function submissionTools(canvas, pseudonymizer) {
7199
7199
  title: "List Submissions",
7200
7200
  description: "List all submissions for an assignment. Use `include` to attach user, assignment, rubric_assessment, submission_history, or visibility. Filter with `student_ids`, `workflow_state`, or `grading_period_id`. Defaults to including submission_comments.",
7201
7201
  inputSchema: {
7202
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
7203
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
7202
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
7203
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
7204
7204
  include: _zod.z.array(_zod.z.enum(SUBMISSION_LIST_INCLUDE)).optional().describe(
7205
7205
  'Extra fields to include (Canvas include[] param). Defaults to ["submission_comments"] when omitted.'
7206
7206
  ),
7207
- student_ids: _chunkDEFB5PL2cjs.canvasIdList.call(void 0, { sentinels: ["all", "self"] }).optional().describe(
7207
+ student_ids: _chunk3X2VLRJJcjs.canvasIdList.call(void 0, { sentinels: ["all", "self"] }).optional().describe(
7208
7208
  'Restrict to submissions for these user IDs (pass large IDs as strings). Use "all" or "self" for shortcuts.'
7209
7209
  ),
7210
- section_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe("Restrict to submissions in these sections"),
7210
+ section_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe("Restrict to submissions in these sections"),
7211
7211
  grouped: _zod.z.boolean().optional().describe("Return one submission per group rather than per student"),
7212
7212
  workflow_state: _zod.z.enum(SUBMISSION_WORKFLOW_STATE).optional().describe("Only include submissions in this workflow state"),
7213
- grading_period_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).optional().describe("Restrict to a grading period")
7213
+ grading_period_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).optional().describe("Restrict to a grading period")
7214
7214
  },
7215
7215
  annotations: {
7216
7216
  readOnlyHint: true,
@@ -7244,9 +7244,9 @@ function submissionTools(canvas, pseudonymizer) {
7244
7244
  title: "Get Submission",
7245
7245
  description: "Get a single submission for a specific user on an assignment. Defaults to including submission_comments. Pass `include` to add rubric_assessment, submission_history, visibility, course, user, or read_status.",
7246
7246
  inputSchema: {
7247
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
7248
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
7249
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID"),
7247
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
7248
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
7249
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID"),
7250
7250
  include: _zod.z.array(_zod.z.enum(SUBMISSION_GET_INCLUDE)).optional().describe(
7251
7251
  'Extra fields to include (Canvas include[] param). Defaults to ["submission_comments"] when omitted.'
7252
7252
  )
@@ -7275,9 +7275,9 @@ function submissionTools(canvas, pseudonymizer) {
7275
7275
  title: "Grade Submission",
7276
7276
  description: "Post or update a grade for a submission. Requires grading permissions.",
7277
7277
  inputSchema: {
7278
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
7279
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
7280
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID"),
7278
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
7279
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
7280
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID"),
7281
7281
  grade: _zod.z.string().describe('The grade to assign (e.g. "95", "A", "pass")')
7282
7282
  },
7283
7283
  annotations: {
@@ -7298,9 +7298,9 @@ function submissionTools(canvas, pseudonymizer) {
7298
7298
  title: "Comment on Submission",
7299
7299
  description: "Add a text comment to a submission.",
7300
7300
  inputSchema: {
7301
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
7302
- assignment_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
7303
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID"),
7301
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
7302
+ assignment_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas assignment ID"),
7303
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID"),
7304
7304
  comment: _zod.z.string().describe("The comment text to add")
7305
7305
  },
7306
7306
  annotations: {
@@ -7331,9 +7331,9 @@ function submissionFileTools(canvas, pseudonymizer) {
7331
7331
  title: "List Course Submission Files",
7332
7332
  description: 'List every file attachment submitted by students across all assignments in a course. Returns a manifest \u2014 one entry per file \u2014 including the original filename, a file_id for re-fetching via download_file, content type, and size. Useful for bulk-archiving student work before a course expires or a Free-For-Teacher account is concluded. Outputs are bounded by max_files (default 500); when the limit is hit, truncated is true and truncation_note explains how to retrieve the rest. Download URLs are time-limited (typically 1 hour) \u2014 use the returned file_id with download_file to get a fresh URL at download time. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, user_name is a stable per-course pseudonym (e.g. "Student 1"); user_id (the raw numeric Canvas ID) is always returned and works as a stable per-student folder key.',
7333
7333
  inputSchema: {
7334
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID."),
7335
- assignment_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe("Restrict to these assignment IDs. Omit to scan all assignments."),
7336
- student_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe(
7334
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID."),
7335
+ assignment_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe("Restrict to these assignment IDs. Omit to scan all assignments."),
7336
+ student_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe(
7337
7337
  "Restrict to these student user IDs. Omit to include all students. When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, pass the real Canvas user_id after resolving the pseudonym via resolve_pseudonym."
7338
7338
  ),
7339
7339
  workflow_state: _zod.z.enum(WORKFLOW_STATE).optional().describe("Only include submissions in this workflow state. Omit to include all states."),
@@ -7434,10 +7434,10 @@ function submissionsAwaitingGradingTools(canvas, pseudonymizer) {
7434
7434
  title: "List Submissions Awaiting Grading",
7435
7435
  description: "Lists all submissions in a course that still need a human grade, sorted oldest-waiting first.\n\nSurfaces two categories:\n- workflow_state=submitted: assignments submitted by students but not yet graded at all.\n- workflow_state=pending_review: Classic Quiz submissions where Canvas auto-graded the objective questions but left essays or manually-scored questions for the instructor.\n\nReturns a triage list grouped by assignment or Classic Quiz, with per-submission details: student identity, workflow state, submitted_at, and whether the submission has pending manual-grading questions.\n\nParameters:\n- course_id (required): Canvas course ID to scan.\n- assignment_ids (optional): limit the scan to specific assignment IDs.\n- include_quizzes (default true): include Classic Quiz assignments in the scan.\n- include_assignments (default true): include non-quiz assignments.\n- only_pending_review (default false): when true, return only pending_review submissions (quiz essays awaiting manual scoring), omitting regular ungraded assignments.\n\nKnown limitations:\n- New Quizzes (Quizzes.Next) may not appear with 'pending_review' workflow state here; use SpeedGrader or the New Quizzes interface for their grading queue.\n- Fill-in-the-blank answers that Canvas auto-marked are not surfaced.\n- V1 returns submission-level state only; per-question detail is not included.\n- When CANVAS_PSEUDONYMIZE_STUDENTS is enabled, student names are replaced with pseudonyms. Use resolve_pseudonym to look up the real identity.",
7436
7436
  inputSchema: {
7437
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe(
7437
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe(
7438
7438
  "Canvas course ID to scan for submissions awaiting grading."
7439
7439
  ),
7440
- assignment_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe(
7440
+ assignment_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe(
7441
7441
  "Limit the scan to these specific assignment IDs (numeric Canvas IDs). When omitted, all assignments in the course are scanned."
7442
7442
  ),
7443
7443
  include_quizzes: _zod.z.boolean().default(true).describe(
@@ -7591,7 +7591,7 @@ function userTools(canvas, pseudonymizer) {
7591
7591
  title: "List Students",
7592
7592
  description: "List all students enrolled in a course.",
7593
7593
  inputSchema: {
7594
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
7594
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID")
7595
7595
  },
7596
7596
  annotations: {
7597
7597
  readOnlyHint: true,
@@ -7609,7 +7609,7 @@ function userTools(canvas, pseudonymizer) {
7609
7609
  title: "Get User",
7610
7610
  description: "Get details for a single user by ID.",
7611
7611
  inputSchema: {
7612
- user_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID")
7612
+ user_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas user ID")
7613
7613
  },
7614
7614
  annotations: {
7615
7615
  readOnlyHint: true,
@@ -7640,7 +7640,7 @@ function userTools(canvas, pseudonymizer) {
7640
7640
  title: "Search Users",
7641
7641
  description: "Search for users in a Canvas account by name, login, or email. Use `include` to request email, last_login, avatar_url, time_zone, or uuid in the response.",
7642
7642
  inputSchema: {
7643
- account_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID"),
7643
+ account_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas account ID"),
7644
7644
  search_term: _zod.z.string().describe("The search term (name, login, or email)"),
7645
7645
  sort: _zod.z.enum(USER_SORT).optional().describe("Sort field"),
7646
7646
  order: _zod.z.enum(["asc", "desc"]).optional().describe("Sort order"),
@@ -7667,7 +7667,7 @@ function userTools(canvas, pseudonymizer) {
7667
7667
  title: "List Course Users",
7668
7668
  description: "List users in a course with optional Canvas filters. Use `include` to request email, enrollments, avatar_url, bio, and other fields otherwise omitted from the default response. Use `enrollment_type` / `enrollment_state` to narrow by role or status, `search_term` to filter by name/login, `user_ids` to fetch a specific subset, and `sort`/`order` to control ordering.",
7669
7669
  inputSchema: {
7670
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
7670
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID"),
7671
7671
  enrollment_type: _zod.z.array(_zod.z.enum(COURSE_USER_ENROLLMENT_TYPE)).optional().describe("Filter by one or more enrollment types"),
7672
7672
  enrollment_state: _zod.z.array(_zod.z.enum(COURSE_USER_ENROLLMENT_STATE)).optional().describe("Filter by enrollment state (e.g. active, invited)"),
7673
7673
  include: _zod.z.array(_zod.z.enum(COURSE_USER_INCLUDE)).optional().describe("Extra fields to include on each user (Canvas include[] param)"),
@@ -7676,7 +7676,7 @@ function userTools(canvas, pseudonymizer) {
7676
7676
  // forbids an ID field that accepts arbitrary strings, so this narrows to the
7677
7677
  // canonical ID forms plus the one SIS prefix the rest of this repo documents
7678
7678
  // (`sis_user_id:`, as in outcomes.ts). Called out in the PR as a narrowing.
7679
- user_ids: _chunkDEFB5PL2cjs.canvasIdList.call(void 0, { prefixes: ["sis_user_id"] }).optional().describe(
7679
+ user_ids: _chunk3X2VLRJJcjs.canvasIdList.call(void 0, { prefixes: ["sis_user_id"] }).optional().describe(
7680
7680
  'Restrict the result to the given user IDs (pass large IDs as strings). SIS user IDs may be given as "sis_user_id:<sis id>".'
7681
7681
  ),
7682
7682
  search_term: _zod.z.string().optional().describe("Partial name or full login/SIS ID to filter users by"),
@@ -7808,7 +7808,7 @@ async function scanQuizzes(canvas, courseId, warnings) {
7808
7808
  canvas.assignments.list(courseId)
7809
7809
  ]);
7810
7810
  const classicQuizzes = quizzes.filter((quiz) => CLASSIC_QUIZ_TYPES3.has(quiz.quiz_type));
7811
- const classicFindings = await _chunkDEFB5PL2cjs.mapWithConcurrency.call(void 0,
7811
+ const classicFindings = await _chunk3X2VLRJJcjs.mapWithConcurrency.call(void 0,
7812
7812
  classicQuizzes,
7813
7813
  QUIZ_SCAN_CONCURRENCY_LIMIT,
7814
7814
  async (quiz) => {
@@ -7834,7 +7834,7 @@ async function scanQuizzes(canvas, courseId, warnings) {
7834
7834
  }
7835
7835
  );
7836
7836
  const newQuizAssignments = assignments.filter((a) => a.is_quiz_lti_assignment === true);
7837
- const newQuizFindings = await _chunkDEFB5PL2cjs.mapWithConcurrency.call(void 0,
7837
+ const newQuizFindings = await _chunk3X2VLRJJcjs.mapWithConcurrency.call(void 0,
7838
7838
  newQuizAssignments,
7839
7839
  QUIZ_SCAN_CONCURRENCY_LIMIT,
7840
7840
  async (assignment) => {
@@ -7859,7 +7859,7 @@ function linkAuditTools(canvas) {
7859
7859
  title: "Audit Course Links",
7860
7860
  description: 'Scan a course\'s content (pages, assignments, syllabus, announcements, and optionally quizzes) for broken or outdated links and images. Returns structured findings: cross-course references (links that still point at a previous copy of the course \u2014 the canonical stale-copy failure after a course import) and empty/malformed URLs. Pass "quizzes" in `include` to also scan Classic quiz descriptions/questions and New Quiz item stems \u2014 these break silently for students while still rendering in the instructor\u2019s own preview. `quizzes` is opt-in (off by default). Structural checks only \u2014 no outbound HTTP requests. Requires instructor permissions in the course.',
7861
7861
  inputSchema: {
7862
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
7862
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
7863
7863
  include: _zod.z.array(_zod.z.enum(["pages", "assignments", "syllabus", "announcements", "quizzes"])).optional().describe(
7864
7864
  "Content sources to scan. Omit to scan the default four: pages, assignments, syllabus, announcements. `quizzes` is opt-in \u2014 pass it explicitly to also scan Classic quiz descriptions/questions and New Quiz item stems; it issues one extra Canvas API call per quiz/New Quiz in the course."
7865
7865
  )
@@ -8184,7 +8184,7 @@ async function scanQuizzesAccessibility(canvas, courseId, warnings) {
8184
8184
  canvas.assignments.list(courseId)
8185
8185
  ]);
8186
8186
  const classicQuizzes = quizzes.filter((quiz) => CLASSIC_QUIZ_TYPES4.has(quiz.quiz_type));
8187
- const classicFindings = await _chunkDEFB5PL2cjs.mapWithConcurrency.call(void 0,
8187
+ const classicFindings = await _chunk3X2VLRJJcjs.mapWithConcurrency.call(void 0,
8188
8188
  classicQuizzes,
8189
8189
  QUIZ_SCAN_CONCURRENCY_LIMIT2,
8190
8190
  async (quiz) => {
@@ -8209,7 +8209,7 @@ async function scanQuizzesAccessibility(canvas, courseId, warnings) {
8209
8209
  }
8210
8210
  );
8211
8211
  const newQuizAssignments = assignments.filter((a) => a.is_quiz_lti_assignment === true);
8212
- const newQuizFindings = await _chunkDEFB5PL2cjs.mapWithConcurrency.call(void 0,
8212
+ const newQuizFindings = await _chunk3X2VLRJJcjs.mapWithConcurrency.call(void 0,
8213
8213
  newQuizAssignments,
8214
8214
  QUIZ_SCAN_CONCURRENCY_LIMIT2,
8215
8215
  async (assignment) => {
@@ -8238,7 +8238,7 @@ function accessibilityAuditTools(canvas) {
8238
8238
  title: "Audit Course Accessibility",
8239
8239
  description: 'Scan a course\'s content (pages, assignments, syllabus, announcements, and optionally quizzes) for structurally-detectable WCAG 2.1 accessibility problems: images missing alt text or with low-quality (filename/generic) alt text, non-descriptive link text ("click here"), adjacent duplicate links, skipped/empty/overlong headings, and tables missing headers, header scope, or captions. Each finding carries a WCAG success criterion and a severity (error = unambiguous failure, advisory = needs human review). Structural checks only \u2014 no color-contrast checking (requires rendered theme CSS this tool cannot see) and no list-misuse detection in this version. Pass "quizzes" in `include` to also scan Classic quiz descriptions/questions and New Quiz item stems (opt-in, off by default). Complements \u2014 does not replace \u2014 Canvas\'s own in-app Accessibility Checker (course navigation \u2192 Accessibility \u2192 Scan Course), which covers the same WCAG areas plus rendered color contrast and offers in-UI remediation. Requires instructor permissions in the course.',
8240
8240
  inputSchema: {
8241
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
8241
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("Canvas course ID"),
8242
8242
  include: _zod.z.array(_zod.z.enum(["pages", "assignments", "syllabus", "announcements", "quizzes"])).optional().describe(
8243
8243
  "Content sources to scan. Omit to scan the default four: pages, assignments, syllabus, announcements. `quizzes` is opt-in \u2014 pass it explicitly to also scan Classic quiz descriptions/questions and New Quiz item stems."
8244
8244
  )
@@ -8357,7 +8357,7 @@ function appointmentGroupTools(canvas, pseudonymizer) {
8357
8357
  title: "Get Appointment Group",
8358
8358
  description: "Get a single appointment group by ID, including its time slots and participant counts.",
8359
8359
  inputSchema: {
8360
- appointment_group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The appointment group ID"),
8360
+ appointment_group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The appointment group ID"),
8361
8361
  include: includeSchema
8362
8362
  },
8363
8363
  annotations: { readOnlyHint: true, openWorldHint: true },
@@ -8410,7 +8410,7 @@ function appointmentGroupTools(canvas, pseudonymizer) {
8410
8410
  title: "Update Appointment Group",
8411
8411
  description: "Update an existing appointment group. Use publish=true to make a draft group visible to participants, or add new time slots via new_appointments.",
8412
8412
  inputSchema: {
8413
- appointment_group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The appointment group ID"),
8413
+ appointment_group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The appointment group ID"),
8414
8414
  title: _zod.z.string().optional().describe("New title"),
8415
8415
  description: _zod.z.string().optional().describe("New description"),
8416
8416
  location_name: _zod.z.string().optional().describe("Location name"),
@@ -8435,7 +8435,7 @@ function appointmentGroupTools(canvas, pseudonymizer) {
8435
8435
  title: "Delete Appointment Group",
8436
8436
  description: "Delete an appointment group and cancel any existing reservations. Provide cancel_reason to notify participants.",
8437
8437
  inputSchema: {
8438
- appointment_group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The appointment group ID"),
8438
+ appointment_group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The appointment group ID"),
8439
8439
  cancel_reason: _zod.z.string().optional().describe("Message to include in cancellation notifications")
8440
8440
  },
8441
8441
  annotations: { destructiveHint: true, openWorldHint: true },
@@ -8449,7 +8449,7 @@ function appointmentGroupTools(canvas, pseudonymizer) {
8449
8449
  title: "List Appointment Group Users",
8450
8450
  description: "List participants (users) who have reserved a slot in an appointment group.",
8451
8451
  inputSchema: {
8452
- appointment_group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The appointment group ID")
8452
+ appointment_group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The appointment group ID")
8453
8453
  },
8454
8454
  annotations: { readOnlyHint: true, openWorldHint: true },
8455
8455
  handler: async (params) => {
@@ -8468,7 +8468,7 @@ function appointmentGroupTools(canvas, pseudonymizer) {
8468
8468
  title: "List Appointment Group Groups",
8469
8469
  description: "List student groups that have reserved a slot in an appointment group (when participant_type=Group).",
8470
8470
  inputSchema: {
8471
- appointment_group_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The appointment group ID")
8471
+ appointment_group_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The appointment group ID")
8472
8472
  },
8473
8473
  annotations: { readOnlyHint: true, openWorldHint: true },
8474
8474
  handler: async (params) => {
@@ -8484,7 +8484,7 @@ function appointmentGroupTools(canvas, pseudonymizer) {
8484
8484
  title: "Next Appointment",
8485
8485
  description: "Get the current user's next upcoming appointment across all (or specified) appointment groups.",
8486
8486
  inputSchema: {
8487
- appointment_group_ids: _zod.z.array(_chunkDEFB5PL2cjs.canvasIdInput.call(void 0, )).optional().describe("Limit to specific appointment group IDs")
8487
+ appointment_group_ids: _zod.z.array(_chunk3X2VLRJJcjs.canvasIdInput.call(void 0, )).optional().describe("Limit to specific appointment group IDs")
8488
8488
  },
8489
8489
  annotations: { readOnlyHint: true, openWorldHint: true },
8490
8490
  audience: "shared",
@@ -8721,7 +8721,7 @@ function pseudonymTools(pseudonymizer) {
8721
8721
  audience: "educator",
8722
8722
  description: 'Resolve a stable pseudonym (e.g. "Student 7") back to a Canvas user_id within a course. Use only when a teacher has explicitly asked to identify a specific student in an artifact. Every call is audit-logged.',
8723
8723
  inputSchema: {
8724
- course_id: _chunkDEFB5PL2cjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID the pseudonym was assigned in"),
8724
+ course_id: _chunk3X2VLRJJcjs.canvasIdInput.call(void 0, ).describe("The Canvas course ID the pseudonym was assigned in"),
8725
8725
  pseudonym: _zod.z.string().describe('The pseudonym to resolve, e.g. "Student 7"')
8726
8726
  },
8727
8727
  annotations: {
@@ -8831,7 +8831,7 @@ function buildHandler(tool, pseudonymizer, toolCallGate) {
8831
8831
  }
8832
8832
  return response;
8833
8833
  } catch (error) {
8834
- if (!(error instanceof _chunkZT2BWA2Jcjs.CanvasApiError)) {
8834
+ if (!(error instanceof _chunk2RKEK44Ecjs.CanvasApiError)) {
8835
8835
  console.error(`Unexpected error in tool "${tool.name}":`, error);
8836
8836
  }
8837
8837
  return {
@@ -8897,7 +8897,7 @@ function registerSyllabusResource(server, canvas) {
8897
8897
  const rawCourseId = String(variables.courseId);
8898
8898
  let courseId;
8899
8899
  try {
8900
- courseId = _chunkDEFB5PL2cjs.normalizeCanvasIdInput.call(void 0, rawCourseId);
8900
+ courseId = _chunk3X2VLRJJcjs.normalizeCanvasIdInput.call(void 0, rawCourseId);
8901
8901
  } catch (e7) {
8902
8902
  return {
8903
8903
  contents: [
@@ -8925,7 +8925,7 @@ function registerSyllabusResource(server, canvas) {
8925
8925
  ]
8926
8926
  };
8927
8927
  } catch (error) {
8928
- if (!(error instanceof _chunkZT2BWA2Jcjs.CanvasApiError)) {
8928
+ if (!(error instanceof _chunk2RKEK44Ecjs.CanvasApiError)) {
8929
8929
  console.error("Unexpected error in syllabus resource:", error);
8930
8930
  }
8931
8931
  return {
@@ -8964,8 +8964,8 @@ function registerAssignmentDescriptionResource(server, canvas) {
8964
8964
  let courseId;
8965
8965
  let assignmentId;
8966
8966
  try {
8967
- courseId = _chunkDEFB5PL2cjs.normalizeCanvasIdInput.call(void 0, rawCourseId);
8968
- assignmentId = _chunkDEFB5PL2cjs.normalizeCanvasIdInput.call(void 0, rawAssignmentId);
8967
+ courseId = _chunk3X2VLRJJcjs.normalizeCanvasIdInput.call(void 0, rawCourseId);
8968
+ assignmentId = _chunk3X2VLRJJcjs.normalizeCanvasIdInput.call(void 0, rawAssignmentId);
8969
8969
  } catch (e8) {
8970
8970
  return {
8971
8971
  contents: [{ uri, mimeType: "text/plain", text: "Invalid course or assignment ID" }]
@@ -8984,7 +8984,7 @@ function registerAssignmentDescriptionResource(server, canvas) {
8984
8984
  ]
8985
8985
  };
8986
8986
  } catch (error) {
8987
- if (!(error instanceof _chunkZT2BWA2Jcjs.CanvasApiError)) {
8987
+ if (!(error instanceof _chunk2RKEK44Ecjs.CanvasApiError)) {
8988
8988
  console.error("Unexpected error in assignment-description resource:", error);
8989
8989
  }
8990
8990
  return {
@@ -10384,14 +10384,14 @@ function resolvePseudonymizer(config) {
10384
10384
  });
10385
10385
  }
10386
10386
  function createCanvasMCPServer(config) {
10387
- const canvas = new (0, _chunkDEFB5PL2cjs.CanvasClient)({
10387
+ const canvas = new (0, _chunk3X2VLRJJcjs.CanvasClient)({
10388
10388
  token: config.token,
10389
10389
  baseUrl: config.baseUrl
10390
10390
  });
10391
10391
  const pseudonymizer = resolvePseudonymizer(config);
10392
10392
  const server = new (0, _mcpjs.McpServer)({
10393
10393
  name: "canvas-lms-mcp",
10394
- version: _chunkZT2BWA2Jcjs.version
10394
+ version: _chunk2RKEK44Ecjs.version
10395
10395
  });
10396
10396
  const features = {
10397
10397
  assignmentSubmission: config.enableAssignmentSubmission,
@@ -10412,4 +10412,4 @@ function createCanvasMCPServer(config) {
10412
10412
 
10413
10413
 
10414
10414
  exports.Pseudonymizer = Pseudonymizer; exports.createSharedPseudonymizer = createSharedPseudonymizer; exports.createCanvasMCPServer = createCanvasMCPServer;
10415
- //# sourceMappingURL=chunk-HJWLGW54.cjs.map
10415
+ //# sourceMappingURL=chunk-2UETRKXN.cjs.map