Skip to main content
Glama
README.md
# Canvas MCP

MCP (Model Context Protocol) server for Canvas LMS. Exposes Canvas courses, assignments, modules, pages, files, grades, and submissions as tools for AI agents.

## Tools

| Tool | Description |
|------|-------------|
| `list_courses` | List all active courses |
| `get_course` | Course details, optionally with syllabus |
| `list_modules` | Modules with items (pages, files, assignments) |
| `list_assignments` | All assignments with due dates and points |
| `get_assignment` | Full assignment with description + rubric |
| `submit_url` | Submit a URL to an assignment |
| `submit_text` | Submit text to an assignment |
| `list_pages` | List course pages |
| `get_page` | Get page content as plain text |
| `get_file` | File metadata and download URL |
| `list_files` | List all files (may 403 on some instances) |
| `list_announcements` | Course announcements |
| `list_discussions` | Discussion topics |
| `list_groups` | Groups in a course |
| `list_group_members` | Members of a group |
| `my_grades` | Your graded submissions with rubric feedback |
| `get_submission` | Your submission for a specific assignment |
| `upcoming_events` | Upcoming calendar events |
| `todo_items` | Canvas TODO items |
| `whoami` | Authenticated user profile |

## Resources

| URI | Description |
|-----|-------------|
| `canvas://courses` | All active courses as JSON |
| `canvas://todo` | Current TODO items as JSON |

## Setup

### Environment Variables

```bash
export CANVAS_API_TOKEN="your-canvas-token"
export CANVAS_BASE_URL="https://your-institution.instructure.com"
```

Generate a token at: `<your-canvas-url>/profile/settings` → `+ New Access Token`

### Install

```bash
pip install -e .
```

### Run

```bash
canvas-mcp              # stdio transport (for MCP clients)
```

### Add to Hermes config.yaml

```yaml
mcp_servers:
  canvas:
    command: canvas-mcp
    env:
      CANVAS_API_TOKEN: "your-token"
      CANVAS_BASE_URL: "https://psu.instructure.com"
```

### Add to Claude Desktop

```json
{
  "mcpServers": {
    "canvas": {
      "command": "canvas-mcp",
      "env": {
        "CANVAS_API_TOKEN": "your-token",
        "CANVAS_BASE_URL": "https://psu.instructure.com"
      }
    }
  }
}
```

## Design Decisions

- **No stdout output from tools** — tools return structured dicts/lists only, safe for coding agents
- **HTML is stripped** — all Canvas HTML content is converted to readable plain text
- **Responses are slimmed** — only relevant fields returned, no noise
- **Pagination handled** — follows Canvas `Link` headers automatically (up to 10 pages)
- **Graceful 403 handling** — `list_files` returns an error dict with a hint instead of crashing
- **Client cleanup** — every tool call opens and closes its own client connection

## Testing

```bash
pip install pytest pytest-asyncio
pytest -v
```

Tests use a `MockTransport` that intercepts HTTP at the httpx layer — no real Canvas calls.
Three test files:
- `test_client.py` — Canvas API client unit tests
- `test_server.py` — tool functions, HTML stripping, slimming helpers
- `test_integration.py` — full pipeline: tool → client → mock HTTP → structured response

## License

MIT