canvas-parent-mcp 1.3.0 → 1.4.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/bundle.js +24 -13
- package/dist/index.js +1 -1
- package/mint.yaml +20 -5
- package/package.json +3 -3
- package/server.json +2 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "MCP server for Canvas LMS (Instructure) — courses, grades, assignments, announcements, planner, conversations, files",
|
|
10
|
-
"version": "1.
|
|
10
|
+
"version": "1.4.0"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "Canvas LMS",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "Canvas LMS (Instructure) MCP server for Claude — student/observer access via natural language",
|
|
18
|
-
"version": "1.
|
|
18
|
+
"version": "1.4.0",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canvas-parent-mcp",
|
|
3
3
|
"displayName": "Canvas LMS",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
5
|
"description": "Canvas LMS (Instructure) MCP server for Claude — courses, grades, assignments, announcements, planner, conversations, files",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Hall",
|
package/dist/bundle.js
CHANGED
|
@@ -3314,8 +3314,8 @@ var require_utils = __commonJS({
|
|
|
3314
3314
|
var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
|
|
3315
3315
|
var HOST_DELIM_RE = /[@/?#:]/g;
|
|
3316
3316
|
var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
|
|
3317
|
-
function reescapeHostDelimiters(host,
|
|
3318
|
-
const re =
|
|
3317
|
+
function reescapeHostDelimiters(host, isIP2) {
|
|
3318
|
+
const re = isIP2 ? HOST_DELIM_NO_COLON_RE : HOST_DELIM_RE;
|
|
3319
3319
|
re.lastIndex = 0;
|
|
3320
3320
|
return host.replace(re, (ch) => HOST_DELIMS[ch]);
|
|
3321
3321
|
}
|
|
@@ -3804,7 +3804,7 @@ var require_fast_uri = __commonJS({
|
|
|
3804
3804
|
fragment: void 0
|
|
3805
3805
|
};
|
|
3806
3806
|
let malformedAuthorityOrPort = false;
|
|
3807
|
-
let
|
|
3807
|
+
let isIP2 = false;
|
|
3808
3808
|
if (options.reference === "suffix") {
|
|
3809
3809
|
if (options.scheme) {
|
|
3810
3810
|
uri = options.scheme + ":" + uri;
|
|
@@ -3853,9 +3853,9 @@ var require_fast_uri = __commonJS({
|
|
|
3853
3853
|
if (ipv4result === false) {
|
|
3854
3854
|
const ipv6result = normalizeIPv6(parsed.host);
|
|
3855
3855
|
parsed.host = ipv6result.host.toLowerCase();
|
|
3856
|
-
|
|
3856
|
+
isIP2 = ipv6result.isIPV6;
|
|
3857
3857
|
} else {
|
|
3858
|
-
|
|
3858
|
+
isIP2 = true;
|
|
3859
3859
|
}
|
|
3860
3860
|
}
|
|
3861
3861
|
if (parsed.scheme === void 0 && parsed.userinfo === void 0 && parsed.host === void 0 && parsed.port === void 0 && parsed.query === void 0 && !parsed.path) {
|
|
@@ -3872,7 +3872,7 @@ var require_fast_uri = __commonJS({
|
|
|
3872
3872
|
}
|
|
3873
3873
|
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
|
|
3874
3874
|
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
|
|
3875
|
-
if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) &&
|
|
3875
|
+
if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP2 === false && nonSimpleDomain(parsed.host)) {
|
|
3876
3876
|
try {
|
|
3877
3877
|
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
3878
3878
|
} catch (e) {
|
|
@@ -3886,7 +3886,7 @@ var require_fast_uri = __commonJS({
|
|
|
3886
3886
|
parsed.scheme = unescape(parsed.scheme);
|
|
3887
3887
|
}
|
|
3888
3888
|
if (parsed.host !== void 0) {
|
|
3889
|
-
parsed.host = reescapeHostDelimiters(unescape(parsed.host),
|
|
3889
|
+
parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP2);
|
|
3890
3890
|
}
|
|
3891
3891
|
}
|
|
3892
3892
|
if (parsed.path) {
|
|
@@ -7199,7 +7199,7 @@ var require_permessage_deflate = __commonJS({
|
|
|
7199
7199
|
acceptAsServer(offers) {
|
|
7200
7200
|
const opts = this._options;
|
|
7201
7201
|
const accepted = offers.find((params) => {
|
|
7202
|
-
if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === "number" && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === "number" && !params.client_max_window_bits) {
|
|
7202
|
+
if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === "number" && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === "number" && (typeof params.client_max_window_bits === "number" ? opts.clientMaxWindowBits > params.client_max_window_bits : !params.client_max_window_bits)) {
|
|
7203
7203
|
return false;
|
|
7204
7204
|
}
|
|
7205
7205
|
return true;
|
|
@@ -37096,6 +37096,7 @@ function classifyBridgeError(err) {
|
|
|
37096
37096
|
}
|
|
37097
37097
|
|
|
37098
37098
|
// node_modules/@fetchproxy/server/dist/ws-server.js
|
|
37099
|
+
import { isIP } from "node:net";
|
|
37099
37100
|
function envWsPort() {
|
|
37100
37101
|
const raw = process.env.FETCHPROXY_WS_PORT;
|
|
37101
37102
|
if (raw === void 0 || raw.trim() === "")
|
|
@@ -37107,6 +37108,15 @@ function envWsPort() {
|
|
|
37107
37108
|
return void 0;
|
|
37108
37109
|
return port;
|
|
37109
37110
|
}
|
|
37111
|
+
function envWsHost() {
|
|
37112
|
+
const raw = process.env.FETCHPROXY_WS_HOST;
|
|
37113
|
+
if (raw === void 0)
|
|
37114
|
+
return void 0;
|
|
37115
|
+
const host = raw.trim();
|
|
37116
|
+
if (host === "" || isIP(host) === 0)
|
|
37117
|
+
return void 0;
|
|
37118
|
+
return host;
|
|
37119
|
+
}
|
|
37110
37120
|
var FetchproxyProtocolError = class extends Error {
|
|
37111
37121
|
constructor(message) {
|
|
37112
37122
|
super(message);
|
|
@@ -37355,7 +37365,7 @@ var FetchproxyServer = class {
|
|
|
37355
37365
|
}
|
|
37356
37366
|
this.opts = {
|
|
37357
37367
|
port: opts.port ?? envWsPort() ?? 37149,
|
|
37358
|
-
host: opts.host ?? "127.0.0.1",
|
|
37368
|
+
host: opts.host ?? envWsHost() ?? "127.0.0.1",
|
|
37359
37369
|
serverName: opts.serverName,
|
|
37360
37370
|
version: opts.version,
|
|
37361
37371
|
domains: [...opts.domains],
|
|
@@ -37641,6 +37651,7 @@ var FetchproxyServer = class {
|
|
|
37641
37651
|
return {
|
|
37642
37652
|
role: this.role,
|
|
37643
37653
|
port: this.opts.port,
|
|
37654
|
+
host: this.opts.host,
|
|
37644
37655
|
serverVersion: this.opts.version,
|
|
37645
37656
|
fetchTimeoutMs: this.opts.fetchTimeoutMs ?? 0,
|
|
37646
37657
|
bridgeReviveDelayMs: this.opts.bridgeReviveDelayMs ?? 0,
|
|
@@ -39226,7 +39237,7 @@ function loadAccount(env = process.env) {
|
|
|
39226
39237
|
// package.json
|
|
39227
39238
|
var package_default = {
|
|
39228
39239
|
name: "canvas-parent-mcp",
|
|
39229
|
-
version: "1.
|
|
39240
|
+
version: "1.4.0",
|
|
39230
39241
|
mcpName: "io.github.chrischall/canvas-parent-mcp",
|
|
39231
39242
|
description: "Canvas LMS (Instructure) MCP server \u2014 student/observer read access with optional file download",
|
|
39232
39243
|
author: "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -39274,8 +39285,8 @@ var package_default = {
|
|
|
39274
39285
|
},
|
|
39275
39286
|
dependencies: {
|
|
39276
39287
|
"@chrischall/mcp-utils": "^0.17.1",
|
|
39277
|
-
"@fetchproxy/bootstrap": "^2.
|
|
39278
|
-
"@fetchproxy/server": "^2.
|
|
39288
|
+
"@fetchproxy/bootstrap": "^2.2.0",
|
|
39289
|
+
"@fetchproxy/server": "^2.2.0",
|
|
39279
39290
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
39280
39291
|
dotenv: "^17.4.2",
|
|
39281
39292
|
zod: "^4.4.3"
|
|
@@ -40491,7 +40502,7 @@ try {
|
|
|
40491
40502
|
}
|
|
40492
40503
|
await runMcp({
|
|
40493
40504
|
name: "canvas",
|
|
40494
|
-
version: "1.
|
|
40505
|
+
version: "1.4.0",
|
|
40495
40506
|
// x-release-please-version
|
|
40496
40507
|
tools: [
|
|
40497
40508
|
(server) => {
|
package/dist/index.js
CHANGED
package/mint.yaml
CHANGED
|
@@ -63,16 +63,31 @@ env:
|
|
|
63
63
|
$MCP_DATA_DIR/.canvas-parent-mcp/session.json.
|
|
64
64
|
egress:
|
|
65
65
|
allow:
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
66
|
+
# Only hosts the SERVER process actually fetches; hosts that appear solely
|
|
67
|
+
# in a URL this server builds and returns are excluded. Matching is EXACT:
|
|
68
|
+
# an apex entry covers no subdomain, and `*.` covers labels beneath it but
|
|
69
|
+
# not the apex — which is why the wildcard below is a wildcard.
|
|
70
|
+
#
|
|
71
|
+
# Canvas is multi-tenant per district: CANVAS_BASE_URL is a
|
|
72
|
+
# <district>.instructure.com host (cms.instructure.com is the CMS district)
|
|
73
|
+
# and every API call, the form login and the OAuth refresh go to it.
|
|
74
|
+
# Narrow the wildcard to YOUR district's host if you prefer. A self-hosted
|
|
75
|
+
# Canvas (a CANVAS_BASE_URL outside instructure.com) is env-selected and
|
|
76
|
+
# must be added here by hand.
|
|
77
|
+
#
|
|
78
|
+
# canvas_download_file follows the file URL Canvas returns, and a hosted
|
|
79
|
+
# district's download 302s to Instructure's file store, whose host carries
|
|
80
|
+
# the region (inst-fs-iad-prod.inscloudgate.net, -dub-, -syd-, …). The
|
|
81
|
+
# exact host is discovered at runtime, hence the wildcard.
|
|
69
82
|
#
|
|
70
83
|
# sso.canvaslms.com is deliberately NOT here: the hosted server never
|
|
71
84
|
# contacts it. session-login.ts only INSPECTS a redirect's Location for
|
|
72
85
|
# that host, and qr-login.ts is the separate canvas-parent-mcp-qr-login
|
|
73
|
-
# bin, not the child this manifest configures.
|
|
74
|
-
|
|
86
|
+
# bin, not the child this manifest configures. The fetchproxy fallback
|
|
87
|
+
# lifts cookies through the browser bridge, which is not a dial either.
|
|
88
|
+
- "*.instructure.com"
|
|
75
89
|
- cms.instructure.com
|
|
90
|
+
- "*.inscloudgate.net"
|
|
76
91
|
|
|
77
92
|
state:
|
|
78
93
|
dataDir: true
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canvas-parent-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"mcpName": "io.github.chrischall/canvas-parent-mcp",
|
|
5
5
|
"description": "Canvas LMS (Instructure) MCP server — student/observer read access with optional file download",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@chrischall/mcp-utils": "^0.17.1",
|
|
51
|
-
"@fetchproxy/bootstrap": "^2.
|
|
52
|
-
"@fetchproxy/server": "^2.
|
|
51
|
+
"@fetchproxy/bootstrap": "^2.2.0",
|
|
52
|
+
"@fetchproxy/server": "^2.2.0",
|
|
53
53
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
54
54
|
"dotenv": "^17.4.2",
|
|
55
55
|
"zod": "^4.4.3"
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/canvas-parent-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.4.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "canvas-parent-mcp",
|
|
14
|
-
"version": "1.
|
|
14
|
+
"version": "1.4.0",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|