canvas-parent-mcp 2.1.8 → 2.1.10

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.
@@ -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": "2.1.8"
10
+ "version": "2.1.10"
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": "2.1.8",
18
+ "version": "2.1.10",
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": "2.1.8",
4
+ "version": "2.1.10",
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",
@@ -21,5 +21,5 @@
21
21
  "mcp"
22
22
  ],
23
23
  "skills": "./skills/",
24
- "mcp": "./.mcp.json"
24
+ "mcpServers": "./.mcp.json"
25
25
  }
package/.mcp.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "mcpServers": {
3
3
  "canvas": {
4
- "command": "node",
5
- "args": ["${CLAUDE_PLUGIN_ROOT}/dist/bundle.js"],
4
+ "command": "npx",
5
+ "args": ["-y", "canvas-parent-mcp"],
6
6
  "env": {
7
7
  "CANVAS_BASE_URL": "${CANVAS_BASE_URL}",
8
8
  "CANVAS_TOKEN": "${CANVAS_TOKEN}",
package/README.md CHANGED
@@ -48,7 +48,7 @@ If none succeed, you get an error that names every escape hatch.
48
48
  CANVAS_BASE_URL=https://cms.instructure.com
49
49
  ```
50
50
 
51
- Install the ContextMint Bridge browser extension from its [releases page](https://github.com/nullnet-app/contextmint-bridge/releases) (Chrome: download the chrome zip, unzip it, and load it unpacked at `chrome://extensions` with Developer mode on — there is no Chrome Web Store listing yet; Safari: not available yet — it will ship inside the ContextMint app, which has no public download yet, so use Chrome for now), sign into your Canvas instance once, and the MCP reads your session cookies at startup. After that, all Canvas API calls go directly from Node — the extension is **not** in the request hot path. Works with any auth flow (SSO/SAML/2FA included) because Canvas itself handled the sign-in.
51
+ Install the ContextMint Bridge browser extension from its [releases page](https://github.com/nullnet-app/contextmint-bridge/releases) (Chrome: download the chrome zip, unzip it, and load it unpacked at `chrome://extensions` with Developer mode on — there is no Chrome Web Store listing yet; Safari: not available yet — it will ship inside the ContextMint app, which has no public download yet, so use Chrome for now), sign into your Canvas instance, and the MCP reads your session cookies from the browser on the first request and again whenever Canvas answers 401 (the session expired). In between, Canvas API calls go directly from Node — the extension is **not** in the request hot path, but it must stay reachable (browser running, extension installed) for the MCP to renew the session. Works with any auth flow (SSO/SAML/2FA included) because Canvas itself handled the sign-in.
52
52
 
53
53
  > **Where the extension comes from.** ContextMint Bridge is the fetchproxy browser extension under its new name, from the same maintainer — fetchproxy's own README ([Extension](https://github.com/chrischall/fetchproxy#extension)) points to it. Its source is public at [nullnet-app/contextmint-bridge](https://github.com/nullnet-app/contextmint-bridge): build it yourself (`npm run build`, per its README), or check a release zip against the `.sha256` file published beside it:
54
54
  >
@@ -101,6 +101,12 @@ If your account uses SSO and you can't use fetchproxy (e.g. headless server), mi
101
101
 
102
102
  See `.env.example`.
103
103
 
104
+ ### Session cache
105
+
106
+ In username/password and OAuth modes the signed-in session is cached between runs, so a restart does not log in (or spend a refresh-token exchange) again. The cache file — `$MCP_DATA_DIR/.canvas-parent-mcp/session.json` by default, or `CANVAS_SESSION_FILE` — holds the live `canvas_session` + `pseudonym_credentials` cookies or the OAuth access token **in plaintext**. It is created owner-only (0600, in a 0700 directory), and only the credential binding is stored as a salted digest; your username, password and refresh token are never written to it. Token and fetchproxy modes never write the cache.
107
+
108
+ Backup and sync tools that run as you can still copy that file. On a shared or backed-up machine, set `CANVAS_SESSION_CACHE=false` to keep the session in memory only (each start then re-authenticates).
109
+
104
110
  ### Bootstrapping OAuth via the mobile QR code
105
111
 
106
112
  If your Canvas admin has disabled personal-access-token creation (some institutions restrict tokens to "the mobile app only") AND your account uses SSO so username/password can't auth, you can mint OAuth credentials by going through the same QR-login flow that the official Canvas mobile apps use:
package/dist/auth.js CHANGED
@@ -31,12 +31,15 @@
31
31
  //
32
32
  // 4. fetchproxy fallback (new)
33
33
  // When no env vars are set, lift the user's session out of their
34
- // already-signed-in canvas tab. `@fetchproxy/bootstrap` opens a
35
- // one-shot WebSocket bridge, asks the extension for the
34
+ // already-signed-in canvas tab. resolveAuth() does not read the
35
+ // browser itself: it hands the client a `refresh` function, and the
36
+ // client calls it lazily on the first request and again on every 401.
37
+ // Each lift asks the extension (via `@fetchproxy/bootstrap`) for the
36
38
  // `canvas_session` + `pseudonym_credentials` cookies (declared
37
- // upfront — that's the security boundary), and closes the bridge.
38
- // Subsequent Canvas API calls go out via plain Node `fetch()` with
39
- // those cookies attached — fetchproxy is NOT in the request hot path.
39
+ // upfront — that's the security boundary). Between lifts, Canvas API
40
+ // calls go out via plain Node `fetch()` with those cookies attached —
41
+ // fetchproxy is NOT in the request hot path, but the extension must
42
+ // stay reachable for the life of the server so a 401 can re-lift.
40
43
  //
41
44
  // Note: `pseudonym_credentials` is HttpOnly, which is fine —
42
45
  // @fetchproxy/bootstrap@^0.3.0 uses `chrome.cookies.get` to read