Skip to main content
Glama

moodle-mcp

Servidor del Protocolo de Contexto de Modelo (MCP) para Moodle. Permite a los agentes de IA publicar y gestionar contenido pedagógico —lecciones, recursos, actividades— en Moodle a través de servicios web con idempotencia garantizada.

CI npm license: MIT

Estado: v0.1 MVP.


Qué es

moodle-mcp es un servidor MCP basado en stdio que expone un pequeño conjunto de fachadas de alto nivel más una primitiva de bajo nivel ws_raw para publicar una "Ficha" pedagógica canónica (un archivo markdown con frontmatter YAML) en un curso de Moodle como secciones, páginas, recursos y actividades reales. Cada escritura es una actualización (upsert) mediante idnumber, por lo que volver a publicar la misma Ficha nunca crea duplicados.

Consumidor principal: Claude Desktop impulsando el flujo de trabajo de enseñanza de idiomas de Italicia. Pero es un adaptador genérico de código abierto: cualquier agente compatible con MCP + cualquier instancia de Moodle 4.x/5.x con servicios web habilitados puede usarlo.

Herramientas expuestas en la v0.1

Herramienta

Propósito

obtener_contexto_curso

Instantánea de un curso: metadatos, secciones, lecciones publicadas recientemente por MCP, recuentos de matriculaciones.

publicar_ficha_clase

Publicar una FichaClase (ruta absoluta de markdown) como una sección de Moodle + actualizaciones de módulos.

publicar_preview

Igual que el anterior pero forzado a oculto + devuelve una URL de vista previa.

confirmar_preview

Hacer que una sección previamente oculta y sus módulos sean visibles para los estudiantes.

ws_raw

Puerta de escape: llamar a cualquier función de WS de Moodle directamente.

No incluido en la v0.1 (planificado para la v0.2+): publicar_ficha_examen, sync_alumnos_csv, transporte HTTP/SSE, constructor GIFT, carga de activos multipart, creación automática de módulos.

Instalación

# Via npx (recommended for Claude Desktop)
npx -y @marcosnahuel/moodle-mcp

# Or install globally
npm install -g @marcosnahuel/moodle-mcp

Requiere Node.js 20 o superior.

Configuración (variables de entorno)

Variable

Requerido

Predeterminado

Descripción

MOODLE_URL

URL HTTPS completa de la instancia de Moodle.

MOODLE_WS_TOKEN

Token de servicios web con permisos de edición.

MOODLE_WS_TIMEOUT_MS

no

30000

Tiempo de espera por solicitud.

MOODLE_WS_MAX_RETRIES

no

3

Intentos de reintento en fallos transitorios.

MOODLE_WS_RATE_LIMIT_PER_SEC

no

10

Límite de tasa de token-bucket.

MCP_LOG_LEVEL

no

info

error / warn / info / debug.

MOODLE_ALLOW_INSECURE

no

false

Permitir URLs http:// (puerta de escape solo para desarrollo).

Configuración de Claude Desktop

Añadir a claude_desktop_config.json (ver examples/setup-claude-desktop.md para la ruta exacta por SO):

{
  "mcpServers": {
    "moodle": {
      "command": "npx",
      "args": ["-y", "moodle-mcp"],
      "env": {
        "MOODLE_URL": "https://your-moodle.example.com",
        "MOODLE_WS_TOKEN": "your-ws-token"
      }
    }
  }
}

Reinicia Claude Desktop. Las cinco herramientas anteriores deberían estar ahora disponibles para el agente.

Ejemplos

1. Tomar una instantánea de un curso antes de actuar

// tool call
{
  "name": "obtener_contexto_curso",
  "arguments": { "course_id": 42, "incluir_ultimas_clases": 5 }
}

Respuesta (abreviada):

{
  "course": { "id": 42, "fullname": "Italiano A1", "shortname": "ITA-A1", "format": "topics", "startdate": 1700000000 },
  "secciones": [{ "id": 100, "name": "Unidad 3", "section": 3, "visible": true, "modules_count": 6 }],
  "ultimas_clases": [{ "seccion_id": 100, "seccion_name": "Unidad 3", "ficha_idnumber": "mcp:a9993e364706816aba3e2571" }],
  "matriculados": { "total": 18, "docentes": 1, "alumnos": 17 }
}

2. Publicar una FichaClase (primero vista previa)

{
  "name": "publicar_preview",
  "arguments": {
    "ficha_path": "/home/alicia/fichas/italiano/a1-2026/u3/c5.md",
    "course_id": 42
  }
}

La respuesta incluye preview_url que Alicia puede abrir para revisar. Una vez aprobada:

{
  "name": "confirmar_preview",
  "arguments": { "seccion_id": 100, "recursos_ids": [501, 502, 503] }
}

3. Puerta de escape: llamar a una función WS sin procesar

{
  "name": "ws_raw",
  "arguments": {
    "function_name": "core_webservice_get_site_info",
    "params": {}
  }
}

Respuesta:

{ "data": { "sitename": "Aula Italicia", "release": "5.0.2+", ... } }

Idempotencia

Cada recurso creado por este MCP lleva un idnumber estable con la forma:

mcp:<first 24 chars of sha1(ficha.id + "|" + component_id)>

Volver a publicar la misma Ficha encuentra el recurso existente por idnumber y lo actualiza en su lugar. Nada se duplica. Es seguro volver a intentarlo en cualquier lugar y en cualquier momento.

Advertencias de la v0.1

La v0.1 es honesta sobre su límite de capacidad. De forma fiable:

  • Busca un curso, sus secciones y módulos.

  • Encuentra recursos "propios" mediante el prefijo de idnumber mcp:.

  • Actualiza la visibilidad de módulos preexistentes (el flujo de trabajo vista previa → confirmar).

  • Muestra errores estructurados de Moodle con campos code estables.

  • Nunca registra tokens, nunca propaga seguimientos de pila (stack traces).

La v0.1 todavía no:

  • Sube archivos de activos mediante multipart al área de archivos temporales de Moodle. Las llamadas planificadas para la carga de activos se informan en advertencias: agrégalos manualmente la primera vez.

  • Crea secciones o módulos nuevos a través de servicios web. Cuando un módulo aún no existe, la herramienta devuelve el estado "missing" más una advertencia. Instalar local_wsmanagesections (o equivalente) y conectar esos puntos finales es trabajo para la v0.2.

Ambas brechas se detectan mediante el conjunto de integración en tests/integration/ cuando se ejecuta contra un Moodle docker real.

Desarrollo

git clone https://github.com/marcosnahuel/moodle-mcp
cd moodle-mcp
npm install

npm run typecheck         # tsc --noEmit
npm test                  # vitest unit suite
npm run test:coverage     # with v8 coverage (≥80% enforced)
npm run build             # tsup → dist/

# Integration — requires docker
docker compose -f tests/integration/docker-compose.test.yml up -d
export MOODLE_TEST_URL=http://localhost:8081
export MOODLE_TEST_TOKEN=<generate in Moodle admin>
export MOODLE_TEST_COURSE=<course id>
npm run test:integration
docker compose -f tests/integration/docker-compose.test.yml down -v

Seguridad

  • El token nunca se registra. Los tokens que aparecen en cualquier campo de cualquier registro de log se reemplazan por ***.

  • Las URLs en los mensajes de error también se redactan.

  • Se requiere HTTPS a menos que MOODLE_ALLOW_INSECURE=true (solo para desarrollo).

  • El MCP solo se comunica con Moodle a través de REST de servicios web. Sin autenticación por cookies, sin web scraping, sin acceso directo a la base de datos.

Contribución

Consulta CONTRIBUTING.md para conocer las convenciones de problemas, PR y confirmaciones.

Al participar en este proyecto, aceptas cumplir con el CODE_OF_CONDUCT.md.

Licencia

MIT © 2026 Italicia — ver LICENSE.

Install Server
A
security – no known vulnerabilities
A
license - permissive license
A
quality - A tier

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

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/MarcosNahuel/moodle-mcp'

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