Skip to main content
Glama
RyK57

canvas-mcp-server

by RyK57

canvas-mcp-server

Servidor MCP para la API REST de Canvas LMS. Da a un LLM acceso de lectura a tus cursos, tareas, calificaciones, entregas, anuncios, discusiones, módulos, páginas y archivos.

20 herramientas, todas de solo lectura.

Requisitos

  • Node.js 18+

  • Una cuenta de Canvas en cualquier institución

  • Un token de acceso desde Account → Settings → New Access Token en tu interfaz web de Canvas

Instalar

npm install
npm run build

Configurar

Canvas no tiene un host de API compartido: cada institución ejecuta el suyo. Ambas variables siguientes son obligatorias.

{
  "mcpServers": {
    "canvas": {
      "command": "node",
      "args": ["/absolute/path/to/canvas-mcp-server/dist/index.js"],
      "env": {
        "CANVAS_BASE_URL": "https://bcourses.berkeley.edu",
        "CANVAS_ACCESS_TOKEN": "your-token-here"
      }
    }
  }
}

Variable

Obligatoria

Predeterminado

Propósito

CANVAS_BASE_URL

El host de Canvas de tu institución, con esquema incluido, sin ruta final

CANVAS_ACCESS_TOKEN

Account → Settings → New Access Token

CANVAS_REQUEST_TIMEOUT_MS

no

30000

Tiempo de espera por solicitud

TRANSPORT

no

stdio

stdio o http

PORT / HOST

no

3000 / 127.0.0.1

Dirección de enlace del transporte HTTP

MCP_PATH_SECRET

cuando está alojado

Sirve el endpoint en /mcp/<secret>. Obligatorio cuando HOST no es loopback

ALLOWED_ORIGINS

no

localhost + claude.ai

Lista de orígenes permitidos separados por comas

Inspecciona las herramientas de forma interactiva:

CANVAS_BASE_URL=https://your.canvas CANVAS_ACCESS_TOKEN=your-token npm run inspect

Despliegue (para conectores de Claude mobile / claude.ai)

Claude se conecta a conectores personalizados desde la nube de Anthropic, no desde tu dispositivo, por lo que mobile y claude.ai necesitan que esto sea accesible a través de HTTPS público. Claude Code y Claude Desktop no lo necesitan; usa stdio allí en su lugar.

1. Genera un secreto de ruta

openssl rand -hex 32

El servidor se niega a iniciarse en una interfaz que no sea loopback sin MCP_PATH_SECRET configurado, porque un endpoint público que contiene tu token de Canvas es un proxy abierto a tu cuenta. Con él configurado, el endpoint se mueve a /mcp/<secret> y cualquier otra ruta devuelve 404, incluido un secreto incorrecto, por lo que sondear el host no revela que allí vive un servidor MCP.

2. Despliega

El Dockerfile y railway.json incluidos funcionan tal cual en Railway, Render o Fly. La imagen establece TRANSPORT=http y HOST=0.0.0.0 y se ejecuta como un usuario no root. Configura tres variables en el panel de la plataforma:

Variable

Valor

CANVAS_BASE_URL

el host de Canvas de tu institución

CANVAS_ACCESS_TOKEN

tu token

MCP_PATH_SECRET

el valor del paso 1

PORT es inyectado por la plataforma. /healthz es una sonda de actividad sin autenticación.

3. Verifica

curl -s https://your-app.up.railway.app/healthz

4. Añade el conector

En claude.ai en un navegador — los conectores no se pueden añadir desde la aplicación móvil:

  1. Customize → Connectors → Add custom connector

  2. URL: https://your-app.up.railway.app/mcp/<secret>

  3. En tu teléfono, abre un chat y actívalo en + → Connectors

Trata esa URL como una contraseña. Si se filtra, rota MCP_PATH_SECRET y vuelve a añadir el conector.

Herramientas

Coursescanvas_list_courses, canvas_get_course, canvas_get_grades, canvas_list_enrollments, canvas_get_profile

Assignmentscanvas_list_assignments, canvas_get_assignment, canvas_get_submission, canvas_list_quizzes

Plannercanvas_list_planner_items, canvas_list_upcoming, canvas_list_calendar_events

Announcements and discussionscanvas_list_announcements, canvas_list_discussions, canvas_get_discussion

Course contentcanvas_list_modules, canvas_list_module_items, canvas_list_pages, canvas_get_page, canvas_list_files

Cada herramienta de lectura acepta response_format: "markdown" | "json". Markdown es el predeterminado y está optimizado para que lo lea un LLM; JSON es la carga útil estructurada completa. structuredContent siempre se rellena independientemente del formato.

Ejemplos

"¿Qué hay que entregar esta semana?"canvas_list_planner_items con end_date a una semana vista. Abarca todos los cursos en una sola llamada e informa del estado de las entregas. Por defecto comienza desde hoy, así que para "en qué me he retrasado" pasa un start_date anterior explícito.

"¿Cuáles son mis calificaciones?"canvas_get_grades. Una llamada, todos los cursos activos, puntuación actual y calificación con letra.

"¿Qué anunciaron mis profesores esta semana?"canvas_list_courses para los ids, luego canvas_list_announcements con todos a la vez.

"¿Qué tengo que hacer realmente para el proyecto 2?"canvas_list_assignments con search_term="project 2" para obtener el id, luego canvas_get_assignment para las instrucciones completas.

Notas de diseño

Solo lectura por construcción. Cada herramienta lleva readOnlyHint: true y destructiveHint: false, y el cliente no tiene ninguna ruta de escritura expuesta. Los tokens de Canvas llevan la autoridad completa de tu cuenta: pueden enviar tareas, publicar en discusiones y cambiar la configuración del perfil, por lo que el servidor se niega deliberadamente a exponer nada de eso. Una prueba lo verifica: si alguna vez se añade una herramienta de escritura, la suite falla.

La URL base es obligatoria, no tiene valor predeterminado. A diferencia de las API de un solo inquilino, Canvas ejecuta una instancia por institución. No hay un valor predeterminado razonable, y un token emitido por el Canvas de una escuela no tiene sentido en otra, por lo que el servidor falla al iniciarse en lugar de engañarte con 401 más tarde.

La paginación vive en una cabecera. Canvas informa de "¿hay una página siguiente?" en una cabecera Link RFC 5988 y nunca devuelve un recuento total. Esas URL están documentadas como opacas, por lo que has_more se lee de la cabecera mientras que page/per_page siguen siendo los controles visibles para el llamador: un agente obtiene un simple next_page que seguir en lugar de un cursor que enhebrar.

Los ids se solicitan como cadenas. Los ids de Canvas son enteros de 64 bits, que JavaScript no puede representar exactamente. El cliente envía Accept: application/json+canvas-string-ids, que Canvas respeta devolviendo cada id como una cadena, por lo que los ids sobreviven intactos a un viaje de ida y vuelta JSON.

El HTML se aplana antes de llegar al modelo. Las descripciones de tareas, anuncios, publicaciones de discusión y páginas se almacenan como HTML. Pasarlo tal cual consume un contexto enorme en marcado, por lo que las etiquetas se convierten en saltos de línea, las entidades se decodifican y los cuerpos largos se resumen manteniendo el html_url para la versión completa.

include[] no está expuesto. Canvas tiene dos docenas de opciones de include, difieren entre los endpoints de lista y de curso individual, y la mayoría controlan campos que un agente no necesita. Cada herramienta solicita lo que necesita y muestra solo los interruptores que cambian lo que un usuario vería: include_syllabus, include_grades, include_submission.

Los ids de curso se normalizan en códigos de contexto. Algunos endpoints de Canvas abordan los cursos como course_1234 en lugar de 1234. Ambas formas se aceptan en todas partes y se convierten, por lo que el agente nunca tiene que recordar qué endpoint quiere cuál.

Los errores se resuelven en acciones siguientes. Un 404 nombra la herramienta que produce ids válidos para ese recurso. Un 403 distingue un problema de permisos de un límite de tasa agotado, que Canvas devuelve confusamente bajo el mismo estado. Un 401 señala que un token del Canvas de una escuela no funcionará en otra.

Dos peculiaridades de Canvas se manejan en lugar de transmitirse. La calificación que un curso informa en enrollments[].computed_current_score es el mismo número que la API de Enrollments llama grades.current_score; ambos se leen. Y el campo submissions de un elemento del planificador es el booleano false — no un objeto — cuando no hay nada que entregar, lo cual se comprueba antes de leerlo.

Advertencias

  • Los anuncios no se pueden listar globalmente: Canvas requiere al menos un id de curso, por lo que canvas_list_courses debe ejecutarse primero.

  • canvas_list_discussions aplica su filtro scope después de paginar, por lo que una página filtrada puede devolverse más corta que per_page sin ser el final de los resultados.

  • Canvas omite los elementos de módulo de la respuesta de lista para los módulos que considera grandes; canvas_list_module_items los obtiene.

  • Las páginas se abordan por slug de url (week-1-reading), no por título. canvas_list_pages devuelve el slug en su campo url.

  • El endpoint de calendario acepta como máximo 10 cursos e ignora silenciosamente el resto; canvas_list_calendar_events informa cuando recorta.

  • Las calificaciones reflejan solo lo que un instructor ha publicado, y se omiten por completo para los cursos configurados para ocultar las calificaciones finales.

Estructura del proyecto

src/
├── index.ts               # entry point, transport selection
├── constants.ts           # enum values, limits, character limit
├── types.ts               # interfaces for every Canvas entity
├── services/
│   └── canvas-client.ts   # fetch wrapper, auth, Link pagination, error → guidance mapping
├── schemas/
│   ├── inputs.ts          # Zod input schemas
│   └── outputs.ts         # structuredContent schemas
├── formatters/
│   ├── response.ts        # pagination, truncation, HTML flattening, format dispatch
│   └── entities.ts        # per-entity markdown rendering
└── tools/
    ├── courses.ts
    ├── assignments.ts
    ├── planner.ts
    ├── announcements.ts
    └── content.ts

Pruebas

npm run build
npm test            # 43 checks: MCP handshake, tools, pagination, formatting, errors (mocked API)
npm run test:http   # 19 checks: config validation, path-secret gating, method handling, origins

Ambas suites se ejecutan contra un mock local, por lo que no se necesita token ni acceso a la red.

-
license - not tested
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Gateway between LLM agents and world data through eight tools and a bundled endpoint catalog.

  • Read-only MCP server for ClassQuill, a tutoring-business-management platform.

  • Read-only MCP server for Muovi, Argentina's trust-first local services marketplace (6 tools).

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/RyK57/canvas-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server