moodle-mcp
moodle-mcp
Model Context Protocol server for Moodle LMS — connect Hermes, Claude Code, and OpenCode to your Moodle. Fetch assignments, grades, and deadlines, sync to Obsidian, and get WhatsApp alerts.
Overview • Features • Quick Start • Configuration • Agent Setup • Tools • Obsidian Sync
Overview
moodle-mcp bridges the Moodle Web Services API with the Model Context Protocol, so AI agents can act as your academic assistant. It was built for Polibatam (multi-class filtering) but works with any Moodle instance that has Web Services enabled.
Fork of loyaniu/moodle-mcp — extended from 22 to 40 tools with Obsidian sync, material downloads, submission tools, calendar integration, concurrent fetching, and semester auto-archive.
Works with any Moodle LMS — just pointMOODLE_URL at your instance. The Polibatam class filter (MOODLE_MY_CLASS) is optional.
Features
Assignments & deadlines — filtered by class slot, sorted by urgency, with actionable task lists
Grades & progress — course health checks, study load, and completion tracking
Course content & search — sections, modules, materials, announcements, recent activity
Obsidian sync — one-command export of dashboards, deadlines, and course notes (with semester auto-archive)
Material downloads — list and download course files and assignment attachments
Submissions — submit text, check status, and read feedback
Calendar — upcoming events, create reminders (H-2), mark activities complete
Agent-ready — single
install-mcp.shfor Hermes, Claude Code, and OpenCode
Quick Start
One-line install
curl -fsSL https://raw.githubusercontent.com/zuckdorsey/moodle-mcp/main/scripts/install-mcp.sh | bashAuto-detects installed agents and configures each one. For a dry run:
bash scripts/install-mcp.sh --dry-runVerify
# Hermes (profile: akademik)
hermes --profile akademik mcp test moodle
# → ✓ Connected ✓ Tools discovered: 40
# Claude Code
claude mcp list
# Run tests
PYTHONPATH=src .venv/bin/python -m unittest discover -s tests -vPrefer local source over PyPI when developing — the launcher setsPYTHONPATH to src/ automatically.
Configuration
1. Get your Moodle token
Open
https://<your-moodle>/user/managetoken.phpFind the row with Moodle mobile web service in
ServiceCopy the token
2. Create .env
cp .env.example .envMOODLE_URL=https://your-moodle.example.com/webservice/rest/server.php
MOODLE_TOKEN=your_token_here
# Optional — Polibatam class-slot filter (e.g. Pagi C, Siang A)
MOODLE_MY_CLASS=Pagi C
# Optional — custom vault path
OBSIDIAN_VAULT_PATH=/home/you/Obsidian VaultVariable | Required | Description |
| yes | Moodle REST endpoint ( |
| yes | Mobile web service token |
| no | Regex filter for multi-class assignment titles |
| no | Vault root (default: |
3. Install package
# with uv (recommended)
uv pip install -e .
# or pip
pip install -e .Never commit.env — it contains a token with full API access. It is already in .gitignore.
Agent Setup
Pick your agent — all use the same local launcher at scripts/moodle_mcp_local_launch.py.
Hermes Agent (recommended)
bash scripts/install-mcp.sh --agent hermes --profile akademikManual (~/.hermes/profiles/akademik/config.yaml):
mcp_servers:
moodle:
command: /home/you/Programming/Python/moodle-mcp/.venv/bin/python
args: [/home/you/Programming/Python/moodle-mcp/scripts/moodle_mcp_local_launch.py]
env:
MOODLE_URL: ${MOODLE_URL}
MOODLE_TOKEN: ${MOODLE_TOKEN}
MOODLE_MY_CLASS: "Pagi C"
OBSIDIAN_VAULT_PATH: "/home/you/Obsidian Vault"Claude Code
bash scripts/install-mcp.sh --agent claude-code
# or manually
claude mcp add -s user moodle-mcp -- python3 /path/to/moodle-mcp/scripts/moodle_mcp_local_launch.pyGlobal JSON (~/.claude/settings.json):
{
"mcpServers": {
"moodle-mcp": {
"command": "python3",
"args": ["/path/to/moodle-mcp/scripts/moodle_mcp_local_launch.py"],
"env": {
"MOODLE_URL": "https://your-moodle/webservice/rest/server.php",
"MOODLE_TOKEN": "your_token_here"
}
}
}
}OpenCode
bash scripts/install-mcp.sh --agent opencode~/.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/webservice/rest/server.php",
"MOODLE_TOKEN": "your_token_here"
}
}
}
}Claude Desktop / Cursor
Add to claude_desktop_config.json:
{
"mcpServers": {
"moodle-mcp": {
"command": "uvx",
"args": ["moodle-mcp"],
"env": {
"MOODLE_URL": "https://your-moodle/webservice/rest/server.php",
"MOODLE_TOKEN": "your_token_here"
}
}
}
}Restart the desktop app — tools appear in the picker.
Tools
40 tools across 7 groups. Call them by name from any connected agent (e.g. "list my Moodle courses" → get_my_courses).
Tool | Description |
| Enrolled courses |
| Sections & modules for a course |
| Search across all materials |
| News forum announcements |
| Recent activity since timestamp |
| New materials/announcements |
Tool | Description |
| Assignments (class-slot filtered) |
| Submission & grading status |
| Deadlines sorted by due date |
| Past-due, unsubmitted |
| Prioritized urgency list |
| Status + requirements + materials |
| Deliverables & criteria |
| Content relevant to assignment |
| Subtasks with critical path |
| Timeline, resources, milestones |
| Submit text answer |
| Feedback & rubric results |
Tool | Description |
| Overview or per-course detail |
| Completion progress |
| Health check (progress + grades + overdue) |
| Assignment distribution by week |
| Detailed submission & feedback |
Tool | Description |
| Upcoming Moodle events |
| Create H-2 reminder |
| Completion status |
| Mark activity complete |
Tool | Description |
| Courses + deadlines + grades |
| Overdue, today, recent grades |
| Submitted, graded, overdue, progress |
| Natural language routing |
| Course change detection |
Tool | Description |
| Full vault sync (auto-archive on semester rollover) |
| Deadlines only |
| Course outline as note |
| List downloadable files |
| Download to |
| Download assignment files |
Try:"what's due this week?" → get_upcoming_deadlines, "analyze tugas basis data" → analyze_assignment, "sync ke Obsidian" → sync_moodle_to_obsidian.
Obsidian Sync
Sync creates notes under Academic/Moodle in your vault:
Obsidian Vault/Academic/
Moodle/ ← current semester (always up-to-date)
.semester_courses.json ← hidden state (course IDs)
Dashboard.md
Deadlines.md
Grades.md
Courses/
Archive/
Semester-2026-07/ ← auto-created on rollover
Dashboard.md
Courses/
Archive-README.mdSemester auto-archive triggers when >50% of course IDs change (or all are new). A single-course swap is ignored.
PYTHONPATH=src python - <<'PY'
from moodle_mcp import api
print(api.sync_moodle_to_obsidian())
PYSecurity Notes
Your Moodle token grants full API access as your user. Treat it like a password.
Tokens are loaded server-side and never sent to the model.
Inject
MOODLE_URL/MOODLE_TOKENas environment secrets in CI.moodle.pyuses browser-likeUser-Agent+ POST for Cloudflare compatibility.
Acknowledgements
Fork of loyaniu/moodle-mcp — credit to all original contributors:
Contributor | Role |
Original author, Moodle REST integration, core server | |
Dashboard, study load, health checks | |
Course content & search fixes | |
Security assessment badge |
Additions in this fork
Obsidian sync + semester auto-archive
Material downloads & assignment attachments
Submission & feedback tools, calendar & completion
Polibatam class-slot filter (
MOODLE_MY_CLASS)Concurrent fetch (~10× faster actionable tasks)
Universal
install-mcp.shfor Hermes / Claude Code / OpenCode