ZHAW Moodle MCP Server
This MCP server lets Claude access your university Moodle (ZHAW and other Swiss universities) for courses, materials, downloads, deadlines, and announcements, after you log in yourself.
Check, log in to, or log out of your Moodle session without sharing your password
List your courses (active, past, future, or all) and view course structure, sections, and activities
Read Moodle pages and text blocks as Markdown, including links
List learning resources such as files, folders, external links, and pages
Download files, folder contents, or files linked from pages; returns local paths
Read text from PDFs, PowerPoint, Word, HTML, and text files, with page/slide ranges
Sync a single course or all active courses, with dry-run and update-changed options; never deletes local files
Search courses, sections, materials, assignments, quizzes, and folder files
Get upcoming and overdue deadlines across courses
List assignments with dates, submission status, grading status, and descriptions
Get recent announcements, optionally filtered by course or time
Get recent changes since a given time, including new/updated materials, announcements, and deadlines
Provides tools for working with ZHAW Moodle: list courses, retrieve course structure and content, find and download learning resources, sync local copies, and see deadlines, assignments, announcements, and recent changes.
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., "@ZHAW Moodle MCP Server What do I need to submit this week?"
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.
Moodle MCP for Swiss universities
Use your university's Moodle from Claude: courses, materials, downloads, deadlines and announcements. Works with ZHAW, FHNW, ETH, EPFL and the other Swiss universities below, and with any other Moodle 4 site. You log in yourself (usually with SWITCH edu-ID) — your password is never seen or stored, and everything stays on your computer.
Unofficial student project, not affiliated with any university. Course material is for personal study only.
Formerly zhaw-moodle-mcp. Existing setups keep working: uvx zhaw-moodle-mcp now installs this
package, and your login and settings stay where they are. For the Claude Desktop extension,
install the new swiss-moodle-<version>.mcpb over the old one.
Quick start
Claude Desktop (recommended)
Download
swiss-moodle-<version>.mcpbfrom the latest release.Double-click it, or in Claude Desktop open Settings → Extensions → Advanced settings → Install Extension… and pick the file. Click Install.
Enter your university under University: its short name from the table below (e.g.
fhnw) or the web address of your Moodle. You can also leave it empty and simply tell Claude in the chat which university you study at.Open a new chat and ask "Which Moodle courses do I have?". The first start takes a few seconds; then a browser opens for the login.
To switch universities later, change University in the extension's settings (or, if you left it empty, ask Claude to switch). In the chat's + → prompts menu you find ready-made study sessions: study assistant, last lecture summary, deadlines overview, what's new, exam preparation.
Claude Code
Install uv, then (with your university's short name):
claude mcp add moodle -e MOODLE_MCP_INSTITUTION=fhnw -- uvx swiss-moodle-mcp@latestAsk Claude
"Summarise the last lecture of Software Engineering 1", "Show all my deadlines as a table",
"Sync all my courses", "What's new since Monday?". Files go to a folder named after your
university in your home directory (e.g. ~/FHNW).
Related MCP server: NCCU Moodle MCP
Universities
University | Short name | Moodle | Status |
ZHAW |
| moodle.zhaw.ch | tested |
BFH |
| moodle.bfh.ch | not tested yet |
EPFL |
| moodle.epfl.ch | not tested yet |
ETH |
| moodle-app2.let.ethz.ch | not tested yet |
FFHS |
| moodle.ffhs.ch | not tested yet |
FHGR |
| moodle.fhgr.ch | not tested yet |
FHNW |
| moodle.fhnw.ch | not tested yet |
HES-SO |
| cyberlearn.hes-so.ch | not tested yet |
HFTM |
| moodle.hftm.ch | not tested yet |
OST |
| moodle.ost.ch | not tested yet |
PHLU |
| moodle.phlu.ch | not tested yet |
UNIFR |
| moodle.unifr.ch | not tested yet |
UNIGE |
| moodle.unige.ch | not tested yet |
UNIL |
| moodle.unil.ch | not tested yet |
UNINE |
| moodle.unine.ch | not tested yet |
USI |
| not tested yet | |
SUPSI |
| not tested yet |
"Not tested yet": the site runs Moodle 4, but nobody has used this server there
yet. It should work - you can help by running uvx swiss-moodle-mcp doctor, which tries every
feature on one of your courses and prints a report without course names or personal data, and
posting it as a compatibility report.
Not listed? Use the address of your Moodle instead of a short name (copy it from the browser while you are on your Moodle). The Moodle must be version 4.0 or newer; other learning platforms (ILIAS, OLAT, Canvas) are not supported.
Good to know
Browser: login uses your default browser if it is Chrome, Edge, Brave or Vivaldi, otherwise another installed one (Firefox and Safari are not supported).
Updates: the extension is updated by installing a newer
.mcpb; withuvx ...@latest(Claude Code) updates install automatically when Claude starts.Extension does not start: it runs with uv. If Claude Desktop reports that
uvis missing, install uv and restart Claude completely (also from the tray).Sync never deletes local files. Logging out (ask Claude, or
uvx swiss-moodle-mcp logout) removes the stored session and the login browser profile; a running server notices it.Session and settings live in
~/.swiss-moodle-mcpon Windows (outside AppData, so Claude from the Microsoft Store and the command line share them) and in the usual app folders on macOS/Linux, with a separateinstances/<moodle host>folder per Moodle site. Folders namedzhaw-moodle-mcpfrom older versions keep being used.
Configuration
Choose your university once with uvx swiss-moodle-mcp setup (a list to pick from, or
setup fhnw, or setup <address of your Moodle>); uvx swiss-moodle-mcp universities lists the
known ones and uvx swiss-moodle-mcp status shows what is set. You can also just tell Claude your
university ("I study at FHNW"); it stores the choice for you. If you used this server before
v0.5, ZHAW stays selected.
The extension asks for the university, download folder and browser in its settings. Otherwise
run uvx swiss-moodle-mcp config-path to see where config.toml goes:
[moodle]
institution = "zhaw" # or bfh, epfl, ethz, ffhs, fhgr, fhnw, hes-so, hftm, ost, phlu, unifr,
# unige, unil, unine, usi, supsi - or the address of any other Moodle
# download_directory = "~/Studium/{short}" # default ~/ZHAW, ~/FHNW, ...
[browser]
name = "auto" # or "chrome", "msedge", "brave", "vivaldi"
# executable_path = "C:/path/to/browser.exe" # any other Chromium-based browserDevelopment
uv sync
uv run pytest
uv run ruff check .In this folder Claude Code picks up the server from .mcp.json, plus a
study assistant subagent (copy it to ~/.claude/agents/ to use it
everywhere). Build the Claude Desktop extension with uv run python scripts/build_extension.py (needs Node.js).
Pushing a vX.Y.Z tag that matches pyproject.toml publishes to PyPI and attaches the .mcpb
to a GitHub release.
Available Tools
16 toolsmoodle_auth_statusARead-onlyIdempotent
Check whether a valid ZHAW Moodle session exists. Never returns credentials.
Inputs: no named parameters. Returns: state, message, moodle_url, authenticated
moodle_download_resourceAIdempotent
Download a file, all files of a folder, or files linked in a page/text block, and return the local paths.
By default files go to the managed directory <download_directory>/<course>/<section>/,
which moodle_sync_course also uses.
Args:
resource_id: id from moodle_list_resources ("<cmid>" or "<folder cmid>/<path>"),
or a file link's resource_id from moodle_get_content ("<page/label id>/<file>");
the id of a page or text block downloads all files linked in it
destination: optional target directory; relative paths are resolved
against the configured download directory
overwrite: replace an existing local file (otherwise it is left as is)
Inputs: resource_id (required), overwrite, destination. Returns: files, failed, resource_id
moodle_get_announcementsARead-onlyIdempotent
Recent announcements ("Ankündigungen") posted by lecturers, newest first, with the message text of the most recent ones.
Args:
course_id: restrict to one course (default: all current courses)
since: only announcements newer than this: ISO date/datetime (2026-09-14) or relative (7d, 12h, 2w)
limit: maximum number of announcements
Inputs: limit, since, course_id. Returns: announcements
moodle_get_contentARead-onlyIdempotent
Read the text of a Moodle page ("Textseite") or text block ("Textfeld"/label) as Markdown, with the links it contains. Such texts often hold instructions, rules for assignments and exams, or reading lists. Opening a page counts as a view in Moodle.
Args:
activity_id: id (cmid) of a page or label from moodle_get_course or moodle_search
Inputs: activity_id (required). Returns: id, url, name, note, +8 more
moodle_get_courseARead-onlyIdempotent
Get the structure of a course: sections, nested subsections and all activities/materials (files, folders, links, pages, quizzes, assignments, ...). Text blocks (labels) include their text.
Args:
course_id: course id from moodle_list_courses
Inputs: course_id (required). Returns: course, sections
moodle_get_deadlinesARead-onlyIdempotent
Open to-dos with deadlines across all courses (assignment due dates, quiz closing times, ...), sorted by date. Answers "What do I need to submit this week?". Activities already completed are not listed.
Args:
days_ahead: how far to look ahead (days)
course_id: restrict to one course
include_overdue: also list overdue to-dos from the last 30 days
Inputs: course_id, days_ahead, include_overdue. Returns: now, note, until, deadlines
moodle_get_recent_changesARead-onlyIdempotent
What changed in Moodle since a point in time: new or updated materials and activities, new announcements, and new or changed deadlines, grouped by course. Answers "What is new in Moodle since Monday?".
Args:
since: ISO date/datetime (2026-09-14, 2026-09-14T08:00) or relative (7d, 12h, 2w)
course_id: restrict to one course (default: all current courses)
Inputs: since, course_id. Returns: since, until, courses, unchanged_courses
moodle_list_assignmentsARead-onlyIdempotent
Assignments with opening date, deadline, submission and grading status and description. Without course_id all current courses are included (one request per assignment).
Args:
course_id: restrict to one course
Inputs: course_id. Returns: failed, assignments
moodle_list_coursesARead-onlyIdempotent
List the user's ZHAW Moodle courses.
Args:
status: "active" (current semester, default), "past", "future" or "all"
Inputs: status. Returns: courses
moodle_list_resourcesARead-onlyIdempotent
List learning materials of a course: files (pdf, powerpoint, word, excel, zip, ...), folders, external links and Moodle pages, with their section.
Args:
course_id: course id from moodle_list_courses
include_folder_contents: also list the individual files inside folders
(one extra request per folder)
Inputs: course_id (required), include_folder_contents. Returns: course_id, resources
moodle_loginAIdempotent
Log in to ZHAW Moodle. Opens a browser window where the USER signs in with SWITCH edu-ID (incl. MFA) themselves; returns once login is detected. Never ask the user for their password. Other tools log in automatically when needed.
Args:
force: open the login browser even if the current session is still valid
Inputs: force. Returns: state, message, moodle_url, authenticated
moodle_logoutADestructiveIdempotent
Log out: end the Moodle session and delete the locally stored browser session and cookies. The next Moodle request will require a new login.
Inputs: no named parameters. Returns: message, logged_out, server_session_invalidated
moodle_read_fileAIdempotent
Read the text of a course file (PDF, PowerPoint .pptx, Word .docx, HTML, text).
Downloads the file first if needed. Use this to summarise or explain lecture slides,
scripts and exercise sheets. Long files come in parts: continue with next_pages.
Args:
resource_id: id of a single file from moodle_list_resources, moodle_search or
moodle_get_content (folder files: "<folder id>/<path>")
pages: page/slide range for PDF and PowerPoint, e.g. "1-10", "5" or "11-"
max_chars: maximum characters to return (1000-100000)
Inputs: resource_id (required), pages, max_chars. Returns: note, path, text, pages, +5 more
moodle_searchARead-onlyIdempotent
Search Moodle by name: courses, sections, materials (files, folders, links, pages), assignments, quizzes and files inside folders. Case- and umlaut-insensitive, tolerant to small typos; all words must match (e.g. "OR ZGB", "Übung 3", "Semesterprogramm").
Args:
query: words to look for
course_id: restrict to one course
kinds: restrict result kinds: course, section, module (activities/materials), file (in folders)
source: "index" = local index of names (fast; current courses are refreshed automatically),
"moodle" = Moodle's full-text search (also finds words inside text areas),
"auto" = index first, Moodle full-text search if nothing matches
limit: maximum number of hits
refresh: re-read the courses from Moodle before searching
Inputs: query (required), kinds, limit, source, +2 more. Returns: hits, note, query, source, +1 more
moodle_sync_allAIdempotent
Synchronise all active (current semester) courses into the local download directory and return a per-course summary. Same rules as moodle_sync_course.
Args:
dry_run: only report what would change, download nothing
update_changed: re-download files that changed on Moodle
Inputs: dry_run, update_changed. Returns: courses, dry_run, download_directory
moodle_sync_courseAIdempotent
Synchronise all files of a course into the local download directory. Downloads new files, re-downloads changed ones and reports what changed. Files removed from Moodle are reported but never deleted locally.
Args:
course_id: course id from moodle_list_courses
dry_run: only report what would change, download nothing
update_changed: re-download files that changed on Moodle
Inputs: course_id (required), dry_run, update_changed. Returns: new, failed, dry_run, removed, +7 more
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 16 tools
Most tools target a distinct Moodle action and resource type, and the descriptions make the differences clear. A few closely related pairs—such as list_resources vs get_course and get_deadlines vs list_assignments—could be confused at selection time, but the usage guidance separates them well.
All tools share the moodle_ prefix and nearly all follow a verb_noun pattern such as list_courses, read_file, and get_announcements. The convention is broken slightly by moodle_auth_status and the bare verbs login/logout, though the overall pattern remains predictable.
With 16 tools, the set is just above the typical well-scoped 3-15 range, but each tool serves a distinct workflow spanning auth, course navigation, content access, search, deadlines, announcements, and change tracking. No tool feels redundant, so the count is justified.
The server covers the full read-side workflow for a student-facing Moodle assistant: session handling, course discovery, structural overview, content extraction and download, offline syncing, search, deadlines, assignments, announcements, and recent changes. There are no obvious dead ends for the core workflows implied by the tool set.
Maintenance
Related MCP Connectors
Notes, files, GitHub, and Drive through one MCP connection.
Notes, files, GitHub, and Drive through one MCP connection.
Notes, files, GitHub, and Drive through one MCP connection.
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceEnables MCP hosts to query NTULearn courses, announcements, calendar events, and grades, and to download course files into organized folder hierarchies.6-
- FlicenseAqualityBmaintenanceEnables students to access Moorle courses, assignments, grades, announcements, and notifications through authenticated MCP tools.11-
- AlicenseNot gradedqualityCmaintenanceEnables read-only Moodle access through MCP for querying courses, content, assignments, grades, forums, discussions, submissions, and calendar events, while supporting multiple profiles and local ICS export.358 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables users to retrieve Modeus schedules, iStudent grade/rating data, and eLearn course listings, content, and files through local MCP tools while using their university service login.1Apache 2.0