SkillAgentSearch skills...

Moodle-MCP

Zero-dependency MCP server for the Moodle Web Service API — read-only course, assignment, quiz, deadline and file tools for Claude, Cursor and any MCP client. Actively maintained · v1.4.0 · 10 tools · docs in 10 languages.

Install / Use

claude mcp add Faixiang -- npx -y github:Faixiang/Moodle-MCP

If the server publishes to npm under a different name, use that package instead — check the repo README.

About this skill
🔌

MCP Server

Model Context Protocol server

Quality Score

84/100

Supported Platforms

Claude Code
Claude Desktop
Cursor

Our assessment of Moodle-MCP

Moodle-MCP scores 84/100 on our quality scale, 606th of 939 AI & Machine Learning skills we index.

Its MCP Server is 14 KB long, well organised into 27 sections with 6 code examples: a thorough specification that gives an agent plenty to work with.

It has 10 GitHub stars, so there is little community track record yet; judge it on its content.

Substance
30/30
Structure
20/20
Description
15/15
Adoption
4/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated today, so Moodle-MCP is actively maintained.
  • It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 97/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

Safety scan

No issues found

Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands.

Automated pattern scan on 2026-11-02. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.

Moodle-MCP compared with similar skills

All 4 of these similar skills score higher than Moodle-MCP; compare them before choosing.

SkillScoreStarsUpdatedFormat
Moodle-MCP (this skill)by Faixiang8410todayMCP Server
claude-memby thedotmack100109.6ktodayCLAUDE.md
Agent-Reachby Panniantong100107.7k1d agoCLAUDE.md
Understand-Anythingby Egonex-AI10089.7k7d agoCLAUDE.md
headroomby headroomlabs-ai10078.6k1d agoCLAUDE.md

Frequently asked questions

How do I install Moodle-MCP?
Run claude mcp add Faixiang -- npx -y github:Faixiang/Moodle-MCP. The install tabs above show the steps for each supported agent.
Which AI agents does Moodle-MCP work with?
It is written for Claude Code, Claude Desktop and Cursor, as a MCP Server file. Other agents that read the same format can often use it too.
Is Moodle-MCP safe to use?
Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. It is MIT-licensed and scores 97/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is Moodle-MCP still maintained?
The repository was last updated today, so Moodle-MCP is actively maintained.
<div align="center"> <img src="docs/banner.svg" alt="Moodle-MCP" width="100%">

Moodle-MCP

Your Moodle, as tools an AI agent can actually use

Read assignments, deadlines and course files straight out of the Moodle Web Service API — no browser, no scraping, no clicking.

<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-yellow.svg" alt="MIT License"></a> <img src="https://img.shields.io/badge/python-3.8%2B-3772FF?logo=python&logoColor=white" alt="Python 3.8+"> <img src="https://img.shields.io/badge/MCP-2024--11--05-8A2BE2" alt="MCP 2024-11-05"> <img src="https://img.shields.io/badge/Moodle-3.x%20%7C%204.x-F98012?logo=moodle&logoColor=white" alt="Moodle 3.x / 4.x"> <img src="https://img.shields.io/badge/dependencies-0-success" alt="Zero dependencies"> <a href="https://github.com/Faixiang/Moodle-MCP/stargazers"><img src="https://img.shields.io/github/stars/Faixiang/Moodle-MCP?style=social" alt="GitHub stars"></a> <img src="https://img.shields.io/badge/version-1.4.0-1f6feb" alt="Version 1.4.0"> <img src="https://img.shields.io/badge/status-actively%20maintained-brightgreen" alt="Actively maintained">

<p> <b>English</b> · <a href="README.zh-CN.md">简体中文</a> · <a href="README.zh-TW.md">繁體中文</a> · <a href="README.ja.md">日本語</a> · <a href="README.ko.md">한국어</a> · <a href="README.es.md">Español</a> · <a href="README.fr.md">Français</a> · <a href="README.de.md">Deutsch</a> · <a href="README.pt-BR.md">Português</a> · <a href="README.ru.md">Русский</a> </p> </div>

Companion skill — moodle-course-watch This server is the plumbing; the skill is the workflow on top of it. It diffs new coursework, mirrors missing week folders, lists what is still unsubmitted, and walks through the downloaded files with graded key points. It is mounted as a git submodule in this repository at skill/moodle-course-watch/ (clone with --recurse-submodules), and is also a standalone repo for anyone who wants only the skill.


Actively maintained. Latest release v1.3.0 (2026-10-27): quizzes are no longer a blind spot — moodle_quiz_status reads real attempt state and scores. Full changelog at the end of this file.

Preview 🖥️

<img src="docs/preview.svg" alt="Example MCP session" width="100%">

Why this exists 🎯

Moodle powers a large share of universities and colleges worldwide, yet it had no general-purpose MCP server. Scraping it with a headless browser is slow, brittle and tends to trip WAFs — while Moodle itself already ships a stable, documented REST API.

This project is the missing wrapper: one zero-dependency Python file, ten read-only tools, working against any Moodle 3.x/4.x site with Web Services enabled.

No pip install. No node. No browser. Just python server.py.

Features ✨

Data retrieval

  • Deadline-aware — assignments split into due soon, overdue and no pressure, with days remaining computed for you
  • Weekly digest — recent additions + deadlines + overdue in a single call, formatted for direct reading
  • Course files — section structure and file lists with direct download URLs and modified times, metadata only, nothing downloaded
  • Diagnostics built in — moodle_site_info reports site version, account identity and which functions your token may actually call

Engineering

  • Zero dependencies — Python standard library only (urllib, json, ssl), so nothing pollutes your runtime
  • Single file — copy server.py anywhere; no package layout, no build step
  • stdio JSON-RPC 2.0 — drops into Claude Desktop, Cursor, Marvis or any MCP-compatible client
  • WAF-friendly — serialised calls with a 150 ms gap, because hammering Moodle gets you 502
  • Read-only by design — no submit, enrol, edit or delete endpoint exists in the code

Tools 🧰

| Tool | What it does | Arguments | |---|---|---| | moodle_setup_guide | Step-by-step guide for getting a Moodle web-service token and wiring it into this server (browser UI path, SSO caveat, config.json and environment-variable options). Needs no token, so it always works. Call it on first setup or after a TOKEN_MISSING error. | — | | moodle_config_status | Self-check of the local configuration: config.json path, existence and parse result, MOODLE_URL / MOODLE_TOKEN environment variables, effective URL, where the token came from and its length. The token itself is masked to the first 4 characters. Needs no token. | — | | moodle_site_info | Validate the token, return site name, Moodle version, current user and the list of web-service functions the account may call (diagnostics). | — | | moodle_list_courses | List every enrolled course with id, shortname and fullname. | — | | moodle_recent_updates | Content added or updated in the last N days (assignments, files, announcements), newest first. | days (default 7), course_ids | | moodle_pending_assignments | Unsubmitted assignments, split into due soon / overdue / no pressure, with deadline and days remaining. | ahead_days (default 14), course_ids | | moodle_quiz_status | Per-quiz attempt state straight from mod_quiz_get_user_attempts: submitted / in progress / never started, with best score, open–close window, time limit and a window closed flag. | course_ids, only_pending | | moodle_course_files | Section structure and file list for one course, including direct download URLs and modified times. Metadata only — nothing is downloaded. | course_id | | moodle_download_week | Download one week's files (slides + assignment attachments) into a local folder named after the section — Week N when the section title carries a week number, otherwise the section's own title (Online Judge Questions, Project Submission). Creates folders, verifies sizes, skips files already present. Omit dest_root to get the list only. | course_id, week (e.g. 6 or "Week 6", or all), dest_root | | moodle_weekly_digest | The one-shot summary: recent additions + due-soon + overdue + counts. Best starting point. | days (default 7), ahead_days (default 14) |

moodle_download_week only writes to your local disk — it never submits anything to Moodle. File URLs returned by the read tools already carry your token, so they download as-is: treat them as secrets and keep them out of logs, screenshots and public repos.

Requirements 📦

| Component | Notes | |---|---| | Python | 3.8+ (standard library only) | | MCP protocol | 2024-11-05 | | Moodle | 3.x / 4.x with Web Services + REST protocol enabled | | Account | Holds the webservice/rest:use capability | | Verified against | Moodle 4.3.6, full 435-function grant |

Quick start 🚀

① Get a token

Moodle needs a personal access token. Pick whichever works for your site:

A. Web UI (recommended, works with SSO accounts)

  1. Log in to your Moodle site
  2. Avatar → Preferences → Account → Security → Manage access keys
  3. Create, name it Moodle-MCP, service = Moodle mobile web service
  4. Copy the token

B. Mobile-app service via script (only if your site has local passwords)

python get_token.py

Walks through /login/token.php with the moodle_mobile_app service and validates the result. Password input is hidden and never logged. If your account is SSO-only this returns invalidlogin — use method A instead.

C. Environment variables

MOODLE_URL=https://moodle.your-school.edu
MOODLE_TOKEN=your_token_here

② Configure

Create config.json next to server.py (or copy config.example.json):

{
  "url": "https://moodle.your-school.edu",
  "token": "your_token_here"
}

Environment variables take precedence over the file.

③ Register the server

Claude Desktop / Cursor (mcp.json):

{
  "mcpServers": {
    "moodle": {
      "command": "python",
      "args": ["/absolute/path/to/Moodle-MCP/server.py"]
    }
  }
}

Use an absolute path to server.py. If you have several Python installs, point command at the full interpreter path.

④ Verify

Ask your client to call moodle_site_info. A working setup returns the site name, Moodle version and your user record. If it fails, jump to Troubleshooting.

Configuration reference ⚙️

| Key | Type | Required | Description | |---|---|---|---| | url / MOODLE_URL | string | yes | Base URL of your Moodle site, no trailing path | | token / MOODLE_TOKEN | string | yes | Personal access token from Manage access keys | | config.json | file | optional | Read from the directory containing server.py |

Precedence: environment variables → config.json → error.

Usage examples 💬

"What do I still owe this week?"

The agent calls moodle_weekly_digest and gets back a ready-to-read brief:

## Due in the next 7 days, not submitted
| CIS225 Data Structures | A10021 Crosswords  | 2026-10-29 23:59 | 3 days |
| CIS225 Data Structures | A10022 Cow Jogging | 2026-10-29 23:59 | 3 days |

## Overdue
| CIS225 Data Structures | A10009 Dancing | 2026-10-11 23:59 | 15 days late |

## Totals
Submitted/graded: 51 | Outstanding: 25 (due soon 4, overdue 14, other 7)

Other prompts that work well:

| Prompt | Tool it lands on | |---|---| | "What new material appeared in CIS225 this week?" | moodle_recent_updates | | "List the files in GER405, don't download anything" | moodle_course_files | | "Which of my courses have nothing overdue?" | moodle_pending_assignments | | "Is my token still valid?" | moodle_site_info |

Troubleshooting 🤔

<details> <summary><b><code>invalidlogin</code> when running get_token.py</b></summary>

Your account authenticates through SSO/OIDC only, so /login/token.php has no local password to check. Use method A — create the token in Manage access keys instead.

</details> <details> <summary><b><code>502</code> or connection reset during a call</b></summary>

The site's WAF is rate-limiting you. This server already serialises calls and pauses 150 ms between them; if you still hit it, wait a few minutes and retry, and avoid firing several tools in parallel.

</details> <details> <summary><b>Tools return empty lists</b></summary>

Check three things: Web Services and the REST protocol are enabled site-wide; the account has webservice/rest:use; and any course_ids filter you passed is correct. Run moodle_site_info first — if the function list is short, the admin restricted your grant to the mobile subset.

</details> <details> <summary><b>Turnitin deadlines are missing</b></summary>

Expected. turnitintooltwo is its own module without mod_assign semantics and exposes no usable deadline field, so it is the one remaining blind spot. Check those in the web UI.

</details> <details> <summary><b>Quiz deadlines are missing from <code>moodle_weekly_digest</code></b></summary>

By design. Quizzes live in mod_quiz, not mod_assign, so they have their own tool: moodle_quiz_status returns attempt state, best score and the open–close window for every quiz.

</details> <details> <summary><b>A deadline shows as "not set"</b></summary>

The teacher never configured a due date for that assignment. There is nothing to compute; the item still appears so you don't forget it exists.

</details> <details> <summary><b>Garbled characters in Windows terminals</b></summary>

Output is UTF-8. In legacy consoles run chcp 65001 first, or use Windows Terminal.

</details>

Security notes 🔒

  • The token is a credential. Store it in config.json or an environment variable, never in a repo. .gitignore already excludes config.json and get_token.log.
  • get_token.py never logs the password — only its length — and reads it with getpass.
  • Every tool is read-only by design, so a leaked token cannot modify or delete coursework through this server. Revoke it from *Manage access ke

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars10
CategoryAI
Updated13h ago
Forks0

Languages

Python

Trust signals

97/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

1 info