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

@mikael_david/canvas-mcp

v0.2.4

Published

MCP server for Canvas LMS — list weekly agenda, read assignments, submit files/text, post on discussions

Readme

canvas-mcp

A Model Context Protocol (MCP) server that turns the Canvas LMS API into a small, well-typed toolbox an LLM can actually use.

Built around one principle: never confuse "this assignment needs a submission" with "I already submitted". Every tool that returns an assignment surfaces those as two separate fields.

What it can do

| Tool | What it does | |---|---| | canvas_me | Authenticated user (sanity check that the token works) | | canvas_courses | List active courses with ids, codes and dates | | canvas_week | Headline tool: list every planner item in a date range with explicit requires_submission, submission_status, due_at and accepted_submission_types. Defaults to the next 7 days. | | canvas_todo | Items Canvas thinks need user action right now | | canvas_assignment | Full assignment + my current submission state, in one call. Description converted to Markdown. Accepts a Canvas URL or course_id + assignment_id. | | canvas_submit_file | Three-step Canvas file upload (request URL → upload binary → confirm) wrapped in a single call | | canvas_submit_text | Submit a text answer for online_text_entry | | canvas_submit_url | Submit a URL for online_url | | canvas_discussion | Fetch a discussion topic with the full entry tree + participant names + Markdown | | canvas_post_to_discussion | Create a top-level entry on a topic (forum answer) | | canvas_reply_to_entry | Reply to a peer's entry (forum comment) | | canvas_grades | My current and final score per course |

All endpoints that take a Canvas resource accept either an explicit pair of ids or a full Canvas URL like https://lms.jala.university/courses/700/assignments/13882. Just paste it in.

Requirements

  • Node 20 or newer
  • A Canvas Personal Access Token (Account → Settings → New Access Token)

Install

Looking for a step-by-step in Brazilian Portuguese? See GUIDE.md. Want to point an AI assistant (Gemini CLI, Cursor, Cline, Claude Code) at this server? See AGENTS.md.

Option 1 — npx (recommended)

The server is published on npm. The MCP client launches it on demand, so there is nothing to install ahead of time. Just reference it in your client config (see Wire it into Claude Code).

Option 2 — Global install

npm install -g @mikael_david/canvas-mcp
canvas-mcp --help    # confirms the binary is on PATH

Option 3 — From source

git clone https://gitlab.com/mikaeldavidlopes/canvas-mcp.git
cd canvas-mcp
pnpm install   # or: npm install
pnpm build     # or: npm run build

Get a Canvas Personal Access Token

The server never knows or asks for your password — it talks to Canvas with a token tied to your account.

  1. Open Canvas (e.g. https://lms.jala.university) and log in.
  2. Click your avatar → AccountSettings.
  3. Scroll to Approved Integrations+ New Access Token.
  4. Purpose: canvas-mcp. Expiration: leave blank for no expiry, or pick a date.
  5. Copy the token shown once — Canvas will not show it again.

Configure credentials

The server reads credentials from, in order:

  1. Environment variables CANVAS_BASE_URL + CANVAS_API_TOKEN.
  2. JSON file at the path in CANVAS_CREDENTIALS_FILE.
  3. JSON file at ~/.openclaw/canvas_credentials.json.

The JSON file looks like:

{
  "base_url": "https://lms.jala.university",
  "token": "your_personal_access_token_here"
}

A .env.example is provided for the env-var path. Whichever option you pick, the token stays on your machine and is never logged.

Wire it into Claude Code

Easiest path, using the CLI:

claude mcp add --scope user canvas \
  -e CANVAS_BASE_URL=https://lms.jala.university \
  -e CANVAS_API_TOKEN=your_personal_access_token_here \
  -- npx -y @mikael_david/canvas-mcp

Or edit ~/.claude.json (user scope) / .mcp.json (project scope) directly:

{
  "mcpServers": {
    "canvas": {
      "command": "npx",
      "args": ["-y", "@mikael_david/canvas-mcp"],
      "env": {
        "CANVAS_BASE_URL": "https://lms.jala.university",
        "CANVAS_API_TOKEN": "your_personal_access_token_here"
      }
    }
  }
}

If you installed from source, swap the command:

"command": "node",
"args": ["/absolute/path/to/canvas-mcp/dist/index.js"]

After saving, restart Claude Code and run /mcp to confirm canvas shows as Connected.

Wire it into Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the equivalent on your platform:

{
  "mcpServers": {
    "canvas": {
      "command": "npx",
      "args": ["-y", "@mikael_david/canvas-mcp"],
      "env": {
        "CANVAS_BASE_URL": "https://lms.jala.university",
        "CANVAS_API_TOKEN": "your_personal_access_token_here"
      }
    }
  }
}

Try it without an MCP client

A smoke test exercises the read-only tools against the live API:

pnpm tsx scripts/smoke-test.ts

It prints the first ~600 characters of each response, so you can confirm the token works and the data looks right before plugging the server into a client.

Design notes

  • The submission ambiguity, solved. canvas_week and canvas_assignment both return requires_submission (derived from submission_types) and submission_status (derived from the workflow state). Callers never have to guess what the columns mean.
  • HTML to Markdown. Canvas serves HTML in assignment descriptions and discussion entries. Every text field passes through Turndown so LLMs read it cleanly, without <p> and <span> everywhere.
  • URL parsing. Every resource-bound tool also accepts the full Canvas URL. Pasting URLs is the most natural path when the LLM is reasoning about an assignment.
  • No quiz submission. Listing quizzes works through canvas_week, but actually answering a quiz needs the dynamic question flow which is out of scope for this MVP. Read-only is fine for now.
  • Credentials are never logged. Errors include the path and status code, never the token.

Project layout

canvas-mcp/
├── src/
│   ├── index.ts          MCP server entry (stdio)
│   ├── client.ts         HTTP client with pagination + 3-step file upload
│   ├── auth.ts           Credential resolution (env / file / default path)
│   ├── tools.ts          The 11 tools
│   ├── types.ts          Canvas API shapes the MCP exposes
│   └── utils/
│       ├── html.ts       HTML → Markdown via Turndown
│       ├── pagination.ts Link header parser
│       └── url.ts        Canvas URL parser
├── scripts/
│   └── smoke-test.ts     Read-only sanity check against the live API
├── package.json
├── tsconfig.json
├── tsup.config.ts
└── README.md

Sharing with classmates

This server has no shared state and stores no credentials. Anyone with a Canvas account (any instance) can use the same npm package.

The shortest pitch to a classmate:

  1. Send them the package name: @mikael_david/canvas-mcp.
  2. Point them at GUIDE.md (Brazilian Portuguese, end-to-end walkthrough including how to create the Canvas token).
  3. They run the claude mcp add command, restart Claude Code, and they're done.

What stays personal: each person uses their own Canvas token, and Canvas filters everything by token owner. Course list, grades, planner, submissions — all scoped to the individual.

What is shared safely: the code itself.

If a classmate is on a different Canvas (e.g. https://canvas.instructure.com), they just change CANVAS_BASE_URL. The same 12 tools work.

License

MIT.