---
name: iblai-connect-d2l-brightspace
description: "Read and write D2L Brightspace data through the Brightspace APIs (Valence) and Data Hub / Brightspace Data Sets and expose it to an ibl.ai agent as an MCP tool. Use when the user asks an agent to work with D2L Brightspace data, or to set up a D2L Brightspace MCP connection on ibl.ai."
metadata:
  kind: guide
---

# D2L Brightspace connector for AI agents

> A starting point maintained on ibl.ai at https://ibl.ai/developer/connectors/d2l-brightspace — not part of the iblai/vibe repository. Checked against D2L's documentation on October 20, 2026; test it against your own D2L Brightspace setup before you rely on it.

Brightspace is D2L's learning management system for schools, universities and organisations. It holds org units (courses), enrollments, users, content, assignment dropboxes, grades and Brightspace Data Sets exports.

## Auth & conventions

- **API:** Brightspace APIs (Valence) and Data Hub / Brightspace Data Sets (REST). Routes take the form /d2l/api/{component}/{version}/...; lp covers users, enrollments and org structure, le covers grades, content and dropboxes. Data Hub serves Brightspace Data Sets as bulk extracts.
- **Base URL:** https://{targethost}/d2l/api/{component}/{version}/
- **Access:** Issued by your administrator. An administrator registers the app in Brightspace's Manage Extensibility tool, choosing OAuth 2 scopes and the authorization code or client credentials grant, which yields a client ID.
- **Auth:** OAuth 2.0 authorization code; OAuth 2.0 client credentials (JWT client assertion). Authorize at https://auth.brightspace.com/oauth2/auth; token at https://auth.brightspace.com/core/connect/token. Scopes look like enrollment:orgunit:read; core:*:* is the fallback. Token lifetime is set from 1,800 to 72,000 seconds.
- **Limits:** Token-bucket credits per caller; 429 when exhausted. Headers: X-Rate-Limit-Remaining, X-Request-Cost, X-Rate-Limit-Reset / Retry-After. Paging uses PagedResultSet (Bookmark, HasMoreItems) or ObjectListPage (Next URL).
- Keep D2L Brightspace credentials in environment variables or the ibl.ai credential store. Never print a token in chat and never commit one to a file.
- Destructive or outward-facing calls are marked **Confirm with the user first** — do.

## Reads

- **My enrollments** — GET /d2l/api/lp/(version)/enrollments/myenrollments/ (scope enrollment:own_enrollment:read).
- **Classlist** — GET /d2l/api/le/(version)/(orgUnitId)/classlist/paged/ lists users in a course (scope enrollment:orgunit:read).
- **Grade objects and values** — GET /d2l/api/le/(version)/(orgUnitId)/grades/ and .../grades/values/(userId)/ (scopes grades:gradeobjects:read, grades:gradevalues:read).
- **Assignment dropboxes** — GET /d2l/api/le/(version)/(orgUnitId)/dropbox/folders/ and .../folders/(folderId)/submissions/.
- **Users** — GET /d2l/api/lp/(version)/users/whoami and GET /d2l/api/lp/(version)/users (scope users:userdata:read).
- **Brightspace Data Sets** — GET /d2l/api/lp/(version)/datasets/bds lists data sets; extracts download per schema and plugin (scope datasets:bds:read).

## Writes

- **Grade values** — PUT /d2l/api/le/(version)/(orgUnitId)/grades/(gradeObjectId)/values/(userId) (scope grades:gradevalues:write). **Confirm with the user first.**
- **Enrollments** — POST /d2l/api/lp/(version)/enrollments/ creates; DELETE .../enrollments/orgUnits/(orgUnitId)/users/(userId) removes. **Confirm with the user first.**
- **Dropbox feedback** — POST /d2l/api/le/(version)/(orgUnitId)/dropbox/folders/(folderId)/feedback/(entityType)/(entityId) posts feedback. **Confirm with the user first.**
- **Users** — POST /d2l/api/lp/(version)/users creates a user; /users/batch/ creates up to 500 (scope users:userdata:create).

## Expose it to an ibl.ai agent (MCP)

D2L did not publish an MCP server of its own when this skill was checked. Host a small MCP server that wraps the calls above, then register it below.

First install the ibl.ai platform skills and connect your organization (writes `IBLAI_ORG`, `IBLAI_USERNAME` and `IBLAI_API_KEY` to `.env`):

```bash
npx skills add iblai/vibe --all
# then, in your coding agent:
/iblai-api-login
```

Every call below sends `Authorization: Api-Token $IBLAI_API_KEY`.

1. **Register the server** — `POST https://api.iblai.app/dm/api/ai-mentor/orgs/$IBLAI_ORG/users/$IBLAI_USERNAME/mcp-servers/` with `name`, `url`, `transport` (`sse` | `websocket` | `streamable_http`) and `auth_type` (`none` | `token` | `oauth2`). Capture the returned `id`.
   - D2L Brightspace supports per-user OAuth: `auth_type=oauth2` with `auth_scope=user` and a linked `oauth_service` makes each person connect their own account in the chat. It needs an `auth_{provider}` credential in the organization's credential store first.
2. **Create the connection** — `POST https://api.iblai.app/dm/api/ai-mentor/orgs/$IBLAI_ORG/users/$IBLAI_USERNAME/mcp-server-connections/` with `server`, `scope` (`platform` | `mentor` | `user`), `auth_type`, and either `credentials` + `authorization_scheme` or a `connected_service` id for OAuth. Credentials are masked on read; never send a masked value back.
3. **Enable it on the agent** — `GET https://api.iblai.app/dm/api/ai-mentor/orgs/$IBLAI_ORG/users/$IBLAI_USERNAME/mentors/{agent_id}/settings/`, add `mcp-tool` to `tool_slugs` and the server id to `mcp_servers`, then `PATCH` the full lists back. They are replaced, not merged.

Full reference: https://ibl.ai/developer/platform/mcp/mcp-connections and the `/iblai-api-agent-mcp` skill.

## Example prompts

- "List students in HIST 110 who have not submitted to the Research Paper dropbox."
- "Show my grade book values for each student in Biology section 3."
- "Enroll this teaching assistant in all three sections of CHEM 101."
- "Download the latest Users and Enrollments Brightspace Data Sets extracts."

## Guardrails

- Grades, submissions, enrollments and user records held by a school are FERPA-protected education records.
- Request the narrowest D2L Brightspace scopes or role the task needs, and prefer a read-only credential for agents that only answer questions.
- Return the fields the user asked for, not whole records; do not paste personal data into chat that the user did not request.
- Before any write, show the user exactly what will change and wait for a yes.
- Respect the documented limits above: page through results and back off on rate-limit responses instead of retrying in a loop.

## References

- Brightspace Developer Platform: getting started: https://docs.valence.desire2learn.com/basic/firstlist.html
- Brightspace OAuth 2.0: https://docs.valence.desire2learn.com/basic/oauth2.html
- Brightspace API calling conventions: https://docs.valence.desire2learn.com/basic/apicall.html
- This connector on ibl.ai: https://ibl.ai/developer/connectors/d2l-brightspace
- ibl.ai MCP server connections: https://ibl.ai/developer/platform/mcp/mcp-connections
