Skip to main content
Glama
GodPuffin

Personal Canvas MCP

by GodPuffin

Personal Canvas MCP

An MIT-licensed, single-user MCP server for student-visible Canvas LMS data. Each owner deploys their own copy to Vercel, keeps their Canvas personal access token in deployment secrets, and connects approved AI clients through OAuth.

The server is stateless: Canvas is queried on demand. There is no database, sync job, or content cache.

Personal/development use only. Do not ask other people to paste Canvas personal access tokens into your deployment. A multi-user product must use institution-approved Canvas OAuth and comply with Instructure's OAuth guidance and API policy.

Deploy with Vercel

The main button deploys the recommended Clerk OAuth configuration. A separate bearer-token Deploy Button is available for clients that support custom authorization headers.

What agents can access

The curated tools cover the connected owner's profile; courses, favorites, groups, activity and syllabi; assignments, differentiated due dates, rubrics, grades, missing work, submissions and feedback; calendar, planner and announcements; modules, pages, files and document extraction; discussions and visible replies; and classic/New Quiz data that Canvas actually reveals to a student.

Inbox conversations, recipient search, rosters, and standalone profiles for other students are deliberately absent. Discussion authors appearing in replies are the narrow exception. New Quiz endpoints vary by institution and student permissions, so unavailable detail is returned as a typed capability limitation. The server never attempts teacher-only quiz endpoints.

With CANVAS_PERMISSION_PRESET=planner, three additional tools create, update, and delete the owner's planner notes. Delete requires confirm: true. Assignment submission and course mutation tools do not exist.

Related MCP server: Canvas Agent

Deploy to Vercel

  1. Click Deploy with Vercel above. Vercel clones this repository, creates the project, and requires its native Clerk Marketplace integration.

  2. Enter the requested Canvas values. Only the non-sensitive settings CANVAS_PERMISSION_PRESET=read and MCP_AUTH_MODE=clerk are prefilled; no token, key, hostname, or email is placed in the button URL.

  3. Complete the Clerk Marketplace provisioning step. Vercel creates a Clerk application and automatically syncs NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY into the project environments.

  4. Deploy and open /. The page says whether configuration is ready without showing the Canvas hostname, email, or any secret.

  5. If Vercel cannot supply VERCEL_PROJECT_PRODUCTION_URL, set MCP_PUBLIC_URL to the stable production origin and redeploy.

You can also fork the repository and import it through Vercel's New Project flow manually.

Canvas credentials

Create a personal access token in your own Canvas account's Account → Settings → Approved Integrations → New Access Token area. Some institutions disable this feature or require administrator approval.

Set:

CANVAS_BASE_URL=https://school.instructure.com
CANVAS_ACCESS_TOKEN=your-personal-token
CANVAS_PERMISSION_PRESET=read
MCP_OWNER_EMAIL=you@example.com

CANVAS_BASE_URL must be an HTTPS origin. Tokens are sent only in the downstream Canvas Authorization header. They are never placed in URLs, MCP results, or operational logs.

Authentication modes

MCP_AUTH_MODE=clerk is the recommended production mode and the mode that supports normal remote-MCP installation in ChatGPT and Claude. Authentication protects access to the deployment; it is separate from the Canvas token used downstream.

The recommended Deploy Button installs Vercel's native Clerk integration, provisions a Clerk application, and syncs the publishable and secret keys. You do not paste those keys into the Deploy Button form. If you import the repository manually or deliberately use a separately managed Clerk application, configure the keys yourself:

  1. Create a Clerk application and add its publishable and secret keys:

    MCP_AUTH_MODE=clerk
    NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_...
    CLERK_SECRET_KEY=sk_...
  2. Whether Clerk was provisioned automatically or manually, open its Dashboard and enable OAuth for MCP, consent, and PKCE. Create the custom scopes canvas:read and canvas:planner. Prefer Client ID Metadata Documents (CIMD), and enable Dynamic Client Registration (DCR) only for older clients that require it; DCR exposes a public client-registration endpoint.

  3. Configure the allowed account so its verified email exactly matches MCP_OWNER_EMAIL.

  4. If the preset is read, clients need canvas:read. The planner preset requires both canvas:read and canvas:planner.

The Marketplace integration provisions and synchronizes credentials, but it cannot choose your MCP scopes, owner account, consent policy, or client-registration compatibility settings. Those remain one-time Clerk Dashboard steps. For a production Clerk instance, follow Clerk's domain setup instructions; a custom production domain may be required.

The app publishes RFC 9728 resource metadata at both:

/.well-known/oauth-protected-resource
/.well-known/oauth-protected-resource/mcp

It also exposes Clerk-compatible authorization-server metadata at /.well-known/oauth-authorization-server. Invalid, expired, revoked, wrong-owner, or under-scoped tokens receive an OAuth bearer challenge before MCP executes.

Static bearer token (optional)

For Codex, Cursor, VS Code, Claude Code, and other clients that can attach a custom header, Clerk can be omitted:

Deploy bearer-token mode with Vercel

MCP_AUTH_MODE=token
MCP_ACCESS_TOKEN=a-random-secret-of-at-least-32-characters

Generate a secret with a cryptographically secure password manager or openssl rand -hex 32. Configure the client to send:

Authorization: Bearer <MCP_ACCESS_TOKEN>

This mode has no OAuth discovery flow, so it is not installable through the ordinary ChatGPT or Claude remote-connector UI. It is intentionally useful for self-hosters whose client supports custom bearer headers.

Example Codex configuration:

[mcp_servers.canvas]
url = "https://your-project.vercel.app/mcp"
bearer_token_env_var = "PERSONAL_CANVAS_MCP_TOKEN"

No authentication (local only)

MCP_AUTH_MODE=none works only when NODE_ENV is not production. A production deployment with this value fails closed. Do not expose an unauthenticated server to the internet.

Local development

Requirements: Node.js 20.9 or newer and npm.

npm install
cp .env.example .env.local
npm run dev

On Windows PowerShell, replace the copy command with:

Copy-Item .env.example .env.local

For the simplest local smoke test, set MCP_AUTH_MODE=none, start the app, and connect an MCP Inspector to http://localhost:3000/mcp. Restore clerk or token before any remote deployment.

MCP behavior and safety

  • The endpoint is stateless Streamable HTTP at GET|POST|DELETE /mcp and uses the Node.js runtime.

  • Canvas IDs are requested and preserved as strings to avoid JavaScript integer precision loss.

  • Every URL path is selected by a fixed tool implementation; there is no generic API-request tool.

  • Pagination returns page/per-page/has-next metadata. Aggregate requests run sequentially to respect Canvas request-cost limits.

  • 429 and transient 5xx failures receive bounded exponential retries. Authentication, authorization, missing/expired resources, throttling, malformed responses, and unavailable capabilities have typed errors.

  • Canvas HTML is converted to sanitized text. MCP results explicitly label Canvas content as untrusted external material.

  • Logs are disabled in the MCP handler. If you add observability, record only redacted operation names, status, latency, and Canvas request cost—never request parameters or response bodies.

File extraction limits

canvas_extract_file supports plain text, HTML, CSV, PDF, DOCX, PPTX, and XLSX. It does not support legacy DOC/PPT/XLS, OCR-only PDFs, encrypted/password-protected files, macros, or embedded executables.

  • Source: 10 MiB maximum

  • OOXML archive: 2,000 entries and 64 MiB expanded-data maximum before parsing

  • Extracted source: 500,000 characters maximum

  • Returned page: 20,000 characters by default, 50,000 maximum

  • Continuation: pass the returned nextOffset

Signed download URLs are never returned. Downloaded bytes and extracted text live only for the current request.

Verification

npm test
npm run typecheck
npm run lint
npm run build
npm audit

The automated suite covers origin validation, query encoding, string IDs, HTML and secret sanitization, pagination, retries, HTTP error mapping, optional bearer auth, permission-based registration, MIME spoofing, extraction continuation, and archive expansion limits.

Before relying on a deployment, also perform a live smoke test against a disposable Canvas course and use the MCP Inspector. Verify tool discovery, a cross-course overview, locked/empty/concluded course behavior, differentiated due dates, hidden grades, submission feedback, quiz visibility, file extraction, OAuth reconnect/revocation, and planner-note create/update/delete when enabled. Client-specific connection behavior should be checked in every client you intend to support.

Future multi-user architecture

Canvas credential lookup is behind CanvasCredentialProvider. A future institution-approved OAuth implementation can replace the environment provider without changing tool handlers. That version will also need per-user encrypted token storage, refresh/revocation handling, tenant isolation, institutional developer-key approval, and an updated privacy/security review.

License

MIT

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers