Canvas MCP
by overtimepog
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
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues