Skip to main content
Glama
salvadoracuna

canvas-mcp

README.md
# canvas-mcp

An MCP server that exposes Canvas LMS data (courses, assignments, announcements) to any MCP-compatible client (Claude Desktop, Claude Code, etc.).

> **This repository ships with no credentials.** There is no Canvas token and no
> email address anywhere in it. You supply your own token in a local `.env` file
> that is git-ignored and never leaves your machine. See
> [Where your token goes](#where-your-token-goes).

## Prerequisites

- [uv](https://docs.astral.sh/uv/) (Python package manager)
- A Canvas LMS account with an API token

## Setup

### 1. Generate a Canvas API token

1. Log in to your school's Canvas site (for example `https://canvas.fen.uchile.cl`)
2. Go to **Account → Settings → Approved Integrations**
3. Click **+ New Access Token**, give it a name, and copy the token

### 2. Configure the environment

<a id="where-your-token-goes"></a>

**Where your token goes:** in a file named exactly `.env`, in the root of this
project folder (right next to `main.py`). That file is listed in `.gitignore`,
so git will never commit or push it.

Copy the template:

```bash
cp .env.example .env
```

Then open `.env` and fill in the blanks:

```
# Your Canvas instance URL -- change this to your school's Canvas address
CANVAS_URL=https://canvas.fen.uchile.cl

# Paste the token from step 1 here
CANVAS_API_TOKEN=

# Optional second account (use account="udd" in the tools). Leave blank if unused.
CANVAS_UDD_URL=
CANVAS_UDD_TOKEN=
```

Only `CANVAS_URL` and `CANVAS_API_TOKEN` are required. The `CANVAS_UDD_*` pair is
for an optional second Canvas account; leave both blank if you only have one.

> Never commit `.env`, never paste your token into a chat, and never put it in a
> file that gets shared. It grants full access to your Canvas account. If it
> leaks, delete the token in Canvas (**Account -> Settings -> Approved
> Integrations**) and generate a new one.

### 3. Install dependencies

```bash
uv sync
```

### 4. Run the server manually (optional test)

```bash
uv run python main.py
```

The server communicates over stdio, so it won't print anything until an MCP client connects.

## Connecting to Claude Desktop

Add the following to your Claude Desktop config file:

**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`  
**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "canvas": {
      "command": "uv",
      "args": ["run", "--project", "/absolute/path/to/canvas-mcp", "python", "main.py"]
    }
  }
}
```

Replace `/absolute/path/to/canvas-mcp` with the real path to this folder. Use
forward slashes `/` even on Windows.

> No token goes in this file. It is read from your `.env` (see
> [Where your token goes](#where-your-token-goes)) -- `python-dotenv` loads it
> automatically.

## Connecting to Claude Code

Add the MCP server in your Claude Code settings or run:

```bash
claude mcp add canvas -- uv run --project /absolute/path/to/canvas-mcp python main.py
```

## Available Tools

| Tool | Description |
|------|-------------|
| `get_courses` | Lists all active enrolled courses |
| `get_assignments(days_ahead=30)` | Lists upcoming assignments sorted by due date |
| `get_announcements` | Lists recent announcements per course |

## Project structure

```
canvas-mcp/
├── main.py          # MCP server
├── .env             # Your token lives here (git-ignored, never pushed)
├── .env.example     # Template
├── pyproject.toml   # Project metadata & dependencies
└── uv.lock          # Locked dependency versions
```

TDQS

A3.6/5.0

Scored across 10 tools

Disambiguation5/5

Every tool targets a distinct resource and action. get_courses vs get_assignments vs get_announcements are clearly separated, and even similar tools like get_course_files (listing) and read_course_file (reading content) are unambiguous.

Naming Consistency4/5

All tools follow a verb_noun pattern with 'get_' prefix, except read_course_file which uses 'read_'. This is a minor deviation but the rest are consistent, and the naming is predictable overall.

Tool Count5/5

The 10 tools are well-scoped for a read-only Canvas LMS server. They cover the main course-related resources without being excessive, fitting comfortably within the ideal 3-15 range.

Completeness4/5

For a read-only surface, it covers the major resources: courses, assignments, announcements, files, modules, people, grades, discussions, and pages. Minor gaps exist (e.g., no single-course detail endpoint, no calendar events), but the core read workflows are covered without dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues