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 ServerWhat 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: ntulearn-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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| state | Yes | |
| message | Yes | |
| moodle_url | Yes | |
| authenticated | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds valuable behavioral context by stating 'Never returns credentials,' which is a meaningful guarantee beyond what annotations provide, especially for an authentication-related tool.
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?
The description is two short sentences with zero filler. The primary function is stated first, and the security-relevant caveat about credentials is a meaningful second sentence that earns its place.
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 zero-parameter, read-only status-check tool with an output schema and rich annotations, the description is fully adequate. An agent has everything it needs to select and invoke this tool correctly without additional detail.
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?
The input schema has zero parameters and 100% schema coverage, so there are no parameter semantics for the description to explain. The baseline of 4 applies because the schema fully handles an empty parameter set and the description has nothing to add.
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 uses a specific verb ('Check') and a precise resource ('valid ZHAW Moodle session'), making the tool's purpose immediately clear. It also distinguishes itself from moodle_login and moodle_logout by focusing on session status rather than session creation or destruction.
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?
The description implies the tool should be used when an agent needs to verify session validity before acting, but it does not explicitly state when to use it versus alternatives like moodle_login or moodle_logout, nor does it mention any exclusions. The usage context is reasonably clear from the purpose, but no explicit routing guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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)
| Name | Required | Description | Default |
|---|---|---|---|
| overwrite | No | ||
| destination | No | ||
| resource_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| files | Yes | |
| failed | No | Linked files that could not be loaded |
| resource_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds valuable behavioral details beyond the annotations: it explains the default destination path, the overwrite behavior ('replace an existing local file (otherwise it is left as is)'), and that it returns local paths. It also clarifies the resource_id format. The annotations already indicate non-read-only (readOnlyHint=false) and non-destructive (destructiveHint=false), and the description aligns without contradiction. It doesn't discuss permissions or error handling, but the core behaviors are transparent.
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?
The description is well-structured with a clear first sentence stating the purpose, followed by a brief note on default behavior, then a concise Args section. It front-loads the key information and avoids redundancy. Every sentence earns its place, and the format is easy to scan.
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?
Given the tool's moderate complexity (3 parameters, one required) and the presence of an output schema (which likely documents return values), the description covers the essential operational details: input sources, default destination, overwrite behavior, and parameter formats. It does not cover error conditions or prerequisites (like authentication), but those may be handled by sibling tools or the output schema. Overall, it is sufficiently complete for an agent to invoke it correctly.
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?
Schema description coverage is 0%, so the description must compensate. The Args section thoroughly explains each parameter: resource_id (with specific formats from other tools), destination (optional, relative paths resolved against the configured download directory), and overwrite (boolean behavior). This goes far beyond the bare schema, providing essential meaning and context for correct usage.
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 a precise action: 'Download a file, all files of a folder, or files linked in a page/text block, and return the local paths.' It names the resource types and the output, and it clearly distinguishes from sibling tools like moodle_get_content (which likely retrieves content without downloading) and moodle_sync_course (which is a broader sync operation). This is specific and unambiguous.
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?
The description provides contextual guidance by specifying where resource_ids come from ('id from moodle_list_resources...' or 'file link's resource_id from moodle_get_content') and notes that moodle_sync_course uses the same download directory. However, it does not explicitly state when to use this tool over alternatives (e.g., 'use this instead of moodle_get_content when you need local files') or provide exclusion criteria. The usage is implied but not fully spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| since | No | ||
| course_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| announcements | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=true, covering safety and idempotency. The description adds behavioral specifics: announcements are sorted newest first, and the most recent ones include message text. It also clarifies the 'since' parameter accepts ISO dates or relative formats. This adds value beyond the annotations without contradicting them.
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?
The description is efficient and front-loaded with the core purpose. The Args section is logically structured and each parameter is explained in a single line. While slightly verbose with the example format, it avoids redundancy and is not overly long. The content earns its place.
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?
Given that an output schema exists (as indicated) and annotations cover safety, the description covers the essential aspects: what the tool returns (announcements with message text), ordering, and parameter semantics. It does not mention error handling or edge cases, but for a read-only retrieval tool this is acceptable. The description is complete enough for an agent to call it correctly.
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?
Schema description coverage is 0%, so the description fully carries the burden of explaining parameters. It explicitly defines course_id (restrict to one course, default all current courses), since (only newer than, with ISO or relative examples), and limit (maximum number). This is thorough and compensates completely for the lack of schema descriptions.
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 clearly states the tool retrieves recent announcements posted by lecturers, ordered newest first, and includes the message text of the most recent ones. This is a specific verb+resource with clear scope and distinguishes it from sibling tools like moodle_get_recent_changes (which likely covers broader changes) and moodle_get_content (generic content retrieval). The mention of 'Ankündigungen' adds context for the Moodle domain.
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?
The description provides no explicit guidance on when to use this tool versus alternatives, nor any exclusions. It lists parameters but does not state typical use cases, prerequisites, or contrast with similar tools like moodle_get_recent_changes or moodle_get_deadlines. An agent would need to infer usage from the name and purpose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| activity_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| url | No | |
| name | Yes | |
| note | No | |
| text | Yes | Content as Markdown |
| links | No | |
| module | Yes | page or label |
| section | Yes | |
| course_id | Yes | |
| accessible | No | |
| course_name | Yes | |
| modified_at | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey readOnly, idempotent, and openWorld behavior. The description adds genuinely useful behavioral context beyond those annotations: opening the page counts as a view in Moodle, and the output is Markdown containing links. This is valuable and not contradictory.
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?
The description is compact and front-loaded with the core purpose, followed by relevant use context and parameter guidance. Every sentence earns its place; there is no filler or repetition.
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?
Given the tool has only one parameter, an output schema, and safety-relevant annotations, the description covers the essential workflow, input provenance, and a subtle behavioral caveat. Nothing critical is missing for an agent to invoke it correctly.
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?
The input schema only exposes an integer named activity_id. The description adds essential meaning: it is a cmid of a page or label, and it should be sourced from moodle_get_course or moodle_search. With 0% schema coverage, this fully compensates.
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 names a specific action ('Read the text'), a concrete resource type ('Moodle page or text block'), and the output format ('as Markdown, with the links it contains'). This clearly distinguishes it from list/download/sync sibling tools.
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?
It provides clear usage context by noting these texts often contain instructions, rules, and reading lists, and it tells the caller where to obtain the correct activity_id ('from moodle_get_course or moodle_search'). It does not explicitly contrast with moodle_list_resources or moodle_download_resource, so it falls just short of full alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| course_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| course | Yes | |
| sections | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, covering safety and idempotency. The description adds behavioral detail by specifying that text blocks (labels) include their text and enumerating the activity types included. It does not contradict annotations. It also does not mention pagination or size limits, but the output schema likely covers return structure.
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?
The description is concise and front-loaded with the primary purpose. It uses a list to enumerate included content and then explains the parameter. Every sentence adds value; there is no fluff. Slightly longer than necessary but acceptable.
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?
Given that an output schema exists, the description need not detail return values. It covers the tool's function, parameter semantics, and includes a prerequisite hint. It does not mention potential errors or rate limits, but for a read-only getter with annotations covering safety, it is sufficiently complete for an agent to call it correctly.
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?
The schema provides only the parameter name and type with no description (0% coverage). The description compensates by explaining that course_id is a 'course id from moodle_list_courses', giving the agent a source for the value. This is meaningful guidance beyond the schema.
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 clearly states the tool's purpose: to retrieve the structure of a course including sections, subsections, and all activity types. It differentiates from siblings like moodle_list_courses (which lists courses) and moodle_get_content (which likely retrieves specific content). The verb 'Get' and specific resource 'course structure' make it unambiguous.
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?
The description implies usage for exploring a course's structure, and mentions that course_id comes from moodle_list_courses, giving a prerequisite. However, it does not explicitly state when to prefer this over alternative tools like moodle_get_content or moodle_sync_course, nor does it provide exclusions. The usage is implied rather than explicitly guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| course_id | No | ||
| days_ahead | No | ||
| include_overdue | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| now | Yes | |
| note | No | |
| until | Yes | |
| deadlines | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, and open-world behavior, so the description adds valuable behavioral details: results are sorted by date, completed activities are omitted, and overdue items are drawn from the last 30 days when enabled. This goes beyond what annotations provide without contradicting them.
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?
The description is compact and front-loaded: a one-sentence purpose statement, a clarifying example query, a succinct filtering note, and a clean parameter list. Every sentence earns its place and there is no redundant restatement of the tool name or schema.
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 simple, read-only tool with three optional parameters and an output schema, the description covers scope, filtering behavior, sorting, and the overdue window. Nothing essential is missing to help an agent select and invoke it correctly.
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?
Schema description coverage is 0%, but the description fully compensates with an Args block explaining all three parameters in plain language: days_ahead, course_id, and include_overdue. Each parameter's meaning is clear and directly usable by an agent.
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 clearly states the tool returns open to-dos with deadlines across all courses, sorted by date, with concrete examples like assignment due dates and quiz closing times. It also frames the purpose with a natural-language question, which distinguishes it from sibling tools like moodle_list_assignments or moodle_get_recent_changes.
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?
The description explicitly tells the agent when to use the tool by tying it to the query 'What do I need to submit this week?' and clarifies that completed activities are excluded. It does not explicitly discuss when not to use it or alternatives, but the usage context is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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)
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | 7d | |
| course_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| since | Yes | |
| until | Yes | |
| courses | Yes | |
| unchanged_courses | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and idempotentHint=true, covering safety and idempotency. The description adds the scope of changes (materials, activities, announcements, deadlines) and grouping by course, but doesn't detail output format or limits. Since an output schema exists, this is adequate but not rich; the description adds some value beyond annotations but not extensive 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?
Two short paragraphs: the first front-loads the purpose with a clear question, the second lists parameters concisely. No filler; every sentence earns its place.
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 only 2 optional params and an output schema present, the description covers the main use case and parameter semantics. It doesn't mention pagination, limits, or performance implications, but for a read-only aggregate query this is acceptable given the output schema covers return values. Slightly incomplete for edge cases, hence a 4.
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?
Schema coverage is 0%, so the description must compensate. It explains 'since' with ISO formats and relative strings (7d, 12h, 2w) and clarifies 'course_id' restricts to one course with a default of all current courses. This is helpful and goes beyond the schema's type/default, though it could mention timezone handling or validation edge cases.
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 a specific verb ('What changed') and resource ('in Moodle'), enumerating concrete change types (materials, activities, announcements, deadlines) and grouping by course. It clearly answers the intended question and differentiates itself from siblings like moodle_get_announcements or moodle_get_deadlines by being an aggregate overview.
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?
Provides a concrete use case ('Answers What is new in Moodle since Monday?') and implies it's for a broad overview across course content. However, it doesn't explicitly contrast with alternatives (e.g., 'for announcements only, use moodle_get_announcements'), so it misses explicit when-not guidance, preventing a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| course_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| failed | No | Assignments that could not be read |
| assignments | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, covering safety and result variability. The description adds a useful behavioral detail: 'one request per assignment' when course_id is omitted, which informs the agent about potential multiple API calls. It does not contradict the annotations and provides additional context beyond them.
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?
The description is concise, with two main sentences and a separate Args line. The first sentence front-loads the purpose, and the second explains default behavior. The structure is slightly fragmented but not overly verbose; every sentence contributes meaning.
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?
The description covers the key behavior (listing assignments, scope control via course_id, and the multi-request implication). An output schema exists, so return structure need not be described. No critical missing information for a tool of this complexity, though it does not mention error handling or edge cases (e.g., invalid course_id), which are minor.
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?
Schema description coverage is 0%, so the description must fully explain the parameter. It does: 'course_id: restrict to one course' clearly conveys the meaning and effect. For a single optional parameter, this is sufficient and adds value beyond the schema.
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 explicitly states the tool lists assignments with specific fields (opening date, deadline, submission, grading status, description). The verb 'list' and resource 'assignments' are clear and distinguish it from siblings like moodle_list_courses or moodle_list_resources.
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?
The description explains the default behavior when course_id is omitted ('all current courses are included') and the effect of providing course_id ('restrict to one course'), giving context for usage. However, it does not explicitly mention when to prefer this tool over alternatives like moodle_get_deadlines or moodle_get_course, so usage guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
moodle_list_coursesARead-onlyIdempotent
List the user's ZHAW Moodle courses.
Args:
status: "active" (current semester, default), "past", "future" or "all"
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | active |
Output Schema
| Name | Required | Description |
|---|---|---|
| courses | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so no safety disclaimer is needed. The description adds the status-scoping behavior ('active' means current semester and is the default) and the available filters, which is useful but not extensive.
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?
At two short lines, the description is tight and front-loaded, with no filler or repetition of the schema. Every sentence contributes meaning.
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?
Given the single optional parameter, a default value, and an output schema, the description is nearly sufficient for correct invocation. The main omissions are an explicit note that authentication is required and a pointer to alternative list tools, but these are minor for such a simple read-only operation.
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?
The schema provides the status enum and default but has no descriptions, so the schema description coverage is 0%. The description compensates by clarifying that 'active' means the current semester and is the default; however, 'past', 'future', and 'all' are left to be inferred from their names.
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 opens with 'List the user's ZHAW Moodle courses,' giving a concrete verb, resource, and scope. It does not explicitly distinguish itself from sibling tools like moodle_list_resources or moodle_get_course, so it falls short of a 5.
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?
The description provides no guidance on when to choose this tool over siblings such as moodle_get_course, moodle_list_resources, or moodle_search, and no prerequisites are stated. The status parameter and its default are parameter semantics rather than usage strategy, so the tool offers no when-to-use or when-not-to-use context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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)
| Name | Required | Description | Default |
|---|---|---|---|
| course_id | Yes | ||
| include_folder_contents | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| course_id | Yes | |
| resources | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint, openWorldHint, and idempotentHint, so the agent knows the tool is safe and non-mutating. The description adds that listing folder contents requires an extra request per folder, which is useful but doesn't deeply describe other behaviors like performance or error handling. Given annotations cover safety, the description does not need to repeat it, but could add more on side effects.
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?
The description is succinct and front-loaded with the core purpose. The parameter details are listed in a clear, bullet-like format without redundancy. Every sentence serves a purpose, making it efficient and easy to scan.
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?
The tool is relatively simple with just two parameters and an output schema present, so the description doesn't need to explain return values. It covers the main functionality and parameter semantics. The only missing piece is explicit guidance on when to use this vs. alternatives, but that's a minor gap given the clear purpose.
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?
The schema has 0% description coverage, so parameters are only defined by their types and names. The description clarifies that course_id should come from moodle_list_courses, adding value beyond the schema. For include_folder_contents, it explains the meaning and the cost of an extra request per folder. This is helpful but could be even more detailed on the outcome of setting it to false.
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 clearly states the tool's purpose: listing learning materials (files, folders, links, pages) with their section. It specifies the resource types and the context (course). This distinguishes it from siblings like moodle_get_content and moodle_download_resource, which are for retrieval and download, not listing.
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?
The description implies usage: call this when you need an overview of a course's materials, and mentions the optional flag to include folder contents. However, it does not explicitly state when not to use it or name alternatives like moodle_get_content for specific content retrieval, or moodle_download_resource for downloading. The context is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| force | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| state | Yes | |
| message | Yes | |
| moodle_url | Yes | |
| authenticated | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by explaining the browser-window behavior, MFA involvement, return condition ('returns once login is detected'), and the explicit prohibition against asking for the user's password. This gives the agent a clear mental model of the tool's interactive side effects. No contradiction with readOnlyHint false, openWorldHint true, or idempotentHint true.
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?
The description is compact, front-loaded with the core purpose, and every sentence adds necessary detail. The Args section is clearly formatted and directly explains the only parameter.
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 an interactive login tool, the description covers the key operational facts: what triggers login, who performs authentication, when to use force, what causes a return, and what the agent must never do. An output schema exists, so return-value details are not needed here.
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?
The input schema only provides a title and default for 'force', but the description's Args section explains it precisely: 'open the login browser even if the current session is still valid'. This fully compensates for the 0% schema description coverage.
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 a specific action and resource: 'Log in to ZHAW Moodle', and clarifies the interaction model with 'Opens a browser window where the USER signs in with SWITCH edu-ID (incl. MFA) themselves'. It clearly distinguishes this from sibling tools by noting that other tools log in automatically when needed.
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?
The description provides clear usage context: this tool performs interactive user login, the user must sign in themselves, and the agent must never ask for a password. It also conveys that other tools handle their own authentication, which implies this tool is for explicit interactive login rather than routine use, though it does not name specific sibling alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| message | Yes | |
| logged_out | Yes | |
| server_session_invalidated | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as destructive and non-read-only; the description adds meaningful context that the local browser session and cookies are deleted and that the next request requires a new login. This goes beyond the structured annotations without contradicting them.
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?
Two short sentences with no filler. The action and consequences are front-loaded and every clause earns its place.
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 zero-parameter logout tool with output schema, annotations, and a clear behavior description, an agent has everything needed to invoke it correctly. No important gaps remain.
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?
The tool has zero parameters, so the baseline is 4. There is nothing for the description to add about parameters.
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?
Description states a specific verb ('Log out') and resource ('Moodle session'), and clarifies what happens ('delete locally stored browser session and cookies'). It clearly distinguishes from siblings like moodle_login and moodle_auth_status.
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 is provided about when to use logout versus alternatives such as moodle_login or moodle_auth_status. The description implies use when ending a session, but it does not explicitly state context, prerequisites, or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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)
| Name | Required | Description | Default |
|---|---|---|---|
| pages | No | ||
| max_chars | No | ||
| resource_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| path | Yes | Local file the text was read from |
| text | Yes | Extracted text; pages/slides are marked '--- Seite N ---' / '--- Folie N ---' |
| pages | No | Range contained in text, e.g. '1-12' |
| file_type | Yes | pdf, powerpoint, word, html or text |
| truncated | No | |
| next_pages | No | Pass as `pages` to continue reading |
| resource_id | Yes | |
| total_pages | No | Pages (PDF) or slides (PowerPoint) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations (readOnlyHint=false) are explained by the disclosed side effect 'Downloads the file first if needed', so the agent understands why this tool is not purely read-only. 'Long files come in parts: continue with next_pages' discloses pagination behavior beyond what annotations provide. No contradiction with annotations.
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?
Purpose and use case are front-loaded in the first two sentences, followed by a compact behavioral note and a dedicated Args section. Every sentence adds unique value, and the added length is fully justified by the 0% schema coverage.
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?
The output schema and annotations already cover return shape and safety profile, so the description only needs purpose, behavior, and parameters — all covered in depth. The only miss is edge-case behavior for unsupported formats or empty results, which is minor given the schema/annotation richness.
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?
Schema coverage is 0% — none of the three parameters have descriptions — so the description carries the full burden and succeeds. The Args block documents resource_id provenance plus the '<folder id>/<path>' syntax, gives concrete formats/examples for pages ('1-10', '5', '11-'), and states the valid range for max_chars (1000-100000).
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 action ('Read the text of a course file') with the supported formats listed (PDF, .pptx, .docx, HTML, text), which clearly separates it from siblings like moodle_download_resource (binary download) and moodle_get_content (listing content). The use-case sentence ('summarise or explain lecture slides, scripts and exercise sheets') further pins down intent.
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?
Tells the agent when to reach for it ('Use this to summarise or explain lecture slides, scripts and exercise sheets') and even where to source the resource_id from (moodle_list_resources, moodle_search, moodle_get_content), including folder-file syntax. It does not explicitly name when-not-to-use alternatives (e.g., moodle_download_resource for the raw binary), but the download-then-read phrasing implies that boundary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| kinds | No | ||
| limit | No | ||
| query | Yes | ||
| source | No | auto | |
| refresh | No | ||
| course_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| hits | Yes | |
| note | No | |
| query | Yes | |
| source | Yes | |
| indexed_courses | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the operation read-only, idempotent, and open-world. The description adds meaningful behavioral context: case/umlaut-insensitivity, typo tolerance, the all-words-must-match rule, refresh behavior, and the fallback logic of 'auto'. This goes beyond the annotation-provided safety profile.
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?
The description is compact and front-loaded: purpose first, then matching behavior, then a clean Args list. Every sentence earns its place and no irrelevant detail is included.
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?
Given an output schema, read-only annotations, and six parameters, the description covers matching semantics, source selection, scoping by course and kind, limit, and refresh. It provides everything an agent needs to invoke the tool correctly without requiring further inference.
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?
With schema description coverage at 0%, the description fully compensates by explaining all six parameters: query, course_id, kinds, source, limit, and refresh. Each parameter gets a concise, meaningful explanation that the bare schema does not provide.
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?
Description states a specific verb ('Search') and resource ('Moodle by name') and enumerates the exact kinds of entities covered, plus the special case of files inside folders. This is distinct from sibling list/get tools and conveys exactly what the tool does.
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?
Provides clear context for when to use the tool and, importantly, explains the three source modes ('index', 'moodle', 'auto') and when each is appropriate. It does not explicitly name sibling alternatives or exclusion conditions, but the source-selection guidance is strong enough to guide an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | ||
| update_changed | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| courses | Yes | |
| dry_run | Yes | |
| download_directory | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare non-read, idempotent, and non-destructive behavior. The description usefully adds that dry_run only reports changes without downloading, that update_changed controls re-download of changed files, and that a per-course summary is returned. The vague 'Same rules as moodle_sync_course' reference prevents a 5.
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?
The description is compact and front-loaded with the main purpose, followed by two brief parameter explanations. The only slight weakness is the cryptic 'Same rules as moodle_sync_course', though it does not add bulk.
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?
Given the output schema exists, the return summary does not need detailed explanation. The description covers action, scope, target directory, and flag semantics. The main gap is that 'Same rules as moodle_sync_course' leaves important behavioral details dependent on another tool's description.
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?
Schema description coverage is 0%, so the description fully carries the burden for parameter meaning. It clearly explains dry_run ('only report what would change, download nothing') and update_changed ('re-download files that changed on Moodle'), which is exactly what an agent needs.
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 a specific verb ('Synchronise'), a clear scope ('all active (current semester) courses'), a target ('local download directory'), and a return value ('per-course summary'). It is easily distinguished from moodle_sync_course by the 'all' scope.
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?
The description implies this is for syncing all active courses and refers to moodle_sync_course for the underlying rules, but it never explicitly says when to use this tool versus syncing a single course. 'Same rules as moodle_sync_course' gives context but not a clear routing decision.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | ||
| course_id | Yes | ||
| update_changed | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| new | No | |
| failed | No | |
| dry_run | Yes | |
| removed | No | Gone from Moodle; local files are kept |
| renamed | No | |
| updated | No | |
| restored | No | Known files missing locally, re-downloaded |
| course_id | Yes | |
| unchanged | No | |
| course_name | Yes | |
| download_directory | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses key behavioral traits: it never deletes files locally, it reports changes, and it can perform a dry run. This goes beyond the annotations, which only state readOnlyHint=false, openWorldHint=true, idempotentHint=true, destructiveHint=false. The description adds context about what the tool does and doesn't do, which is valuable. However, it doesn't mention potential side effects like network usage or disk space, but the core behavior is well covered.
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?
The description is concise and well-structured. It starts with a clear one-sentence summary, then elaborates on behavior, and finally lists parameter explanations. The parameter descriptions are formatted as a list, making them easy to scan. It could be slightly more concise by removing the Args section since the schema already lists parameters, but the added semantics justify the length.
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?
The description covers the tool's purpose, behavior, and parameter semantics. It also has an output schema, so return values are likely documented there. The description doesn't mention prerequisites like being logged in, but that's likely handled by other tools (moodle_login) and the annotations. Overall, it's complete enough for an agent to use correctly.
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?
The description explains the meaning of all three parameters: course_id (from moodle_list_courses), dry_run (only report, download nothing), and update_changed (re-download changed files). This adds value beyond the schema, which only provides types and defaults. The description clarifies the semantics of each parameter, especially dry_run and update_changed, which are not self-explanatory from the schema alone.
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 clearly states the tool's purpose: synchronise all course files into a local download directory. It specifies the action (synchronise), the resource (course files), and the target (local download directory). It also distinguishes itself from siblings by mentioning it reports changes and never deletes locally, which differentiates it from moodle_download_resource and moodle_sync_all.
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?
The description explains the tool's behavior in detail: downloads new files, re-downloads changed ones, reports changes, and never deletes locally. It also explains the dry_run parameter's effect. However, it doesn't explicitly state when to use this tool versus alternatives like moodle_sync_all or moodle_download_resource, though the behavior description implies its use case.
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.
1 tool update
v0.4.0- Added
moodle_read_file
15 tool updates
v0.3.0- First observed
moodle_auth_status - First observed
moodle_download_resource - First observed
moodle_get_announcements - First observed
moodle_get_content - First observed
moodle_get_course - First observed
moodle_get_deadlines - First observed
moodle_get_recent_changes - First observed
moodle_list_assignments - First observed
moodle_list_courses - First observed
moodle_list_resources - First observed
moodle_login - First observed
moodle_logout - First observed
moodle_search - First observed
moodle_sync_all - First observed
moodle_sync_course
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
- FlicenseAqualityCmaintenanceEnables MCP-compatible clients to read courses, assignments, announcements, files, and grades from a Canvas LMS instance.10-
- FlicenseNot gradedqualityAmaintenanceEnables MCP hosts to query NTULearn courses, announcements, calendar events, and grades, and to download course files into organized folder hierarchies.4-
- AlicenseNot gradedqualityBmaintenanceA read-only MCP server that exposes courses, assignments, calendar events, announcements, participants, and course materials from IIIT Hyderabad's Moodle instance through browser automation with persistent CAS-authenticated sessions.1MIT
- FlicenseAqualityBmaintenanceEnables students to access Moorle courses, assignments, grades, announcements, and notifications through authenticated MCP tools.11-