brightspace-mcp-server 3.15.0 → 3.15.1

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.
@@ -37,6 +37,7 @@ export function registerGetCalendarEvents(server, apiClient, config) {
37
37
  // have gone out independently. Collect it rather than failing the
38
38
  // whole call and losing every course that *did* answer.
39
39
  const pendingCourseIds = [];
40
+ const failedCourseIds = [];
40
41
  let firstAuthError = null;
41
42
  const events = results
42
43
  .flatMap((result, i) => {
@@ -48,23 +49,37 @@ export function registerGetCalendarEvents(server, apiClient, config) {
48
49
  log("DEBUG", `get_calendar_events: sign-in pending for course ${courses[i].id}`, result.reason);
49
50
  return [];
50
51
  }
51
- log("DEBUG", `get_calendar_events: skipping course ${courses[i].id} after fetch failure`, result.reason);
52
+ // Anything else (a 404, a 5xx, a dropped connection) still must
53
+ // not make the course vanish: an exam missing from a list that
54
+ // looks complete reads as "no exam" (#262).
55
+ failedCourseIds.push(courses[i].id);
56
+ log("DEBUG", `get_calendar_events: calendar unavailable for course ${courses[i].id}`, result.reason);
52
57
  return [];
53
58
  })
54
59
  .filter((event) => includeGenerated || !event.generatedFrom)
55
60
  .sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime());
56
61
  log("INFO", `get_calendar_events: Retrieved ${events.length} events across ${courses.length} courses` +
57
- (pendingCourseIds.length > 0 ? ` (${pendingCourseIds.length} pending sign-in)` : ""));
62
+ (pendingCourseIds.length > 0 ? ` (${pendingCourseIds.length} pending sign-in)` : "") +
63
+ (failedCourseIds.length > 0 ? ` (${failedCourseIds.length} failed)` : ""));
58
64
  // The response is always a bare array, pending sign-in or not — a
59
- // shape change would break every existing caller. A pending course
60
- // instead adds a second content block carrying the notice, which
61
- // names which course ids are unavailable.
62
- if (pendingCourseIds.length === 0) {
65
+ // shape change would break every existing caller. A pending or failed
66
+ // course instead adds a second content block carrying the notice,
67
+ // which names which course ids are unavailable.
68
+ const notices = [];
69
+ if (pendingCourseIds.length > 0) {
70
+ notices.push("Sign-in to Brightspace is still in progress, so calendar events for " +
71
+ `${pendingCourseIds.length} course(s) (${pendingCourseIds.join(", ")}) could not be fetched ` +
72
+ `yet. ${authPendingNotice(firstAuthError)} Call get_calendar_events again once sign-in finishes.`);
73
+ }
74
+ if (failedCourseIds.length > 0) {
75
+ notices.push(`Calendar events for ${failedCourseIds.length} course(s) (${failedCourseIds.join(", ")}) ` +
76
+ "could not be read from Brightspace, so they are missing from this list. Do not report " +
77
+ "these courses as having no events: call get_calendar_events again with that courseId.");
78
+ }
79
+ if (notices.length === 0) {
63
80
  return toolResponse(events);
64
81
  }
65
- return toolResponseWithNotice(events, "Sign-in to Brightspace is still in progress, so calendar events for " +
66
- `${pendingCourseIds.length} course(s) (${pendingCourseIds.join(", ")}) could not be fetched ` +
67
- `yet. ${authPendingNotice(firstAuthError)} Call get_calendar_events again once sign-in finishes.`);
82
+ return toolResponseWithNotice(events, notices.join(" "));
68
83
  }
69
84
  catch (error) {
70
85
  return sanitizeError(error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brightspace-mcp-server",
3
- "version": "3.15.0",
3
+ "version": "3.15.1",
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",