canvas-lms-mcp 1.17.0 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/canvas/index.cjs +3 -3
- package/dist/canvas/index.js +2 -2
- package/dist/{chunk-Z3YUWFEE.js → chunk-5P4FUG7Q.js} +2 -2
- package/dist/{chunk-C55DPF4U.cjs → chunk-CDWLOZQ2.cjs} +146 -74
- package/dist/chunk-CDWLOZQ2.cjs.map +1 -0
- package/dist/{chunk-EPBWT2FM.cjs → chunk-EXAIZYJY.cjs} +2 -2
- package/dist/chunk-EXAIZYJY.cjs.map +1 -0
- package/dist/{chunk-GS52LL5U.cjs → chunk-LTBTS6YA.cjs} +3 -3
- package/dist/{chunk-GS52LL5U.cjs.map → chunk-LTBTS6YA.cjs.map} +1 -1
- package/dist/{chunk-KE4SUTYQ.js → chunk-YQY5WM7K.js} +123 -51
- package/dist/chunk-YQY5WM7K.js.map +1 -0
- package/dist/{chunk-FUNEDFU6.js → chunk-Z5EZRC5F.js} +2 -2
- package/dist/chunk-Z5EZRC5F.js.map +1 -0
- package/dist/http.cjs +5 -5
- package/dist/http.js +3 -3
- package/dist/init.cjs +3 -3
- package/dist/init.js +1 -1
- package/dist/server.cjs +4 -4
- package/dist/server.js +3 -3
- package/dist/stdio.cjs +4 -4
- package/dist/stdio.js +3 -3
- package/dist/tools/accounts.d.ts +2 -1
- package/dist/tools/accounts.d.ts.map +1 -1
- package/dist/tools/catalog.d.ts +2 -1
- package/dist/tools/catalog.d.ts.map +1 -1
- package/dist/tools/conversations.d.ts +2 -1
- package/dist/tools/conversations.d.ts.map +1 -1
- package/dist/tools/enrollments.d.ts +2 -1
- package/dist/tools/enrollments.d.ts.map +1 -1
- package/dist/tools/gradebook-history.d.ts +2 -1
- package/dist/tools/gradebook-history.d.ts.map +1 -1
- package/dist/tools/groups.d.ts +2 -1
- package/dist/tools/groups.d.ts.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/outcomes.d.ts +2 -1
- package/dist/tools/outcomes.d.ts.map +1 -1
- package/dist/tools/submissions.d.ts +2 -1
- package/dist/tools/submissions.d.ts.map +1 -1
- package/dist/tools/users.d.ts +2 -1
- package/dist/tools/users.d.ts.map +1 -1
- package/package.json +2 -1
- package/dist/chunk-C55DPF4U.cjs.map +0 -1
- package/dist/chunk-EPBWT2FM.cjs.map +0 -1
- package/dist/chunk-FUNEDFU6.js.map +0 -1
- package/dist/chunk-KE4SUTYQ.js.map +0 -1
- /package/dist/{chunk-Z3YUWFEE.js.map → chunk-5P4FUG7Q.js.map} +0 -0
package/README.md
CHANGED
|
@@ -13,6 +13,16 @@ MCP server for [Canvas LMS](https://www.instructure.com/canvas). Read courses, a
|
|
|
13
13
|
|
|
14
14
|
116 tools across Canvas courses, assignments, submissions, gradebook history, rubrics, quizzes, New Quizzes (LTI), files, users, groups, enrollments, discussions, modules, pages, calendar, conversations, peer reviews, accounts, analytics, outcomes, student workflows, dashboard, and health checks. Three deployment modes: stdio, HTTP, and library import.
|
|
15
15
|
|
|
16
|
+
## One-click install (Claude Desktop)
|
|
17
|
+
|
|
18
|
+
1. **[Download `canvas-lms-mcp.mcpb`](https://github.com/bruchris/canvas-lms-mcp/releases/latest/download/canvas-lms-mcp.mcpb)** from the latest release.
|
|
19
|
+
2. Double-click the file (or drag it into Claude Desktop's Extensions settings).
|
|
20
|
+
3. When prompted, paste your Canvas API token and Canvas API base URL (e.g. `https://school.instructure.com/api/v1`).
|
|
21
|
+
|
|
22
|
+
No terminal, no Node.js install, no config-file editing — Claude Desktop bundles the runtime and handles config for you. The same `.mcpb` works in Claude Code and MCP for Windows.
|
|
23
|
+
|
|
24
|
+
Prefer the terminal? Use the [Quick Start](#quick-start) below.
|
|
25
|
+
|
|
16
26
|
## Comparison
|
|
17
27
|
|
|
18
28
|
| | canvas-lms-mcp | [vishalsachdev/canvas-mcp](https://github.com/vishalsachdev/canvas-mcp) | [DMontgomery40/mcp-canvas-lms](https://github.com/DMontgomery40/mcp-canvas-lms) |
|
package/dist/canvas/index.cjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkLTBTS6YAcjs = require('../chunk-LTBTS6YA.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunkEXAIZYJYcjs = require('../chunk-EXAIZYJY.cjs');
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
exports.CanvasApiError =
|
|
16
|
+
exports.CanvasApiError = _chunkEXAIZYJYcjs.CanvasApiError; exports.CanvasClient = _chunkLTBTS6YAcjs.CanvasClient; exports.CanvasHttpClient = _chunkEXAIZYJYcjs.CanvasHttpClient; exports.appendCanvasQuery = _chunkEXAIZYJYcjs.appendCanvasQuery; exports.toCanvasQuery = _chunkEXAIZYJYcjs.toCanvasQuery;
|
|
17
17
|
//# sourceMappingURL=index.cjs.map
|
package/dist/canvas/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CanvasClient
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-5P4FUG7Q.js";
|
|
4
4
|
import {
|
|
5
5
|
CanvasApiError,
|
|
6
6
|
CanvasHttpClient,
|
|
7
7
|
appendCanvasQuery,
|
|
8
8
|
toCanvasQuery
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-Z5EZRC5F.js";
|
|
10
10
|
export {
|
|
11
11
|
CanvasApiError,
|
|
12
12
|
CanvasClient,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CanvasHttpClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Z5EZRC5F.js";
|
|
4
4
|
|
|
5
5
|
// src/canvas/courses.ts
|
|
6
6
|
var DEFAULT_LIST_INCLUDE = ["term"];
|
|
@@ -1395,4 +1395,4 @@ export {
|
|
|
1395
1395
|
OUTCOME_EXCLUDE_OPTIONS,
|
|
1396
1396
|
CanvasClient
|
|
1397
1397
|
};
|
|
1398
|
-
//# sourceMappingURL=chunk-
|
|
1398
|
+
//# sourceMappingURL=chunk-5P4FUG7Q.js.map
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _chunkLTBTS6YAcjs = require('./chunk-LTBTS6YA.cjs');
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
var
|
|
14
|
+
var _chunkEXAIZYJYcjs = require('./chunk-EXAIZYJY.cjs');
|
|
15
15
|
|
|
16
16
|
// src/server.ts
|
|
17
17
|
var _mcpjs = require('@modelcontextprotocol/sdk/server/mcp.js');
|
|
@@ -446,7 +446,7 @@ async function appendAuditFile(filePath, line) {
|
|
|
446
446
|
|
|
447
447
|
// src/tools/accounts.ts
|
|
448
448
|
var _zod = require('zod');
|
|
449
|
-
function accountTools(canvas) {
|
|
449
|
+
function accountTools(canvas, pseudonymizer) {
|
|
450
450
|
return [
|
|
451
451
|
{
|
|
452
452
|
name: "get_account",
|
|
@@ -517,9 +517,12 @@ function accountTools(canvas) {
|
|
|
517
517
|
openWorldHint: true
|
|
518
518
|
},
|
|
519
519
|
handler: async (params) => {
|
|
520
|
-
|
|
520
|
+
const account_id = params.account_id;
|
|
521
|
+
const users = await canvas.accounts.listUsers(account_id, {
|
|
521
522
|
search_term: params.search_term
|
|
522
523
|
});
|
|
524
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _6 => _6.isEnabled, 'call', _7 => _7()])) return users;
|
|
525
|
+
return pseudonymizer.anonymizeUsers(String(account_id), users);
|
|
523
526
|
}
|
|
524
527
|
},
|
|
525
528
|
{
|
|
@@ -544,7 +547,7 @@ function accountTools(canvas) {
|
|
|
544
547
|
|
|
545
548
|
// src/tools/errors.ts
|
|
546
549
|
function formatError(error) {
|
|
547
|
-
if (error instanceof
|
|
550
|
+
if (error instanceof _chunkEXAIZYJYcjs.CanvasApiError) {
|
|
548
551
|
const status = error.status;
|
|
549
552
|
const message = error.message;
|
|
550
553
|
const ltiMarkers = ["Tool not configured", "tool is not configured"];
|
|
@@ -596,7 +599,7 @@ function analyticsTools(canvas) {
|
|
|
596
599
|
inputSchema: {
|
|
597
600
|
course_id: _zod.z.number().describe("The Canvas course ID"),
|
|
598
601
|
search_term: _zod.z.string().describe("The keyword or phrase to search for"),
|
|
599
|
-
content_types: _zod.z.array(_zod.z.enum(
|
|
602
|
+
content_types: _zod.z.array(_zod.z.enum(_chunkLTBTS6YAcjs.SEARCH_CONTENT_TYPES)).optional().describe(
|
|
600
603
|
"Content types to search. Defaults to all types: pages, discussions, assignments, announcements."
|
|
601
604
|
)
|
|
602
605
|
},
|
|
@@ -608,7 +611,7 @@ function analyticsTools(canvas) {
|
|
|
608
611
|
const courseId = params.course_id;
|
|
609
612
|
const searchTerm = params.search_term;
|
|
610
613
|
const types = _nullishCoalesce(params.content_types, () => ( [
|
|
611
|
-
...
|
|
614
|
+
..._chunkLTBTS6YAcjs.SEARCH_CONTENT_TYPES
|
|
612
615
|
]));
|
|
613
616
|
if (types.length === 0) return { results: [] };
|
|
614
617
|
const settled = await Promise.allSettled(
|
|
@@ -970,7 +973,7 @@ function calendarTools(canvas) {
|
|
|
970
973
|
|
|
971
974
|
// src/tools/conversations.ts
|
|
972
975
|
|
|
973
|
-
function conversationTools(canvas) {
|
|
976
|
+
function conversationTools(canvas, pseudonymizer) {
|
|
974
977
|
return [
|
|
975
978
|
{
|
|
976
979
|
name: "list_conversations",
|
|
@@ -981,7 +984,9 @@ function conversationTools(canvas) {
|
|
|
981
984
|
openWorldHint: true
|
|
982
985
|
},
|
|
983
986
|
handler: async () => {
|
|
984
|
-
|
|
987
|
+
const conversations = await canvas.conversations.list();
|
|
988
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _8 => _8.isEnabled, 'call', _9 => _9()])) return conversations;
|
|
989
|
+
return Promise.all(conversations.map((c) => pseudonymizer.anonymizeConversation(c)));
|
|
985
990
|
}
|
|
986
991
|
},
|
|
987
992
|
{
|
|
@@ -995,7 +1000,9 @@ function conversationTools(canvas) {
|
|
|
995
1000
|
openWorldHint: true
|
|
996
1001
|
},
|
|
997
1002
|
handler: async (params) => {
|
|
998
|
-
|
|
1003
|
+
const conversation = await canvas.conversations.get(params.conversation_id);
|
|
1004
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _10 => _10.isEnabled, 'call', _11 => _11()])) return conversation;
|
|
1005
|
+
return pseudonymizer.anonymizeConversation(conversation);
|
|
999
1006
|
}
|
|
1000
1007
|
},
|
|
1001
1008
|
{
|
|
@@ -1401,7 +1408,7 @@ var ENROLLMENT_INCLUDE = [
|
|
|
1401
1408
|
"current_points",
|
|
1402
1409
|
"grades"
|
|
1403
1410
|
];
|
|
1404
|
-
function enrollmentTools(canvas) {
|
|
1411
|
+
function enrollmentTools(canvas, pseudonymizer) {
|
|
1405
1412
|
return [
|
|
1406
1413
|
{
|
|
1407
1414
|
name: "list_enrollments",
|
|
@@ -1429,7 +1436,11 @@ function enrollmentTools(canvas) {
|
|
|
1429
1436
|
opts.grading_period_id = params.grading_period_id;
|
|
1430
1437
|
if (params.enrollment_term_id !== void 0)
|
|
1431
1438
|
opts.enrollment_term_id = params.enrollment_term_id;
|
|
1432
|
-
|
|
1439
|
+
const enrollments = await canvas.enrollments.list(opts);
|
|
1440
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _12 => _12.isEnabled, 'call', _13 => _13()])) return enrollments;
|
|
1441
|
+
return Promise.all(
|
|
1442
|
+
enrollments.map((e) => pseudonymizer.anonymizeEnrollment(e.course_id, e))
|
|
1443
|
+
);
|
|
1433
1444
|
}
|
|
1434
1445
|
},
|
|
1435
1446
|
{
|
|
@@ -1450,6 +1461,7 @@ function enrollmentTools(canvas) {
|
|
|
1450
1461
|
openWorldHint: true
|
|
1451
1462
|
},
|
|
1452
1463
|
handler: async (params) => {
|
|
1464
|
+
const course_id = params.course_id;
|
|
1453
1465
|
const opts = {};
|
|
1454
1466
|
if (params.type !== void 0) opts.type = params.type;
|
|
1455
1467
|
if (params.state !== void 0) opts.state = params.state;
|
|
@@ -1461,7 +1473,9 @@ function enrollmentTools(canvas) {
|
|
|
1461
1473
|
opts.grading_period_id = params.grading_period_id;
|
|
1462
1474
|
if (params.enrollment_term_id !== void 0)
|
|
1463
1475
|
opts.enrollment_term_id = params.enrollment_term_id;
|
|
1464
|
-
|
|
1476
|
+
const enrollments = await canvas.enrollments.listForCourse(course_id, opts);
|
|
1477
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _14 => _14.isEnabled, 'call', _15 => _15()])) return enrollments;
|
|
1478
|
+
return Promise.all(enrollments.map((e) => pseudonymizer.anonymizeEnrollment(course_id, e)));
|
|
1465
1479
|
}
|
|
1466
1480
|
},
|
|
1467
1481
|
{
|
|
@@ -1626,7 +1640,18 @@ function fileTools(canvas) {
|
|
|
1626
1640
|
|
|
1627
1641
|
// src/tools/gradebook-history.ts
|
|
1628
1642
|
|
|
1629
|
-
function
|
|
1643
|
+
async function anonymizeHistoryVersion(courseId, version2, pseudonymizer) {
|
|
1644
|
+
if (!version2.user_name || !version2.user_id) return version2;
|
|
1645
|
+
const minimalUser = {
|
|
1646
|
+
id: version2.user_id,
|
|
1647
|
+
name: version2.user_name,
|
|
1648
|
+
sortable_name: version2.user_name,
|
|
1649
|
+
short_name: version2.user_name
|
|
1650
|
+
};
|
|
1651
|
+
const pseudo = await pseudonymizer.anonymizeUser(courseId, minimalUser);
|
|
1652
|
+
return { ...version2, user_name: pseudo.name };
|
|
1653
|
+
}
|
|
1654
|
+
function gradebookHistoryTools(canvas, pseudonymizer) {
|
|
1630
1655
|
return [
|
|
1631
1656
|
{
|
|
1632
1657
|
name: "list_gradebook_history_days",
|
|
@@ -1678,7 +1703,21 @@ function gradebookHistoryTools(canvas) {
|
|
|
1678
1703
|
const date = params.date;
|
|
1679
1704
|
const grader_id = params.grader_id;
|
|
1680
1705
|
const assignment_id = params.assignment_id;
|
|
1681
|
-
|
|
1706
|
+
const submissions = await canvas.gradebookHistory.listSubmissions(
|
|
1707
|
+
course_id,
|
|
1708
|
+
date,
|
|
1709
|
+
grader_id,
|
|
1710
|
+
assignment_id
|
|
1711
|
+
);
|
|
1712
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _16 => _16.isEnabled, 'call', _17 => _17()])) return submissions;
|
|
1713
|
+
return Promise.all(
|
|
1714
|
+
submissions.map(async (s) => ({
|
|
1715
|
+
...s,
|
|
1716
|
+
versions: s.versions ? await Promise.all(
|
|
1717
|
+
s.versions.map((v) => anonymizeHistoryVersion(course_id, v, pseudonymizer))
|
|
1718
|
+
) : s.versions
|
|
1719
|
+
}))
|
|
1720
|
+
);
|
|
1682
1721
|
}
|
|
1683
1722
|
},
|
|
1684
1723
|
{
|
|
@@ -1699,7 +1738,15 @@ function gradebookHistoryTools(canvas) {
|
|
|
1699
1738
|
const assignment_id = params.assignment_id;
|
|
1700
1739
|
const user_id = params.user_id;
|
|
1701
1740
|
const ascending = params.ascending;
|
|
1702
|
-
|
|
1741
|
+
const versions = await canvas.gradebookHistory.getFeed(course_id, {
|
|
1742
|
+
assignment_id,
|
|
1743
|
+
user_id,
|
|
1744
|
+
ascending
|
|
1745
|
+
});
|
|
1746
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _18 => _18.isEnabled, 'call', _19 => _19()])) return versions;
|
|
1747
|
+
return Promise.all(
|
|
1748
|
+
versions.map((v) => anonymizeHistoryVersion(course_id, v, pseudonymizer))
|
|
1749
|
+
);
|
|
1703
1750
|
}
|
|
1704
1751
|
}
|
|
1705
1752
|
];
|
|
@@ -1707,7 +1754,7 @@ function gradebookHistoryTools(canvas) {
|
|
|
1707
1754
|
|
|
1708
1755
|
// src/tools/groups.ts
|
|
1709
1756
|
|
|
1710
|
-
function groupTools(canvas) {
|
|
1757
|
+
function groupTools(canvas, pseudonymizer) {
|
|
1711
1758
|
return [
|
|
1712
1759
|
{
|
|
1713
1760
|
name: "list_groups",
|
|
@@ -1736,7 +1783,9 @@ function groupTools(canvas) {
|
|
|
1736
1783
|
},
|
|
1737
1784
|
handler: async (params) => {
|
|
1738
1785
|
const group_id = params.group_id;
|
|
1739
|
-
|
|
1786
|
+
const users = await canvas.groups.listMembers(group_id);
|
|
1787
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _20 => _20.isEnabled, 'call', _21 => _21()])) return users;
|
|
1788
|
+
return pseudonymizer.anonymizeUsers(`_group_${group_id}`, users);
|
|
1740
1789
|
}
|
|
1741
1790
|
}
|
|
1742
1791
|
];
|
|
@@ -1928,13 +1977,13 @@ function moduleTools(canvas) {
|
|
|
1928
1977
|
|
|
1929
1978
|
// src/tools/outcomes.ts
|
|
1930
1979
|
|
|
1931
|
-
function outcomeTools(canvas) {
|
|
1980
|
+
function outcomeTools(canvas, pseudonymizer) {
|
|
1932
1981
|
return [
|
|
1933
1982
|
{
|
|
1934
1983
|
name: "get_root_outcome_group",
|
|
1935
1984
|
description: "Get the root outcome group for an account or course context.",
|
|
1936
1985
|
inputSchema: {
|
|
1937
|
-
context_type: _zod.z.enum(
|
|
1986
|
+
context_type: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcomes from an account or course context."),
|
|
1938
1987
|
context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context.")
|
|
1939
1988
|
},
|
|
1940
1989
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
@@ -1947,7 +1996,7 @@ function outcomeTools(canvas) {
|
|
|
1947
1996
|
name: "list_outcome_groups",
|
|
1948
1997
|
description: "List all outcome groups for an account or course context.",
|
|
1949
1998
|
inputSchema: {
|
|
1950
|
-
context_type: _zod.z.enum(
|
|
1999
|
+
context_type: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcome groups from an account or course context."),
|
|
1951
2000
|
context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context.")
|
|
1952
2001
|
},
|
|
1953
2002
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
@@ -1960,10 +2009,10 @@ function outcomeTools(canvas) {
|
|
|
1960
2009
|
name: "list_outcome_group_links",
|
|
1961
2010
|
description: "List all outcome links in an account or course context.",
|
|
1962
2011
|
inputSchema: {
|
|
1963
|
-
context_type: _zod.z.enum(
|
|
2012
|
+
context_type: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_CONTEXT_TYPES).describe("Whether to read outcome links from an account or course context."),
|
|
1964
2013
|
context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context."),
|
|
1965
|
-
outcome_style: _zod.z.enum(
|
|
1966
|
-
outcome_group_style: _zod.z.enum(
|
|
2014
|
+
outcome_style: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_DETAIL_LEVELS).optional().describe('Outcome detail level. Use "full" to include expanded outcome fields.'),
|
|
2015
|
+
outcome_group_style: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_DETAIL_LEVELS).optional().describe(
|
|
1967
2016
|
'Outcome group detail level. Use "full" to include expanded outcome group fields.'
|
|
1968
2017
|
)
|
|
1969
2018
|
},
|
|
@@ -1981,7 +2030,7 @@ function outcomeTools(canvas) {
|
|
|
1981
2030
|
name: "get_outcome_group",
|
|
1982
2031
|
description: "Get details for a specific outcome group in an account or course context.",
|
|
1983
2032
|
inputSchema: {
|
|
1984
|
-
context_type: _zod.z.enum(
|
|
2033
|
+
context_type: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
|
|
1985
2034
|
context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context."),
|
|
1986
2035
|
outcome_group_id: _zod.z.number().describe("The Canvas outcome group ID.")
|
|
1987
2036
|
},
|
|
@@ -1996,10 +2045,10 @@ function outcomeTools(canvas) {
|
|
|
1996
2045
|
name: "list_outcome_group_outcomes",
|
|
1997
2046
|
description: "List the linked outcomes directly under a specific outcome group.",
|
|
1998
2047
|
inputSchema: {
|
|
1999
|
-
context_type: _zod.z.enum(
|
|
2048
|
+
context_type: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
|
|
2000
2049
|
context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context."),
|
|
2001
2050
|
outcome_group_id: _zod.z.number().describe("The Canvas outcome group ID."),
|
|
2002
|
-
outcome_style: _zod.z.enum(
|
|
2051
|
+
outcome_style: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_DETAIL_LEVELS).optional().describe('Outcome detail level. Use "full" to include expanded outcome fields.')
|
|
2003
2052
|
},
|
|
2004
2053
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
2005
2054
|
handler: async (params) => canvas.outcomes.listGroupOutcomes(
|
|
@@ -2015,7 +2064,7 @@ function outcomeTools(canvas) {
|
|
|
2015
2064
|
name: "list_outcome_group_subgroups",
|
|
2016
2065
|
description: "List the immediate child outcome groups under a specific outcome group.",
|
|
2017
2066
|
inputSchema: {
|
|
2018
|
-
context_type: _zod.z.enum(
|
|
2067
|
+
context_type: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_CONTEXT_TYPES).describe("The outcome group context type."),
|
|
2019
2068
|
context_id: _zod.z.number().describe("The Canvas account ID or course ID for the context."),
|
|
2020
2069
|
outcome_group_id: _zod.z.number().describe("The Canvas outcome group ID.")
|
|
2021
2070
|
},
|
|
@@ -2063,12 +2112,17 @@ function outcomeTools(canvas) {
|
|
|
2063
2112
|
include_hidden: _zod.z.boolean().optional().describe("Include hidden outcomes when Canvas supports it.")
|
|
2064
2113
|
},
|
|
2065
2114
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
2066
|
-
handler: async (params) =>
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2115
|
+
handler: async (params) => {
|
|
2116
|
+
const course_id = params.course_id;
|
|
2117
|
+
const response = await canvas.outcomes.getOutcomeResults(course_id, {
|
|
2118
|
+
user_ids: params.user_ids,
|
|
2119
|
+
outcome_ids: params.outcome_ids,
|
|
2120
|
+
include_alignments: params.include_alignments,
|
|
2121
|
+
include_hidden: params.include_hidden
|
|
2122
|
+
});
|
|
2123
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _22 => _22.isEnabled, 'call', _23 => _23()])) return response;
|
|
2124
|
+
return pseudonymizer.anonymizeOutcomeResults(course_id, response);
|
|
2125
|
+
}
|
|
2072
2126
|
},
|
|
2073
2127
|
{
|
|
2074
2128
|
name: "get_outcome_rollups",
|
|
@@ -2076,29 +2130,34 @@ function outcomeTools(canvas) {
|
|
|
2076
2130
|
inputSchema: {
|
|
2077
2131
|
course_id: _zod.z.number().describe("The Canvas course ID."),
|
|
2078
2132
|
aggregate: _zod.z.enum(["course"]).optional().describe("Aggregate all student rollups into a single course-level rollup."),
|
|
2079
|
-
aggregate_stat: _zod.z.enum(
|
|
2133
|
+
aggregate_stat: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_ROLLUP_AGGREGATE_STATS).optional().describe('Statistic to use when aggregate="course".'),
|
|
2080
2134
|
user_ids: _zod.z.array(_zod.z.union([_zod.z.number(), _zod.z.string()])).optional().describe('Optional Canvas user IDs or SIS user IDs prefixed with "sis_user_id:".'),
|
|
2081
2135
|
outcome_ids: _zod.z.array(_zod.z.number()).optional().describe("Optional outcome IDs to restrict the rollups."),
|
|
2082
2136
|
include_courses: _zod.z.boolean().optional().describe("Include linked course details in the response payload."),
|
|
2083
|
-
exclude: _zod.z.array(_zod.z.enum(
|
|
2084
|
-
sort_by: _zod.z.enum(
|
|
2137
|
+
exclude: _zod.z.array(_zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_EXCLUDE_OPTIONS)).optional().describe("Optional rollup exclusions for missing users or missing outcome results."),
|
|
2138
|
+
sort_by: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_ROLLUP_SORT_BY).optional().describe("Sort rollups by student name or by a specific outcome score."),
|
|
2085
2139
|
sort_outcome_id: _zod.z.number().optional().describe('Outcome ID to sort by when sort_by="outcome".'),
|
|
2086
|
-
sort_order: _zod.z.enum(
|
|
2140
|
+
sort_order: _zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_SORT_ORDER).optional().describe("Sort order to apply when sorting rollups."),
|
|
2087
2141
|
add_defaults: _zod.z.boolean().optional().describe("Include default mastery colors and levels when Canvas supports it.")
|
|
2088
2142
|
},
|
|
2089
2143
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
2090
|
-
handler: async (params) =>
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2144
|
+
handler: async (params) => {
|
|
2145
|
+
const course_id = params.course_id;
|
|
2146
|
+
const response = await canvas.outcomes.getOutcomeRollups(course_id, {
|
|
2147
|
+
aggregate: params.aggregate,
|
|
2148
|
+
aggregate_stat: params.aggregate_stat,
|
|
2149
|
+
user_ids: params.user_ids,
|
|
2150
|
+
outcome_ids: params.outcome_ids,
|
|
2151
|
+
include_courses: params.include_courses,
|
|
2152
|
+
exclude: params.exclude,
|
|
2153
|
+
sort_by: params.sort_by,
|
|
2154
|
+
sort_outcome_id: params.sort_outcome_id,
|
|
2155
|
+
sort_order: params.sort_order,
|
|
2156
|
+
add_defaults: params.add_defaults
|
|
2157
|
+
});
|
|
2158
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _24 => _24.isEnabled, 'call', _25 => _25()])) return response;
|
|
2159
|
+
return pseudonymizer.anonymizeOutcomeResults(course_id, response);
|
|
2160
|
+
}
|
|
2102
2161
|
},
|
|
2103
2162
|
{
|
|
2104
2163
|
name: "get_outcome_contributing_scores",
|
|
@@ -2126,7 +2185,7 @@ function outcomeTools(canvas) {
|
|
|
2126
2185
|
description: "Get mastery distribution analytics for outcomes in a course, optionally filtered by students or outcomes.",
|
|
2127
2186
|
inputSchema: {
|
|
2128
2187
|
course_id: _zod.z.number().describe("The Canvas course ID."),
|
|
2129
|
-
exclude: _zod.z.array(_zod.z.enum(
|
|
2188
|
+
exclude: _zod.z.array(_zod.z.enum(_chunkLTBTS6YAcjs.OUTCOME_EXCLUDE_OPTIONS)).optional().describe("Optional exclusions for missing users or missing outcome results."),
|
|
2130
2189
|
outcome_ids: _zod.z.array(_zod.z.number()).optional().describe("Optional outcome IDs to restrict the distribution results."),
|
|
2131
2190
|
student_ids: _zod.z.array(_zod.z.union([_zod.z.number(), _zod.z.string()])).optional().describe('Optional Canvas student IDs or SIS user IDs prefixed with "sis_user_id:".'),
|
|
2132
2191
|
include_alignment_distributions: _zod.z.boolean().optional().describe("Include contributing score distributions for alignments."),
|
|
@@ -2898,7 +2957,7 @@ var SUBMISSION_GET_INCLUDE = [
|
|
|
2898
2957
|
"read_status"
|
|
2899
2958
|
];
|
|
2900
2959
|
var SUBMISSION_WORKFLOW_STATE = ["submitted", "unsubmitted", "graded", "pending_review"];
|
|
2901
|
-
function submissionTools(canvas) {
|
|
2960
|
+
function submissionTools(canvas, pseudonymizer) {
|
|
2902
2961
|
return [
|
|
2903
2962
|
{
|
|
2904
2963
|
name: "list_submissions",
|
|
@@ -2922,6 +2981,7 @@ function submissionTools(canvas) {
|
|
|
2922
2981
|
openWorldHint: true
|
|
2923
2982
|
},
|
|
2924
2983
|
handler: async (params) => {
|
|
2984
|
+
const course_id = params.course_id;
|
|
2925
2985
|
const opts = {};
|
|
2926
2986
|
if (params.include !== void 0)
|
|
2927
2987
|
opts.include = params.include;
|
|
@@ -2934,11 +2994,13 @@ function submissionTools(canvas) {
|
|
|
2934
2994
|
opts.workflow_state = params.workflow_state;
|
|
2935
2995
|
if (params.grading_period_id !== void 0)
|
|
2936
2996
|
opts.grading_period_id = params.grading_period_id;
|
|
2937
|
-
|
|
2938
|
-
|
|
2997
|
+
const submissions = await canvas.submissions.list(
|
|
2998
|
+
course_id,
|
|
2939
2999
|
params.assignment_id,
|
|
2940
3000
|
opts
|
|
2941
3001
|
);
|
|
3002
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _26 => _26.isEnabled, 'call', _27 => _27()])) return submissions;
|
|
3003
|
+
return Promise.all(submissions.map((s) => pseudonymizer.anonymizeSubmission(course_id, s)));
|
|
2942
3004
|
}
|
|
2943
3005
|
},
|
|
2944
3006
|
{
|
|
@@ -2957,15 +3019,18 @@ function submissionTools(canvas) {
|
|
|
2957
3019
|
openWorldHint: true
|
|
2958
3020
|
},
|
|
2959
3021
|
handler: async (params) => {
|
|
3022
|
+
const course_id = params.course_id;
|
|
2960
3023
|
const opts = {};
|
|
2961
3024
|
if (params.include !== void 0)
|
|
2962
3025
|
opts.include = params.include;
|
|
2963
|
-
|
|
2964
|
-
|
|
3026
|
+
const submission = await canvas.submissions.get(
|
|
3027
|
+
course_id,
|
|
2965
3028
|
params.assignment_id,
|
|
2966
3029
|
params.user_id,
|
|
2967
3030
|
opts
|
|
2968
3031
|
);
|
|
3032
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _28 => _28.isEnabled, 'call', _29 => _29()])) return submission;
|
|
3033
|
+
return pseudonymizer.anonymizeSubmission(course_id, submission);
|
|
2969
3034
|
}
|
|
2970
3035
|
},
|
|
2971
3036
|
{
|
|
@@ -3037,7 +3102,7 @@ var COURSE_USER_INCLUDE = [
|
|
|
3037
3102
|
];
|
|
3038
3103
|
var USER_SORT = ["username", "email", "sis_id", "integration_id", "last_login"];
|
|
3039
3104
|
var SEARCH_USER_INCLUDE = ["email", "last_login", "avatar_url", "time_zone", "uuid"];
|
|
3040
|
-
function userTools(canvas) {
|
|
3105
|
+
function userTools(canvas, pseudonymizer) {
|
|
3041
3106
|
return [
|
|
3042
3107
|
{
|
|
3043
3108
|
name: "list_students",
|
|
@@ -3051,7 +3116,9 @@ function userTools(canvas) {
|
|
|
3051
3116
|
},
|
|
3052
3117
|
handler: async (params) => {
|
|
3053
3118
|
const course_id = params.course_id;
|
|
3054
|
-
|
|
3119
|
+
const users = await canvas.users.listStudents(course_id);
|
|
3120
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _30 => _30.isEnabled, 'call', _31 => _31()])) return users;
|
|
3121
|
+
return pseudonymizer.anonymizeUsers(course_id, users);
|
|
3055
3122
|
}
|
|
3056
3123
|
},
|
|
3057
3124
|
{
|
|
@@ -3065,8 +3132,9 @@ function userTools(canvas) {
|
|
|
3065
3132
|
openWorldHint: true
|
|
3066
3133
|
},
|
|
3067
3134
|
handler: async (params) => {
|
|
3068
|
-
const
|
|
3069
|
-
|
|
3135
|
+
const user = await canvas.users.get(params.user_id);
|
|
3136
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _32 => _32.isEnabled, 'call', _33 => _33()])) return user;
|
|
3137
|
+
return pseudonymizer.anonymizeUser("_global", user);
|
|
3070
3138
|
}
|
|
3071
3139
|
},
|
|
3072
3140
|
{
|
|
@@ -3096,16 +3164,15 @@ function userTools(canvas) {
|
|
|
3096
3164
|
openWorldHint: true
|
|
3097
3165
|
},
|
|
3098
3166
|
handler: async (params) => {
|
|
3167
|
+
const account_id = params.account_id;
|
|
3099
3168
|
const opts = {};
|
|
3100
3169
|
if (params.sort !== void 0) opts.sort = params.sort;
|
|
3101
3170
|
if (params.order !== void 0) opts.order = params.order;
|
|
3102
3171
|
if (params.include !== void 0)
|
|
3103
3172
|
opts.include = params.include;
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
opts
|
|
3108
|
-
);
|
|
3173
|
+
const users = await canvas.users.searchUsers(account_id, params.search_term, opts);
|
|
3174
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _34 => _34.isEnabled, 'call', _35 => _35()])) return users;
|
|
3175
|
+
return pseudonymizer.anonymizeUsers(String(account_id), users);
|
|
3109
3176
|
}
|
|
3110
3177
|
},
|
|
3111
3178
|
{
|
|
@@ -3126,6 +3193,7 @@ function userTools(canvas) {
|
|
|
3126
3193
|
openWorldHint: true
|
|
3127
3194
|
},
|
|
3128
3195
|
handler: async (params) => {
|
|
3196
|
+
const course_id = params.course_id;
|
|
3129
3197
|
const opts = {};
|
|
3130
3198
|
if (params.enrollment_type !== void 0)
|
|
3131
3199
|
opts.enrollment_type = params.enrollment_type;
|
|
@@ -3138,7 +3206,9 @@ function userTools(canvas) {
|
|
|
3138
3206
|
if (params.search_term !== void 0) opts.search_term = params.search_term;
|
|
3139
3207
|
if (params.sort !== void 0) opts.sort = params.sort;
|
|
3140
3208
|
if (params.order !== void 0) opts.order = params.order;
|
|
3141
|
-
|
|
3209
|
+
const users = await canvas.users.listCourseUsers(course_id, opts);
|
|
3210
|
+
if (!_optionalChain([pseudonymizer, 'optionalAccess', _36 => _36.isEnabled, 'call', _37 => _37()])) return users;
|
|
3211
|
+
return pseudonymizer.anonymizeUsers(course_id, users);
|
|
3142
3212
|
}
|
|
3143
3213
|
}
|
|
3144
3214
|
];
|
|
@@ -3304,7 +3374,9 @@ function pseudonymTools(pseudonymizer) {
|
|
|
3304
3374
|
// src/tools/index.ts
|
|
3305
3375
|
var PSEUDONYM_META_NOTE = "Student names and contact info in this response have been replaced with stable pseudonyms (CANVAS_PSEUDONYMIZE_STUDENTS=true). Real names are not available to this tool.";
|
|
3306
3376
|
function getAllTools(canvas, pseudonymizer) {
|
|
3307
|
-
const domainTools = toolDomainCatalog.flatMap(
|
|
3377
|
+
const domainTools = toolDomainCatalog.flatMap(
|
|
3378
|
+
(registration) => registration.getTools(canvas, pseudonymizer)
|
|
3379
|
+
);
|
|
3308
3380
|
const conditional = pseudonymizer ? pseudonymTools(pseudonymizer) : [];
|
|
3309
3381
|
return [...domainTools, ...conditional];
|
|
3310
3382
|
}
|
|
@@ -3318,12 +3390,12 @@ function registerAllTools(server, canvas, pseudonymizer) {
|
|
|
3318
3390
|
const response = {
|
|
3319
3391
|
content: [{ type: "text", text }]
|
|
3320
3392
|
};
|
|
3321
|
-
if (_optionalChain([pseudonymizer, 'optionalAccess',
|
|
3393
|
+
if (_optionalChain([pseudonymizer, 'optionalAccess', _38 => _38.isEnabled, 'call', _39 => _39()])) {
|
|
3322
3394
|
response._meta = { pseudonymized: true, note: PSEUDONYM_META_NOTE };
|
|
3323
3395
|
}
|
|
3324
3396
|
return response;
|
|
3325
3397
|
} catch (error) {
|
|
3326
|
-
if (error instanceof
|
|
3398
|
+
if (error instanceof _chunkEXAIZYJYcjs.CanvasApiError) {
|
|
3327
3399
|
} else {
|
|
3328
3400
|
console.error(`Unexpected error in tool "${tool.name}":`, error);
|
|
3329
3401
|
}
|
|
@@ -3371,7 +3443,7 @@ function registerSyllabusResource(server, canvas) {
|
|
|
3371
3443
|
]
|
|
3372
3444
|
};
|
|
3373
3445
|
} catch (error) {
|
|
3374
|
-
if (!(error instanceof
|
|
3446
|
+
if (!(error instanceof _chunkEXAIZYJYcjs.CanvasApiError)) {
|
|
3375
3447
|
console.error("Unexpected error in syllabus resource:", error);
|
|
3376
3448
|
}
|
|
3377
3449
|
return {
|
|
@@ -3420,7 +3492,7 @@ function registerAssignmentDescriptionResource(server, canvas) {
|
|
|
3420
3492
|
]
|
|
3421
3493
|
};
|
|
3422
3494
|
} catch (error) {
|
|
3423
|
-
if (!(error instanceof
|
|
3495
|
+
if (!(error instanceof _chunkEXAIZYJYcjs.CanvasApiError)) {
|
|
3424
3496
|
console.error("Unexpected error in assignment-description resource:", error);
|
|
3425
3497
|
}
|
|
3426
3498
|
return {
|
|
@@ -3439,14 +3511,14 @@ function registerAllResources(server, canvas) {
|
|
|
3439
3511
|
|
|
3440
3512
|
// src/server.ts
|
|
3441
3513
|
function createCanvasMCPServer(config) {
|
|
3442
|
-
const canvas = new (0,
|
|
3514
|
+
const canvas = new (0, _chunkLTBTS6YAcjs.CanvasClient)({
|
|
3443
3515
|
token: config.token,
|
|
3444
3516
|
baseUrl: config.baseUrl
|
|
3445
3517
|
});
|
|
3446
3518
|
const pseudonymizer = _nullishCoalesce(config.pseudonymizer, () => ( new Pseudonymizer({ baseUrl: config.baseUrl })));
|
|
3447
3519
|
const server = new (0, _mcpjs.McpServer)({
|
|
3448
3520
|
name: "canvas-lms-mcp",
|
|
3449
|
-
version:
|
|
3521
|
+
version: _chunkEXAIZYJYcjs.version
|
|
3450
3522
|
});
|
|
3451
3523
|
registerAllTools(server, canvas, pseudonymizer);
|
|
3452
3524
|
registerAllResources(server, canvas);
|
|
@@ -3457,4 +3529,4 @@ function createCanvasMCPServer(config) {
|
|
|
3457
3529
|
|
|
3458
3530
|
|
|
3459
3531
|
exports.Pseudonymizer = Pseudonymizer; exports.createCanvasMCPServer = createCanvasMCPServer;
|
|
3460
|
-
//# sourceMappingURL=chunk-
|
|
3532
|
+
//# sourceMappingURL=chunk-CDWLOZQ2.cjs.map
|