Moodle e IA, por fin juntos: así hemos construido local_mcp
Moodle and AI, together at last: how we built local_mcp
Hemos hecho nuestro propio plugin MCP para Moodle: local_mcp. Vive dentro de Moodle, de la 4.5 a la 5.2, es GPLv3 y se conecta con OAuth 2.1, sin tokens eternos. La escritura viene desactivada por defecto y todo simula antes de guardar. Qué le ahorra a un profesor (montar cursos, cuestionarios, corregir), los fallos de permisos que solo salieron en uso real y una pregunta de fondo: si una IA ya puede corregir y poner notas, qué falta para dejarle la educación en sus manos.
We built our own MCP plugin for Moodle: local_mcp. It lives inside Moodle, from 4.5 to 5.2, is GPLv3 and connects through OAuth 2.1, with no everlasting tokens. Writing is off by default and everything runs a dry run before saving. What it saves a teacher (building courses, quizzes, grading), the permission bugs that only showed up in real use, and a deeper question: if an AI can already grade and give marks, what is still missing before we hand education over to it?
Lo escribe Sergio. Lo lee una voz generada · Written by Sergio. Read by a generated voice · Colophon
TranscripciónTranscript · del guión del episodio· from the episode script
Hola, bienvenidos a un nuevo episodio de El podcast de Sergio. Si me habéis ido siguiendo, ya sabéis que llevo mucho tiempo metido en Moodle. Y también sabéis que últimamente casi todo lo que hago pasa por la inteligencia artificial. Durante bastante tiempo han sido dos mundos separados en mi cabeza. Por un lado, las plataformas de formación, los cursos, los profesores, los alumnos. Por otro, los asistentes, los agentes, las herramientas que conectan la IA con cosas reales. Y ha llegado el momento de juntar ambas cosas. Hoy os quiero contar cómo lo hemos hecho, qué hemos construido y qué nos hemos encontrado por el camino. Sin adornos, con los fallos incluidos. La idea es sencilla. Que un asistente de IA pueda trabajar dentro de un Moodle de verdad. Que pueda leer un curso, crear una tarea, corregir una entrega o montar un cuestionario. Pero siempre con permisos, con control y con el profesor decidiendo. Para eso existe un estándar que se llama MCP, que es la forma en la que un asistente se conecta con un sistema externo. Y la pregunta que nos hicimos fue muy simple. ¿Qué hay ya hecho para Moodle? Pero antes de contestar a eso, dejadme explicar por qué ahora y no hace un año. Hasta hace poco, la IA en educación era sobre todo un chat aparte. El profesor abría una ventana, le pedía ideas para un tema, copiaba el texto y lo pegaba a mano en Moodle. Luego hacía lo mismo con las preguntas de un cuestionario, una por una. Y si quería corregir con ayuda, descargaba las entregas, las pasaba por el chat y volvía a subir las notas. Eso ayuda, pero es un trabajo de ida y vuelta que cansa. La IA veía el contenido, pero no veía el curso. No sabía qué alumnos había, qué tareas estaban abiertas ni qué notas faltaban. Lo que ha cambiado es que ahora los asistentes ya pueden usar herramientas. Pueden consultar un sistema, proponer un cambio y aplicarlo, si les dejas. Y en ese momento, la pregunta deja de ser qué texto me escribe la IA. La pregunta pasa a ser qué trabajo me puede quitar dentro de mi aula virtual. Para alguien que lleva años con Moodle, eso lo cambia todo. Porque Moodle es justo el sitio donde pasa el trabajo pesado de un profesor. Matricular, organizar, crear actividades, corregir, revisar resultados. Si la IA puede entrar ahí con las llaves adecuadas, el ahorro es real. Y si entra sin las llaves adecuadas, el riesgo también lo es. Ese equilibrio es justo lo que nos interesaba resolver.
Lo primero que hicimos fue buscar. No tiene sentido construir algo si ya existe y funciona bien. Y esto es lo que encontramos. Moodle HQ, que es el equipo oficial de Moodle, no tiene un MCP. Existe MoodlIA, el plugin local_moodlia, pero solo va en Moodle 5.2 y está en beta. Hay un plugin que se llama webservice_mcp, de onbirdev. No es de Moodle HQ, y tiene unas quinientas cuarenta instalaciones. Lo que hace es exponer las funciones externas de Moodle en bruto, con un wstoken. Funciona, pero le da al asistente todo el catálogo tal cual, sin pensar en cómo trabaja un profesor. Luego está moodle-mcp-server, de csmediapro. Es solo de lectura y está hecho en Node, así que corre fuera de Moodle. Y hay otro moodle-mcp escrito en Rust, pensado para estudiantes. Todos tienen su sitio. Pero ninguno era lo que nosotros buscábamos. Y os explico por qué, sin quitarle mérito a nadie. Lo oficial, de momento, no existe. Lo más cercano a oficial solo va en la versión más nueva, y en beta. Y la mayoría de centros no están en la versión más nueva, ni deberían correr para estarlo. Exponer las funciones en bruto tiene otro problema. Moodle tiene muchísimas funciones externas, pensadas para programadores, no para un asistente. Si le das todo eso a una IA, tiene que adivinar qué combinación de llamadas equivale a crear un cuestionario con preguntas. Y cuando adivina, a veces se equivoca. Lo de solo lectura está bien para consultar, pero se queda corto para el día a día de un profesor. Y lo pensado para estudiantes resuelve otro problema distinto. Así que vimos un hueco claro. Un plugin que viva dentro de Moodle, que respete sus permisos, que piense en tareas de profesor y no en funciones sueltas, y que sea seguro antes que rápido.
Lo que faltaba era algo que viviera dentro de Moodle, que fuera seguro desde el primer día y que pudiera escribir, no solo leer. Así que hemos hecho nuestro propio plugin. Se llama local_mcp. Es GPLv3 y funciona en Moodle de la 4.5 a la 5.2. Desde la primera versión lleva OAuth 2.1 con PKCE. Eso significa que no hay que andar copiando tokens eternos de un sitio a otro. Hay tres alcances, lectura, escritura y administración, y los tokens duran una hora. La escritura viene desactivada al instalar. Si quieres que el asistente cambie cosas, lo tienes que activar tú. La lectura está disponible para cualquier usuario autenticado. La escritura, solo para profesores con permiso de edición y para gestores. Las copias de cursos grandes van en segundo plano, y el asistente puede preguntar cómo van con get_task_status. Hay auditoría de lo que se hace y un límite de peticiones. Y los borrados piden primero una simulación, lo que llamamos dryRun, y después una confirmación. Hay una parte que para mí es muy importante. Hemos hecho una página que se llama Mis tokens MCP, pensada para gente que no es técnica. Un profesor tiene que poder conectar su asistente sin pelearse con nada. También incluye un skill y unos prompts MCP. Diseñar un curso, corregir, o crear un cuestionario a partir de un contenido. Y todos simulan antes de guardar. Luego está build_course. Le pasas un JSON y te monta un curso entero. Tiene modo de prueba, y si algo falla a mitad, deshace todo. Y además importa preguntas en formato GIFT o XML.
Hasta aquí, la lista de características. Pero lo que de verdad importa es qué cambia para un profesor un lunes por la mañana. Así que vamos a bajarlo a tierra. Primer caso, preparar un curso nuevo. Le describes al asistente lo que quieres, por ejemplo un curso con varios temas, una página de presentación y una tarea en cada tema. Con el prompt de diseñar curso, el asistente te propone la estructura. Con build_course, esa estructura se convierte en un curso real. Primero en modo de prueba, para que veas qué va a crear. Y si algo falla a mitad, no te deja un curso a medias, porque deshace todo. Segundo caso, reutilizar lo que ya tienes. Muchos profesores tienen un curso plantilla que copian cada año. El asistente puede hacer esa copia, ponerle el nombre que toca, y si el curso es grande, la copia va en segundo plano. Tú no te quedas esperando, y el asistente puede ir consultando cómo va. Tercer caso, los cuestionarios. Tienes un tema escrito, unos apuntes o una página del curso. Con el prompt de crear cuestionario desde contenido, el asistente lee ese material y te propone preguntas. Las revisas, las ajustas, y solo entonces se guardan. Y si ya tienes un banco de preguntas en GIFT o en XML, se pueden importar directamente. Cuarto caso, corregir. Aquí es donde más horas se van. El asistente puede leer las entregas de una tarea, proponerte una nota y un comentario para cada alumno. Tú lo revisas, cambias lo que no te convenza, y se guarda. En la prueba que os contaré ahora, yo puse un ocho sobre diez con su comentario, todo desde la conversación. Quinto caso, la gestión del día a día. Dar de alta un alumno, matricularlo, organizarlo en grupos, o suspender a alguien que ya no debe entrar. Son tareas pequeñas, pero se acumulan. Y sexto caso, entender cómo va la clase. Leer los resultados de un cuestionario y preguntar en lenguaje normal qué preguntas han fallado más, o quién no ha entregado. Fijaos en una cosa. En todos estos casos el asistente hace el trabajo mecánico, y el profesor mira, decide y confirma. Y para que esto lo pueda usar cualquiera, no solo quien sabe de tecnología, está la página Mis tokens MCP. Un profesor entra, ve sus conexiones y las gestiona sin tener que llamar a nadie.
Ahora viene la parte que más me divierte contar. Lo hemos ido montando por fases, y en un orden muy concreto. La primera fase fue la lectura. La versión 0.1 tenía seis herramientas de lectura y pasaba cuarenta y siete de cuarenta y siete tests. Empezamos por ahí porque leer es lo que no puede romper nada. La segunda fase fueron los permisos y la escritura. La 0.2 trajo los permisos y las primeras herramientas de escritura, con cincuenta y cuatro de cincuenta y cuatro tests. Y la 0.4.1 completó la escritura, con treinta y cuatro herramientas. La tercera fase fueron las categorías y los tokens. La 0.5.0 añadió las categorías y las páginas de tokens, y pasa los tests y phpcs tanto en la 4.5 como en la 5.2. Y la última fase fueron los esquemas, que arreglamos en la 0.8.1, y ya os contaré por qué. Hoy el plugin tiene cuarenta y siete herramientas. No quisimos que el asistente pudiera cambiar nada antes de tener claro quién podía cambiar qué. Y desde el principio, con OAuth, sin atajos de tokens fijos que luego cuesta quitar. Pero los tests no lo son todo. Así que hice una prueba en vivo con MCP Inspector, conectando por OAuth. Creé un curso, una página y una tarea. Di de alta un usuario y lo matriculé. Corregí su entrega, con un ocho sobre diez y un comentario. Creé un cuestionario con preguntas, el alumno lo hizo, y leí los resultados. También probé los grupos y suspender usuarios. Es decir, un ciclo completo de un curso, de principio a fin, hablando con un asistente. Y probé los dos lados. El del profesor, que crea y corrige. Y el del alumno, que entra, hace el cuestionario y debe ver solo lo suyo. Ese segundo lado es el que más sorpresas dio, como vais a ver ahora.
Y ahora, los tropiezos, que también los hubo. El primero, la copia desde plantilla ignoraba el nombre que le pedías al curso. Lo arreglamos en la 0.2.1. Pero lo más interesante fueron cinco fallos que solo salían fuera de los tests. Dos librerías que no se cargaban. Los intentos de cuestionario se estaban filtrando por el usuario cero. Las medias eran visibles para los estudiantes, cuando no debían serlo. Y los tokens no le daban escritura a un profesor de curso. Todo eso pasaba los tests y, sin embargo, fallaba en uso real. Fijaos en qué tipo de fallos son. Uno de ellos dejaba ver a los alumnos algo que no debían ver. Otro impedía trabajar a un profesor que sí tenía derecho. Son justo los fallos que más importan en una plataforma educativa, los de permisos. Y son los que un test con un administrador nunca encuentra, porque el administrador lo puede todo. Es la mejor lección de todo el proceso. Los tests te dan confianza, pero la prueba con un usuario de verdad es la que te dice la verdad. Otro tropiezo fueron los esquemas. El Inspector rechazaba algunos, y eso lo corregimos en la 0.8.1. Y queda uno pendiente. create_group crea el grupo, pero no devuelve respuesta. Eso irá en la 0.8.2. Además, hubo algunos errores que no tenían que ver con el plugin, sino con la migración del entorno de desarrollo de un Mac mini a otro más nuevo.
Mientras lo montábamos, salieron un par de debates que creo que merece la pena compartir. El primero, si MCP está pasado frente a los skills. Últimamente se oye mucho que con los skills ya no hace falta MCP. Nosotros creemos que son complementarios. El skill le dice al asistente cómo trabajar. El MCP le da acceso al Moodle. Un skill sin acceso es un manual sin herramientas. Y un acceso sin skill es darle las llaves a alguien que no sabe cómo trabaja un profesor. Uno sin el otro se queda cojo. Por eso el plugin trae las dos cosas. El segundo debate fue el del dinero. ¿Cómo se gana dinero con un plugin que es GPL y que cualquiera puede descargar? Pues como se ha hecho siempre en el mundo Moodle. Con instalación y soporte. Con un servicio en la nube, un SaaS, para quien no quiera mantener nada. Con formación. Y con desarrollos a medida. El código es libre, pero el tiempo y la experiencia no se descargan. Un centro puede instalarlo solo, y nos parece perfecto. Pero muchos preferirán que alguien lo configure bien, que les forme a los profesores y que responda cuando algo falle. Y ahí es donde tiene sentido un negocio honesto alrededor de un plugin libre.
Y hubo una reflexión más, que no me quito de la cabeza. Quizá, con algo así, en un futuro lleguemos a una educación que la lleve totalmente una IA. Y lo digo en serio, porque técnicamente ya no es ciencia ficción. Con estas herramientas, un asistente ya puede corregir una entrega y poner una nota. Puede crear el contenido de un tema y montar un cuestionario. Puede matricular a un alumno y leer sus resultados. Todo eso lo he hecho yo en las pruebas, hablando con él. Es decir, la capacidad ya está ahí. Solo falta dar el paso. Entonces, ¿por qué no lo damos todavía? Creo que la respuesta no es técnica. Es de confianza. Confiamos en un profesor porque lo conocemos, porque se ha formado, porque responde de lo que hace. Y aquí aparece la pregunta incómoda. Si una IA pone un cinco en lugar de un seis, ¿quién responde de esa nota? ¿El centro, el profesor que activó la herramienta, o quien hizo el plugin? Hoy no tenemos una respuesta clara, y mientras no la tengamos, alguien tiene que firmar. Por eso, de momento, el plugin trae la escritura apagada. Por eso todo simula antes de guardar, y los borrados piden confirmación. No es desconfianza hacia la IA. Es que la decisión, y la responsabilidad, siguen siendo de una persona. Y creo que tiene sentido que la confianza se gane poco a poco, como con cualquiera que empieza en un trabajo. Primero miras lo que propone. Luego compruebas que suele acertar. Después, quizá, le dejas hacer cosas pequeñas sin revisar. La simulación y la confirmación son eso, la forma de ir comprobando. Y la auditoría permite saber, después, qué se hizo y quién lo pidió. También hay algo que va más allá de la nota. Un profesor no solo corrige. Se da cuenta de que un alumno está desmotivado, de que una pregunta estaba mal planteada, de que a la clase le ha costado un tema. Una IA puede detectar parte de eso en los datos. Pero no sé si el alumno siente lo mismo cuando el comentario lo escribe una máquina. Ahora bien, eso no significa que el papel del profesor se quede igual. Quizá deje de pasar horas corrigiendo y montando cursos, y pase más tiempo acompañando, revisando y decidiendo. O quizá, algún día, la confianza llegue y ese último botón lo pulse la propia IA. No lo sé. Y te lo dejo como pregunta. Si ya se puede hacer, ¿qué tendría que pasar para que tú lo dejaras en sus manos?
¿Y ahora qué? Mañana toca la prueba en aula.sergiocomeron.com. Después saldrá la 0.8.2, con el arreglo de create_group. Y cuando esté listo, lo publicaremos. Todavía no está publicado, y no voy a poner fecha, porque prefiero sacarlo bien que sacarlo pronto. Mañana es importante porque lo vamos a ver funcionar en un aula, no solo en una prueba de laboratorio. Seguro que aparecen cosas nuevas, como han ido apareciendo hasta ahora. Y las contaremos igual, sin esconderlas. Si trabajáis con Moodle y os interesa probarlo, estad atentos. Para mí, este proyecto junta las dos cosas que más me gustan. Moodle e inteligencia artificial, por fin en el mismo sitio. Gracias por escuchar, y nos oímos en el próximo episodio.