brightspace-mcp-server 3.2.0 → 3.4.0
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/README.md +1 -0
- package/build/api/cache.js +0 -1
- package/build/api/client.js +0 -1
- package/build/api/errors.js +0 -1
- package/build/api/index.js +0 -1
- package/build/api/paginate.js +0 -1
- package/build/api/rate-limiter.js +0 -1
- package/build/api/retry.js +0 -1
- package/build/api/types.js +0 -1
- package/build/api/version-discovery.js +0 -1
- package/build/auth/auth-cooldown.js +0 -1
- package/build/auth/auth-lock.js +0 -1
- package/build/auth/auth-runner.js +0 -1
- package/build/auth/browser-auth.js +0 -1
- package/build/auth/browser-state-store.js +0 -1
- package/build/auth/credential-store.js +0 -1
- package/build/auth/duo-mfa.js +0 -1
- package/build/auth/encrypted-store.js +0 -1
- package/build/auth/index.js +0 -1
- package/build/auth/legacy-profile.js +0 -1
- package/build/auth/legacy-state.js +0 -1
- package/build/auth/purdue-sso.js +0 -1
- package/build/auth/session-store.js +0 -1
- package/build/auth/sso-flow.js +0 -1
- package/build/auth/suny-sso.js +0 -1
- package/build/auth/token-manager.js +0 -1
- package/build/auth/token-mint.js +0 -1
- package/build/auth/western-sso.js +0 -1
- package/build/auth-cli.js +0 -1
- package/build/index.js +4 -4
- package/build/setup.js +0 -1
- package/build/tools/download-file.js +0 -1
- package/build/tools/get-announcements.js +0 -3
- package/build/tools/get-assignment-files.js +0 -1
- package/build/tools/get-assignments.js +5 -6
- package/build/tools/get-classlist-emails.js +0 -1
- package/build/tools/get-course-content.js +8 -9
- package/build/tools/get-discussions.js +0 -1
- package/build/tools/get-my-courses.js +0 -1
- package/build/tools/get-my-grades.js +0 -1
- package/build/tools/get-roster.js +0 -1
- package/build/tools/get-server-info.js +32 -0
- package/build/tools/get-syllabus.js +1 -2
- package/build/tools/get-upcoming-due-dates.js +0 -1
- package/build/tools/get-video-transcript.js +0 -1
- package/build/tools/index.js +1 -1
- package/build/tools/schemas.js +1 -1
- package/build/tools/tool-helpers.js +1 -2
- package/build/types/index.js +0 -1
- package/build/update.js +0 -1
- package/build/utils/atomic-write.js +0 -1
- package/build/utils/browser-install.js +0 -1
- package/build/utils/commands.js +0 -1
- package/build/utils/config-store.js +0 -1
- package/build/utils/config.js +0 -1
- package/build/utils/course-filter.js +0 -1
- package/build/utils/deep-links.js +0 -1
- package/build/utils/download-errors.js +0 -1
- package/build/utils/download-helpers.js +0 -1
- package/build/utils/errors.js +0 -1
- package/build/utils/file-validator.js +10 -2
- package/build/utils/html-converter.js +16 -11
- package/build/utils/install-sites.js +0 -1
- package/build/utils/logger.js +0 -1
- package/build/utils/mcp-client-cli.js +0 -1
- package/build/utils/modified-since.js +0 -1
- package/build/utils/pdf-extractor.js +0 -1
- package/build/utils/secure-config.js +0 -1
- package/build/utils/self-update.js +0 -1
- package/build/utils/transcript/captions.js +0 -1
- package/build/utils/transcript/errors.js +0 -1
- package/build/utils/transcript/kaltura.js +0 -1
- package/build/utils/transcript/platform.js +0 -1
- package/build/utils/transcript/types.js +0 -1
- package/build/utils/transcript/youtube.js +0 -1
- package/build/utils/update-checker.js +0 -1
- package/build/utils/zip-extract.js +0 -1
- package/package.json +1 -2
- package/build/api/cache.d.ts +0 -15
- package/build/api/cache.d.ts.map +0 -1
- package/build/api/cache.js.map +0 -1
- package/build/api/client.d.ts +0 -141
- package/build/api/client.d.ts.map +0 -1
- package/build/api/client.js.map +0 -1
- package/build/api/errors.d.ts +0 -27
- package/build/api/errors.d.ts.map +0 -1
- package/build/api/errors.js.map +0 -1
- package/build/api/index.d.ts +0 -13
- package/build/api/index.d.ts.map +0 -1
- package/build/api/index.js.map +0 -1
- package/build/api/paginate.d.ts +0 -23
- package/build/api/paginate.d.ts.map +0 -1
- package/build/api/paginate.js.map +0 -1
- package/build/api/rate-limiter.d.ts +0 -17
- package/build/api/rate-limiter.d.ts.map +0 -1
- package/build/api/rate-limiter.js.map +0 -1
- package/build/api/retry.d.ts +0 -42
- package/build/api/retry.d.ts.map +0 -1
- package/build/api/retry.js.map +0 -1
- package/build/api/types.d.ts +0 -39
- package/build/api/types.d.ts.map +0 -1
- package/build/api/types.js.map +0 -1
- package/build/api/version-discovery.d.ts +0 -16
- package/build/api/version-discovery.d.ts.map +0 -1
- package/build/api/version-discovery.js.map +0 -1
- package/build/auth/auth-cooldown.d.ts +0 -24
- package/build/auth/auth-cooldown.d.ts.map +0 -1
- package/build/auth/auth-cooldown.js.map +0 -1
- package/build/auth/auth-lock.d.ts +0 -7
- package/build/auth/auth-lock.d.ts.map +0 -1
- package/build/auth/auth-lock.js.map +0 -1
- package/build/auth/auth-runner.d.ts +0 -61
- package/build/auth/auth-runner.d.ts.map +0 -1
- package/build/auth/auth-runner.js.map +0 -1
- package/build/auth/browser-auth.d.ts +0 -94
- package/build/auth/browser-auth.d.ts.map +0 -1
- package/build/auth/browser-auth.js.map +0 -1
- package/build/auth/browser-state-store.d.ts +0 -19
- package/build/auth/browser-state-store.d.ts.map +0 -1
- package/build/auth/browser-state-store.js.map +0 -1
- package/build/auth/credential-store.d.ts +0 -29
- package/build/auth/credential-store.d.ts.map +0 -1
- package/build/auth/credential-store.js.map +0 -1
- package/build/auth/duo-mfa.d.ts +0 -23
- package/build/auth/duo-mfa.d.ts.map +0 -1
- package/build/auth/duo-mfa.js.map +0 -1
- package/build/auth/encrypted-store.d.ts +0 -25
- package/build/auth/encrypted-store.d.ts.map +0 -1
- package/build/auth/encrypted-store.js.map +0 -1
- package/build/auth/index.d.ts +0 -14
- package/build/auth/index.d.ts.map +0 -1
- package/build/auth/index.js.map +0 -1
- package/build/auth/legacy-profile.d.ts +0 -3
- package/build/auth/legacy-profile.d.ts.map +0 -1
- package/build/auth/legacy-profile.js.map +0 -1
- package/build/auth/legacy-state.d.ts +0 -14
- package/build/auth/legacy-state.d.ts.map +0 -1
- package/build/auth/legacy-state.js.map +0 -1
- package/build/auth/purdue-sso.d.ts +0 -57
- package/build/auth/purdue-sso.d.ts.map +0 -1
- package/build/auth/purdue-sso.js.map +0 -1
- package/build/auth/session-store.d.ts +0 -28
- package/build/auth/session-store.d.ts.map +0 -1
- package/build/auth/session-store.js.map +0 -1
- package/build/auth/sso-flow.d.ts +0 -42
- package/build/auth/sso-flow.d.ts.map +0 -1
- package/build/auth/sso-flow.js.map +0 -1
- package/build/auth/suny-sso.d.ts +0 -53
- package/build/auth/suny-sso.d.ts.map +0 -1
- package/build/auth/suny-sso.js.map +0 -1
- package/build/auth/token-manager.d.ts +0 -74
- package/build/auth/token-manager.d.ts.map +0 -1
- package/build/auth/token-manager.js.map +0 -1
- package/build/auth/token-mint.d.ts +0 -32
- package/build/auth/token-mint.d.ts.map +0 -1
- package/build/auth/token-mint.js.map +0 -1
- package/build/auth/western-sso.d.ts +0 -15
- package/build/auth/western-sso.d.ts.map +0 -1
- package/build/auth/western-sso.js.map +0 -1
- package/build/auth-cli.d.ts +0 -4
- package/build/auth-cli.d.ts.map +0 -1
- package/build/auth-cli.js.map +0 -1
- package/build/index.d.ts +0 -10
- package/build/index.d.ts.map +0 -1
- package/build/index.js.map +0 -1
- package/build/setup.d.ts +0 -10
- package/build/setup.d.ts.map +0 -1
- package/build/setup.js.map +0 -1
- package/build/tools/download-file.d.ts +0 -16
- package/build/tools/download-file.d.ts.map +0 -1
- package/build/tools/download-file.js.map +0 -1
- package/build/tools/get-announcements.d.ts +0 -77
- package/build/tools/get-announcements.d.ts.map +0 -1
- package/build/tools/get-announcements.js.map +0 -1
- package/build/tools/get-assignment-files.d.ts +0 -12
- package/build/tools/get-assignment-files.d.ts.map +0 -1
- package/build/tools/get-assignment-files.js.map +0 -1
- package/build/tools/get-assignments.d.ts +0 -19
- package/build/tools/get-assignments.d.ts.map +0 -1
- package/build/tools/get-assignments.js.map +0 -1
- package/build/tools/get-classlist-emails.d.ts +0 -12
- package/build/tools/get-classlist-emails.d.ts.map +0 -1
- package/build/tools/get-classlist-emails.js.map +0 -1
- package/build/tools/get-course-content.d.ts +0 -12
- package/build/tools/get-course-content.d.ts.map +0 -1
- package/build/tools/get-course-content.js.map +0 -1
- package/build/tools/get-discussions.d.ts +0 -12
- package/build/tools/get-discussions.d.ts.map +0 -1
- package/build/tools/get-discussions.js.map +0 -1
- package/build/tools/get-my-courses.d.ts +0 -13
- package/build/tools/get-my-courses.d.ts.map +0 -1
- package/build/tools/get-my-courses.js.map +0 -1
- package/build/tools/get-my-grades.d.ts +0 -13
- package/build/tools/get-my-grades.d.ts.map +0 -1
- package/build/tools/get-my-grades.js.map +0 -1
- package/build/tools/get-roster.d.ts +0 -12
- package/build/tools/get-roster.d.ts.map +0 -1
- package/build/tools/get-roster.js.map +0 -1
- package/build/tools/get-syllabus.d.ts +0 -12
- package/build/tools/get-syllabus.d.ts.map +0 -1
- package/build/tools/get-syllabus.js.map +0 -1
- package/build/tools/get-upcoming-due-dates.d.ts +0 -13
- package/build/tools/get-upcoming-due-dates.d.ts.map +0 -1
- package/build/tools/get-upcoming-due-dates.js.map +0 -1
- package/build/tools/get-video-transcript.d.ts +0 -13
- package/build/tools/get-video-transcript.d.ts.map +0 -1
- package/build/tools/get-video-transcript.js.map +0 -1
- package/build/tools/index.d.ts +0 -21
- package/build/tools/index.d.ts.map +0 -1
- package/build/tools/index.js.map +0 -1
- package/build/tools/schemas.d.ts +0 -83
- package/build/tools/schemas.d.ts.map +0 -1
- package/build/tools/schemas.js.map +0 -1
- package/build/tools/tool-helpers.d.ts +0 -27
- package/build/tools/tool-helpers.d.ts.map +0 -1
- package/build/tools/tool-helpers.js.map +0 -1
- package/build/types/index.d.ts +0 -63
- package/build/types/index.d.ts.map +0 -1
- package/build/types/index.js.map +0 -1
- package/build/update.d.ts +0 -10
- package/build/update.d.ts.map +0 -1
- package/build/update.js.map +0 -1
- package/build/utils/atomic-write.d.ts +0 -18
- package/build/utils/atomic-write.d.ts.map +0 -1
- package/build/utils/atomic-write.js.map +0 -1
- package/build/utils/browser-install.d.ts +0 -23
- package/build/utils/browser-install.d.ts.map +0 -1
- package/build/utils/browser-install.js.map +0 -1
- package/build/utils/commands.d.ts +0 -26
- package/build/utils/commands.d.ts.map +0 -1
- package/build/utils/commands.js.map +0 -1
- package/build/utils/config-store.d.ts +0 -24
- package/build/utils/config-store.d.ts.map +0 -1
- package/build/utils/config-store.js.map +0 -1
- package/build/utils/config.d.ts +0 -10
- package/build/utils/config.d.ts.map +0 -1
- package/build/utils/config.js.map +0 -1
- package/build/utils/course-filter.d.ts +0 -31
- package/build/utils/course-filter.d.ts.map +0 -1
- package/build/utils/course-filter.js.map +0 -1
- package/build/utils/deep-links.d.ts +0 -17
- package/build/utils/deep-links.d.ts.map +0 -1
- package/build/utils/deep-links.js.map +0 -1
- package/build/utils/download-errors.d.ts +0 -45
- package/build/utils/download-errors.d.ts.map +0 -1
- package/build/utils/download-errors.js.map +0 -1
- package/build/utils/download-helpers.d.ts +0 -31
- package/build/utils/download-helpers.d.ts.map +0 -1
- package/build/utils/download-helpers.js.map +0 -1
- package/build/utils/errors.d.ts +0 -21
- package/build/utils/errors.d.ts.map +0 -1
- package/build/utils/errors.js.map +0 -1
- package/build/utils/file-validator.d.ts +0 -56
- package/build/utils/file-validator.d.ts.map +0 -1
- package/build/utils/file-validator.js.map +0 -1
- package/build/utils/html-converter.d.ts +0 -17
- package/build/utils/html-converter.d.ts.map +0 -1
- package/build/utils/html-converter.js.map +0 -1
- package/build/utils/install-sites.d.ts +0 -60
- package/build/utils/install-sites.d.ts.map +0 -1
- package/build/utils/install-sites.js.map +0 -1
- package/build/utils/logger.d.ts +0 -10
- package/build/utils/logger.d.ts.map +0 -1
- package/build/utils/logger.js.map +0 -1
- package/build/utils/mcp-client-cli.d.ts +0 -12
- package/build/utils/mcp-client-cli.d.ts.map +0 -1
- package/build/utils/mcp-client-cli.js.map +0 -1
- package/build/utils/modified-since.d.ts +0 -19
- package/build/utils/modified-since.d.ts.map +0 -1
- package/build/utils/modified-since.js.map +0 -1
- package/build/utils/pdf-extractor.d.ts +0 -14
- package/build/utils/pdf-extractor.d.ts.map +0 -1
- package/build/utils/pdf-extractor.js.map +0 -1
- package/build/utils/secure-config.d.ts +0 -6
- package/build/utils/secure-config.d.ts.map +0 -1
- package/build/utils/secure-config.js.map +0 -1
- package/build/utils/self-update.d.ts +0 -61
- package/build/utils/self-update.d.ts.map +0 -1
- package/build/utils/self-update.js.map +0 -1
- package/build/utils/transcript/captions.d.ts +0 -40
- package/build/utils/transcript/captions.d.ts.map +0 -1
- package/build/utils/transcript/captions.js.map +0 -1
- package/build/utils/transcript/errors.d.ts +0 -14
- package/build/utils/transcript/errors.d.ts.map +0 -1
- package/build/utils/transcript/errors.js.map +0 -1
- package/build/utils/transcript/kaltura.d.ts +0 -8
- package/build/utils/transcript/kaltura.d.ts.map +0 -1
- package/build/utils/transcript/kaltura.js.map +0 -1
- package/build/utils/transcript/platform.d.ts +0 -23
- package/build/utils/transcript/platform.d.ts.map +0 -1
- package/build/utils/transcript/platform.js.map +0 -1
- package/build/utils/transcript/types.d.ts +0 -22
- package/build/utils/transcript/types.d.ts.map +0 -1
- package/build/utils/transcript/types.js.map +0 -1
- package/build/utils/transcript/youtube.d.ts +0 -8
- package/build/utils/transcript/youtube.d.ts.map +0 -1
- package/build/utils/transcript/youtube.js.map +0 -1
- package/build/utils/update-checker.d.ts +0 -112
- package/build/utils/update-checker.d.ts.map +0 -1
- package/build/utils/update-checker.js.map +0 -1
- package/build/utils/zip-extract.d.ts +0 -15
- package/build/utils/zip-extract.d.ts.map +0 -1
- package/build/utils/zip-extract.js.map +0 -1
package/README.md
CHANGED
|
@@ -117,6 +117,7 @@ npx -y brightspace-mcp-server@latest auth
|
|
|
117
117
|
| Roster | "Who are the TAs for ECE 264?" · "Get me my instructor's email" |
|
|
118
118
|
| Discussions | "What are people saying in the final project thread?" · "Summarize the latest discussion posts" |
|
|
119
119
|
| Video transcripts | "What did the professor say about pinch-off in Tuesday's lecture recording?" · "Summarize last week's BoilerCast video" — works for Kaltura and YouTube embeds; other platforms report that they aren't supported yet |
|
|
120
|
+
| Troubleshooting | "Which version of the Brightspace server am I running?" · "Where is my Brightspace config file?" — `get_server_info` reports the version, Node runtime, platform, config and session paths, school URL, and whether a credential is stored, without contacting Brightspace or revealing secrets |
|
|
120
121
|
| Planning | "Build me a study schedule based on my upcoming due dates" · "Which class needs the most attention right now?" — pulls from assignments, quizzes, and graded discussion topics (any topic with a due date) |
|
|
121
122
|
|
|
122
123
|
|
package/build/api/cache.js
CHANGED
package/build/api/client.js
CHANGED
package/build/api/errors.js
CHANGED
package/build/api/index.js
CHANGED
package/build/api/paginate.js
CHANGED
package/build/api/retry.js
CHANGED
package/build/api/types.js
CHANGED
package/build/auth/auth-lock.js
CHANGED
package/build/auth/duo-mfa.js
CHANGED
package/build/auth/index.js
CHANGED
package/build/auth/purdue-sso.js
CHANGED
package/build/auth/sso-flow.js
CHANGED
package/build/auth/suny-sso.js
CHANGED
package/build/auth/token-mint.js
CHANGED
package/build/auth-cli.js
CHANGED
package/build/index.js
CHANGED
|
@@ -16,7 +16,7 @@ import { startUpdateChecks } from "./utils/update-checker.js";
|
|
|
16
16
|
import { readFileSync } from "node:fs";
|
|
17
17
|
import { fileURLToPath } from "node:url";
|
|
18
18
|
import { dirname, resolve } from "node:path";
|
|
19
|
-
import { registerGetMyCourses, registerGetUpcomingDueDates, registerGetMyGrades, registerGetAnnouncements, registerGetAssignments, registerGetAssignmentFiles, registerGetCourseContent, registerDownloadFile, registerGetClasslistEmails, registerGetRoster, registerGetSyllabus, registerGetDiscussions, registerGetVideoTranscript, } from "./tools/index.js";
|
|
19
|
+
import { registerGetMyCourses, registerGetUpcomingDueDates, registerGetMyGrades, registerGetAnnouncements, registerGetAssignments, registerGetAssignmentFiles, registerGetCourseContent, registerDownloadFile, registerGetClasslistEmails, registerGetRoster, registerGetSyllabus, registerGetDiscussions, registerGetVideoTranscript, registerGetServerInfo, } from "./tools/index.js";
|
|
20
20
|
const __filename = fileURLToPath(import.meta.url);
|
|
21
21
|
const __dirname = dirname(__filename);
|
|
22
22
|
const PKG_VERSION = (() => {
|
|
@@ -113,11 +113,12 @@ else {
|
|
|
113
113
|
registerGetSyllabus(server, apiClient);
|
|
114
114
|
registerGetDiscussions(server, apiClient);
|
|
115
115
|
registerGetVideoTranscript(server, apiClient);
|
|
116
|
-
|
|
116
|
+
registerGetServerInfo(server, config, PKG_VERSION);
|
|
117
|
+
log("DEBUG", "MCP tools registered (14 tools)");
|
|
117
118
|
// Connect stdio transport
|
|
118
119
|
const transport = new StdioServerTransport();
|
|
119
120
|
await server.connect(transport);
|
|
120
|
-
log("INFO", "Brightspace MCP Server by Rohan Muppa — running on stdio (
|
|
121
|
+
log("INFO", "Brightspace MCP Server by Rohan Muppa — running on stdio (14 tools registered)");
|
|
121
122
|
log("INFO", "Setup: see README.md for MCP client configuration (Claude Desktop, ChatGPT Desktop, Cursor, etc.)");
|
|
122
123
|
}
|
|
123
124
|
catch (error) {
|
|
@@ -136,4 +137,3 @@ else {
|
|
|
136
137
|
});
|
|
137
138
|
main();
|
|
138
139
|
}
|
|
139
|
-
//# sourceMappingURL=index.js.map
|
package/build/setup.js
CHANGED
|
@@ -60,8 +60,6 @@ export function mapNewsItem(item) {
|
|
|
60
60
|
title: item.Title,
|
|
61
61
|
body: item.Body?.Text ?? "",
|
|
62
62
|
createdBy: item.CreatedBy?.DisplayName ?? "Unknown",
|
|
63
|
-
createdDate: item.CreatedDate,
|
|
64
|
-
startDate: item.StartDate,
|
|
65
63
|
date: effectiveDate(item),
|
|
66
64
|
isPinned: item.IsPinned,
|
|
67
65
|
lastModified: item.LastModifiedDate ?? null,
|
|
@@ -166,4 +164,3 @@ export function registerGetAnnouncements(server, apiClient, config) {
|
|
|
166
164
|
}
|
|
167
165
|
});
|
|
168
166
|
}
|
|
169
|
-
//# sourceMappingURL=get-announcements.js.map
|
|
@@ -147,8 +147,8 @@ export async function fetchCourseAssignments(apiClient, courseId, baseUrl) {
|
|
|
147
147
|
name: folder.Name,
|
|
148
148
|
url: baseUrl ? assignmentUrl(baseUrl, courseId, folder.Id) : null,
|
|
149
149
|
instructions: folder.CustomInstructions?.Html
|
|
150
|
-
? convertHtmlToMarkdown(folder.CustomInstructions.Html)
|
|
151
|
-
:
|
|
150
|
+
? convertHtmlToMarkdown(folder.CustomInstructions.Html).markdown
|
|
151
|
+
: "",
|
|
152
152
|
dueDate: folder.DueDate,
|
|
153
153
|
points: folder.Assessment?.ScoreDenominator ?? null,
|
|
154
154
|
isGroup: folder.GroupTypeId !== null,
|
|
@@ -178,7 +178,7 @@ export async function fetchCourseAssignments(apiClient, courseId, baseUrl) {
|
|
|
178
178
|
? {
|
|
179
179
|
score: feedback.Score,
|
|
180
180
|
feedback: feedback.Feedback?.Html
|
|
181
|
-
? convertHtmlToMarkdown(feedback.Feedback.Html)
|
|
181
|
+
? convertHtmlToMarkdown(feedback.Feedback.Html).markdown
|
|
182
182
|
: null,
|
|
183
183
|
}
|
|
184
184
|
: null,
|
|
@@ -268,8 +268,8 @@ export async function fetchCourseAssignments(apiClient, courseId, baseUrl) {
|
|
|
268
268
|
name: quiz.Name,
|
|
269
269
|
url: baseUrl ? quizUrl(baseUrl, courseId, quiz.QuizId) : null,
|
|
270
270
|
instructions: descriptionHtml
|
|
271
|
-
? convertHtmlToMarkdown(descriptionHtml)
|
|
272
|
-
:
|
|
271
|
+
? convertHtmlToMarkdown(descriptionHtml).markdown
|
|
272
|
+
: "",
|
|
273
273
|
dueDate: quiz.DueDate,
|
|
274
274
|
startDate: quiz.StartDate,
|
|
275
275
|
endDate: quiz.EndDate,
|
|
@@ -404,4 +404,3 @@ export function registerGetAssignments(server, apiClient, config) {
|
|
|
404
404
|
}
|
|
405
405
|
});
|
|
406
406
|
}
|
|
407
|
-
//# sourceMappingURL=get-assignments.js.map
|
|
@@ -69,9 +69,9 @@ async function buildContentTree(apiClient, courseId, modules, progressMap, typeF
|
|
|
69
69
|
id: item.Id,
|
|
70
70
|
title: item.Title,
|
|
71
71
|
description: item.Description?.Text ?? null,
|
|
72
|
-
dueDate: item.ModuleDueDate
|
|
73
|
-
isHidden: item.IsHidden,
|
|
74
|
-
isLocked: item.IsLocked,
|
|
72
|
+
...(item.ModuleDueDate ? { dueDate: item.ModuleDueDate } : {}),
|
|
73
|
+
...(item.IsHidden ? { isHidden: item.IsHidden } : {}),
|
|
74
|
+
...(item.IsLocked ? { isLocked: item.IsLocked } : {}),
|
|
75
75
|
lastModified: item.LastModifiedDate ?? null,
|
|
76
76
|
children: processedChildren,
|
|
77
77
|
});
|
|
@@ -90,12 +90,12 @@ async function buildContentTree(apiClient, courseId, modules, progressMap, typeF
|
|
|
90
90
|
topicType,
|
|
91
91
|
id: item.Id,
|
|
92
92
|
title: item.Title,
|
|
93
|
-
isHidden: item.IsHidden,
|
|
94
|
-
isLocked: item.IsLocked,
|
|
95
|
-
dueDate: item.DueDate
|
|
93
|
+
...(item.IsHidden ? { isHidden: item.IsHidden } : {}),
|
|
94
|
+
...(item.IsLocked ? { isLocked: item.IsLocked } : {}),
|
|
95
|
+
...(item.DueDate ? { dueDate: item.DueDate } : {}),
|
|
96
96
|
lastModified: item.LastModifiedDate ?? null,
|
|
97
97
|
isCompleted: topicProgress?.IsRead ?? false,
|
|
98
|
-
completedDate: topicProgress
|
|
98
|
+
...(topicProgress?.DateCompleted ? { completedDate: topicProgress.DateCompleted } : {}),
|
|
99
99
|
};
|
|
100
100
|
// Add type-specific content
|
|
101
101
|
if (item.TopicType === 1) {
|
|
@@ -109,7 +109,7 @@ async function buildContentTree(apiClient, courseId, modules, progressMap, typeF
|
|
|
109
109
|
}
|
|
110
110
|
// HTML content — include body converted to markdown
|
|
111
111
|
if (item.Description?.Html) {
|
|
112
|
-
topic.content = convertHtmlToMarkdown(item.Description.Html);
|
|
112
|
+
topic.content = convertHtmlToMarkdown(item.Description.Html).markdown;
|
|
113
113
|
}
|
|
114
114
|
tree.push(topic);
|
|
115
115
|
}
|
|
@@ -237,4 +237,3 @@ export function registerGetCourseContent(server, apiClient) {
|
|
|
237
237
|
}
|
|
238
238
|
});
|
|
239
239
|
}
|
|
240
|
-
//# sourceMappingURL=get-course-content.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Purdue Brightspace MCP Server
|
|
3
|
+
* Copyright (c) 2026 Rohan Muppa. All rights reserved.
|
|
4
|
+
* Licensed under MIT — see LICENSE file for details.
|
|
5
|
+
*/
|
|
6
|
+
import { getConfigStorePath } from "../utils/config-store.js";
|
|
7
|
+
import { GetServerInfoSchema } from "./schemas.js";
|
|
8
|
+
import { toolResponse } from "./tool-helpers.js";
|
|
9
|
+
/**
|
|
10
|
+
* Register get_server_info tool.
|
|
11
|
+
*
|
|
12
|
+
* Answers from the startup config alone: no network call, so it can never
|
|
13
|
+
* trigger a sign-in. hasStoredCredential reflects the keychain lookup made at
|
|
14
|
+
* startup, which is the credential this process actually holds. Nothing
|
|
15
|
+
* secret — password, username, token, cookie — is ever included.
|
|
16
|
+
*/
|
|
17
|
+
export function registerGetServerInfo(server, config, version) {
|
|
18
|
+
server.registerTool("get_server_info", {
|
|
19
|
+
title: "Get Server Info",
|
|
20
|
+
description: "Report which version of the Brightspace MCP server is running, the Node.js runtime, platform, config file path, session state directory, configured school URL, and whether a credential is stored. Use this for troubleshooting or when the user asks which version they have. Never contacts Brightspace and never returns secrets.",
|
|
21
|
+
inputSchema: GetServerInfoSchema,
|
|
22
|
+
}, async () => toolResponse({
|
|
23
|
+
version,
|
|
24
|
+
node: process.version,
|
|
25
|
+
platform: process.platform,
|
|
26
|
+
arch: process.arch,
|
|
27
|
+
configPath: getConfigStorePath(),
|
|
28
|
+
sessionStatePath: config.sessionDir,
|
|
29
|
+
schoolUrl: config.baseUrl,
|
|
30
|
+
hasStoredCredential: config.password !== undefined,
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
@@ -61,7 +61,7 @@ export function registerGetSyllabus(server, apiClient) {
|
|
|
61
61
|
}
|
|
62
62
|
// Convert description HTML to markdown
|
|
63
63
|
const description = overview?.Description?.Html
|
|
64
|
-
? convertHtmlToMarkdown(overview.Description.Html)
|
|
64
|
+
? convertHtmlToMarkdown(overview.Description.Html).markdown
|
|
65
65
|
: null;
|
|
66
66
|
// Always attempt to fetch the attachment so we can extract PDF text
|
|
67
67
|
let attachmentBuffer = null;
|
|
@@ -159,4 +159,3 @@ export function registerGetSyllabus(server, apiClient) {
|
|
|
159
159
|
}
|
|
160
160
|
});
|
|
161
161
|
}
|
|
162
|
-
//# sourceMappingURL=get-syllabus.js.map
|
package/build/tools/index.js
CHANGED
|
@@ -17,7 +17,7 @@ export { registerGetRoster } from "./get-roster.js";
|
|
|
17
17
|
export { registerGetSyllabus } from "./get-syllabus.js";
|
|
18
18
|
export { registerGetDiscussions } from "./get-discussions.js";
|
|
19
19
|
export { registerGetVideoTranscript } from "./get-video-transcript.js";
|
|
20
|
+
export { registerGetServerInfo } from "./get-server-info.js";
|
|
20
21
|
// Re-export shared helpers and schemas for convenience
|
|
21
22
|
export { toolResponse, errorResponse, sanitizeError } from "./tool-helpers.js";
|
|
22
23
|
export * from "./schemas.js";
|
|
23
|
-
//# sourceMappingURL=index.js.map
|
package/build/tools/schemas.js
CHANGED
|
@@ -113,4 +113,4 @@ export const GetRosterSchema = z.object({
|
|
|
113
113
|
limit: z.coerce.number().int().positive().max(1000).default(100)
|
|
114
114
|
.describe("Maximum users to return. Default 100. The response reports the true total and whether it was truncated."),
|
|
115
115
|
});
|
|
116
|
-
|
|
116
|
+
export const GetServerInfoSchema = z.object({});
|
|
@@ -24,7 +24,7 @@ export function toolResponse(data) {
|
|
|
24
24
|
const content = [
|
|
25
25
|
{
|
|
26
26
|
type: "text",
|
|
27
|
-
text: JSON.stringify(data
|
|
27
|
+
text: JSON.stringify(data),
|
|
28
28
|
},
|
|
29
29
|
];
|
|
30
30
|
const notice = getUpdateNotice();
|
|
@@ -166,4 +166,3 @@ export function sanitizeError(error) {
|
|
|
166
166
|
// Default fallback
|
|
167
167
|
return errorResponse("An unexpected error occurred. Please try again.");
|
|
168
168
|
}
|
|
169
|
-
//# sourceMappingURL=tool-helpers.js.map
|
package/build/types/index.js
CHANGED
package/build/update.js
CHANGED
package/build/utils/commands.js
CHANGED
|
@@ -23,4 +23,3 @@ export const SETUP_COMMAND = `npx -y ${PACKAGE_NAME}@latest setup`;
|
|
|
23
23
|
export const GLOBAL_INSTALL_COMMAND = `npm install -g ${PACKAGE_NAME}@latest`;
|
|
24
24
|
/** Drop cached npx copies so the next `@latest` genuinely refetches. */
|
|
25
25
|
export const CLEAR_NPX_CACHE_COMMAND = "npx clear-npx-cache";
|
|
26
|
-
//# sourceMappingURL=commands.js.map
|
package/build/utils/config.js
CHANGED
package/build/utils/errors.js
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* Licensed under MIT — see LICENSE file for details.
|
|
5
5
|
*/
|
|
6
6
|
import path from "node:path";
|
|
7
|
-
import { fileTypeFromBuffer } from "file-type";
|
|
8
7
|
import sanitizeFilename from "sanitize-filename";
|
|
9
8
|
import { DownloadError } from "./download-errors.js";
|
|
10
9
|
/**
|
|
@@ -20,6 +19,15 @@ import { DownloadError } from "./download-errors.js";
|
|
|
20
19
|
* extension instead, which admits the formats the allowlist already intended
|
|
21
20
|
* and still refuses everything else.
|
|
22
21
|
*/
|
|
22
|
+
// file-type v21 is ESM-only and costs ~50ms; defer the import to first use
|
|
23
|
+
// since validateFileType is already async.
|
|
24
|
+
let fileTypeFromBufferPromise;
|
|
25
|
+
function getFileTypeFromBuffer() {
|
|
26
|
+
if (!fileTypeFromBufferPromise) {
|
|
27
|
+
fileTypeFromBufferPromise = import("file-type").then((m) => m.fileTypeFromBuffer);
|
|
28
|
+
}
|
|
29
|
+
return fileTypeFromBufferPromise;
|
|
30
|
+
}
|
|
23
31
|
const CFB_MIME = "application/x-cfb";
|
|
24
32
|
const CFB_EXTENSION_MIMES = {
|
|
25
33
|
".doc": "application/msword",
|
|
@@ -113,6 +121,7 @@ export function validateDownloadPath(baseDir, filename) {
|
|
|
113
121
|
*/
|
|
114
122
|
export async function validateFileType(buffer, allowedTypes = ALLOWED_MIME_TYPES, filename) {
|
|
115
123
|
// Try magic byte detection first
|
|
124
|
+
const fileTypeFromBuffer = await getFileTypeFromBuffer();
|
|
116
125
|
const detected = await fileTypeFromBuffer(buffer);
|
|
117
126
|
if (detected) {
|
|
118
127
|
if (detected.mime === CFB_MIME) {
|
|
@@ -181,4 +190,3 @@ export function validateBaseUrl(url, expectedBaseUrl) {
|
|
|
181
190
|
throw new Error(`URL must start with ${expectedBaseUrl}, got: ${url.substring(0, 50)}...`);
|
|
182
191
|
}
|
|
183
192
|
}
|
|
184
|
-
//# sourceMappingURL=file-validator.js.map
|
|
@@ -3,15 +3,21 @@
|
|
|
3
3
|
* Copyright (c) 2026 Rohan Muppa. All rights reserved.
|
|
4
4
|
* Licensed under MIT — see LICENSE file for details.
|
|
5
5
|
*/
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
import { createRequire } from "node:module";
|
|
7
|
+
// turndown is CJS and costs ~50ms to import; defer it to first use via
|
|
8
|
+
// createRequire so callers keep a synchronous API instead of turning async.
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
let turndownService;
|
|
11
|
+
function getTurndownService() {
|
|
12
|
+
if (!turndownService) {
|
|
13
|
+
const TurndownService = require("turndown");
|
|
14
|
+
turndownService = new TurndownService({
|
|
15
|
+
headingStyle: "atx",
|
|
16
|
+
codeBlockStyle: "fenced",
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return turndownService;
|
|
20
|
+
}
|
|
15
21
|
/**
|
|
16
22
|
* Convert D2L HTML content to clean markdown.
|
|
17
23
|
* Returns both markdown (for LLM readability) and raw HTML (for fallback).
|
|
@@ -25,7 +31,7 @@ export function convertHtmlToMarkdown(html) {
|
|
|
25
31
|
return { markdown: "", html: "" };
|
|
26
32
|
}
|
|
27
33
|
try {
|
|
28
|
-
const markdown =
|
|
34
|
+
const markdown = getTurndownService().turndown(html);
|
|
29
35
|
return { markdown, html };
|
|
30
36
|
}
|
|
31
37
|
catch (error) {
|
|
@@ -33,4 +39,3 @@ export function convertHtmlToMarkdown(html) {
|
|
|
33
39
|
return { markdown: html, html };
|
|
34
40
|
}
|
|
35
41
|
}
|
|
36
|
-
//# sourceMappingURL=html-converter.js.map
|
package/build/utils/logger.js
CHANGED