Brightspace-mcp

kennethchapman99/Brightspace-mcp

3.2

If you are the rightful owner of Brightspace-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

The Brightspace MCP Server is a dedicated service that connects D2L Brightspace with AI models using the Model Context Protocol (MCP).

Tools
4
Resources
0
Prompts
0

Brightspace MCP

A Model Context Protocol (MCP) server for D2L Brightspace that exposes common LMS workflows as safe tools. Built for local use with Claude (stdio) and containerized for cloud environments.

Highlights

  • OAuth2 refresh-token auth with automatic refresh, 401 retry, and 429 backoff.
  • High-value tools for real workflows (whoami, courses, users, enrollments, announcements, content, assignments, quizzes, grades) + a generic API call.
  • Version-aware helpers (LP/LE) with fallback candidates.
  • Ready for Claude Desktop/Claude Code (stdio) and for containerized deployment.
  • Unit tests + CI; detailed enterprise guide in Brightspace-MCP.md.

Quick Start

python -m venv .venv
source .venv/bin/activate
pip install -e .
cp .env.example .env  # fill BS_* values

# Mint a refresh token locally (optional helper)
python brightspace_mcp_launcher.py

# Run the MCP server (stdio)
brightspace-mcp --stdio

Environment variables (see .env.example)

  • BS_BASE_URL, BS_CLIENT_ID, BS_CLIENT_SECRET, BS_REFRESH_TOKEN
  • Optional versions: BS_LP_VERSION, BS_LE_VERSION, and *_VERSION_CANDIDATES
  • Optional BS_TOKEN_URL to pin a tenant-specific token endpoint

Connect to Claude

  • Claude Desktop: Edit claude_desktop_config.json and add:
{
  "mcpServers": {
    "brightspace": {
      "command": "/abs/path/to/repo/.venv/bin/brightspace-mcp",
      "args": ["--stdio"],
      "env": {
        "BS_BASE_URL": "https://your.brightspace.host",
        "BS_CLIENT_ID": "...",
        "BS_CLIENT_SECRET": "...",
        "BS_REFRESH_TOKEN": "..."
      }
    }
  }
}
  • Claude Code (VS Code): Add a custom MCP server with the same command/args/env.

Docker

docker build -t brightspace-mcp:latest .
docker run --rm \
  -e BS_BASE_URL=... -e BS_CLIENT_ID=... \
  -e BS_CLIENT_SECRET=... -e BS_REFRESH_TOKEN=... \
  brightspace-mcp:latest

AWS (Overview)

  • Run the container on ECS Fargate. Inject BS_* via AWS Secrets Manager. Keep service internal behind a gateway that speaks MCP or add an HTTP shim if needed.
  • See Brightspace-MCP.md for enterprise guidance (security, scaling, observability, SLOs).

Testing

pip install -e .[test]
pytest -q      # unit tests

Live integration tests are opt-in and require BS_* env vars.

Supported Tools (summary)

  • Generic: bs.api_call, bs.request, bs.paginate, bs.build_path, bs.upload_multipart, bs.download_b64
  • Identity/Discovery: bs.whoami, bs.list_org_units, bs.list_courses, bs.list_users, bs.get_user
  • Enrollments: bs.list_course_enrollments, bs.enroll_user, bs.unenroll_user
  • Announcements: bs.list_announcements, bs.create_announcement, bs.update_announcement, bs.delete_announcement
  • Content: bs.get_content_toc, bs.get_content_topic, bs.download_content_topic_file_b64, bs.create_content_module, bs.create_content_topic
  • Assignments (Dropbox): bs.list_assignments, bs.get_assignment, bs.create_assignment
  • Quizzes: bs.list_quizzes, bs.get_quiz
  • Grades: bs.list_grade_items, bs.get_user_grades, bs.create_grade_item, bs.upsert_user_grade_value

Full details: see Brightspace-MCP.md.

Security

  • Do not commit secrets. .gitignore excludes .env, tokens.json, .tokens.lock.
  • Store secrets in AWS Secrets Manager for cloud deployments. Rotate regularly.

Contributing

See CONTRIBUTING.md. Security policy in SECURITY.md.

Demonstrate Integration: Show Anthropics (and other partners) that D2L can integrate with Claude via MCP, enabling Claude to fetch and manipulate Brightspace data and interact with other MCP partner tools. • Support Multiple Use Cases: Provide tools for admins, instructors, and students to automate or simplify common tasks (detailed in the next section). • Proper Architecture (Not just a Hack): Design the server following best practices (modularity, security, error handling, etc.) rather than a quick one-off script. • Deployable to AWS: Start with a local prototype, but design with cloud deployment in mind (AWS architecture for staging/production), including considerations for scalability, reliability, and maintainability.

Use Cases and Features

We plan to implement a suite of tools (functions) within the Brightspace MCP server to support high-value use cases for various roles. These tools will leverage Brightspace’s REST APIs (and other services like Google/Microsoft) to perform the desired actions, orchestrated through AI. The primary features envisioned include: • 1. Semester Start Automation (Admins): A tool (or set of tools) to orchestrate beginning-of-term setup tasks. For example, “Start Semester” could automatically create course shells from templates, enroll instructors/students, roll over content, and publish welcome announcements in each course. Instead of an admin doing these steps manually, Claude (via the MCP server) could execute them in sequence. This might be implemented as a single composite tool (for demo simplicity) or as multiple granular tools (course creation, enrollment, etc.) that the AI can call in order. • 2. Syllabus Builder (Instructors): Tools to help faculty assemble a course syllabus by pulling in content from various sources: • Policy Retrieval: Fetch institutional policy documents (e.g. academic integrity, disability services) from internal repositories (Google Drive, SharePoint, etc.) via their APIs. The MCP server might include connectors to Google/Microsoft to retrieve these docs by ID or search term. • Course Data: Gather Brightspace course info (learning outcomes, schedules, existing content) via Brightspace API. • Assembly: The AI (Claude) can then compose a draft syllabus by combining the retrieved policy text with course-specific data. The MCP server can provide the raw pieces (policy text, course info) and possibly a tool to create or update a Brightspace syllabus file or HTML topic. • 3. Flashcard Generator (Students): Tools to automatically create study aids from course materials. For instance, a “Generate Flashcards” tool could: • Pull content (lecture notes, slide text, or textbook excerpts) from Brightspace (using content module APIs or file download). • Optionally accept a topic or chapter as input. • Feed the content to an AI prompt (within Claude) to produce Q&A pairs (flashcards), which could then be returned or even stored in Brightspace (perhaps as a quiz or a document). • (Note: This feature leverages Claude’s strength in text generation – the MCP server supplies the content context, and Claude generates the flashcard questions/answers). • 4. Study Group Matchmaker (Students/Admins): A tool to intelligently form study groups. This would involve: • Gathering student data: enrollment in a course, their schedules (if available via an external calendar or input form), learning preferences (possibly via a survey or Brightspace profile data), and performance metrics (e.g. quiz scores or assignment grades from Brightspace). • The MCP server could aggregate this data (from Brightspace API for grades and groups, and possibly a CSV or Google Sheet for schedules/preferences if not in Brightspace). • The AI can then analyze this data to suggest optimal groupings – e.g. mixing students with complementary strengths, matching free times for meetings, ensuring diversity of learning styles, etc. • The outcome might be a suggested list of study groups with members and rationale, which could be presented to the admin or instructor. (In future, possibly even auto-create group structures in Brightspace via the API.)

Each of these features will be exposed as one or more MCP tools that Claude can invoke. For the demo, we’ll focus on implementing the minimum needed to showcase the concept (even if behind the scenes some logic is simplified or stubbed). Over time, we can expand to match the breadth of functionality seen in other LMS MCP integrations (for example, the Canvas MCP server offers 50+ tools covering almost all LMS functions ).

High-Level Architecture

Figure: Model Context Protocol architecture (conceptual). The AI assistant (Claude) connects to the Brightspace MCP Server (via JSON-RPC over a channel such as HTTP or stdio). The Brightspace MCP Server acts as a facade to Brightspace and other services – it receives structured tool calls from Claude and invokes Brightspace’s REST API (or Google/Microsoft APIs for external data) to fulfill the request, then returns results. This design follows the MCP paradigm where each MCP server runs independently and specializes in connecting the AI to a particular system . The host AI application uses an MCP client to manage the communication, so the AI remains agnostic of the Brightspace API specifics. 

Components: • Claude (AI MCP Client): Claude (likely Claude Desktop or Claude in a cloud environment) will serve as the MCP client and the AI brain. It will load the Brightspace MCP server’s schema (tools list and their input/output format) and decide when to call those tools during a conversation. For example, if a user asks “Organize my courses for the new semester,” Claude might call the “semester_start” tool on the Brightspace MCP. • Brightspace MCP Server: This is our service (to be developed). It advertises a set of tools (functions) that can be called via the MCP interface. It encapsulates: • Brightspace API Client Module: In our code, this is represented by the BrightspaceClient class (brightspace_mcp.py). It handles low-level HTTP calls to Brightspace’s REST APIs (GET/POST/PUT), including OAuth2 token refresh, retry on 401/429, pagination, and file upload/download helpers. This client will be used internally by our tools to interact with Brightspace. Having a dedicated client module follows an Adapter pattern – it abstracts Brightspace’s API into Python methods. • Tool Handlers: These are the async functions (like bs.list_courses, bs.create_announcement, etc. in main.py) decorated as mcp.tool. Each corresponds to an action or query Claude can perform. For example, we will have tools such as bs.whoami (to get user info), bs.create_course, bs.enroll_user, bs.get_content, etc., as well as higher-level orchestrations like bs.semester_start() that uses multiple lower-level API calls. Tools will return JSON results (the MCP protocol expects JSON serializable outputs), which Claude then interprets or presents. • External Data Connectors: In addition to Brightspace, our MCP server may integrate with Google Drive, SharePoint, or other internal data sources for the syllabus-builder use case. We can implement this either by directly calling their REST APIs (using their Python SDKs or HTTP calls with OAuth tokens) or by leveraging existing MCP servers (e.g., a Google Drive MCP server). For a self-contained demo, we might include a simple Google Drive integration in our server (with a tool like bs.get_policy_doc(gdoc_id) to fetch a document text, requiring a Google OAuth token in config). This keeps the architecture to one MCP server for simplicity, though in principle one could run separate MCP servers (one for Brightspace, one for Google, etc.) and Claude’s MCP client can connect to multiple servers . In either case, our Brightspace MCP will be designed to allow adding such connectors modularly. • Brightspace LMS (and Other External Systems): These are the actual endpoints our server interacts with. The Brightspace REST API (cloud or self-hosted D2L environment) is the primary system. We will register an OAuth2 application in Brightspace to obtain credentials (client ID/secret and refresh token) for API access. Similarly, if connecting to Google/Microsoft, we need API credentials for those. The MCP server does not expose these credentials to the AI; it only exposes higher-level tool functions. This separation ensures the AI can only perform allowed operations through predefined tools, aligning with MCP’s security intent .

Workflow: When Claude (AI) needs to use Brightspace data or actions, it will issue a JSON-RPC call to the Brightspace MCP server’s tool endpoint. For example, Claude might call bs.list_courses{"page_size":10}. The MCP server receives this, the corresponding handler calls the BrightspaceClient (which makes an HTTP GET to /d2l/api/lp/1.46/courses/), and then returns the JSON result (list of courses). Claude then uses that data in its response to the user or decides on further tool calls. This loop continues as needed. The MCP server remains active awaiting commands and processes each in turn. The protocol and architecture ensure a clean separation: Claude doesn’t directly call Brightspace’s API or database; it goes through the MCP server which translates and mediates the requests .

By structuring the integration as an MCP server, we adhere to proven architectural patterns: • Facade/Gateway: The MCP server provides a simplified, unified interface to Brightspace functionality, hiding complexity of auth and API specifics . • Adapter: It adapts Brightspace’s REST endpoints and data formats to the standard MCP tool schema that the AI client understands . • Sidecar style deployment: The MCP server can run independently (e.g., as a container or service in AWS) alongside the AI platform. This isolates Brightspace integration logic from the AI host, improving modularity and maintainability . • Orchestrator: Complex workflows (like “semester start”) can be handled either by the AI orchestrating multiple tool calls or by the server providing a higher-level tool that internally orchestrates multiple Brightspace calls. We will likely implement critical multi-step flows as single tools for reliability (so the server does the orchestration), thereby simplifying Claude’s reasoning needs and ensuring correct execution order (this is effectively building a mini-orchestrator into the server for those cases). This approach aligns with MCP’s capability to simplify coordination logic .

Security and OAuth2

Security is paramount since the MCP server will have privileged access to LMS data and possibly other sensitive docs. OAuth2 will be used for all integrations: • Brightspace OAuth2: We will use Brightspace’s OAuth 2.0 system to obtain an API token. In the prototype, as shown by our code snippet, we use a refresh token (stored in .env) to programmatically fetch an access token for API calls. The reference architecture assumes we have a Brightspace OAuth client (with appropriate scopes) set up for this purpose. Each API tool in the MCP server will require the necessary OAuth scopes – for example, a tool that creates a course needs the orgunit:course:create scope in Brightspace (the Composio integration highlights scope requirements for each action  ). For demo purposes, using an admin-level token with broad scopes is simplest. In a production scenario, we could implement user-specific OAuth (where each user of Claude would auth and we’d store tokens per user) so that actions are done on behalf of the requesting user with proper permissions. However, initially we can use a system account or admin token to keep things straightforward. • Google/Microsoft OAuth: If we connect to Google Drive or Microsoft 365 for document retrieval, we will register separate OAuth apps for those and store the credentials/tokens. The MCP server might hold a service account credential (for institutional Google Drive access) or use a pre-authorized token for a specific shared drive. All such credentials should be stored securely (not hard-coded). In AWS, we’d use Secrets Manager or AWS SSM Parameter Store to keep secrets, injecting them via environment variables. The architecture ensures the AI never sees these secrets – the AI only asks for data via tools like bs.get_policy_doc, and the server internally uses the token to fetch the doc and returns the content. • Access Control: We will ensure the MCP tools only expose functions we want the AI to use. For example, we might not expose a raw “delete user” API unless needed. Each tool can include checks or fixed parameters if needed (e.g., limiting scope of data). In the future, we could even implement role-based filters where certain high-risk tools require user confirmation. For now, clarity on what the AI can do is achieved by the curated list of tools. • Built-in Authentication: The MCP server will likely run as a service that only our AI client or authorized clients can connect to. For local Claude Desktop, it starts the server for us (no network exposure). For a cloud deployment, we would protect the endpoint (e.g., require an API key or some token on requests from Claude, or run it within a VPC accessible by Claude for Work only). Ensuring secure comms (HTTPS/WSS if applicable) and auth will be part of production hardening (not critical in a closed demo, but worth planning). • Audit Logging: We will log every tool invocation along with the caller (if identifiable) and outcome. This provides an audit trail of what actions the AI took in Brightspace. Brightspace’s own audit logs will show changes, but having logs at the MCP layer (including read-accesses) is useful for debugging and trust.

By following OAuth2 and careful tool exposure, we align with industry best practices. Other MCP integrations emphasize “built-in authentication and security” as a feature , meaning our design similarly must ensure only authorized access and safe operations through the MCP server.

Logging and Tracing

For the prototype, we will implement basic logging and tracing: • Request/Response Logging: Each incoming tool call (from the AI client) can be logged (tool name, parameters, timestamp) and each response or error likewise logged. We can use Python’s logging module to emit structured logs (e.g., JSON lines or key-value pairs) for easy analysis. These logs should not contain sensitive data (we might sanitize or omit sensitive fields in parameters). • Error Handling: The BrightspaceClient already catches common errors (HTTP status codes, exceptions) and returns status and error info. We’ll ensure that errors are logged with stack traces on the server side for debugging. The AI can receive a sanitized error message (from the returned JSON) so it can handle it or apologize to the user. Comprehensive error handling was noted as a strength in the Canvas MCP implementation (with “comprehensive error handling” built-in ), so we aim to match that by handling network errors, Brightspace errors (4xx, 5xx codes), and timeouts gracefully. • Distributed Tracing (future): In an AWS deployment, if we have multiple instances or want deeper insight, we can integrate with tracing systems. For example, using AWS X-Ray or OpenTelemetry to trace a request from the AI through our MCP server to Brightspace and back. This would help identify performance bottlenecks (like a slow Brightspace API call). For now, this might be overkill, but the architecture won’t preclude adding such instrumentation. • Performance Metrics: We can log timing info (how long each tool call takes) and perhaps counts of certain events. Over time, we might integrate with CloudWatch or a monitoring dashboard to see how the MCP server is used (e.g., number of announcements created, etc.). This helps in scaling decisions later. • Tracing IDs: We may assign a correlation ID per request (perhaps the MCP client does this already with request IDs). Ensuring each log line can be tied to a specific tool invocation and conversation is helpful if we need to trace back an AI action when reviewing logs.

For initial development, simple console logging (stdout) is fine (Claude Desktop can even display some logs if run in a terminal). When moving to AWS, we’ll pipe logs to CloudWatch. We should also include a health check endpoint (e.g., /healthz) that returns OK – this isn’t directly used by Claude, but is useful for AWS (e.g., ALB target group health checks or k8s liveness probes) to know the service is up.

Deployment Strategy (Local → AWS)

We will architect the solution to run locally first and then transition to AWS with minimal changes: • Local Development: During initial prototyping, the MCP server can be run on a developer’s machine or a VM. Using the FastMCP framework (as in our main.py), we likely have the option to run the server either as a subprocess controlled by Claude Desktop (via stdio pipes) or as a standalone HTTP server. For ease, we might use stdio for Claude Desktop (which spawns the server via config) to test in the desktop app. We’ll also add an option to launch it as an HTTP server (there is mention of FastMCP likely being built on FastAPI or Starlette under the hood, which could serve HTTP requests). This will allow cloud deployment. • Containerization: We will create a Dockerfile for the Brightspace MCP server. The container will include our code and necessary dependencies (httpx, FastMCP, any SDKs). The Canvas MCP open-source project, for example, provides a Docker image for easy deployment . We will do similarly so that the server can run in AWS Fargate/ECS or Kubernetes. Containerization ensures environment parity (what works locally will work in AWS). • AWS Infrastructure: For an initial deployment, we can use AWS Fargate (serverless containers) behind an Application Load Balancer or API Gateway. The architecture might look like: • An ECS task running our MCP container, in a private subnet. • An Application Load Balancer mapping a public endpoint (or maybe restricted to certain IPs) to the service’s port (if we want external access). Alternatively, if using Claude for Work within the same VPC or through a secure tunnel, we could keep it internal. • AWS Secrets Manager to store Brightspace and Google credentials, injected as env vars. • CloudWatch for logs. • Auto-scaling group if needed (we can scale out horizontally by running multiple instances behind the ALB if one instance can’t handle the load; though for demo, one is fine). • State Management: The server is mostly stateless (each request is independent, aside from the in-memory Brightspace access token which can be re-fetched if a new instance starts). This stateless design is cloud-friendly – we can spin up multiple containers and each will obtain its own access token as needed. If we need to share state (e.g., caching some results or heavy computations), we could use an external cache like Redis or a database, but that’s likely unnecessary initially. • Scaling Considerations: Brightspace API has rate limits; our design with retries (as in BrightspaceClient for 429 handling) helps. In a heavier load scenario (many simultaneous AI requests), we might need to implement a queue or throttle within tools to avoid hitting Brightspace too fast. We might also enable concurrency by running multiple event loop workers or threads. The reference architecture should mention this: in production, one might increase throughput by either scaling vertically (multi-threaded server or async concurrency) or horizontally (multiple instances). The goal is not immediate heavy load, but we document that to “harden for load and availability,” we would: • Deploy multiple instances across availability zones (for high availability). • Possibly use a rate-limiter or token bucket to ensure API calls stay within allowed limits. • Implement more fine-grained error recovery (e.g., if Brightspace is down or returns 500, maybe the tool could inform the AI to retry later). • Add monitoring alarms on error rates or latency to proactively catch issues.

In summary, the deployment will evolve from a simple local server to a containerized cloud service. By using standard frameworks and Docker, we ensure this transition is smooth. The design is “cloud ready” – much like the Canvas MCP server which touts Docker/Kubernetes support and health checks , we aim for our Brightspace MCP to be easily deployable on AWS.

Roadmap and Future Enhancements

While the initial implementation will focus on core functionality and a demo-able set of features, it’s important to plan for future enhancements to make the Brightspace MCP a robust, production-quality service: • Expand Tool Coverage: Beyond the initial use cases, we should gradually add tools to approach parity with other LMS integrations. For example, tools for managing assignments, grades, discussions, files, groups, etc. (Canvas’s MCP has ~50 tools covering most LMS features  ). We can prioritize based on feedback – e.g., quiz creation, grading assistance, content import/export might be next. • Real-time and Event-Driven Capabilities: Currently, MCP is request-driven (AI calls a tool when it needs). In the future, we might integrate event triggers – for instance, if a new policy document is uploaded or a course shell is created, we could have the MCP server (or a companion process) push a notification or have Claude proactively summarize it. This could involve using Brightspace’s webhooks or an event bus. While not in MCP’s scope (since MCP servers typically respond to AI requests), a complementary service could monitor events and use the Claude API to post messages. This is an advanced scenario for later, but worth noting (and relates to the “real-time synchronization” mentioned in other integrations ). • AI Prompt Enhancements: For tools that involve AI processing (flashcard generation, grouping logic), we might refine prompt templates and even include them as MCP Prompt resources. MCP supports defining prompt templates as part of the server that the AI can use  . We could package, for example, a prompt for “generate flashcards from text” so Claude knows how to format the request and answer. This could improve consistency of AI outputs. • User Experience & Productization: To share with product leaders and eventually users, the end-to-end experience should be polished. This means clear documentation in the .md (like this) and perhaps a demo script. Also, if this goes beyond demo, integrating into the Brightspace UI (e.g., a chat interface in Brightspace that connects to Claude with our MCP server) could be a goal. That would involve front-end work, but the MCP server would remain as the backend brain for LMS operations. • Testing and Quality: As we move from prototype to real product, we need a solid testing strategy. Unit tests for the BrightspaceClient (simulate API responses), integration tests for tool functions, maybe even end-to-end tests with a Brightspace sandbox. The Canvas MCP example is written in TypeScript with strong typing and tests ; our Python implementation should also be tested and possibly typed (we can add type hints to improve reliability). Having tests will also help if multiple developers contribute. • Telemetry and Feedback: Implement mechanisms to gather how the AI uses the tools and whether the results were successful. For example, if an AI attempt fails (due to missing data or misuse of a tool), log that so we can consider refining either the tool or the AI’s instructions. • Community and Partners: Since MCP is an open standard, many connectors are open-source . We should keep an eye on the community (e.g., the Composio or Claude partner directories)  for updates. Possibly, we could contribute our Brightspace MCP to the open-source repo once mature, or leverage improvements others make. Collaboration with other ed-tech partners (like looking at how Canvas or Blackboard are doing MCP) will ensure we aren’t reinventing the wheel.

Finally, as we share this architecture with product leadership, the emphasis is that this approach is innovative yet pragmatic. It uses cutting-edge AI integration standards (MCP) to unlock real use cases in Brightspace, all while following software best practices (modularity, security, cloud readiness). This sets the stage for rapid prototyping (with Claude’s help in development) and iteration. By starting with a sound reference architecture, we can confidently build a prototype that not only wows in demo, but also serves as a foundation for a potential product feature down the line.

References • Anthropic, “Introducing the Model Context Protocol,” 2024 – MCP as a universal standard for connecting AI to data sources  . • Rahul Suresh, “The Architectural Elegance of MCP,” TheMLArchitect, 2025 – Architectural patterns (Facade, Adapter, Sidecar, Orchestrator) and separation of concerns in MCP design  . • Composio MCP Directory – Highlights of the D2L Brightspace MCP integration (features like 45+ tools, built-in auth) . • D. Montgomery, Canvas LMS MCP Server (open-source project) – Demonstrates robust error handling, cloud deployment (Docker/K8s), and a comprehensive set of LMS tools . • Brightspace API documentation – for understanding required OAuth scopes and endpoints (not directly cited above, but referenced in code and design).