utn-mcp
Summary: This server is a read-only UTN aula virtual (Moodle) MCP server exposing only two tools — no writing, file reading, or navigation tools are present.
View your user/site info (
aula_get_site_info): returns data about the logged-in user and the Moodle site.List your courses (
aula_list_courses): lists the courses (materias) you are enrolled in.Both tools take no input parameters and only fetch data; there are no tools for opening courses/forums, reading files, posting, submitting assignments, sending messages, or adding calendar events (unlike the full README tool set).
Supports SSO authentication through Keycloak-based campuses (such as UTN FRBA), automatically configuring the login flow when the campus uses a Keycloak host, and falling back to direct Moodle login otherwise.
Provides tools for interacting with the UTN aula virtual (a Moodle-based LMS), enabling agents to list enrolled courses, browse courses, modules, forums and discussions, read course files (PDFs, Office documents, images, plain text), check assignment status, grades and feedback, post/edit/delete forum messages, submit assignments, answer choices or join groups, send private messages, and add calendar events.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@utn-mcplist my courses in the UTN virtual classroom"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
UTN-MCP — El puente entre tu agente y los sistemas de la Universidad.
Este es el Model Context Protocol server NO OFICIAL de la UTN. Con él podés pedirle a tu agente de preferencia (Claude, ChatGPT, etc.) que busque información y lea los apuntes del aula virtual y, con tu confirmación, que publique en los foros o entregue tareas. Corre en tu computadora o como servidor HTTP con OAuth, para usarlo desde cualquier lado.
Qué podés pedirle
"¿Cuándo es el recuperatorio del primer parcial de Álgebra?"
"¿Qué avisó la profesora de Física esta semana?"
"Resumime la guía de la unidad 3 de Sistemas Operativos."
"Pasame el link para bajar el apunte de calorimetría."
"¿Qué nota me pusieron en el TP1 y qué me corrigieron?"
"Preguntá en el foro de consultas si el parcial incluye la unidad 4."
"Anotame en el grupo 6."
"Agendame el recuperatorio del 14 a las 18."
El agente recorre el aula como lo harías vos: entra al curso, mira los foros y abre los archivos que hagan falta.
Related MCP server: moodle-utn-mcp
Tools
Tool | Qué hace |
| Lista tus cursos. Es el punto de partida. |
| Entra a un curso, un módulo, un foro o una discusión. Cada respuesta trae las direcciones de lo que hay adentro y de un nivel más arriba, así el agente navega sin perderse. |
| Lee un archivo del aula, por partes cuando es largo. |
| Datos de tu usuario y de tu regional en el aula virtual. |
| Abre un hilo en un foro o responde en una discusión. |
| Edita una publicación tuya. |
| Borra una publicación tuya. |
| Entrega una tarea: sube archivos de tu compu, escribe el texto en línea y confirma el envío. |
| Solo en modo HTTP: un link para subir los archivos de una entrega, que usa el agente con |
| Responde una elección o te anota en un grupo. |
| Manda un mensaje privado a un docente o compañero. |
| Agrega un recordatorio a tu calendario del aula. |
Al abrir una tarea, aula_open muestra si la entregaste, cuándo vence y la devolución con la nota. Las tools que escriben le piden al agente que te muestre lo que va a hacer y espere tu confirmación.
Archivos que puede leer
PDF: el texto, página por página. Los escaneados se mandan como imagen de cada página, y el agente los lee igual.
Word (.docx), PowerPoint (.pptx) y Excel (.xlsx): el texto, con las tablas fila por fila.
Imágenes (PNG, JPG, GIF) y texto plano.
Los formatos viejos de Office (.doc, .ppt, .pps), los comprimidos (.zip, .rar) y los videos no se leen. En ese caso el agente te pasa el link para que lo bajes.
Links de descarga
Cada archivo viene con un link del aula virtual que podés abrir en tu navegador. Funciona con tu sesión del aula (si no estás logueado te manda al login) y nunca incluye tu token: ese queda siempre en tu computadora.
Cómo instalar
Necesitás Node.js 20 o superior. No hace falta clonar el repo ni instalar nada a mano: npx descarga el paquete solo.
1. Iniciar sesión
npx -y utn-mcp loginTe pide tu regional, tu usuario y tu contraseña: los mismos con los que entrás al aula virtual. Si no tenés usuario institucional (por ejemplo, en el curso de ingreso), usá el que te dieron para el aula. En Córdoba (FRC) los alumnos entran con el mail completo (<legajo>@<especialidad>.frc.utn.edu.ar), no con el legajo solo; con una cuenta @frc.utn.edu.ar, con lo que va antes de la @. Se hace una sola vez: después el servidor renueva la sesión solo.
2. Agregarlo a tu cliente
Claude Code
claude mcp add utn -- npx -y utn-mcpClaude Desktop: en Settings → Developer → Edit Config, agregá dentro de mcpServers:
"utn": {
"command": "npx",
"args": ["-y", "utn-mcp"]
}En Windows, si no arranca, usá "command": "cmd" y "args": ["/c", "npx", "-y", "utn-mcp"]. Después reiniciá Claude Desktop por completo.
Codex
codex mcp add utn -- npx -y utn-mcpGemini CLI
gemini mcp add utn npx -y utn-mcpOpenClaw
openclaw mcp add utn --command npx --arg -y --arg utn-mcpHermes: en ~/.hermes/config.yaml:
mcp_servers:
utn:
command: "npx"
args: ["-y", "utn-mcp"]Cursor: en ~/.cursor/mcp.json:
{
"mcpServers": {
"utn": { "command": "npx", "args": ["-y", "utn-mcp"] }
}
}VS Code: en .vscode/mcp.json (o con MCP: Add Server desde la paleta de comandos):
{
"servers": {
"utn": { "type": "stdio", "command": "npx", "args": ["-y", "utn-mcp"] }
}
}ChatGPT: solo se conecta a servidores MCP remotos por HTTPS, así que necesita un servidor en modo HTTP publicado en internet (ver Hostearlo para otros). Se agrega como conector desde Configuración → Apps y conectores, con el modo desarrollador activado. Los conectores propios están desde el plan Pro, y ahí solo con las herramientas de lectura; para usar también las de escritura (foros, mensajes, entregas) hace falta Business o superior.
Otros clientes (Windsurf, opencode, etc.): cualquier cliente MCP que lance servidores por STDIO sirve con el comando npx -y utn-mcp.
Instalación global (opcional)
Si preferís tener el comando utn-mcp siempre disponible:
npm i -g utn-mcp
utn-mcp loginy en la config del cliente usás "command": "utn-mcp" sin argumentos.
Regionales
La regional se elige al iniciar sesión, de una lista con las regionales de la UTN. Buenos Aires (FRBA), Córdoba (FRC), Resistencia (FRRE) y Tucumán (FRT) ya están probadas. También está el aula de la Tecnicatura en Programación a distancia del SIED (TUP). El login se adapta solo: si el aula entra por SSO (Keycloak), como FRBA, usa el SSO; si no, el login directo de Moodle.
La lista puede traer regionales que nadie probó todavía: su aula tiene habilitado el servicio que usa UTN-MCP, así que casi seguro anda. En un servidor hosteado, la primera persona que entra con una de esas la deja verificada para el resto. Las que no tienen el servicio habilitado aparecen como "todavía sin soporte": se pueden elegir, pero el login avisa que por ahora no se puede usar y no manda la contraseña.
Si tu campus no está en la lista, abrí un issue con la URL de su aula virtual para sumarlo. Mientras tanto, podés usarlo definiendo en un .env en la carpeta desde donde corrés utn-mcp (o en el entorno):
UTN_AULA_BASE_URL=https://tu-campus.utn.edu.ar
# UTN_SSO_HOST=auth.tu-campus.utn.edu.ar # solo si usa KeycloakAparece como una opción más al iniciar sesión.
UTN_REGIONAL (por ejemplo, UTN_REGIONAL=frt) elige la que viene marcada por defecto, y es la que se usa si en lugar de login definís UTN_USER y UTN_PASS.
Modo HTTP (opcional)
Necesita Node 22.13 o más nuevo. Primero, una vez:
npx -y utn-mcp login --httpTe muestra un token: configurá tu cliente MCP para que mande el header Authorization: Bearer <token>. Después:
npx -y utn-mcp --http --port 3000Levanta el servidor en http://127.0.0.1:3000/mcp, solo accesible desde tu propia máquina. Tenés que dejar la terminal abierta mientras lo uses.
En este modo el servidor no lee archivos de tu disco: para entregar, el agente pide un link con aula_assign_upload_link y sube ahí los archivos con curl si tiene terminal, o te pasa el link para que los elijas desde el navegador.
Hostearlo para otros
En modo HTTP el servidor también es servidor de autorización OAuth: un cliente MCP (Claude, ChatGPT) que se conecta a https://tu-dominio/mcp recibe un 401, descubre el OAuth y abre una página donde el alumno elige su regional y entra con su usuario de la UTN. Cada alumno usa el aula de su regional, aunque sean de regionales distintas. Ese login vincula su aula: la contraseña se usa una sola vez para sacar el token de Moodle y no se guarda. Cuando la sesión del aula vence, el agente le pasa el link de /login para renovarla, sin reconectar el cliente.
Quién puede entrar lo decidís vos: con UTN_MCP_ALLOWED_EMAILS (una lista), o con UTN_MCP_ACCESS_URL, que apunta a un servicio tuyo. El servidor le hace POST con { "email", "usuario", "regional" } y el header Authorization: Bearer <UTN_MCP_ACCESS_SECRET>, y espera { "permitido": true } o { "permitido": false, "motivo": "...", "url": "..." }. Se consulta al conectar y en cada renovación del token (cada hora), así que una baja se aplica sola.
La configuración va en variables de entorno o en un .env en la carpeta desde donde lo corrés (copiá .env.example):
Variable | Para qué | Por defecto |
| Dónde escucha. |
|
| Dirección pública ( |
|
| Servicio que decide quién puede entrar. | — |
| Emails o dominios ( | Entra cualquiera con usuario de la UTN |
| Hosts ( | — |
| Habilita la API de | — |
| Página donde el usuario renueva su sesión del aula; el agente se la pasa. |
|
| Base de sesiones y su clave de cifrado (32 bytes en base64). | En la carpeta de config |
Con Docker, detrás de un reverse proxy con HTTPS en la misma máquina (red host, para que el rate limit del login vea la IP real):
docker build -t utn-mcp .
docker run -d --name utn-mcp --network host --restart unless-stopped \
-e HOST=127.0.0.1 -e PORT=8100 -e UTN_MCP_PUBLIC_URL=https://mcp.tu-dominio.com \
-e UTN_MCP_KEY=$(openssl rand -base64 32) -v utn-mcp-data:/data utn-mcpGuardá esa UTN_MCP_KEY: sin ella no se pueden descifrar las sesiones guardadas.
Dónde se guardan tus datos
Instalado en tu computadora, todo queda ahí:
Usuario y contraseña: en el gestor de credenciales del sistema (Windows Credential Manager, Keychain en macOS, Secret Service en Linux).
Token del aula virtual: en
%APPDATA%\utn-mcp\session.json(Windows) o~/.config/utn-mcp/session.json(Linux y macOS).En modo HTTP: la contraseña no se guarda; la sesión va cifrada en
utn-mcp.db, en la misma carpeta, con la clave destore.key(o la deUTN_MCP_KEY). Del token del cliente solo se guarda el hash.
En Linux sin gestor de credenciales (servidores, Docker, WSL) podés definir las variables de entorno UTN_USER y UTN_PASS en lugar de usar login.
Si usás un servidor hosteado por otra persona, tu sesión del aula la guarda ese servidor (cifrada, y sin tu contraseña): revisá su política de privacidad.
Desarrollo
git clone https://github.com/nialvape/utn-mcp.git
cd utn-mcp
npm install
npm run login # una vez
npm run dev # servidor por STDIO desde src/, con tsx
npm run build # compila a build/pdf.js no es una dependencia del paquete publicado. Está como devDependency, y npm install corre el script prepare, que copia a vendor/pdfjs/ solo los archivos que usa el servidor (~4 MB). Así, quien instala utn-mcp no baja pdf.js entero ni su canvas nativo opcional (~37 MB). Si instalaste con --ignore-scripts, generalo a mano con npm run prepare.
Aviso
Este proyecto no está afiliado ni avalado por la UTN. Usalo bajo tu responsabilidad.
Available Tools
2 toolsaula_get_site_infoC
Datos del usuario logueado en el aula virtual de la UTN FRBA y del sitio Moodle.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It does not indicate whether authentication is required (implicit from 'logged-in user' but not stated), what data fields are returned, or any caching/rate-limit behavior. For a read-only info tool the risk is low, but the description adds little behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single efficient sentence with no wasted words. However, it could be front-loaded more clearly (site info vs user info) and is slightly under-specified for the amount of information it tries to cover.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters, no annotations, and no output schema, the description needs to carry the weight of explaining what data is returned and in what context. It identifies the two data sources but doesn't clarify the return structure or the distinction between the aula virtual and Moodle site, leaving the agent with moderate uncertainty.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so baseline is 4. Nothing to document and nothing missing.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states it returns logged-in user's data from UTN FRBA's virtual classroom and Moodle site, which is a specific resource. However, it mingles two data domains (user profile vs. site info) without clarifying which the tool actually returns, and the tool name says 'site_info' while the description leads with user data. This ambiguity prevents a clear 4.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus the sibling aula_list_courses, no prerequisites, and no indication of what context this information is useful for. The description is purely declarative with zero usage direction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
aula_list_coursesB
Lista los cursos (materias) en los que está inscripto el usuario en el aula virtual.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the scope (user's enrolled courses) which is useful behavioral context, but it does not state whether results are paginated, cached, ordered, or what happens if the user has no enrollments. That leaves notable behavioral gaps for a list operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with zero waste. It states the action and scope immediately and does not pad with redundant or vague phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter, no-annotation, no-output-schema list tool, the description is minimally adequate but incomplete. It does not mention ordering, pagination, empty-state behavior, or the response shape, which an agent might need in the absence of structured metadata.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the baseline is 4. The description adds no parameter detail because there is none to add, and the tool requires no inputs, which is consistent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Lista') and resource ('los cursos/materias'), plus the scope ('en los que está inscripto el usuario en el aula virtual'). It is clearly distinguished from the sibling aula_get_site_info, which presumably returns site metadata rather than enrolled courses.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use guidance or alternatives are given. The description implies it is for retrieving the user's own course enrollment, but it does not say when to choose this over aula_get_site_info or any other retrieval method.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.0- First observed
aula_get_site_info - First observed
aula_list_courses
TDQS
Scored across 2 tools
The two tools have clearly distinct purposes: one returns user/site metadata, the other enumerates enrolled courses. An agent can easily select the right one without overlap.
Both tools follow a consistent verb_noun snake_case pattern with the same 'aula_' prefix (aula_get_site_info, aula_list_courses). Naming is fully predictable.
Only 2 tools for a Moodle-based virtual classroom is very thin; the domain typically requires assignments, grades, deadlines, and content access. The surface feels under-scoped rather than well-bounded.
The surface only covers site info and course listing, with no access to grades, assignments, course contents, or deadlines. These are significant gaps that would cause an agent to hit dead ends for most academic queries.
Maintenance
Related MCP Connectors
AI Agent Utility Layer for agent safety, web monitoring, crypto research and tool discovery.
Access Pollinations models and API capabilities through agent tools.
Web search and page reading for AI agents, including JSON APIs, RSS feeds and YouTube.
Web data for agents: YouTube transcripts, screenshots, Google News, WHOIS, jobs, tech stack, more.
Related MCP Servers
- FlicenseAqualityCmaintenanceEnables AI assistants to query the UTN distance learning Moodle campus, providing tools to list courses, view content, check deadlines, see grades, and more.7-
- FlicenseNot gradedqualityBmaintenanceEnables browser-based login to approved UTN Moodle sites and read-only access to the user's profile, course list, and course activities via local Chromium automation.2-
- AlicenseAqualityCmaintenanceEnables AI agents to access a student's EPFL Moodle data—deadlines, course files, assignments, forums, and grades—through read-only tools.12MIT
- AlicenseNot gradedqualityBmaintenanceConnects AI agents to Argentine universities' Moodle virtual classrooms and SIU Guaraní self-service portals, enabling them to read course materials, announcements, grades, and enrollment data. With user confirmation it can also post to forums, submit assignments, answer choices, and send private messages.MIT