moodle-mcp
moodle-mcp
A Model Context Protocol (MCP) server that connects AI coding agents — Hermes, Claude Code, and OpenCode — to your Moodle LMS. Fetch assignments, grades, deadlines, and sync everything to Obsidian automatically.
✨ Features
📚 Courses & Content
Tool | Description |
| Get all courses the current user is enrolled in |
| Get sections and modules for a specific course |
| Search across all course materials by query string |
| Get announcements from course news forums |
| Get recent activity across courses since a given time |
| Check for new materials or announcements added recently |
📝 Assignments & Deadlines
Tool | Description |
| Get assignments, optionally filtered by course or class slot |
| Get submission and grading status for an assignment |
| Upcoming deadlines sorted by due date |
| Unsubmitted assignments past their due date |
| Prioritized task list sorted by urgency |
| Full analysis: status, requirements, materials, deadline |
| Extract deliverables and evaluation criteria |
| Find course content relevant to an assignment |
| Break assignment into subtasks with critical path |
| Step-by-step plan with timeline, resources, milestones |
| Submit a text-based assignment answer |
| Get feedback and rubric results for a submission |
📊 Grades & Progress
Tool | Description |
| Grade overview for all courses, or detailed for one course |
| Completion progress for one or all courses |
| Health check: progress, grades, unsubmitted/overdue counts |
| Assignment distribution by week (spot heavy weeks) |
| Detailed submission info and feedback |
📅 Calendar & Events
Tool | Description |
| Upcoming events from Moodle |
| Create a personal reminder in the Moodle calendar |
| Check completion status for a specific activity |
| Mark an activity as complete |
🗂️ Aggregated Overviews
Tool | Description |
| Combined overview of courses, deadlines, and grades |
| Daily summary: overdue, today's deadlines, recent grades |
| Weekly summary: submitted, graded, overdue, progress |
| Ask a natural language question, routed to the right data |
🗒️ Obsidian Sync
Tool | Description |
| Sync dashboard, deadlines, grades, and course notes to Obsidian. Auto-archives the previous semester when courses change |
| Export only deadline notes |
| Export a course's full outline as a note |
| List all downloadable files in a course |
| Download all materials to Obsidian/Materials/ |
| Download files attached to an assignment |
🔄 Semester Auto-Archive
When sync_moodle_to_obsidian detects that your Moodle courses have changed significantly (i.e., you moved to a new semester), it automatically archives the previous semester's notes before overwriting:
Obsidian Vault/Academic/
Moodle/ ← always up-to-date (current semester)
.semester_courses.json ← state file (hidden, tracks course IDs)
Dashboard.md
Deadlines.md
Grades.md
Courses/
Archive/
Semester-2026-07/ ← auto-created on semester rollover
Dashboard.md ← snapshot of old semester
Courses/ ← all old course notes preserved
Grades.md
Archive-README.md ← log of what changed and whenTrigger logic: archive fires when >50% of known course IDs are replaced (or all are new). Minor changes (e.g., 1 course dropped/added) are ignored.
🚀 Quick Install
A single install script handles all supported CLI agents automatically:
curl -fsSL https://raw.githubusercontent.com/doomscrollsurvivor/moodle-mcp/main/scripts/install-mcp.sh | bashOr clone first and run locally:
git clone https://github.com/doomscrollsurvivor/moodle-mcp.git
cd moodle-mcp
bash scripts/install-mcp.shThe script detects which agents are installed and configures each one. See scripts/install-mcp.sh for full details.
⚙️ Manual Setup
1. Prerequisites
Python ≥ 3.10
uv(recommended) orpipA Moodle account with Web Services enabled
2. Get Your Moodle Token
Go to
https://<your-moodle-url>/user/managetoken.phpFind the row with Moodle mobile web service in the
ServicecolumnCopy the token
3. Create .env
cp .env.example .envEdit .env:
MOODLE_URL=https://your-moodle-url.example.com/webservice/rest/server.php
MOODLE_TOKEN=your_token_here
# Optional — filter assignments to your own class (Polibatam multi-class fix)
MOODLE_MY_CLASS=Pagi C
# Optional — custom Obsidian vault path
OBSIDIAN_VAULT_PATH=/home/yourname/Obsidian Vault4. Install the Package
# With uv (recommended)
uv pip install -e .
# Or with pip
pip install -e .5. Configure Your Agent
Jump to the section for your agent:
🤖 Hermes Agent
Hermes uses a local Python launcher script for MCP. This is the recommended setup for the akademik profile.
Auto-configure (recommended)
bash scripts/install-mcp.sh --agent hermes --profile akademikManual configure
Copy the launcher:
mkdir -p ~/.hermes/scripts
cp scripts/moodle_mcp_local_launch.py ~/.hermes/scripts/Add to
~/.hermes/profiles/akademik/config.yaml(or~/.hermes/config.yamlfor default):
mcpServers:
moodle:
command: python3
args:
- /home/<you>/.hermes/scripts/moodle_mcp_local_launch.py
env:
MOODLE_URL: "https://your-moodle-url/webservice/rest/server.php"
MOODLE_TOKEN: "your_token_here"
MOODLE_MY_CLASS: "Pagi C"
OBSIDIAN_VAULT_PATH: "/home/<you>/Obsidian Vault"Verify:
hermes --profile akademik mcp test moodleExpected output: ✓ Connected ✓ Tools discovered: 40
🤖 Claude Code
Claude Code reads MCP config from .claude/settings.json (project-level) or ~/.claude/settings.json (global).
Auto-configure
bash scripts/install-mcp.sh --agent claude-codeManual configure — Global
claude mcp add -s user moodle-mcp -- python3 /path/to/moodle-mcp/src/moodle_mcp/server.pyThen set env vars by editing ~/.claude.json (or use the script).
Manual configure — JSON
Add to ~/.claude/settings.json:
{
"mcpServers": {
"moodle-mcp": {
"command": "uvx",
"args": ["moodle-mcp"],
"env": {
"MOODLE_URL": "https://your-moodle-url/webservice/rest/server.php",
"MOODLE_TOKEN": "your_token_here",
"MOODLE_MY_CLASS": "Pagi C",
"OBSIDIAN_VAULT_PATH": "/home/<you>/Obsidian Vault"
}
}
}
}Or to use local source (no PyPI needed):
{
"mcpServers": {
"moodle-mcp": {
"command": "python3",
"args": ["/path/to/moodle-mcp/scripts/moodle_mcp_local_launch.py"],
"env": {
"MOODLE_URL": "https://your-moodle-url/webservice/rest/server.php",
"MOODLE_TOKEN": "your_token_here"
}
}
}
}Verify
claude mcp listIn a Claude Code session: ask "list my Moodle courses" — it should call get_my_courses.
🤖 OpenCode
OpenCode reads MCP config from ~/.config/opencode/config.json or a project-level opencode.json.
Auto-configure
bash scripts/install-mcp.sh --agent opencodeManual configure
Edit ~/.config/opencode/config.json:
{
"mcp": {
"moodle-mcp": {
"command": "python3",
"args": ["/path/to/moodle-mcp/scripts/moodle_mcp_local_launch.py"],
"environment": {
"MOODLE_URL": "https://your-moodle-url/webservice/rest/server.php",
"MOODLE_TOKEN": "your_token_here",
"MOODLE_MY_CLASS": "Pagi C",
"OBSIDIAN_VAULT_PATH": "/home/<you>/Obsidian Vault"
}
}
}
}Verify
opencode run "list all my Moodle courses"🖥️ Claude Desktop / Cursor
Go to Claude → Settings → Developer → Edit Config and open claude_desktop_config.json:
{
"mcpServers": {
"moodle-mcp": {
"command": "uvx",
"args": ["moodle-mcp"],
"env": {
"MOODLE_URL": "https://your-moodle-url/webservice/rest/server.php",
"MOODLE_TOKEN": "your_token_here"
}
}
}
}Restart Claude Desktop. The Moodle tools will appear in the tool picker.
🔌 Advanced: Local Source (No PyPI)
To use the cloned repo directly (useful for development or custom forks):
# From the repo root, install in editable mode
uv pip install -e .
# Then use the local launcher script in MCP configs:
# command: python3
# args: ["/path/to/moodle-mcp/scripts/moodle_mcp_local_launch.py"]The launcher automatically sets PYTHONPATH so the local src/ is used instead of the installed package.
🛡️ Security Notes
Never commit your
.envfile. It contains your Moodle token which grants full API access.Tokens are loaded server-side — they are never sent to the AI model directly.
The
.envfile is in.gitignoreby default.For CI/CD, inject
MOODLE_URLandMOODLE_TOKENas environment secrets.
📖 API Reference
Full Moodle Web Service API: Moodle Dev Docs
🤝 Contributing
Fork the repo
Create a feature branch
Write tests (TDD preferred — run
PYTHONPATH=src python -m unittest discover -s tests -v)Open a PR
🙏 Acknowledgements
This project is a fork of loyaniu/moodle-mcp with extended features. Full credit to all original contributors:
Contributor | Role |
Zhonglin Niu (loyaniu) | Original author — created the project, Moodle REST API integration, core MCP server |
Comprehensive Moodle student dashboard tools (semester overview, study load, health checks) | |
Bug fixes for course content paths and search; README improvements | |
MseeP.ai security assessment badge |
Additions in this fork
Phase 2 — Obsidian sync (
sync_moodle_to_obsidian,export_deadlines_to_obsidian,export_course_outline)Phase 3 — Material downloads (
list_course_material_files,download_course_materials,download_assignment_attachments)Phase 4 — Assignment submission and feedback tools
Phase 6 — Calendar events and activity completion tracking
Polibatam class-slot filter — regex-based multi-class assignment filtering (
MOODLE_MY_CLASS)Concurrent fetch — 10× speedup for actionable tasks via ThreadPoolExecutor
Semester auto-archive — detects course rollover and archives the previous semester's Obsidian notes automatically
Universal install script — one-command setup for Hermes, Claude Code, and OpenCode
📄 License
MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/doomscrollsurvivor/moodle-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server