使用说明
Moodle Student MCP
An MCP server that gives Claude (or any MCP client) read access to your Moodle as a student: courses of every semester, deadlines with submission status, grades and teacher feedback, announcements and forums, quiz questions and reviews, files (read as text or synced to a folder) and "what changed since last time".
Built and tested against the University of Vienna's Moodle (moodle.univie.ac.at, Moodle 5.2) but works with any Moodle that has the mobile web service enabled — which is nearly all of them.
You: What do I have to do this week?
Claude: (get_deadlines) Mon 05.10. 14:00 — SE2 Worksheet 1 closes, not attempted yet.
Wed 07.10. 23:59 — DLfNLP Quiz 01 … Thu 08.10. — your SE2 group-switch registration …
What you can ask
- "What's due in the next two weeks? Did I forget to submit anything?" — flags quiz attempts that were started but never submitted.
- "What's new in Moodle since yesterday?" — new activities, uploaded slides, forum posts, grades with feedback.
- "Summarise the announcements of all my courses."
- "How is SE2 graded and how many points do I have?"
- "Read the slides of lecture 3 in DLfNLP and make me a summary."
- "Download all PDFs of Software Engineering 2 into ~/Uni/SE2/materials."
- "Show me the questions I got wrong in the last Data Analysis quizzes and explain them."
- "I started the SE2 quiz — go through the questions with me." — question text, options, pictures and UML diagrams.
- "Find everything about B-trees in my past courses."
Tools
| Tool | What it does |
|---|---|
status |
Connection check: user, site, current semester, configuration |
list_courses |
Courses by semester (current, past, all, 2025W…) with LV number, group, final grade |
get_course |
Course page: teachers, groups, every section with text, activities (cmid, dates, files, restrictions) |
get_activity |
Everything about one activity — assignment submission/grade/feedback, quiz attempts, page & book text, forum discussions, choices, BBB recordings, attendance, checkmarks, … |
search |
Search activity names, descriptions, labels, section texts, file names and pages across courses |
get_deadlines |
Open to-dos (dashboard timeline) with status: not attempted / in progress — not submitted / submitted |
get_calendar |
All calendar events in a date range (incl. booked appointments) |
get_grades |
Per course: every grade item, %, weight, teacher feedback. Without course: semester overview |
get_activity_status |
Moodle's "Activities" overview: due date, submission status, grade per activity — also for plugins (offline quizzes, checkmarks, …) |
get_quiz_questions |
Questions of a quiz attempt in progress: text, how to answer, every option (choices, dropdowns, drag items, drop zones), saved answer, time left; pictures and inline SVG diagrams as images |
get_quiz_review |
Question-by-question review of quiz attempts: my answer, ✓/✗, correct answer, feedback |
get_announcements |
News-forum posts across current courses, full text |
get_forum / get_discussion |
Forums of a course, discussions of a forum, whole threads |
get_notifications / get_messages |
Moodle notifications and private/group messages |
list_files |
Every file of a course (resources, folders, pages, books, assignment attachments) |
read_file |
Text of PDF (per page), PPTX (per slide + notes), DOCX, XLSX, ODT, notebooks, HTML, code; images are shown to the model |
download_files |
Incremental sync of a course's files into a folder (skips unchanged, never deletes or overwrites your edits, videos opt-in) |
get_updates |
What changed since your last check (or a date): activities, files, posts, grades, notifications |
fetch_page |
Any Moodle page as Markdown via the optional web session |
Full reference with parameters and example output: docs/TOOLS.md. Everyday recipes (morning check, folder sync, exam prep, a sync skill for Claude Code): docs/WORKFLOWS.md.
Prompts (slash commands in Claude Code / Claude Desktop): weekly_briefing, course_sync <course>,
exam_prep <course> [topic], semester_report [semester].
Course arguments are forgiving: 471264, 051050, SE2, DLfNLP, software engineering 2, or
SE1 2025W for an older run of a course.
Install
Requires Python ≥ 3.10. With uv (recommended):
uv tool install git+https://github.com/Ilya-Grigoryev/moodle-student-mcp
# or from a local checkout: uv tool install /path/to/moodle-student-mcp
or with pip / pipx:
pipx install git+https://github.com/Ilya-Grigoryev/moodle-student-mcp
This installs the moodle-mcp command. Update later with uv tool upgrade moodle-student-mcp
(or uv tool install --force <path> for a local checkout).
Set up your token
Moodle's mobile app uses a personal web-service token. You can get the same token from your browser session — no admin rights needed.
Default browser with your existing passkeys (macOS)
moodle-mcp setup --system-browser --url https://moodle.univie.ac.at
This opens your default browser with your existing profile, SSO session and password manager.
Sign in normally and allow the browser to open Moodle MCP Login when prompted. A temporary
macOS URL handler receives the token automatically; no browser dependency or DevTools is needed.
The handler and its private callback file are removed after login, cancellation or timeout.
This mode uses macOS's osacompile, codesign and LaunchServices tools.
If your institution forces a particular mobile-app URL scheme, use the private-browser mode below.
Automatic private-browser login (optional, cross-platform)
Install the browser extra and Chromium once. With uv (reinstalls the tool with the extra):
uv tool install --force "moodle-student-mcp[browser] @ git+https://github.com/Ilya-Grigoryev/moodle-student-mcp"
"$(uv tool dir)/moodle-student-mcp/bin/python" -m playwright install chromium
moodle-mcp setup --browser --url https://moodle.univie.ac.at
Or with pip in a virtual environment:
python -m pip install "moodle-student-mcp[browser] @ git+https://github.com/Ilya-Grigoryev/moodle-student-mcp"
python -m playwright install chromium
moodle-mcp setup --browser --url https://moodle.univie.ac.at
For a local checkout, use uv tool install --force "moodle-student-mcp[browser] @ /path/to/moodle-student-mcp"
or python -m pip install -e ".[browser]" instead. Chromium must be installed with the Python
interpreter Moodle MCP runs in; if it is missing, setup --browser prints the exact command.
A separate browser window opens. Sign in normally, including your institution's SSO and MFA;
the token is captured, verified against Moodle, and saved automatically with permissions 600.
No DevTools or copying is required. The login response is checked against the selected site and
this login attempt. Browser cookies/profile are not saved. Passwords and MFA codes stay in the
browser; they are never requested in the terminal or sent to your AI assistant.
This isolated window does not have your existing browser profile or synced passkeys. On macOS,
use --system-browser above if you need your existing password manager.
Close the private window or press Ctrl+C to cancel. The default timeout is five minutes; use
--timeout 600 for more time. If the browser cannot start or your Moodle disables mobile
web services, setup reports an error without changing the saved configuration.
Manual setup (no browser dependency)
The original copy-and-paste flow remains available:
moodle-mcp setup
It asks for your Moodle URL and prints a link like
https://moodle.univie.ac.at/admin/tool/mobile/launch.php?service=moodle_mobile_app&passport=….
- Log in to Moodle in your browser as usual.
- Open DevTools (F12) → Network tab and tick Preserve log.
- Open the printed link in the same tab. Moodle redirects to
moodlemobile://token=…— the browser can't open that, but the request shows up in the Network list (Chrome: the last entry; you may also get an "Open app?" prompt). Copy the fullmoodlemobile://token=…URL (right click → Copy URL, or take it from theLocationresponse header of thelaunch.phprequest). Tip: in Firefox the failed redirect usually leavesmoodlemobile://token=…in the address bar, which is the easiest place to copy it from. - Paste it into
moodle-mcp setup. It decodes the token, verifies it and saves it to~/.config/moodle-mcp/config.json(permissions600).
Then check everything: moodle-mcp check.
Tokens stay valid until you revoke them (Moodle → Preferences → Security keys) or the site expires them.
Connect your MCP client
Claude Code
claude mcp add moodle -s user -- moodle-mcp
(use the absolute path from which moodle-mcp if moodle-mcp is not on the PATH of your shell).
Claude Desktop — claude_desktop_config.json:
{ "mcpServers": { "moodle": { "command": "/absolute/path/to/moodle-mcp" } } }
Cursor — ~/.cursor/mcp.json:
{ "mcpServers": { "moodle": { "command": "/absolute/path/to/moodle-mcp" } } }
Instead of the config file you can pass everything as environment variables in the client config
("env": {"MOODLE_URL": "…", "MOODLE_TOKEN": "…"}).
Configuration
Environment variables override ~/.config/moodle-mcp/config.json (keys in brackets).
Variable (key) |
Default | Meaning |
|---|---|---|
MOODLE_URL (url) |
— | Site root, e.g. https://moodle.univie.ac.at (the old /webservice/rest/server.php form works too) |
MOODLE_TOKEN (token) |
— | Web-service token |
MOODLE_PRIVATE_TOKEN (private_token) |
— | Optional, enables the web session (see below) |
MOODLE_LANG (lang) |
en |
Language for Moodle strings and multi-language content |
MOODLE_TIMEZONE (timezone) |
Europe/Vienna |
Timezone for all dates |
MOODLE_DOWNLOAD_DIR (download_dir) |
~/Downloads/moodle |
Default folder for download_files |
MOODLE_EXCLUDE_COURSES (exclude_courses) |
— | Courses to leave out of cross-course overviews (ids, LV numbers, names; comma-separated or a JSON list) |
MOODLE_MCP_CONFIG |
~/.config/moodle-mcp/config.json |
Config file location |
MOODLE_MCP_STATE_DIR / MOODLE_MCP_CACHE_DIR |
~/.local/state/moodle-mcp / ~/.cache/moodle-mcp |
Snapshots for get_updates, file cache |
Courses you hid in Moodle's My courses ("Remove from view") are excluded from overviews too. They stay reachable by name or id.
Use it from the shell
Every tool can be called directly — handy for scripts, cron jobs or debugging:
moodle-mcp tools # list tools and parameters
moodle-mcp call get_deadlines days=7
moodle-mcp call get_course course=SE2 section=3
moodle-mcp call download_files course=SE2 dest=~/Uni/SE2/materials
moodle-mcp call search --json '{"query": "b-tree", "scope": "all"}'
Web session (optional, experimental)
A few plugins have no web-service API at all (group self-registration grouptool, appointment
slots organizer, moodleoverflow forums). The server still reports their dates, status and calendar
events. To read their pages too, it can open a normal web session using Moodle's app auto-login, which
needs the private token that Moodle only hands out right after a fresh login:
- Log out of Moodle and log in again.
- Immediately run
moodle-mcp setupand follow the steps — the pasted URL then contains the private token as well, andfetch_page/get_activitystart showing those pages. The browser modes (--browser,--system-browser) pick it up the same way.
Running setup again without a fresh login keeps the private token saved for the same token; a new token (e.g. another account) replaces it.
Moodle allows one auto-login every 6 minutes; the session cookie is cached in the state directory.
Privacy & safety
- Read-only. The server never submits, posts, marks as read or changes anything in Moodle. The
only write is
download_filessaving files to a folder you choose. - Requests go only to your Moodle site. Files are downloaded only from that host.
- The token lives in your MCP client config or in a
600config file and is never logged or shown in tool output. - Remember that whatever a tool returns is sent to the LLM you are using.
Troubleshooting
| Problem | Fix |
|---|---|
Moodle rejected the token (invalidtoken) |
Token expired or revoked — run moodle-mcp setup again |
Moodle is not configured |
Run moodle-mcp setup or set MOODLE_URL + MOODLE_TOKEN |
… matches several courses |
Use the course id from list_courses, or add a semester: "SE1 2025W" |
Review … is not available |
The teacher hides quiz reviews (often until the quiz closes) |
Lecture times missing in get_calendar |
Many universities keep timetables outside Moodle (e.g. u:space) |
| Another Moodle than univie | Works the same; semester detection falls back to course start dates |
Development
git clone https://github.com/Ilya-Grigoryev/moodle-student-mcp && cd moodle-student-mcp
uv venv && uv pip install -e ".[dev]"
.venv/bin/pytest # unit + tool tests against a fake Moodle
.venv/bin/ruff check src tests
.venv/bin/python scripts/live_smoke.py # optional: every tool against your real Moodle
Layout: client.py (async WS client: batching, cache, retries, downloads), courses.py (semesters,
course resolution), tools/ (one module per tool group), quizreview.py, extract.py, html.py.
The design and the analysis it is based on are in docs/SPEC.md.
License
MIT — see LICENSE.