---
name: iblai-connect-canvas
description: "Read and write Canvas LMS data through the Canvas LMS REST API (plus Canvas GraphQL API and LTI 1.3 / LTI Advantage) and expose it to an ibl.ai agent as an MCP tool. Use when the user asks an agent to work with Canvas LMS data, or to set up a Canvas LMS MCP connection on ibl.ai."
metadata:
  kind: guide
---

# Canvas LMS connector for AI agents

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

Canvas is Instructure's learning management system for schools, universities and workforce training. It holds courses, enrollments, assignments, submissions, grades, modules, discussions, files and user messages.

## Auth & conventions

- **API:** Canvas LMS REST API (plus Canvas GraphQL API and LTI 1.3 / LTI Advantage) (REST). REST resources under /api/v1 cover courses, users, enrollments, assignments, submissions, grades and conversations. A GraphQL endpoint at /api/graphql covers a subset with the same permissions.
- **Base URL:** https://{canvas-domain}/api/v1/
- **Access:** Issued by your administrator. On Instructure-hosted Canvas, an institution's admin issues developer keys (client ID and secret) scoped to its root account. A user can also generate a personal access token from /profile for testing.
- **Auth:** OAuth 2.0 authorization code; Personal access token; OAuth 2.0 client credentials with signed JWT (LTI Advantage services). Send Authorization: Bearer <token>. OAuth uses /login/oauth2/auth and /login/oauth2/token; tokens from post-2015 keys expire in 1 hour and need refresh. Admins can enforce per-endpoint scopes like url:GET|/api/v1/courses.
- **Limits:** Throttling is per access token. Each response carries X-Request-Cost and X-Rate-Limit-Remaining; an exhausted quota returns 429. Lists return 10 items by default; set per_page and follow the Link header.
- Keep Canvas LMS 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

- **Courses** — GET /api/v1/courses lists the caller's courses; GET /api/v1/courses/:id returns one course.
- **Enrollments and rosters** — GET /api/v1/courses/:course_id/enrollments and GET /api/v1/courses/:course_id/users list students, teachers, TAs and observers.
- **Assignments** — GET /api/v1/courses/:course_id/assignments lists assignments with due dates and points.
- **Submissions and grades** — GET /api/v1/courses/:course_id/assignments/:assignment_id/submissions lists submissions, scores and grades.
- **Conversations (inbox)** — GET /api/v1/conversations lists the current user's inbox conversations, newest first.

## Writes

- **Assignments** — POST /api/v1/courses/:course_id/assignments creates; PUT .../assignments/:id edits.
- **Grades and comments** — PUT /api/v1/courses/:course_id/assignments/:assignment_id/submissions/:user_id posts a grade or comment visible to the student. **Confirm with the user first.**
- **Enrollments** — POST /api/v1/courses/:course_id/enrollments enrolls a user; DELETE .../enrollments/:id concludes, deactivates or deletes. **Confirm with the user first.**
- **Messages** — POST /api/v1/conversations sends a message to one or more recipients. **Confirm with the user first.**
- **Assignment deletion** — DELETE /api/v1/courses/:course_id/assignments/:id removes an assignment. **Confirm with the user first.**

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

Instructure 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`.
   - Canvas LMS 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 every student in BIO 101 who has not submitted the week 6 lab."
- "Extend the due date of Essay 2 by three days for the whole section."
- "Show the grade distribution for the last quiz in my Statistics course."
- "Draft a Canvas inbox message to students missing two or more assignments."

## Guardrails

- Grades, submissions, enrollments and rosters held by a school are FERPA-protected education records. Workforce deployments hold employee training records.
- Request the narrowest Canvas LMS 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

- Canvas LMS REST API documentation: https://canvas.instructure.com/doc/api/
- Instructure Developer Documentation: Canvas: https://developerdocs.instructure.com/services/canvas
- Canvas OAuth2 overview: https://canvas.instructure.com/doc/api/file.oauth.html
- This connector on ibl.ai: https://ibl.ai/developer/connectors/canvas
- ibl.ai MCP server connections: https://ibl.ai/developer/platform/mcp/mcp-connections
