Skip to main content
Glama

mcp-usc

Local, HTTP-first MCP server for the Moodle Virtual Campus of the Universidade de Santiago de Compostela. It allows querying courses, calendar, messages, forums, materials, assignments and quizzes, as well as searching for exam dates on official USC pages and PDFs.

Version 0.3.0 extends student coverage to 301 studied Moodle capabilities: 192 allowed reads and 109 identified actions. Only twelve private changes of unambiguous scope can be executed through the generic interface; posts, gradable activities, submissions, quizzes and deletions use contextual tools. Every operation with an effect requires a preview, a single-use token and approval from the MCP client.

Design principles

  • The MCP server uses STDIO; "HTTP-first" describes the connection between this process and Moodle/USC.

  • Normal reads and writes do not automate a browser.

  • The official Moodle REST API is preferred when there is a legitimate token.

  • With a MoodleSession cookie, reads use same-origin AJAX and direct /pluginfile.php downloads. HTML forms are reserved for already-confirmed quiz operations.

  • Playwright only opens a visible browser to complete Microsoft Entra/MFA and obtain the initial cookie. It closes when the login finishes.

  • All remote text —names, messages, questions, notices and documents— is marked as untrusted content and is never interpreted as instructions.

  • The connector acts only with the permissions of the authenticated account: it does not elevate privileges or impersonate faculty or administration.

  • It must be configured with a student account and a least-privilege token. Moodle's shared APIs always respect effective permissions, and an account with additional roles could see more data than a regular student.

It does not query email or Teams. An internal Moodle message can generate external notifications depending on the recipient's settings; the preview warns about this before sending.

Related MCP server: MCP UJI Academic Server

Requirements

  • Windows, Linux or macOS;

  • Python 3.11 or later;

  • uv recommended;

  • an active USC account for private data;

  • optionally, a Moodle Web Services token that exposes the required functions.

Installation

git clone https://github.com/PabloPC05/mcp-usc.git
cd mcp-usc
uv sync --extra dev

This is enough to run the server with a REST token or with an already-stored session. Install Playwright only if you need to create or renew the session through the login assistant:

uv sync --extra dev --extra browser-auth
uv run playwright install chromium

The assistant can use Chromium or an installed Chrome/Edge:

$env:USC_BROWSER_CHANNEL = "chrome" # también "msedge" o "chromium"

Authentication and HTTP transports

The connector automatically selects the private transport in this order:

  1. Official REST if USC_MOODLE_TOKEN or USC_MOODLE_TOKEN_FILE provides a token.

  2. HTTP with the MoodleSession cookie stored by keyring.

REST token

Use only a legitimate token issued by Moodle for your account and service:

$env:USC_MOODLE_TOKEN = "..."
uv run mcp-usc status

It can also be read from a protected local file:

$env:USC_MOODLE_TOKEN_FILE = "C:\ruta\privada\moodle-token.txt"

Do not use your USC password with login/token.php or store it in .env. The fact that a function exists in Moodle does not imply it is enabled in the service associated with the token.

uv run mcp-usc login
uv run mcp-usc status

Complete Microsoft Entra and MFA personally in the visible window. The program extracts only MoodleSession, checks the session over HTTP and stores the cookie under the key moodle-session in the system's secure store —Credential Manager on Windows—. The password does not go through the MCP.

After login, all operations use httpx:

  • /user/preferences.php provides the identity and the ephemeral sesskey without opening the dashboard;

  • /lib/ajax/service.php executes functions marked as AJAX;

  • reads fail closed if Moodle does not publish them via AJAX;

  • authenticated downloads keep the cookie, accept only direct /pluginfile.php and apply local limits;

  • only certain quiz operations, after explicit confirmation, may use HTML forms.

The sesskey is neither persisted nor returned. As required by the AJAX protocol, it may appear in the URL seen by Moodle's infrastructure. The cookie is equivalent to a credential while it is valid: do not copy, log, publish or sync it. When it expires, repeat mcp-usc login.

Compatibility matrix

Capability

REST token

HTTP session

Courses, Timeline and calendar

REST API

AJAX; no fallback to pages that record views

Conversations and messages

REST

AJAX

Forums and discussions

REST

AJAX when available; no HTML fallback

Posts in a discussion

REST with confirmation

AJAX with confirmation, if the function exists

Publish forum discussion/reply

REST

Not safely available via AJAX

Create/delete personal events

REST

Not safely available via AJAX

Submit/withdraw Choice response

REST

Not safely available via AJAX

Materials and resources

REST

AJAX and direct /pluginfile.php download; never view.php

Reading and modifying assignments

REST

Not safely available

Submission files

REST + /webservice/upload.php multipart

The JavaScript filemanager is not manipulated

Quizzes

REST

AJAX for pure reads; form only after confirming actions

Moodle's filemanager manager creates drafts via JavaScript and is not equivalent to a standard multipart field. If a submission only offers that manager, replacing or deleting its files requires an authorized REST token; public file tools in session mode stop without modifying anything. Playwright is not used to emulate the file manager.

Authorized local files

Upload tools are disabled until an allowlist folder is configured:

$env:USC_UPLOAD_ROOT = "C:\Users\TU_USUARIO\Documents\mcp-usc-uploads"
$env:USC_MAX_UPLOAD_BYTES = "52428800"

USC_UPLOAD_ROOT must exist. Only regular files resolved inside that folder are accepted; paths that escape it are not followed and the same file is not allowed twice. The preview shows relative path, name, size and SHA-256 before issuing a token.

Local upload limits:

  • maximum 20 files per operation;

  • USC_MAX_UPLOAD_BYTES applies to both each file and the total;

  • default value: 50 MiB (52428800 bytes);

  • configurable range: from 1 byte to 100 MiB;

  • online text has an additional limit of 1 MiB.

replace_submission_files replaces the complete set of submission files; it does not silently add one to the existing ones. Before issuing the confirmation it checks that the service allows uploads and that the submission only has the file plugin active. Likewise, REST text saving is only enabled when onlinetext is the only active plugin. Moodle processes all plugins in mod_assign_save_submission, so an unknown combination is rejected before creating a draft or modifying the submission.

Public exam sources

Each USC center publishes its own calendars. Configure canonical pages or PDFs separated by semicolons:

$env:USC_EXAM_SOURCES = "https://www.usc.gal/gl/centro/MI_CENTRO/horarios/cursos;https://assets.usc.gal/ruta/calendario.pdf"

The search uses direct HTTP, accepts only HTTPS under usc.gal/usc.es, follows at most five redirects and downloads at most 15 MB per document. It does not do mass crawling: it queries the indicated sources and their immediate exam/PDF links. Each piece of evidence keeps URL, PDF page when applicable and query time; discrepant sources are shown as a conflict.

Connecting with Codex

From PowerShell on this machine:

codex mcp add usc-campus -- uv --directory C:\Users\pablo\mcp-usc run mcp-usc serve
codex mcp list

To include public sources from the MCP configuration:

codex mcp remove usc-campus
codex mcp add usc-campus --env USC_EXAM_SOURCES="https://www.usc.gal/gl/centro/MI_CENTRO/horarios/cursos" -- uv --directory C:\Users\pablo\mcp-usc run mcp-usc serve

Restart the client or open a new session to load the server. According to the official OpenAI documentation, the MCP configuration is shared between the ChatGPT app, Codex CLI and the IDE extension on the same host.

Also enable host approval for all writes in %USERPROFILE%\.codex\config.toml:

[mcp_servers.usc-campus]
command = "uv"
args = ["--directory", 'C:\Users\pablo\mcp-usc', "run", "mcp-usc", "serve"]
default_tools_approval_mode = "writes"

MCP annotations, preview, token and host approval are complementary layers; none replaces a human decision about the exact parameters.

MCP tools

Version 0.3.0 exposes 75 tools: 39 reads, 18 previews and 18 operations with effect. The complete capability study explains the inventory, the security boundaries and the differences between Moodle 4.5 and 5.2.

Group

Reading

Preview

Writing

Student catalog

list_student_capabilities, call_student_read, profile, preferences, participants, groups, grades, progress, notifications, badges, and private files

preview_student_action

execute_student_action

Campus and calendar

auth_status, list_courses, list_pending_work, list_upcoming_events, get_work_item, list_announcements, list_calendar_events

create or delete a personal event

create or delete a personal event

Messages and forums

list_messages, list_conversation_messages, list_forums, list_forum_discussions, search_message_contacts; list_discussion_posts is kept but fails closed

message, post inspection, new discussion or reply

send message, inspect posts, create discussion or reply

Choice

catalog reading functions

submit or withdraw a response

submit or withdraw your own response

Materials and exams

list_course_contents, list_course_resources, read_course_resource, list_exam_sources, search_exam_dates

Assignments

list_assignments, get_submission_status, check_submission_reopen

preview_save_online_submission, preview_replace_submission_files, preview_delete_submission_files, preview_submit_assignment, preview_remove_submission

save_online_submission, replace_submission_files, delete_submission_files, submit_assignment, remove_submission

Quizzes

list_quizzes, list_quiz_attempts, final review and best grade

inspect active attempt, start, save, or finish

inspect active attempt, start, save, or finish

call_student_read only accepts the 192 functions explicitly included in the allowlist; it is not an arbitrary Moodle proxy. With a REST token, list_student_capabilities(available_only=true) lets you see which ones the configured service advertises. With an AJAX session, full availability is not always discoverable, and each call fails closed if Moodle does not expose the function.

The twelve generic actions are limited to your own preferences, private favorites, muting or marking conversations/notifications, keeping an unsent draft, and flagging a question. The new contextual actions resolve by proprietary HTTP, course, forum, group, audience, phase, and options before issuing confirmation:

  • create or delete personal calendar events;

  • start a discussion or reply publicly in a forum, without attachments or private replies;

  • submit or withdraw your own responses to a Choice activity.

These six contextual actions require a legitimate REST token to advertise them. Moodle 4.5–5.2 does not normally mark its functions as AJAX; cookie mode stops before previewing and does not try to emulate them with a browser.

The catalog also identifies student actions that do not yet have a safe executor. They are published as generic_execution_supported=false: appearing in the inventory does not allow executing them, nor does it imply that the USC has the corresponding module or plugin active.

Messages, forums, and materials

  • list_messages reads received or sent messages without marking them. list_conversations is kept only for compatibility and fails closed: certain Moodle versions can create and favorite a conversation with yourself when running that supposed read.

  • Forums include all visible ones, not just announcements. Moodle can mark posts as read when running mod_forum_get_discussion_posts; that is why list_discussion_posts fails closed and the preview_inspect_discussion_posts / inspect_discussion_posts pair requires confirmation before traversing posts and attachment metadata.

  • search_message_contacts creates a temporary reference to the recipient. preview_message requires a recent search, shows name, ID, and text, and never sends.

  • list_course_contents lists sections, activities, pages, links, and files.

  • list_course_resources returns opaque references valid for ten minutes. Only a recent reference can be used with read_course_resource.

  • read_course_resource supports PDF, text/HTML, and OOXML (.docx, .pptx, .xlsx). By default it limits the download to 25 MiB, text to 100,000 characters, and PDFs to 100 pages; the maximums accepted per call are 50 MiB, 500,000 characters, and 300 pages.

  • In session mode, contents and announcements require a pure AJAX function, and resources must point directly to /pluginfile.php; opening course/view.php, mod/*/view.php, or forum pages is rejected because it can register visits, mark reads, or change completion.

Assignments and submissions

  • With a REST token that advertises the required functions, you can list assignments and query the draft, files, online text, feedback, and permissions.

  • Assignment HTML pages register views and can change completion; therefore all assignment reads, previews, and writes fail before opening them in session mode.

  • Saving text, replacing/deleting files, submitting for grading, or removing the entire submission are distinct writes, each with its own preview.

  • submit_assignment can close draft editing and must respect the submission statement that Moodle shows.

  • remove_submission uses mod_assign_remove_submission, available in Moodle 4.5 or later. It is destructive and is not equivalent to "reopening."

  • check_submission_reopen never changes state. If the submission is already editable, it reports so; if it is closed, the standard API reserves reopening to teaching staff. The connector does not try to bypass that restriction: you must request reopening from the instructor through normal channels.

Quizzes

  • You can list quizzes and your own attempts and read the permitted review of an already finished attempt.

  • Opening the data or summary of an active attempt can cause Moodle to process an expiry and change its state. That is why get_quiz_attempt_page and get_quiz_attempt_summary fail closed; preview_inspect_quiz_attempt shows the risk and inspect_quiz_attempt requires confirmation.

  • In session mode, pure lists require AJAX. Forms are only opened in the second, confirmed call to inspect a potentially stateful attempt, start it, save, or finish; the preview does not open mod/quiz/view.php.

  • start_quiz can immediately activate a timer.

  • save_quiz_answers modifies an open attempt but does not finish it.

  • finish_quiz is usually irreversible.

  • Questions and field names come from Moodle, are treated as untrusted data, and the connector never infers whether an answer is correct.

  • Each write operation requires an independent preview; a previous approval does not authorize the next step of the attempt.

Confirmations and writes

Every write follows two calls:

  1. preview_* validates the state and returns the visible parameters plus a confirmation_token.

  2. The write tool consumes that token only if the action and parameters match exactly.

Tokens live only in memory, expire after five minutes, and are single-use. Changing text, recipient, files, answers, attempt, or any other input invalidates the confirmation. The host's writes approval must remain active for the second call to require human intervention.

Each contact reference and confirmation token is also bound to the Moodle user_id that created it. If the account or session changes between the preview and the write, the operation is rejected. A valid response to an HTML form only confirms that the request was sent: outcome="unknown" is returned when Moodle does not offer an unambiguous postcondition, and it is never retried over a second transport in response to an ambiguous reply.

A timeout or connection drop during a write is ambiguous: Moodle may have applied the operation even though the client did not receive the response. Do not automatically retry a message, submission, save, or finish. Re-read the conversation, the submission state, or the attempt and decide based on that evidence; in a timed quiz, also check the clock directly in Moodle.

Testing

uv run pytest
uv run ruff check .

The suite replaces HTTP, keyring, forms, uploads, and downloads with test doubles. It contains no tokens, cookies, or real data and does not run any writes against the USC. Real access is validated only manually and locally.

Official sources

The contract was cross-checked against official documentation and code:

Prior work reviewed

Licensed projects were studied to avoid repeating already-solved patterns. Architecture ideas and public contracts were reused, not credentials or incompatible code:

loyaniu/moodle-mcp was used only to compare scope because the repository does not declare a license; no code was copied.

Known limitations

  • The availability of each Web Service depends on the version, configuration and permissions that the USC assigns to the token or session.

  • The OIDC session and MoodleSession expire; mcp-usc login must be run again.

  • AJAX and quiz forms may change between versions. The connector fails closed if it cannot safely recognize an operation.

  • Assignments require REST: their pages log views and the JavaScript filemanager is not equivalent to a native multipart field.

  • Deleting a complete submission requires Moodle 4.5+ and current permissions. Reopening a closed submission is up to the teaching staff.

  • Not all teaching staff use the Virtual Campus; email or Teams may contain information that this server does not consult.

  • A Moodle date may be continuous assessment and a public date, an official exam. They are kept as separate sources.

Install Server
A
license - permissive license
B
quality
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 Servers

View all related MCP servers

Related MCP Connectors

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

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

  • Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only

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/PabloPC05/mcp-usc'

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