brightspace-mcp-server 5.2.2 → 5.2.4
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.
|
@@ -44,8 +44,10 @@ export function registerGetDropboxFolders(server, apiClient) {
|
|
|
44
44
|
}
|
|
45
45
|
catch (error) {
|
|
46
46
|
if (error instanceof ApiError && error.status === 403) {
|
|
47
|
-
return errorResponse("
|
|
48
|
-
"
|
|
47
|
+
return errorResponse("Brightspace refused to list this course's assignment folders (403). Students can " +
|
|
48
|
+
"normally read this list, so the likely causes are that you are not enrolled in this " +
|
|
49
|
+
"course (check the courseId with get_my_courses) or that the course hides its " +
|
|
50
|
+
"Assignments tool from your role. Check the course in Brightspace.", "permission");
|
|
49
51
|
}
|
|
50
52
|
if (error instanceof ApiError && error.status === 404) {
|
|
51
53
|
return toolResponse({
|
|
@@ -45,14 +45,23 @@ export function registerGetMyGroups(server, apiClient) {
|
|
|
45
45
|
try {
|
|
46
46
|
log("DEBUG", "get_my_groups tool called", { args });
|
|
47
47
|
const { courseId } = GetMyGroupsSchema.parse(args);
|
|
48
|
-
const { matches, categoriesUnavailable, unreadCategories } = await fetchMyGroupMemberships(apiClient, courseId);
|
|
48
|
+
const { matches, categoriesUnavailable, categoriesStatus, unreadCategories } = await fetchMyGroupMemberships(apiClient, courseId);
|
|
49
|
+
// An empty `groups` here means "not read", not "none": the field lets a
|
|
50
|
+
// caller tell the two apart without parsing the note (#442).
|
|
49
51
|
if (categoriesUnavailable) {
|
|
50
52
|
return toolResponse({
|
|
51
53
|
courseId,
|
|
52
54
|
groups: [],
|
|
53
|
-
|
|
55
|
+
groupsUnavailable: { status: categoriesStatus ?? null },
|
|
56
|
+
note: categoriesStatus === 403
|
|
57
|
+
? "Brightspace refused this course's group list (403), so whether the current user is in a group " +
|
|
58
|
+
"is unknown. Don't tell them they have no group; they can check Groups in Brightspace."
|
|
59
|
+
: "No groups are visible for this course (it may not use groups, or group info isn't accessible), " +
|
|
60
|
+
"so whether the current user is in a group is unknown.",
|
|
54
61
|
});
|
|
55
62
|
}
|
|
63
|
+
const unreadNames = unreadCategories.map((c) => c.Name || String(c.GroupCategoryId));
|
|
64
|
+
const unreadField = unreadNames.length > 0 ? { unreadCategories: unreadNames } : {};
|
|
56
65
|
const unreadNote = unreadCategories.length === 0 ? undefined
|
|
57
66
|
: `Couldn't read the groups in ${unreadCategories.map((c) => `"${c.Name || c.GroupCategoryId}"`).join(", ")}, ` +
|
|
58
67
|
"so any group the current user has there is not listed.";
|
|
@@ -63,7 +72,7 @@ export function registerGetMyGroups(server, apiClient) {
|
|
|
63
72
|
});
|
|
64
73
|
}
|
|
65
74
|
if (matches.length === 0 && unreadNote) {
|
|
66
|
-
return toolResponse({ courseId, groups: [], note: unreadNote });
|
|
75
|
+
return toolResponse({ courseId, groups: [], ...unreadField, note: unreadNote });
|
|
67
76
|
}
|
|
68
77
|
if (matches.length === 0) {
|
|
69
78
|
log("INFO", `get_my_groups: User is not a member of any group in course ${courseId}`);
|
|
@@ -140,7 +149,7 @@ export function registerGetMyGroups(server, apiClient) {
|
|
|
140
149
|
: "Couldn't read this course's classlist, so member names are null; only user ids are listed" +
|
|
141
150
|
(pageNames.size > 0 ? ", except where memberNames lists a group's members from its member page." : ".");
|
|
142
151
|
const note = [unreadNote, namesNote].filter(Boolean).join(" ") || undefined;
|
|
143
|
-
return toolResponse({ courseId, groups, ...(note ? { note } : {}) });
|
|
152
|
+
return toolResponse({ courseId, groups, ...unreadField, ...(note ? { note } : {}) });
|
|
144
153
|
}
|
|
145
154
|
catch (error) {
|
|
146
155
|
return sanitizeError(error);
|
|
@@ -31,8 +31,10 @@ export function registerGetRubricsForObject(server, apiClient) {
|
|
|
31
31
|
}
|
|
32
32
|
catch (error) {
|
|
33
33
|
if (error instanceof ApiError && error.status === 403) {
|
|
34
|
-
return errorResponse("
|
|
35
|
-
"
|
|
34
|
+
return errorResponse("Brightspace refused to list this course's assignment folders (403). Students can " +
|
|
35
|
+
"normally read this list, so the likely causes are that you are not enrolled in this " +
|
|
36
|
+
"course (check the courseId with get_my_courses) or that the course hides its " +
|
|
37
|
+
"Assignments tool from your role. Check the course in Brightspace.", "permission");
|
|
36
38
|
}
|
|
37
39
|
if (error instanceof ApiError && error.status === 404) {
|
|
38
40
|
return toolResponse({
|
|
@@ -21,7 +21,12 @@ export async function fetchMyGroupMemberships(apiClient, courseId, categoryId) {
|
|
|
21
21
|
}
|
|
22
22
|
catch (error) {
|
|
23
23
|
if (inaccessible(error)) {
|
|
24
|
-
return {
|
|
24
|
+
return {
|
|
25
|
+
matches: [],
|
|
26
|
+
categoriesUnavailable: true,
|
|
27
|
+
categoriesStatus: error.status,
|
|
28
|
+
unreadCategories: [],
|
|
29
|
+
};
|
|
25
30
|
}
|
|
26
31
|
throw error;
|
|
27
32
|
}
|
|
@@ -45,5 +50,5 @@ export async function fetchMyGroupMemberships(apiClient, courseId, categoryId) {
|
|
|
45
50
|
matches.push({ category, group });
|
|
46
51
|
}
|
|
47
52
|
}
|
|
48
|
-
return { matches, categoriesUnavailable: false, unreadCategories };
|
|
53
|
+
return { matches, categoriesUnavailable: false, categoriesStatus: undefined, unreadCategories };
|
|
49
54
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brightspace-mcp-server",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.4",
|
|
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",
|