Read-only Moodle toolkit for agents, MCP servers, and local scripts
This project has been archived.
The maintainers of this project have marked this project as archived. No new releases are expected.
Project description
moodle-study-kit
Read-only Moodle toolkit for students and agents. Provides a Python library, CLI, and MCP server for accessing Moodle course data without any write operations.
Quick start
Install
Pick whichever tool you already have:
uv tool install moodle-study-kit # recommended — adds moodle-study to PATH automatically
pipx install moodle-study-kit # alternative
pip install moodle-study-kit # if you just want the library, or don't have uv/pipx
Windows note: If moodle-study is not recognised after pip install, the Python
Scripts folder may not be on your PATH. Either:
-
Add it manually — find the path with:
py -c "import site; print(site.getusersitepackages())"Then add that directory to your PATH in Windows Settings > System > Environment Variables.
-
Or use the module form directly (works immediately, no PATH changes needed):
py -m moodle_study_kit.cli courses
Set up credentials
moodle-study setup
The setup command will prompt for your Moodle URL, API token, and user ID, then verify the connection and save credentials. See Getting a Moodle API token below if you don't have a token yet.
Non-interactive setup (for scripts and agents):
moodle-study setup --url https://moodle.example.ac.uk --token YOUR_TOKEN
Getting a Moodle API token
Via the Moodle web interface (recommended)
- Log in to your Moodle site in a browser.
- Click your profile picture (top right) → Preferences.
- Under User account, click Security keys.
- Find the Moodle mobile web service row.
- Click Reset to generate a new token (or copy the existing one if shown).
- Copy the token string — this is the long alphanumeric value you need for setup.
Tip: Copy the token value itself (a long string of letters and numbers), not the key name like "Webservice-A3JsY" shown in the table.
Via the token URL (advanced)
If the method above doesn't work for your institution, you can request a token directly:
https://<your-moodle>/login/token.php?username=YOUR_USER&password=YOUR_PASS&service=moodle_mobile_app
Note: Only use this over HTTPS. Never share your token.
Configuration
Credentials are resolved in this order:
- Explicit arguments passed to
MoodleConfig.load(url=..., token=...) - Environment variables:
MOODLE_URL,MOODLE_TOKEN,MOODLE_USERID - Config file (first found):
$MOODLE_CREDS_PATH(if set)- Platform-native config directory (see below)
~/.moodle_creds.json(legacy fallback)
The config directory is determined by platformdirs so it follows each OS's conventions: ~/.config/moodle-study-kit/ on Linux, ~/Library/Application Support/moodle-study-kit/ on macOS, and %APPDATA%\moodle-study-kit\ on Windows. Run moodle-study config to see the active path on your system, or moodle-study config --json for machine-readable output. Existing ~/.moodle_creds.json files are still read as a fallback.
Config file format
{
"url": "https://moodle.example.ac.uk",
"token": "your_token_here",
"userid": 12345
}
Environment variables
export MOODLE_URL="https://moodle.example.ac.uk"
export MOODLE_TOKEN="your_token_here"
export MOODLE_USERID="12345"
CLI usage
moodle-study courses # List enrolled courses
moodle-study deadlines # Show upcoming deadlines (14-day window)
moodle-study deadlines --days 7 # Shorter look-ahead
moodle-study contents 12345 # Show sections for course ID 12345
moodle-study contents EC100 # Look up by course short-code
moodle-study contents MG488 # Prefix match: finds MG488_2526 if unique
moodle-study contents EC100 --week 3 # Filter to a specific week
moodle-study materials EC100 # List all downloadable materials (discovery)
moodle-study materials EC100 --week 3 # Materials for week 3 only
moodle-study download EC100 --week 3 --match slides # Download a file (authenticated)
moodle-study download EC100 --week 3 --index 0 # Download by index
moodle-study summary EC100 --week 3 # AI-generated study notes for a week
moodle-study setup # Guided first-time setup
moodle-study update # Show the safe upgrade command
Add --json before the command for machine-readable JSON output:
moodle-study --json courses
moodle-study --json deadlines
MCP server
For use with Claude Code, OpenClaw, or other MCP-capable agents:
pip install "moodle-study-kit[mcp]"
python -m moodle_study_kit.mcp_server
The server runs as a stdio-based MCP server. Tools: list_courses, get_deadlines, get_course_contents, get_week_materials (discovery), search_course_content, get_weekly_summary, download_material (authenticated fetch).
Claude Code: Add to your Claude Code settings / MCP Servers config:
{
"mcpServers": {
"moodle-study-kit": {
"command": "python",
"args": ["-m", "moodle_study_kit.mcp_server"]
}
}
}
Set MOODLE_URL, MOODLE_TOKEN, MOODLE_USERID as environment variables or in ~/.config/moodle-study-kit/config.json.
OpenClaw: Add to your agent or gateway config:
mcpServers:
moodle:
command: python
args: ["-m", "moodle_study_kit.mcp_server"]
env:
MOODLE_URL: "https://your-moodle.example.ac.uk"
MOODLE_TOKEN: "your_token_here"
MOODLE_USERID: "12345"
CI
Packaging and install smoke tests run automatically on every push and pull request across Linux, macOS, and Windows. The workflow builds both sdist and wheel, installs each in a clean virtual environment, and verifies the CLI entrypoints work.
Development
To work on moodle-study-kit itself (contributors / developers):
git clone <repo-url> && cd moodle-study-kit
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e '.[dev]'
Running tests
pytest
# On Windows, if pytest isn't found on PATH:
py -m pytest
Safety
This package is read-only by design. Every Moodle API call is checked against a hardcoded allowlist in ALLOWED_FUNCTIONS inside the client module. Write-like operations — submitting assignments, posting forum replies, uploading files, creating events, deleting content — are blocked with a SafetyError before any network request is made.
- Your token cannot modify anything on Moodle, even accidentally.
- Agents (Claude Code, OpenClaw, etc.) can use these tools safely.
- Treat your Moodle API token like a password: never commit it to git, never share it, use HTTPS only.
Known limitations
- Token portability varies by institution. Some Moodle instances require specific web-service configurations. Check with your Moodle administrator about enabling REST web services.
- Rate limiting. Moodle servers may throttle rapid API calls. The package handles errors gracefully but cannot bypass institutional limits.
- Only Moodle REST API v2 is supported.
- Course discovery by short-code uses prefix matching (e.g. "MG488" matches "MG488_2526") — see CLI usage above.
For Agent Authors
moodle-study-kit is designed to be agent-friendly:
- Zero configuration needed for discovery — call
list_courses()with no arguments to explore. - Self-documenting tool names and clear purpose descriptions.
- Structured output by default — use
--jsonon CLI, or rely on structured dict/JSON from the Python API. - Graceful degradation with clear error messages when credentials are missing.
Discovery vs. download
There are two distinct steps — discovery and download — with separate commands for each:
| Purpose | CLI | MCP tool |
|---|---|---|
| List available files (metadata only) | moodle-study materials |
get_week_materials() |
| Download a file (authenticated) | moodle-study download |
download_material() |
materials / get_week_materials return metadata including a file_url field. This URL is the raw Moodle address retained for provenance only — do not fetch it directly, as it requires token authentication that is handled internally by download / download_material.
Downloading materials
The download command (CLI) and download_material tool (MCP) provide authenticated file downloads without exposing the Moodle token. The flow:
- Discover materials:
moodle-study materials EC100 --week 3 - Download one:
moodle-study download EC100 --week 3 --match slides
If multiple materials match, you get a structured candidate list with indices:
moodle-study --json download EC100 --week 3
# → {"error": "3 materials match. Use --index ...", "candidates": [...]}
moodle-study --json download EC100 --week 3 --index 0
# → {"local_path": "/path/to/week3_slides.pdf", "file_name": "week3_slides.pdf", ...}
The same workflow is available via MCP:
get_week_materials(course_id=42, week="3") # discover
download_material(course_id=42, week="3", match="slides") # fetch
Example integration in an agent system prompt:
You have access to moodle-study-kit. First run list_courses() to see available courses,
then get_deadlines() to check upcoming work, then explore specific courses with
get_course_contents(). To see what files are available, use get_week_materials(). To
fetch a file, use download_material() — it handles authentication internally. Never
fetch file_url values directly; always use download_material().
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file moodle_study_kit-0.2.6.tar.gz.
File metadata
- Download URL: moodle_study_kit-0.2.6.tar.gz
- Upload date:
- Size: 81.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b5ec4c977f593fec0624063be66229c3c4ab131aca5f48c792ce2164bc1a96c
|
|
| MD5 |
a271ff4fa25522701418238d429f215f
|
|
| BLAKE2b-256 |
d7b90dd7cbdd4992c5f7cb2e9608a7165a659511b2119a5711bb231b3f6fcab3
|
File details
Details for the file moodle_study_kit-0.2.6-py3-none-any.whl.
File metadata
- Download URL: moodle_study_kit-0.2.6-py3-none-any.whl
- Upload date:
- Size: 49.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba3d05e1d2ed02888d1dd34524112cf0a5d9e1482137b586c10f2918e3c6baa2
|
|
| MD5 |
36426f5dec30f8256435400ff01426e4
|
|
| BLAKE2b-256 |
40fd465001d7f81eecd97841f48f5dc89cfccc7c6977ffd42bcb46b5e87e8f41
|