brightspace-mcp-server 5.1.37 → 5.1.39
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/build/tools/get-syllabus.js +18 -4
- package/package.json +2 -2
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { ApiError, DEFAULT_CACHE_TTLS } from "../api/index.js";
|
|
7
7
|
import { GetSyllabusSchema } from "./schemas.js";
|
|
8
|
-
import { toolResponse, sanitizeError, errorResponse, isAuthUnavailable } from "./tool-helpers.js";
|
|
8
|
+
import { toolResponse, sanitizeError, errorResponse, isAuthUnavailable, throwIfCredentialRejected } from "./tool-helpers.js";
|
|
9
9
|
import { convertHtmlToMarkdown } from "../utils/html-converter.js";
|
|
10
10
|
import { stripD2lSessionParams } from "../utils/session-params.js";
|
|
11
11
|
import { secureDownload, readBodyCapped } from "../utils/download-helpers.js";
|
|
@@ -114,7 +114,7 @@ async function discoverExternalSyllabusSources(apiClient, courseId) {
|
|
|
114
114
|
export function registerGetSyllabus(server, apiClient) {
|
|
115
115
|
server.registerTool("get_syllabus", {
|
|
116
116
|
title: "Get Course Syllabus",
|
|
117
|
-
description: "Fetch the syllabus/overview text and optional attachment for a course. Returns the course overview description as markdown. When the syllabus lives in an external LTI tool (e.g. Simple Syllabus), lists those sources in externalSyllabusSources; their contents cannot be read. If some of those lookups could not be completed (e.g. permission denied), externalSyllabusDiscovery says which, and an empty result is then not proof the course has no syllabus. If downloadPath is provided, also downloads the syllabus attachment (e.g. PDF); the directory must already exist, since it is not created for you. IMPORTANT: You MUST ask the user where they want to save the file before calling this tool with a downloadPath.",
|
|
117
|
+
description: "Fetch the syllabus/overview text and optional attachment for a course. Returns the course overview description as markdown. When the syllabus lives in an external LTI tool (e.g. Simple Syllabus), lists those sources in externalSyllabusSources; their contents cannot be read. If some of those lookups could not be completed (e.g. permission denied), externalSyllabusDiscovery says which, and an empty result is then not proof the course has no syllabus. If the attachment request fails with anything but a 404, attachmentUnreadable is true and an empty hasAttachment is not proof the course has no syllabus file. If downloadPath is provided, also downloads the syllabus attachment (e.g. PDF); the directory must already exist, since it is not created for you. IMPORTANT: You MUST ask the user where they want to save the file before calling this tool with a downloadPath.",
|
|
118
118
|
inputSchema: GetSyllabusSchema,
|
|
119
119
|
}, async (args) => {
|
|
120
120
|
try {
|
|
@@ -166,6 +166,9 @@ export function registerGetSyllabus(server, apiClient) {
|
|
|
166
166
|
let attachmentBuffer = null;
|
|
167
167
|
let attachmentFilename = "syllabus";
|
|
168
168
|
let hasAttachment = false;
|
|
169
|
+
// Set when the attachment request failed for any reason but a 404, so
|
|
170
|
+
// a failed read is never reported as "this course has no attachment".
|
|
171
|
+
let attachmentUnreadable = false;
|
|
169
172
|
try {
|
|
170
173
|
const response = await apiClient.getRaw(apiClient.le(courseId, "/overview/attachment"));
|
|
171
174
|
if (response.ok) {
|
|
@@ -193,11 +196,13 @@ export function registerGetSyllabus(server, apiClient) {
|
|
|
193
196
|
}
|
|
194
197
|
}
|
|
195
198
|
catch (error) {
|
|
199
|
+
throwIfCredentialRejected(error);
|
|
196
200
|
if (error instanceof ApiError && error.status === 404) {
|
|
197
201
|
hasAttachment = false;
|
|
198
202
|
}
|
|
199
203
|
else {
|
|
200
|
-
|
|
204
|
+
attachmentUnreadable = true;
|
|
205
|
+
log("INFO", `get_syllabus: Syllabus attachment for course ${courseId} could not be read`, error);
|
|
201
206
|
}
|
|
202
207
|
}
|
|
203
208
|
// Extract text from PDF attachment if available
|
|
@@ -238,7 +243,9 @@ export function registerGetSyllabus(server, apiClient) {
|
|
|
238
243
|
else if (downloadPath && !attachmentBuffer) {
|
|
239
244
|
download = {
|
|
240
245
|
success: false,
|
|
241
|
-
error:
|
|
246
|
+
error: attachmentUnreadable
|
|
247
|
+
? "The syllabus attachment could not be read from Brightspace, so nothing was saved. Try again, or download it from the course in Brightspace."
|
|
248
|
+
: "No attachment found for this course's syllabus.",
|
|
242
249
|
};
|
|
243
250
|
}
|
|
244
251
|
log("INFO", `get_syllabus: Retrieved overview for course ${courseId}`);
|
|
@@ -252,6 +259,13 @@ export function registerGetSyllabus(server, apiClient) {
|
|
|
252
259
|
else {
|
|
253
260
|
result.hasAttachment = hasAttachment;
|
|
254
261
|
}
|
|
262
|
+
if (attachmentUnreadable) {
|
|
263
|
+
result.attachmentUnreadable = true;
|
|
264
|
+
result.attachmentNote =
|
|
265
|
+
"The syllabus attachment could not be read from Brightspace, so this course may still have " +
|
|
266
|
+
"a syllabus file. Do not report the course as having no syllabus attachment: call " +
|
|
267
|
+
"get_syllabus again, or check the course overview in Brightspace.";
|
|
268
|
+
}
|
|
255
269
|
if (download) {
|
|
256
270
|
result.download = download;
|
|
257
271
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brightspace-mcp-server",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.39",
|
|
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",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"file-type": "^22.1.1",
|
|
36
36
|
"playwright": "^1.58.2",
|
|
37
37
|
"sanitize-filename": "^1.6.3",
|
|
38
|
-
"trash": "^
|
|
38
|
+
"trash": "^10.1.1",
|
|
39
39
|
"turndown": "^7.2.2",
|
|
40
40
|
"unpdf": "^1.4.0",
|
|
41
41
|
"zod": "^4.0.0"
|