Skip to main content
Glama

blackboard-mcp

An MCP server for Blackboard Learn (Ultra). Gives Claude, Codex, Cursor and any other MCP client read access to your courses, content, files, grades, deadlines, announcements and discussions, using your own browser session.

npx blackboard-mcp auth login     # sign in once
npx blackboard-mcp install        # register with your MCP client

Then ask your assistant things like:

What do I have due this week? Read me the lecture 4 slides from Machine Learning. How am I doing across all my courses? Catch me up, I've been away a week.


Why this exists

Blackboard's documented REST API requires an OAuth application registered and approved by your institution's Blackboard administrator. Most students and many staff can't get one.

This package targets the internal Ultra API instead: the surface the Blackboard web interface itself calls, authenticated with nothing but a session cookie. It also exposes more than the public API does, including to-do lists, the activity stream, conversations, discussion read state and attendance.

It is read-only in practice, and does not cover quizzes, rubrics or submitting work. See Limitations below.

Related MCP server: McGill myCourses MCP Server

Install

Requires Node.js 22.5+. Older versions work but must sign in with --paste.

npm install -g blackboard-mcp

Or run it without installing, which is what the generated client config uses:

npx -y blackboard-mcp

Signing in

blackboard-mcp auth login

That's the whole flow. No URL, no cookies, no DevTools, no password.

It reads the session from the browser you're already signed in to. Blackboard's BbRouter cookie is emitted only by Blackboard Learn, so finding it identifies both that you have a session and which instance it belongs to. Candidates are verified against the live API before anything is stored.

$ blackboard-mcp auth login

Signed in as Ada Lovelace (a.lovelace@student.example.edu)
Instance:    https://blackboard.example.edu
Imported by: browser (automatic)

Auto-refresh: ENABLED

Works with Chrome, Edge, Brave, Chromium, Vivaldi, Opera and Firefox, including multiple profiles. To see what it can find:

blackboard-mcp auth browsers

You won't have to sign in again

Blackboard sessions expire after about three hours. Two mechanisms avoid re-authenticating:

  1. Keep-alive. While the server runs it pings Blackboard's session endpoint, resetting the inactivity timer. An idle session never expires.

  2. Silent renewal. If the session lapses anyway, the institution's SSO redirect chain is replayed against your identity provider. This is what your browser does when you reload after being logged out.

Renewal works because identity provider sessions outlive Blackboard's by weeks or months. auth login imports those cookies alongside Blackboard's, so renewal needs no human:

GET  /ultra                       -> 302
GET  /                            -> 302
GET  /auth-saml/saml/login        -> 302
GET  login.microsoftonline.com/   -> 200  (auto-submit SAMLResponse)
POST /auth-saml/saml/SSO          -> 302
GET  /ultra                       -> 200  (new session)

The implementation follows redirects and resubmits whatever SSO form comes back, so SAML, WS-Federation and Shibboleth all work without provider-specific code.

auth login verifies this before reporting Auto-refresh: ENABLED, by forcing one full chain through your provider. It then narrows the stored cookies to Blackboard plus your actual provider, discarding anything imported speculatively.

To renew manually:

blackboard-mcp auth refresh

If browser import can't work

Two cases, both reported with the fallback:

  • Chrome 127+ on Windows uses App-Bound Encryption, which by design can't be read by another process.

  • Node older than 22.5 lacks the built-in SQLite needed to read cookie stores.

The manual path:

blackboard-mcp auth login --paste

This asks you to paste a "Copy as cURL" from DevTools (Network tab, right-click a request, Copy, Copy as cURL). A pasted request carries only Blackboard's cookies, not your provider's, so these sessions can't auto-renew and need signing in again every few hours.

Blackboard's session cookie is HttpOnly, so document.cookie can't see it. It only appears on a real request.

Non-interactive:

BLACKBOARD_COOKIE='BbRouter=...; JSESSIONID=...' \
  blackboard-mcp auth login --url https://blackboard.your-university.edu

To check state:

blackboard-mcp auth status
blackboard-mcp doctor      # full diagnostics

Clients

Auth is not per client. blackboard-mcp auth login stores one encrypted session in ~/.blackboard-mcp/, and every client on that machine reads it. Sign in once, then register the server wherever you want it.

blackboard-mcp auth login                # once, per machine
blackboard-mcp install                   # print config for every known client
blackboard-mcp install cursor --write    # or merge it in automatically

--write merges into the existing config rather than overwriting it.

What works where

This is a local MCP server. It runs on your machine over stdio, because it reads your browser session and your Blackboard files, neither of which exists on a server somewhere.

Client

Supported

How

Claude Code (terminal)

yes

claude mcp add

Claude Code (desktop app)

yes

same config as the terminal

Claude Desktop

yes

claude_desktop_config.json

Codex CLI

yes

~/.codex/config.toml

Cursor

yes

~/.cursor/mcp.json

Windsurf

yes

~/.codeium/windsurf/mcp_config.json

VS Code (Copilot)

yes

.vscode/mcp.json

Zed

yes

settings.json

claude.ai in a browser

no

accepts remote servers only

Claude for Work / Team / Enterprise (web)

no

remote only, plus admin approval

ChatGPT (web)

no

remote only

Codex cloud

no

runs server-side, no access to your machine

The four "no" rows are all the same limitation, explained under Web clients below.

Claude Code

Terminal, and the desktop app's Code tab, share ~/.claude.json, so one command covers both:

claude mcp add blackboard --scope user -- npx -y blackboard-mcp

--scope user makes it available in every project. Drop it to scope the server to the current directory only, or use --scope project to write a .mcp.json your teammates get too. Restart the desktop app to pick up a change made in the terminal.

Verify:

claude mcp list

Claude Desktop

Edit claude_desktop_config.json:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • Linux: ~/.config/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "blackboard": { "command": "npx", "args": ["-y", "blackboard-mcp"] }
  }
}

Restart Claude Desktop fully, then look for the tools under the attachments menu.

Codex CLI

Add to ~/.codex/config.toml. Note the key is mcp_servers, with an underscore:

[mcp_servers.blackboard]
command = "npx"
args = ["-y", "blackboard-mcp"]

Or let the CLI write it:

codex mcp add blackboard -- npx -y blackboard-mcp

Cursor and Windsurf

Same shape as Claude Desktop, different file:

  • Cursor, all projects: ~/.cursor/mcp.json

  • Cursor, one project: .cursor/mcp.json

  • Windsurf: ~/.codeium/windsurf/mcp_config.json

{
  "mcpServers": {
    "blackboard": { "command": "npx", "args": ["-y", "blackboard-mcp"] }
  }
}

VS Code

.vscode/mcp.json in the workspace. The top-level key is servers, not mcpServers:

{
  "servers": {
    "blackboard": { "command": "npx", "args": ["-y", "blackboard-mcp"] }
  }
}

Zed

In settings.json, under context_servers:

{
  "context_servers": {
    "blackboard": {
      "source": "custom",
      "command": { "path": "npx", "args": ["-y", "blackboard-mcp"] }
    }
  }
}

Zed's schema for this has changed between releases, so if it does not pick the server up, check Zed's current context-server docs. Every other client in this list uses the flat {"command": "npx", "args": [...]} form.

Any other MCP client

The server speaks MCP over stdio. Anything that can launch a subprocess can use it:

command: npx
args:    ["-y", "blackboard-mcp"]

Optional environment: BLACKBOARD_MCP_ALLOW_WRITES=1 to permit writes, BLACKBOARD_MCP_LOG_LEVEL=debug to troubleshoot. Everything else is read from ~/.blackboard-mcp/.

To confirm a client can talk to it, run the official inspector:

npx @modelcontextprotocol/inspector npx -y blackboard-mcp

Web clients

claude.ai in a browser, Claude for Work on the web, ChatGPT on the web and Codex cloud all reach MCP servers over HTTP, at a public URL. They cannot launch a process on your laptop, which is the only place your Blackboard session exists. So this server does not work in any of them today, and no configuration change makes it work.

Closing that gap means running the server as a hosted HTTP service, which has a consequence worth being explicit about: that service would hold your Blackboard session, and anyone who reached its URL could read your grades and coursework. It would need its own authentication in front of it, and you would be trusting a host with your student credentials.

If you want that, the honest options are:

  1. Keep it local. Use a desktop or terminal client. This is what the package is designed for.

  2. Run it yourself behind a tunnel plus authentication, with the session staying on hardware you control.

  3. Use the official Blackboard REST API instead for anything hosted. It uses OAuth rather than a borrowed session, which is the right shape for a web integration, though it requires an app your institution's Blackboard administrator has approved.

Tools

Every course tool takes a courseId, an internal id like _12345_1 rather than the human course code. Get them from bb_list_courses.

Courses and identity

Tool

Purpose

bb_whoami

Signed-in user and instance

bb_session_status

Session validity, expiry, cookies

bb_list_courses

Enrolled courses with ids, terms, roles. Start here

bb_get_course

Course detail and enabled tools

bb_list_terms

Academic terms

bb_list_roster

Participants and their roles

Content

Tool

Purpose

bb_browse_course

Recursive content tree with folder paths. The main discovery tool

bb_list_content

One level of a folder

bb_get_content

Item detail: body text, attached file, link target, due date

bb_search_content

Search titles and bodies, one course or all

Files

Tool

Purpose

bb_read_file

Download and extract text. Pages through long PDFs

bb_download_file

Save a file to disk

bb_list_files

Every readable document in a course

bb_download_course_files

Bulk download or archive a course

bb_download_submission

Files submitted with an assignment attempt

Grades

Tool

Purpose

bb_list_grades

Grades for one course or all

bb_get_grade_detail

Score, letter grade, attempts, submissions, instructor feedback

bb_grade_summary

Per-course standing and averages

bb_review_quiz_attempt

Read a quiz back question by question, with your answers and scores

bb_submission_status

Definitive "has this been submitted?", with attempt id and timestamp

Deadlines

Tool

Purpose

bb_todo

Overdue, due today and upcoming across all courses

bb_calendar

Calendar events in a date range

bb_course_schedule

A course's recurring meetings

Communication

Tool

Purpose

bb_announcements

Announcements with full text, one course or all

bb_activity_stream

Recent changes across every course

bb_list_conversations

Course message threads

bb_list_discussions

Discussion forums, posts and replies

bb_unread_counts

Unread counts across all courses

bb_attendance

Attendance records

Escape hatch

Tool

Purpose

bb_raw_request

Call any Blackboard API path directly

bb_batch_request

Up to 20 reads in one round trip

bb_list_endpoints

Every endpoint this server knows

bb_mark_reviewed

Mark content reviewed (write, off by default)

Writes

Off unless BLACKBOARD_MCP_ALLOW_WRITES=1 is set.

Tool

Purpose

bb_start_quiz_attempt

Open an attempt on an assessment and list its questions

bb_save_quiz_answer

Answer one question. Overwritable until submitted

bb_save_draft

Save text as a draft, not visible to the instructor, reversible

bb_submit_assignment

Submit text for grading. Irreversible, requires confirm: true

bb_submit_quiz_attempt

Submit an in-progress quiz. Irreversible, requires confirm: true

Both submit tools have three gates: writes must be enabled, confirm must be true, and an existing or already-submitted attempt is refused. Each returns Blackboard's receipt id, which is your proof of submission, and flags a late submission.

bb_submit_quiz_attempt only changes an attempt's status; answers must already be saved on it. An auto-graded test is scored the moment it is submitted, so there is no undo. Inspect the attempt with bb_review_quiz_attempt and get the user's explicit go-ahead first.

Assignment submission is text only, since the file upload flow is not implemented.

bb_save_quiz_answer resolves loose input against the question, so option numbers, option text, booleans for true/false, plain text for essays and numbers for numeric questions all work, and it echoes back how the input was read so you can check it before submitting. Answers are overwritable until the attempt is submitted.

Blackboard strips a question from a submitted attempt when the course hides results, so option resolution works only while an attempt is IN_PROGRESS. On a completed attempt, pass the raw givenAnswer instead.

The Ultra API is larger than what's wrapped here. bb_raw_request is the answer when the tool you need doesn't exist.

Prompts

Workflows your client surfaces as slash commands:

  • whats_due deadlines, triaged, with submission status

  • course_briefing full picture of one course

  • study_pack find, read and synthesise material on a topic

  • catch_up everything that changed while you were away

  • grade_report standing across all courses, with feedback themes

  • find_material locate a specific file or reading

Resources

  • blackboard://me your profile

  • blackboard://courses course list

  • blackboard://course/{courseId}/outline full content tree as JSON

Reading files

bb_read_file extracts text from PDF, HTML and plain-text formats, including code, CSV, JSON, Markdown and subtitles.

Long documents are windowed rather than truncated. A PDF returns a page range plus a note telling the model how to continue, so a 300-page course reader is fully readable without flooding the context.

Office formats (.docx, .pptx, .xlsx) and archives can't be extracted. They're ZIP containers needing an unzip implementation Node doesn't ship, and a native dependency would break npx installs. They still download fine via bb_download_file.

Scanned PDFs with no text layer are detected and reported as needing OCR, rather than returning an empty string that looks like a bug.

Linked documents

Instructors often publish lecture material as a Google Slides, Docs or Sheets link rather than an uploaded file, leaving no bytes in Blackboard at all. bb_read_file resolves these through the provider's export endpoint, so a linked deck reads like an attached file, and bb_list_files lists them as course material.

Two constraints, because that URL is written by a third party and arrives as untrusted content:

  • Provider allowlist. Only Google Docs hosts with a documented export endpoint are fetched. Without this, a pasted link would turn the tool into an arbitrary URL fetcher.

  • No credentials. These fetches carry no Blackboard session and no Google auth, so only material the instructor already made link-shareable is reachable. A privately shared document reports that plainly instead of returning a sign-in page dressed up as slides.

Formats default to the cheapest to read (txt for decks and documents, csv for sheets). Pass format for pdf, pptx, docx or xlsx.

Timestamps are UTC

Every timestamp the API returns is true UTC, and the Z suffix means what it says. This is worth stating because the Ultra web interface renders in the viewer's timezone, which makes "local wall clock stamped as Z" a reasonable suspicion, and that is exactly the wrong conclusion to reach about a deadline.

Two worked examples from a live tenant:

  • A deadline shown in the UI as 23:59 Europe/Madrid comes back as 2026-09-16T21:59:00.000Z. The :59 is the fingerprint of a correctly stored local 23:59.

  • A submission made at 14:07 Madrid reads back as submitted: 2026-09-18T12:07:53.407Z.

So convert for display, and never treat the value as local. Telling a student the wrong deadline is this library's highest-consequence silent failure.

Adapting to your institution

Learn releases and reverse proxies move endpoints around. If something 404s, record a browser session and import it:

blackboard-mcp har import ~/Downloads/blackboard.har --verbose

This detects your instance, compares every real path against the built-in templates, writes corrections to ~/.blackboard-mcp/endpoints.json, and lists the endpoints your tenant exposes that this package doesn't model. Those stay reachable through bb_raw_request.

To record a HAR: DevTools, Network tab, check Preserve log, browse Blackboard, then right-click and Save all as HAR with content.

Current Chrome strips cookies from HAR exports, so a HAR can't sign you in. That's a good default, since a HAR with cookies is a credential file. Treat one like a password.

Security

  • Read-only by default. Non-GET requests are refused unless BLACKBOARD_MCP_ALLOW_WRITES=1 is set. Two Blackboard read operations use non-GET verbs (the batch fan-out and the activity stream) and are explicitly allowed.

  • Sessions are encrypted at rest with AES-256-GCM. The key lives in the macOS Keychain or Linux Secret Service, falling back to a 0600 keyfile. State lives in ~/.blackboard-mcp/.

  • Browser cookies are read locally only. Cookie stores are copied, decrypted with a key the OS already grants this user, and never transmitted. Import pulls identity provider cookies broadly at first, since the provider isn't knowable before the SSO chain names it, so the first renewal prunes the stored jar down to Blackboard plus your actual provider.

  • Cookies never leave your instance. The HTTP client enforces a host allowlist across every redirect hop, so the session can't be sent to a third party even if a redirect or an instructor-pasted link points there.

  • Renewal is scoped by delegation. The SSO replay only sends cookies to your Blackboard host and to hosts Blackboard's own redirect chain named.

  • Untrusted input is treated as data. Server-supplied filenames are sanitised before touching the filesystem, and embedded links are accepted only as instance-relative paths.

  • bb_raw_request is restricted to API path prefixes and rejects traversal.

Your Blackboard account governs what's visible. This server reads exactly what you can read in a browser, and nothing more.

A note on academic data

Grades, feedback and submissions are confidential personal data, and fall under GDPR in the EU and UK. Downloaded files land on your local disk unencrypted, so mind where they go and prefer the narrowest tool for the question. If you're staff acting on student data rather than your own, check your institution's data-handling policy first.

Configuration

Variable

Meaning

BLACKBOARD_URL

Instance origin, overriding stored config

BLACKBOARD_COOKIE

Session cookie for non-interactive login

BLACKBOARD_MCP_ALLOW_WRITES

1 permits write operations

BLACKBOARD_MCP_DOWNLOAD_DIR

Where files are saved

BLACKBOARD_MCP_MAX_DOWNLOAD_BYTES

Per-file ceiling, default 100 MB

BLACKBOARD_MCP_PAGE_SIZE

Default list page size, default 50

BLACKBOARD_MCP_LOG_LEVEL

silent, error, warn, info or debug

BLACKBOARD_MCP_HOME

State directory, default ~/.blackboard-mcp

Use as a library

The package is a usable Blackboard SDK on its own:

import { BlackboardClient } from 'blackboard-mcp';

const bb = await BlackboardClient.create();

for (const m of await bb.listCourses({ availableOnly: true })) {
  console.log(m.course?.displayName);
}

// Recursive content tree, both roots
const items = await bb.walkContents('_12345_1');

// Fan out across courses in one request
const grades = await bb.batch([
  { method: 'GET', relativeUrl: 'v1/courses/_12345_1/gradebook/grades?userId=_1_1' },
]);

CLI

blackboard-mcp [serve]                Run the MCP server on stdio (default)
blackboard-mcp auth login             Sign in, importing from your browser
blackboard-mcp auth status            Session and connectivity status
blackboard-mcp auth browsers          List browser profiles and sessions found
blackboard-mcp auth refresh           Renew the session without signing in
blackboard-mcp auth logout [--purge]  Forget the session
blackboard-mcp har import <file>      Learn this tenant's endpoints
blackboard-mcp doctor                 Diagnose configuration
blackboard-mcp install [client]       Register with an MCP client
blackboard-mcp courses                List your courses
blackboard-mcp endpoints [filter]     Show the endpoint map

Troubleshooting

Run blackboard-mcp doctor first.

NOT_CONFIGURED or NOT_AUTHENTICATED. Run blackboard-mcp auth login.

SESSION_EXPIRED. The session lapsed and couldn't be renewed silently. If auth status shows auto-refresh unavailable, re-run auth login without --paste to capture identity provider cookies. If it shows enabled, your provider session has itself expired: open Blackboard in a browser, sign in, then auth login again.

"No Blackboard session found in any browser". Sign in to Blackboard in a browser first. auth browsers shows what was scanned.

"The captured session was rejected". You copied a request from your SSO provider rather than the Blackboard host, or the tab had already logged out. Copy a request whose URL is your Blackboard hostname.

A tool 404s. Your tenant may differ. Run har import <har> --verbose, then use bb_raw_request for anything unmapped.

Empty course list. Courses you hid in Blackboard are excluded by default; pass includeHidden: true. Organizations are excluded too; pass organizations: "include".

bb_read_file returns nothing for a PDF. It's a scan with no text layer and needs OCR. If your institution has Blackboard Ally, the course may offer an accessible alternative format.

A linked Google deck won't read. It's shared privately rather than link-shared. Only material the instructor made publicly accessible can be fetched, since no credentials are used.

Development

pnpm install
pnpm build
pnpm test            # protocol and unit tests
pnpm typecheck
pnpm inspect         # MCP Inspector against the built server

Limitations

  • Read-only by default. Assignment submission exists but is off unless you enable writes, and it is text only. Posting discussion replies and sending messages aren't implemented.

  • No file attachments on submissions. The upload flow has not been captured, so a submission carries text only. Do not rely on it for work that must include a file.

  • Auto-renewal needs a browser-imported session. A --paste session has no identity provider cookies and will expire in a few hours.

  • Office formats download but don't extract.

  • No OCR for scanned PDFs.

  • Ultra-oriented. Courses in the older Classic experience expose less through this API. bb_raw_request is the fallback.

  • Unofficial. This uses an internal API with no stability guarantee. Blackboard may change it without notice, which is why HAR import exists.

Not affiliated with, endorsed by, or supported by Anthology Inc. or Blackboard. "Blackboard" and "Blackboard Learn" are trademarks of their respective owners.

This tool accesses your own account with your own credentials, reading the same data your browser shows you. Your institution's acceptable-use policy still applies. Don't use it to access data that isn't yours.

MIT

Available Tools

31 tools
bb_activity_streamBlackboard activity streamA
Read-only

The Ultra activity stream: recent grade postings, new content, announcements and due-date reminders across all courses, newest first. A good single call for "what changed recently?".

Inputs: limit, flushCache.

bb_announcementsRead Blackboard announcementsA
Read-only

Lists course announcements with their full text, newest first. Covers every enrolled course by default (via the batch API), or one course when courseId is given. Use this for "what did my instructors post?" or catching up after time away.

Inputs: limit, courseId, fullText, maxCourses, +1 more.

bb_attendanceGet course attendance recordsA
Read-only

Lists the attendance records recorded for the signed-in user in a course (present/absent/late/excused per session), when the instructor uses Blackboard attendance.

Inputs: courseId (required), limit.

bb_batch_requestCall several Blackboard endpoints at onceA
Read-only

Fans out up to 20 GET reads in a single round trip using Blackboard's own batch endpoint. Paths are version-relative, e.g. "v1/courses/_12345_1/groups". Much cheaper than repeated bb_raw_request calls when gathering the same data across many courses.

Inputs: paths (required), maxChars.

bb_browse_courseBrowse a course content treeA
Read-only

Walks the full content outline of a course recursively and returns every item with its folder path, type, and any attached file. This is the primary way to discover what material a course contains. Use maxDepth/maxNodes to bound very large courses.

Inputs: courseId (required), type, rootId, maxDepth, +2 more.

bb_calendarBlackboard calendar eventsA
Read-only

Lists calendar entries in a date range: class sessions, instructor-created events, and assignment due dates. Covers all courses by default. Use bb_todo instead when the question is specifically about assignment deadlines.

Inputs: days, limit, since, until, +1 more.

bb_course_scheduleGet a course meeting scheduleA
Read-only

Lists the recurring class meetings configured for a course (day, time, room). Empty for courses whose instructor never set one up.

Inputs: courseId (required).

bb_download_course_filesBulk download a course's filesA
Read-only

Walks a course and downloads every attached file to a local folder, organised by course. Use for archiving a course or grabbing all slides at once. Respects the configured size limit per file and skips files already on disk.

Inputs: courseId (required), maxFiles, maxNodes, extension.

bb_download_fileDownload a course file to diskA
Read-only

Downloads a file from a content item and saves it locally without extracting text. Use this for Office documents, images, archives, or anything the user wants to keep. Also handles content items that link to Google Slides/Docs/Sheets, fetching the export (pptx/docx/xlsx/pdf). Returns the saved path.

Inputs: courseId (required), contentId (required), all, format, +1 more.

bb_download_submissionDownload a submitted assignment fileA
Read-only

Downloads the files the student submitted with an assignment attempt. Use bb_get_grade_detail first to find the attemptId and columnId.

Inputs: columnId (required), courseId (required), attemptId (required).

bb_get_contentRead a course content itemA
Read-only

Full detail for one content item: its rendered body text, attached file metadata, external link target, due date, and any files embedded in the body HTML. Use this to actually read an announcement-style document or assignment brief.

Inputs: courseId (required), contentId (required), includeChildren.

bb_get_courseGet Blackboard course detailsA
Read-only

Full detail for one course: name, code, term, availability window, Ultra/Classic mode, and the tools enabled in it.

Inputs: courseId (required), includeTools.

bb_get_grade_detailGet grade detail with feedbackA
Read-only

Everything about one gradebook item: the score, rubric/points, due date, every attempt with its timestamp and status, the student's submitted text, and the instructor's written feedback. This is where feedback lives. The grade list does not carry it.

Inputs: columnId (required), courseId (required), includeAttempts.

bb_grade_summarySummarise grade standing per courseA
Read-only

Computes, per course, how many items are graded, the running points total, and the average percentage. Use this for "how am I doing overall?" questions rather than listing every item.

Inputs: maxCourses.

bb_list_contentList content in a course folderA
Read-only

Lists the immediate children of a course folder or lesson, or the top level of the course when no folder is given. Prefer bb_browse_course unless you specifically want one level.

Inputs: courseId (required), limit, contentId.

bb_list_conversationsList course messagesA
Read-only

Lists the message threads (Blackboard "conversations") in a course, and optionally the messages inside one thread.

Inputs: courseId (required), limit, conversationId.

bb_list_coursesList my Blackboard coursesA
Read-only

Lists the courses the signed-in user is enrolled in, with course id, name, term, role and last-access date. The returned courseId (like _12345_1) is what every other course tool needs. Start here.

Inputs: term, search, availableOnly, includeHidden, +1 more.

bb_list_discussionsRead course discussionsA
Read-only

Reads a discussion forum: its top-level posts, and the replies to one post when messageId is given. Find the forumId from a "discussion" item in bb_browse_course (its contentDetail carries conferenceId/id).

Inputs: forumId (required), courseId (required), limit, messageId.

bb_list_endpointsList known Blackboard endpointsA
Read-only

Shows every Blackboard API endpoint this server knows, with the operation name and its path template, plus any local overrides. Useful for discovering what to pass to bb_raw_request.

Inputs: filter.

bb_list_filesList downloadable files in a courseA
Read-only

Walks a course and lists every readable document: attached files, attachments, files embedded in page bodies, and content items that link to Google Slides, Docs or Sheets. Returns name, type, size and the contentId needed to fetch each one.

Inputs: courseId (required), deep, maxNodes, extension.

bb_list_gradesList Blackboard gradesA
Read-only

Lists grades for one course, or across every enrolled course when courseId is omitted. Shows each graded item, the score out of its total, and its status. Cross-course mode uses Blackboard's batch API so it costs roughly one request rather than one per course.

Inputs: courseId, gradedOnly, maxCourses.

bb_list_rosterList course participantsA
Read-only

Lists the people enrolled in a course with their roles. Useful for finding an instructor to contact, or identifying group members.

Inputs: courseId (required), role, limit.

bb_list_termsList Blackboard termsB
Read-only

Lists academic terms defined on the instance, with their date ranges.

Inputs: limit.

bb_mark_reviewedMark course content as reviewedA
Idempotent

Marks a reviewable content item as reviewed (the "Mark Reviewed" button in Ultra). Requires writes to be enabled with BLACKBOARD_MCP_ALLOW_WRITES=1; this server is read-only by default.

Inputs: courseId (required), contentId (required), reviewed.

bb_raw_requestCall a Blackboard API endpoint directlyA

Escape hatch: issues a request against any Blackboard API path using the stored session, and returns the raw JSON. Use this when no dedicated tool covers what you need. The Ultra internal API (/learn/api/v1/...) exposes far more than this server models. Call bb_list_endpoints first to see what is already wrapped.

Inputs: path (required), body, query, method, +1 more.

bb_read_fileRead a course file as textA
Read-only

Downloads a file attached to a content item and extracts its text. Also resolves content items that merely LINK to a Google Slides/Docs/Sheets document (common for lecture decks) by fetching the provider export, so reading works the same either way. PDFs are returned a page-window at a time (use fromPage to continue), so a long document will not flood the context. Handles PDF, HTML, and plain-text/code/CSV; Office formats download but cannot be extracted. This is the tool to use to actually read lecture notes or a handout.

Inputs: courseId (required), contentId (required), format, fileName, +4 more.

bb_search_contentSearch course contentA
Read-only

Searches content item titles and body text for a query string, in one course or across every enrolled course. Use this when the user asks where something is ("where are the lecture slides on transformers?"). Searching all courses walks each tree, so prefer a single courseId when you know it.

Inputs: query (required), limit, courseId, maxCourses, +1 more.

bb_session_statusBlackboard session statusA
Read-only

Reports how much longer the stored Blackboard session is valid, when it was captured, and which cookies it holds. Call this when other tools start failing with session errors.

Inputs: keepAlive.

bb_todoWhat is due on BlackboardA
Read-only

The student to-do list: everything overdue, due today, and coming up, across all courses, in one call. This is the right tool for "what do I have due?", "am I behind?", or "what should I work on?". Grouped by urgency and sorted by date.

Inputs: days, lookBackDays, includeOverdue.

bb_unread_countsUnread message and notification countsA
Read-only

Unread message counts across every course in a single call, plus the overall messages summary. Cheap. Use it to decide whether reading messages is worth it before calling bb_list_conversations.

Inputs: no named parameters.

bb_whoamiWho am I on BlackboardA
Read-only

Returns the signed-in Blackboard user (name, username, student id, email, institution roles) and the configured instance. Use this to confirm authentication is working before other calls.

Inputs: no named parameters.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 31 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose, with descriptions that explicitly differentiate overlapping functions (e.g., bb_list_content vs bb_browse_course, bb_read_file vs bb_download_file). The descriptions often include guidance on when to use one over another, eliminating ambiguity.

    Naming Consistency4/5

    All tools share the 'bb_' prefix and use lowercase with underscores, but naming patterns vary slightly: most are verb_noun (e.g., bb_list_courses, bb_get_content), but a few deviate (bb_whoami, bb_session_status, bb_batch_request). Overall, the pattern is predictable and readable.

    Tool Count2/5

    With 31 tools, the server exceeds the threshold for 'too many' (25+). While the Blackboard domain is broad, the large number may overwhelm agents and increase selection complexity, though each tool serves a specific purpose within the LMS.

    Completeness4/5

    The server covers the major student-facing workflows: course discovery, content browsing and reading, file downloads, grades, to-dos, calendar, messages, discussions, and announcements. Missing write operations (except mark_reviewed) are acknowledged by the read-only default, but the surface is comprehensive for a read-focused client.

    Maintenance

    ActivityMaintained
    ResponsivenessLimited data

    Related MCP Connectors

    • Teachable MCP server for ChatGPT, Claude and any AI agent: update lecture, create coupon, send email, reply to comment and list enrollments in your own Teachable account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to Teachable yourself; Cotlet does not store your password and you need no Teachable API key. About the official Teachable API: Teachable has a public API, but only on the Growth plan and up, and it reads courses and lecture content and manages users, enrollments, pricing plans and transactions (checked 11 Oct 2026). Lesson editing, coupons, emails to students and comments are not in it. Setup and FAQ: https://cotlet.dev/integrations/teachable-api-mcp-server

    • LearnWorlds MCP server for ChatGPT, Claude and any AI agent: list users, list course learners, enroll users, unenroll users, update tags, send message, suspend user and grade assessment in your own LearnWorlds account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to LearnWorlds yourself; Cotlet does not store your password and you need no LearnWorlds API key. About the official LearnWorlds API: LearnWorlds has a REST API (v2) for courses, users, bundles, subscriptions, promotions, payments and certifications, but it comes with the Learning Center plan and higher, and you need your own code to use it (checked 5 Nov 2026). LearnWorlds has no official MCP server. Setup and FAQ: https://cotlet.dev/integrations/learnworlds-api-mcp-server

    • Absorb LMS MCP server for ChatGPT, Claude and any AI agent: list users, list course enrollments, list overdue learners, approve enrollment request, enroll users in a course, message learners, create user and deactivate user in your own Absorb LMS account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to Absorb LMS yourself; Cotlet does not store your password and you need no Absorb LMS API key. About the official Absorb LMS API: Absorb LMS has an Integration API, a REST API with JSON for learners, courses, departments and grades, but it needs a private key tied to your portal that your Absorb account team provides, and your own code (checked 20 Oct 2026). Absorb's Aura MCP for Claude and ChatGPT is planned for 27 Oct 2026 and is read and answer only. Setup and FAQ: https://cotlet.dev/integrations/absorb-lms-api-mcp-server

    • LearnUpon MCP server for ChatGPT, Claude and any AI agent: list users, invite users, add users to group, enroll group on course, enroll users on course, unenroll users, set enrollment complete and disable user in your own LearnUpon account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to LearnUpon yourself; Cotlet does not store your password and you need no LearnUpon API key. About the official LearnUpon API: LearnUpon has a REST API and a reporting MCP server, but neither covers day-to-day admin work from an AI agent (checked 20 Oct 2026). The REST API uses API keys that an admin generates under Settings > Integrations > API Keys, and Support grants them when the option is missing. Setup and FAQ: https://cotlet.dev/integrations/learnupon-api-mcp-server

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI assistants to browse your own university courses by downloading files, slides, announcements, deadlines, grades and lecture transcripts to your machine, then answering questions and searching across them through MCP tools. It logs in with your own account and refreshes only what changed.
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Connects Claude, Cursor, Codex and other AI assistants to Canvas LMS through a normal browser sign-in (SSO and MFA included) instead of an access token, letting them read courses, assignments, rubrics, announcements, discussions, grades, calendar and inbox, and read or save course files locally. It is strictly read-only, sending only GET requests, and keeps all session data on the user's own machine.
      4
      MIT