npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

brightspace-mcp

v1.1.1

Published

MCP server for D2L Brightspace (multi-auth, opt-in writes, session cache)

Readme

brightspace-mcp

CI Docs npm version License: MIT Node.js

📖 Full documentation site →

MCP server for D2L Brightspace. Gives Claude (and any MCP-compatible client) access to your courses, grades, assignments, content, calendar, and more — with multi-strategy authentication, full MFA support, and production-grade resilience built in.


Quick start

npx brightspace-mcp@latest setup   # interactive wizard (recommended for first time)

The interactive wizard handles everything: base URL, auth strategy, MFA, credential storage, and auto-registration with Claude Desktop / Cursor / Windsurf.

For CI pipelines or DevContainers with no TTY, use the non-interactive init command instead:

npx brightspace-mcp@latest init \
  --base-url https://yourschool.brightspace.com \
  --strategy api_token \
  --token-ref env:BRIGHTSPACE_API_TOKEN

Documentation

Deep-dive guides live in docs/ — start with docs/README.md.

| Topic | Doc | |---|---| | Setup walkthrough | docs/setup-guide.md | | Auth strategies | docs/auth-strategies.md | | Known-good presets (Microsoft AAD, etc.) | docs/presets.md | | Write operations (submit, post, mark) | docs/writes.md | | MCP tools reference | docs/tools.md | | MCP Resources + Prompts | docs/tools.md#mcp-resources | | Troubleshooting | docs/troubleshooting.md | | Architecture (DDD) | docs/architecture.md | | Register with MCP clients | docs/clients.md |

For AI assistants and contributors, AGENTS.md is a one-page map of the repo.


Table of contents


Installation

npx (recommended — no install needed)

npx brightspace-mcp@latest setup   # first-time wizard
npx brightspace-mcp@latest serve   # run the server

Global install

npm install -g brightspace-mcp
brightspace-mcp setup
brightspace-mcp serve

From source

git clone https://github.com/JhostinAleck/brightspace-mcp.git
cd brightspace-mcp
npm install && npm run build
node build/cli/main.js serve

Requirements: Node.js ≥ 20.


Authentication strategies

Pick the strategy that matches your Brightspace setup. Run npx brightspace-mcp@latest setup and it will walk you through the right one.

API Token (simplest)

Requires a Valence API token from your Brightspace admin panel.

profiles:
  my_school:
    base_url: https://school.brightspace.com
    auth:
      strategy: api_token
      api_token:
        token_ref: env:BRIGHTSPACE_API_TOKEN
export BRIGHTSPACE_API_TOKEN="your-token"
npx brightspace-mcp@latest serve

Headless (username + password)

Automates HTTP-level login — no browser window. Supports all MFA strategies including Duo Push.

profiles:
  my_school:
    base_url: https://school.brightspace.com
    auth:
      strategy: headless
      headless:
        login_url: https://school.brightspace.com/d2l/login
        username_ref: env:BRIGHTSPACE_USERNAME
        password_ref: env:BRIGHTSPACE_PASSWORD
        mfa:
          strategy: duo_push     # or: totp, manual_prompt, none
          duo_push: {}           # uses defaults: poll every 1s, timeout 120s

Browser (Playwright)

Launches a headless Chromium instance and automates the login UI. Best for SSO flows (Microsoft Azure AD, SAML) where the login page has complex JavaScript.

npm install playwright && npx playwright install chromium
auth:
  strategy: browser
  browser:
    login_url: https://school.brightspace.com/d2l/login
    headless: true
    username_ref: env:BRIGHTSPACE_USERNAME
    password_ref: env:BRIGHTSPACE_PASSWORD
    selectors:
      username: "#i0116"
      password: "#i0118"
      submit: "#idSIButton9"
      password_submit: "#idSIButton9"
      mfa_input: "#idTxtBx_SAOTCC_OTC"
      mfa_submit: "#idSubmit_SAOTCC_Continue"
      post_login: "d2l-labs-navigation"
    mfa:
      strategy: totp
      totp:
        secret_ref: env:BRIGHTSPACE_TOTP_SECRET

The setup wizard includes a Microsoft SSO preset that fills all selectors automatically.

Session Cookie

Paste the D2L session cookies from your browser's DevTools. Useful when other strategies are blocked.

auth:
  strategy: session_cookie
  session_cookie:
    cookie_ref: env:BRIGHTSPACE_COOKIE
    session_ttl_seconds: 3600
# Cookie format: "d2lSessionVal=XXX; d2lSecureSessionVal=YYY"
export BRIGHTSPACE_COOKIE="d2lSessionVal=...; d2lSecureSessionVal=..."

MFA strategies

| Strategy | When to use | |---|---| | none | No MFA on your account | | totp | Authenticator app (Google Authenticator, Authy, etc.) | | duo_push | Duo Security — server polls for mobile approval automatically | | manual_prompt | Any TOTP/OTP — server pauses and asks you to paste the code |

TOTP example

mfa:
  strategy: totp
  totp:
    secret_ref: env:BRIGHTSPACE_TOTP_SECRET   # base32 secret from QR code setup
    digits: 6       # 6 or 8
    period: 30      # seconds
    algorithm: SHA1 # SHA1, SHA256, or SHA512

Duo Push example

mfa:
  strategy: duo_push
  duo_push:
    poll_interval_ms: 1000   # how often to check (default: 1000)
    timeout_ms: 120000       # give up after this many ms (default: 120000)

Configuration reference

Full config file (~/.brightspace-mcp/config.yaml):

default_profile: my_school

profiles:
  my_school:
    base_url: https://school.brightspace.com
    auth:
      strategy: api_token          # api_token | browser | headless | session_cookie | oauth
      api_token:
        token_ref: env:BRIGHTSPACE_API_TOKEN
    session:
      cache_backend: memory        # memory | file | redis
      preemptive_refresh_seconds: 300

output:
  tz: America/Bogota               # IANA timezone; default: auto-detected from system
  locale: es-419                   # en-US | es-419 | pt-BR | fr-CA; default: auto-detected
  format: markdown                 # markdown (default) | plain
  include_meta_footer: true

logging:
  level: info                      # debug | info | warn | error

writes:
  enabled: false
  dry_run: false

# Optional — required when session.cache_backend: redis
redis:
  url: redis://localhost:6379
  key_prefix: "brightspace:"

Credential references

Secret values are never stored in plain text. Use ref: notation to point to the actual value:

| Prefix | Example | Description | |---|---|---| | env:NAME | env:BRIGHTSPACE_API_TOKEN | Read from environment variable | | keychain:service/account | keychain:brightspace-mcp/token | OS keychain (macOS Keychain, GNOME Keyring, Windows Credential Manager) | | file:label | file:api_token | Encrypted file (~/.brightspace-mcp/credentials.enc, AES-256-GCM) |


Output: timezone and language

All tool responses are formatted in your configured timezone and language.

output:
  tz: America/Bogota       # IANA name; default: auto-detected from system
  locale: es-419           # en-US | es-419 | pt-BR | fr-CA; default: auto-detected
  format: markdown         # markdown (default) | plain
  include_meta_footer: true

Run brightspace-mcp setup and choose your timezone and language. Or set it in ~/.brightspace-mcp/config.yaml.


Redis cache

When running multiple instances or want cache persistence across restarts, enable Redis:

1. Add the redis section to config:

redis:
  url: redis://localhost:6379
  key_prefix: "brightspace:"

profiles:
  my_school:
    session:
      cache_backend: redis

2. Install ioredis (optional dependency):

npm install ioredis

3. Start Redis and the server:

docker run -d -p 6379:6379 redis:7-alpine
npx brightspace-mcp@latest serve

The domain cache (courses, grades, assignments, etc.) automatically uses Redis as persistent layer when the redis: section is present in config. Session tokens are stored with TTL derived from the token expiry.


Write operations

Write tools (submit_assignment, post_discussion_reply, mark_announcement_read) are disabled by default and require two separate opt-ins:

1. Config file:

writes:
  enabled: true
  dry_run: false   # set true to preview without mutating D2L

2. CLI flag:

npx brightspace-mcp@latest serve --enable-writes

All write operations:

  • Require a client-supplied idempotency_key (8–128 chars). Repeat calls with the same key return the cached response without re-executing.
  • Emit a WARN-level audit log line with correlation ID, tool name, and redacted args.
  • Respect dry_run: true to return a preview response without touching D2L.

Available tools

Read tools (always available)

| Tool | Description | |---|---| | check_auth | Verify authentication and show the active user identity | | list_my_courses | List all enrolled courses | | get_my_grades | Get grades for a course | | get_assignments | List assignments and dropbox folders | | get_assignment_files | Download and read instructor-posted assignment files | | get_upcoming_due_dates | List assignments due in the next N days | | get_feedback | Read instructor feedback on submitted assignments | | get_syllabus | Fetch the course syllabus | | get_course_content | Browse modules and topics (includes topic IDs) | | get_topic_file | Download and read a content topic file (DOCX, PDF, HTML, plain text) | | get_announcements | List course announcements | | get_discussions | Browse discussion forums and threads | | get_calendar_events | List calendar events in a date range | | get_roster | Get the full course roster | | get_classlist_emails | Get classmate email addresses | | get_my_groups | List group enrollments per course with member rosters | | list_quizzes | List quizzes with attempt counts, time limits, due dates | | get_quiz_attempts | Your attempts on a quiz with scores and timestamps | | list_notifications | User activity feed (announcements, due-date reminders, grade releases) | | search_course | Full-text search across content, announcements, and discussions | | get_audit_log | Local history of write operations (correlation IDs, redacted args) | | get_diagnostics | Show cache stats, circuit breaker state, and version info | | clear_cache | Clear memory and persistent cache backends |

Write tools (require --enable-writes)

| Tool | Description | |---|---| | submit_assignment | Upload a file to a Brightspace Dropbox folder | | post_discussion_reply | Reply to a discussion thread | | mark_announcement_read | Mark an announcement as read |


MCP Resources

Four stable URIs for Brightspace content (readable by any MCP client via resources/read):

| URI | Content | |---|---| | brightspace://{courseId}/syllabus | Course syllabus, HTML stripped | | brightspace://{courseId}/content/topics/{topicId} | Topic file (text extracted from PDF, or base64 fallback) | | brightspace://{courseId}/assignments/{assignmentId}/files | All assignment attachments as text | | brightspace://{courseId}/announcements/{announcementId} | Announcement text |

Obtain IDs from tools like list_my_courses, get_assignments, get_announcements.


MCP Prompts

Four pre-built prompt templates visible in your MCP client's prompt picker:

| Prompt | Arguments | Purpose | |---|---|---| | weekly_briefing | none | 7-day overview: due dates, announcements, recent grades | | grade_audit | course_id? | Grade analysis + what you need to pass | | study_planner | days_ahead? (default 7) | Study plan from due dates and calendar | | course_summary | course_id (required) | Full course overview |


Web UI dashboard

brightspace-mcp ui             # open at http://localhost:9876
brightspace-mcp ui --open      # open browser automatically
brightspace-mcp ui --port 8080 # custom port

Provides: auth status, upcoming due dates, grades, announcements, config editor (form + YAML), cache stats, audit logs, diagnostics. Dark/light mode, tooltips on all fields.


Register with an MCP client

See docs/clients.md for Claude Desktop, Cursor, and Windsurf snippets, or run brightspace-mcp setup which auto-detects and registers for you.

Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "brightspace": {
      "command": "npx",
      "args": ["--yes", "brightspace-mcp@latest", "serve"],
      "env": {
        "BRIGHTSPACE_CONFIG": "/Users/you/.brightspace-mcp/config.yaml"
      }
    }
  }
}

CLI reference

npx brightspace-mcp@latest setup                      Interactive first-time setup wizard (detects system language)
npx brightspace-mcp@latest init [flags]               Non-interactive config writer (CI/scripts, no TTY)
npx brightspace-mcp@latest serve                      Start the MCP server (stdio transport)
npx brightspace-mcp@latest serve --enable-writes      Start with write tools enabled
npx brightspace-mcp@latest ui [--port 9876] [--open]  Local web dashboard at http://localhost:9876
npx brightspace-mcp@latest auth                       Re-authenticate and test the config
npx brightspace-mcp@latest record-auth                Open browser for manual login, capture session cookies
npx brightspace-mcp@latest doctor                     End-to-end smoke test: config → auth → API → list_my_courses
npx brightspace-mcp@latest profile list               List profiles (* marks the default)
npx brightspace-mcp@latest profile use <name>         Switch the default profile
npx brightspace-mcp@latest config show                Print config (secrets redacted)
npx brightspace-mcp@latest config show --resolved     Show all secret refs as [redacted]
npx brightspace-mcp@latest config validate            Validate config schema without running
npx brightspace-mcp@latest config set <path> <value>  Edit a nested config value
npx brightspace-mcp@latest cache clear                Clear memory + file/Redis cache
npx brightspace-mcp@latest cache clear --context <n>  Clear a specific cache context
npx brightspace-mcp@latest upgrade                    Upgrade brightspace-mcp to the latest version

Docker

Standalone

docker pull ghcr.io/jhostinaleck/brightspace-mcp:latest
docker run --rm -i \
  -v "$HOME/.brightspace-mcp:/config:ro" \
  -e BRIGHTSPACE_CONFIG=/config/config.yaml \
  ghcr.io/jhostinaleck/brightspace-mcp:latest serve

With Redis (docker-compose)

# Start server + Redis
docker compose --profile redis up

# Or standalone (in-memory cache)
docker compose up

The config.yaml inside ~/.brightspace-mcp/ must have the redis: section pointing to redis://redis:6379 when using the compose profile.


Architecture highlights

  • Resilience: retry with exponential backoff + jitter, circuit breaker (5 failures → 30s cooldown), request coalescing, bulkhead (max 5 concurrent requests)
  • Cache tiers: HTTP response cache (L1, in-memory, 60s TTL) + domain cache (L2, layered memory → file or Redis)
  • Security: HTTPS-only transport, secrets redaction in all log output, OS keychain integration, AES-256-GCM encrypted credential file, session tokens expire with the D2L token
  • DDD structure: bounded contexts (assignments, authentication, calendar, communications, content, courses, grades, groups, notifications, quizzes) with clean domain / application / infrastructure separation

License

MIT © Jhostin Aleck