brightspace-mcp-server 5.1.30 → 5.1.32

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.
@@ -3,7 +3,6 @@
3
3
  * Copyright (c) 2026 Rohan Muppa. All rights reserved.
4
4
  * Licensed under MIT — see LICENSE file for details.
5
5
  */
6
- import { DEFAULT_CACHE_TTLS } from "./types.js";
7
6
  import { TTLCache } from "./cache.js";
8
7
  import { TokenBucket } from "./rate-limiter.js";
9
8
  import { discoverVersions } from "./version-discovery.js";
@@ -114,7 +113,7 @@ const LE_VERSION = "{le}";
114
113
  * - Auto-discovers LP/LE versions from /d2l/api/versions/ on the first request
115
114
  * - Supports both Bearer tokens and cookie-based auth (auto-detected via "cookie:" prefix)
116
115
  * - Client-side rate limiting using token bucket algorithm
117
- * - In-memory response caching with per-data-type TTLs
116
+ * - In-memory response caching (each caller passes its TTL to get())
118
117
  * - 401 recovery: refresh the token before requesting browser authentication
119
118
  * - HTTPS-only enforcement
120
119
  * - Browser-like User-Agent for requests
@@ -125,7 +124,6 @@ export class D2LApiClient {
125
124
  tokenManager;
126
125
  cache;
127
126
  rateLimiter;
128
- cacheTTLs;
129
127
  timeoutMs;
130
128
  onAuthExpired;
131
129
  authExpiredMessage;
@@ -181,8 +179,6 @@ export class D2LApiClient {
181
179
  this.onAuthExpired = options.onAuthExpired;
182
180
  this.authExpiredMessage = options.authExpiredMessage;
183
181
  this.retryConfig = options.retry ?? {};
184
- // Merge user-provided TTLs with defaults
185
- this.cacheTTLs = { ...DEFAULT_CACHE_TTLS, ...options.cacheTTLs };
186
182
  // Initialize cache and rate limiter
187
183
  this.cache = new TTLCache();
188
184
  // Sized for the per-course fan-out the tools do (a dozen courses is ~60
@@ -62,6 +62,7 @@ export function registerGetMyGroups(server, apiClient) {
62
62
  // though it looks numeric, so it must be coerced before it can be
63
63
  // used as a key alongside the numeric Enrollments ids.
64
64
  let classlistById = new Map();
65
+ let namesUnavailable = false;
65
66
  try {
66
67
  const classlist = await fetchClasslistUsers(apiClient, courseId);
67
68
  classlistById = new Map(classlist.map((u) => [Number(u.Identifier), u]));
@@ -69,6 +70,7 @@ export function registerGetMyGroups(server, apiClient) {
69
70
  catch (error) {
70
71
  if (isMissingOrForbidden(error)) {
71
72
  log("INFO", "get_my_groups: Classlist not accessible, member names will be null", { courseId });
73
+ namesUnavailable = true;
72
74
  }
73
75
  else {
74
76
  throw error;
@@ -90,7 +92,14 @@ export function registerGetMyGroups(server, apiClient) {
90
92
  };
91
93
  });
92
94
  log("INFO", `get_my_groups: Found ${groups.length} groups for course ${courseId}`);
93
- return toolResponse({ courseId, groups, ...(unreadNote ? { note: unreadNote } : {}) });
95
+ // Null names are only meaningful with a reason attached: without one,
96
+ // a caller can't tell "the classlist couldn't be read" from "these
97
+ // members have no names", and may report the group as anonymous.
98
+ const namesNote = namesUnavailable
99
+ ? "Couldn't read this course's classlist, so member names are null; only user ids are listed."
100
+ : undefined;
101
+ const note = [unreadNote, namesNote].filter(Boolean).join(" ") || undefined;
102
+ return toolResponse({ courseId, groups, ...(note ? { note } : {}) });
94
103
  }
95
104
  catch (error) {
96
105
  return sanitizeError(error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brightspace-mcp-server",
3
- "version": "5.1.30",
3
+ "version": "5.1.32",
4
4
  "mcpName": "io.github.RohanMuppa/brightspace",
5
5
  "description": "MCP server for Brightspace (D2L). Check grades, due dates, assignments, announcements, syllabus, rosters and more via Claude, ChatGPT, Cursor, Windsurf, or any MCP client.",
6
6
  "type": "module",