isu-moodle-mcp
isu-moodle-mcp
Conecta Moodle a Claude mediante un servidor MCP. Se divide en dos capas:
Capa API (18 herramientas, la principal): API REST oficial de Web Service. No rastrea HTML, no necesita abrir un navegador.
Capa CDP (6 herramientas, para rellenar huecos) + capa de sistema antiguo (4 herramientas): solo se usa Chrome en modo debug cuando la API realmente no puede obtener algo. La más importante es
probe_course_access()— es la única forma de detectar que "hay un curso que ya no puedes ver".
Para uso normal, la capa API es suficiente. La capa CDP está pensada para preguntas como "¿están todos los cursos que he impartido en la lista?".
Pensado para el taller "Diseño de cursos con IA: aplicaciones prácticas" (2026-08-21) de la Universidad I-Shou. Haz clic en "Usar plantilla" para crear tu propio repositorio, no necesitas una cuenta de GitHub.
Qué es esto
El flipclass-mcp que se demostró en clase es un servidor MCP para FlipClass de la Universidad del Sur de Taiwán. Ese sistema no tiene API,
así que obtiene los datos de dos maneras: rastreo de HTML (32 expresiones xpath) + Chrome en modo debug (matriz de calificaciones, listas de miembros y otras
páginas que no se pueden leer por HTTP puro). Eso es la demostración de "por muy cerrado que esté el sistema, con una cuenta y contraseña se puede hacer ingeniería inversa completa".
Esta es la otra mitad de la misma historia: cuando el sistema tiene API, se puede cambiar todo el backend manteniendo el mismo contrato de herramientas MCP.
flipclass-mcp | moodle-mcp | |
Obtención de datos | Rastreo de HTML + lxml xpath | API REST oficial |
Autenticación | Cuenta/contraseña + token anticsrf + caché de cookies | Un token, sin estado |
Expulsión por inicio de sesión múltiple | Ocurre (problema conocido) | No ocurre |
Lista de miembros / matriz de calificaciones | Requiere abrir Chrome en modo debug con CDP | Disponible directamente en la API |
Email de estudiantes | Se deduce concatenando el número de matrícula | Viene directamente en la lista |
Código relacionado con autenticación | Aprox. 247 líneas | Aprox. 15 líneas |
Chrome en modo debug | Hay que abrirlo cada vez (sin él no hay matriz de calificaciones) | Solo se necesita al consultar relaciones de matrícula |
Los nombres de las herramientas y sus docstrings se mantienen idénticos a propósito, para que puedas comparar directamente cómo se ve la misma necesidad cuando "hay API" y cuando "no hay API".
Related MCP server: Moodle MCP Server
Inicio rápido
1. Obtener el código
git clone https://github.com/scatjay/isu-moodle-mcp.gitSi no tienes git, también puedes pulsar Code → Download ZIP en la página de GitHub.
2. Instalar las dependencias
pip install -r requirements.txtSolo hay dos: requests y mcp.
3. Obtener un token nuevo
python get_token.py https://moodle.你的學校.edu.twTe pedirá tu usuario y contraseña de Moodle; si es correcto, escribirá el token en .env.
Ejecuta este paso en tu propia terminal, no dentro de una conversación con IA. Las transcripciones de conversaciones pueden guardarse o hacerse copias de seguridad; si la contraseña y el token aparecen ahí, es como si se hubieran filtrado.
¿Por qué un token y no usuario/contraseña? Un token se puede revocar, solo tiene los permisos tuyos y, si se filtra, no pierdes todo como con una contraseña.
El token de Moodle caduca por defecto a las 12 semanas — si a mitad del semestre la herramienta falla de repente y dice
invalidtoken, solo tienes que volver a ejecutar este paso.
4. Conectar con Claude
En el archivo de configuración de Claude Desktop (claude_desktop_config.json), añade:
{
"mcpServers": {
"moodle": {
"command": "python",
"args": ["C:/你的路徑/isu-moodle-mcp/server.py"],
"env": {
"MOODLE_URL": "https://moodle.你的學校.edu.tw",
"MOODLE_TOKEN": "貼上 .env 裡那一串",
"MOODLE_LEGACY_URL": "https://舊站網址(沒有舊站就整行刪掉)"
}
}
}
}5. Ejecutar primero el diagnóstico
Después de conectarlo, lo primero que debes pedir a Claude es que ejecute diagnose(). Te dirá si el token es válido,
qué funciones puedes llamar realmente y qué falta. Si no conecta, esta es la primera herramienta que debes ejecutar.
Qué herramientas hay
Tool | Qué hace |
| Diagnóstico de conexión. Si no conecta, ejecuta esto primero. |
| Cursos en curso |
| Todos los cursos que aún puedes ver (consulta las limitaciones conocidas más abajo) |
| Busca tus cursos por palabra clave |
| Cuántas secciones, materiales y tareas tiene el curso |
| Lista de materiales (incluye URL de descarga) |
| Lista de tareas |
| Estado de entregas de toda la clase |
| Lista de matriculados (nombre / email / rol) |
| Matriz de calificaciones: cada estudiante × cada elemento evaluable |
| Estado de finalización de actividades |
| Descarga archivos de materiales |
| Llama directamente a cualquier función de Moodle (para explorar) |
| Informe de entregas: incluye fecha, retrasos y reenvíos |
| Calificaciones detalladas de un estudiante |
| Consulta el email de un estudiante |
| Descarga todo el paquete de un curso: materiales + tareas + lista + calificaciones |
| Descarga el paquete de todos los cursos, de una vez |
Capa CDP (primero ejecuta python start_debug_chrome_moodle.py e inicia sesión en esa ventana)
Tool | Qué hace |
| Comprueba si el Chrome en modo debug responde y si has iniciado sesión |
| Comprueba si todavía puedes entrar en este curso — la pregunta que la API no puede responder |
| Estado de cada matrícula, método, fecha de alta y de baja |
| Escanea y busca cursos que "existen pero ya no puedes ver" |
| Qué servicios tienen qué funciones y quién puede generar tokens |
| Matriz de capacidades de un rol (más de 300 entradas, la API no las da) |
Capa de sistema antiguo (cuando la escuela ha cambiado de plataforma)
Hay que añadir una línea en .env: MOODLE_LEGACY_URL=https://url-del-sitio-antiguo.
Tool | Qué hace |
| Comprueba si el sitio antiguo sigue vivo y si usa API o CDP. Ejecuta esto primero antes de extraer datos. |
| Cursos visibles en el panel del sitio antiguo |
| Versión para sitio antiguo de "¿puedo seguir entrando en este curso?" |
| Secciones y materiales de un curso en el sitio antiguo |
Esta versión no incluye deliberadamente ninguna herramienta de escritura (por ejemplo, mod_assign_save_grade para modificar calificaciones).
Si algo de solo lectura falla, como mucho los datos serán incorrectos; si algo de escritura falla, estarás modificando las calificaciones reales de los estudiantes.
Si de verdad lo necesitas, añádelo tú mismo, pero primero practica en un sitio de pruebas.
Limitaciones conocidas (por favor, lee esta sección completa)
🔴 Los cursos antiguos desaparecen silenciosamente — pero la condición es más restrictiva de lo que crees
core_enrol_get_users_courses solo devuelve los cursos en los que todavía tienes una relación de matrícula activa.
Probado el 2026-08-20 en dos instancias locales de Moodle 4.1.18, verificando punto por punto:
Qué hace la escuela | ¿El curso sigue en tu lista? |
Oculta el curso ( | Sí, se sigue viendo |
La fecha de fin del curso ya ha pasado | Sí, se sigue viendo |
La matrícula del profesor se ha puesto como "desactivada" | Desaparece. Y no da ningún error. |
Esta tabla desmiente una creencia muy extendida (incluida la versión anterior de este mismo README): "ocultar o archivar un curso antiguo hace que desaparezca". La prueba demuestra que no es cierto. Lo que realmente hace desaparecer un curso es solo la última fila. Lo escribo aquí porque: una afirmación desmentida por pruebas que se queda en la documentación es peor que no escribir nada — la seguirías para pedirle a tu administrador algo que no es.
El curso, los estudiantes y las tareas siguen en la base de datos; simplemente no los ves. Y la API no te dice "hay un curso que ya no puedes ver", simplemente no lo menciona.
Por eso, antes de hacer análisis de períodos largos, ejecuta find_hidden_courses() o
probe_course_access(course_id) para comprobar curso por curso, y no te fíes solo de la lista de list_history_courses().
Esa herramienta siempre devuelve un campo caveat para recordártelo; por favor, no lo ignores.
Los errores de Moodle llegan con HTTP 200
Cuando Moodle devuelve un error, el código de estado HTTP sigue siendo 200; el error está oculto en el campo exception del cuerpo.
raise_for_status() no lo detecta en absoluto. Este servidor ya lo gestiona, pero si escribes tu propio código contra Moodle, recuérdalo.
accessexception es difícil de diagnosticar
La lista oficial de causas tiene siete u ocho, y a menos que el administrador active el modo debug en NORMAL o superior,
el mensaje de error no te dice cuál es. Este servidor lo traduce a lenguaje claro y te da las tres causas más probables,
pero para saber con certeza cuál es, tendrás que ejecutar diagnose() y ver qué funciones incluye realmente tu token.
Solo ves tus propios cursos
Esto es una garantía interna de Moodle, no una limitación de esta herramienta. El token hereda exactamente tus permisos, y cada llamada hace una comprobación de permisos a nivel de contexto. Esto es a la vez una garantía de seguridad y una limitación.
Los parámetros de tipo array no se pueden pasar como JSON
El REST de Moodle usa el $_POST de PHP para analizar los datos; los arrays deben escribirse como courseids[0]=5&courseids[1]=7.
Si envías una cadena JSON, se interpretará como una sola cadena y dará invalidparameter. Este servidor ya aplana los arrays automáticamente.
El nombre del parámetro para descargar archivos es diferente
El endpoint REST usa wstoken, pero webservice/pluginfile.php usa token.
Es el detalle que más fácil se pasa por alto al移植. Además, el servicio debe tener activada la opción downloadfiles.
Si get_token.py falla
Error | Significado | Qué hacer |
| Usuario o contraseña incorrectos | El usuario de Moodle no tiene por qué ser tu email |
| El sitio no tiene activado el servicio para móviles | Pide al administrador que active |
| Tu cuenta no tiene permiso para crear tokens | La escuela ha cambiado los permisos por defecto; pide al administrador que te dé un token |
| El sitio está en mantenimiento | Espera un poco y vuelve a intentarlo |
Por defecto, Moodle otorga moodle/webservice:createmobiletoken a todos los usuarios con sesión iniciada,
así que normalmente un profesor puede renovar su token sin necesidad del administrador. Pero la escuela puede cambiar este valor por defecto —
si lo ha cambiado, solo te darás cuenta cuando intentes renovarlo, no se puede detectar desde fuera.
Notas de desarrollo
Esta herramienta es un移植 de flipclass-mcp. Al移植, se eliminó la mitad más dolorosa y se conservó la mitad más valiosa:
Eliminado (aprox. 247 líneas):
_login, gestión de anticsrf, caché de cookies,checkMultiLoginpara inicios de sesión múltiples, análisis con 32 expresiones lxml xpath, conexión CDP (Chrome en modo debug)Conservado: el esqueleto de FastMCP, la firma y el docstring de cada
@mcp.tool()——esto es el verdadero activo, porque es el contrato que ve el LLM
La razón es que ningún paquete Python de Moodle existente servía: moodlepy lleva casi dos años sin actualizarse
y fija las dependencias en attrs<23 (una versión de 2022); moodle_api.py lleva tres años sin actualizarse y no está en PyPI;
python-moodle se mantiene, pero en realidad rastrea HTML, no es un cliente REST.
El REST de Moodle es tan simple que se escribe en una docena de líneas;引入 un paquete sin mantenimiento solo añade deuda técnica.
Licencia
MIT. Úsalo para crear la versión de tu propia escuela, sin necesidad de pedir permiso.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables interaction with Moodle learning management systems through the Moodle REST API. Supports course management, user enrollment, assignments, forums, quizzes, and file operations through natural language.14MIT
- AlicenseNot gradedqualityDmaintenanceEnables interaction with Moodle learning management systems through the REST API. Supports course management, user enrollment, assignment handling, and forum operations through natural language.14MIT
- AlicenseNot gradedqualityCmaintenanceProvides Claude with full access to Moodle learning management systems, enabling interaction with courses, files, assignments, grades, and calendar events. It also supports building Obsidian study vaults from course materials through automated knowledge graph creation.1416MIT
- FlicenseAqualityCmaintenanceEnables read-only querying of Moodle as a student, including courses, assignments, grades, forums, and files, using a personal web services token.11
Related MCP Connectors
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.
Read-only tools over the Safer Agentic AI framework: 238 patterns + 14 heuristics.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/scatjay/isu-moodle-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server