Skip to main content

MCP server exposing a Moodle site as 86 typed AI tools: read courses, grades and deadlines; build courses, quizzes, questions and content.

Project description


Table of contents


What it does

Moodle is the learning platform used by thousands of universities and schools. MCP-Moodle connects it to any Model Context Protocol client — Claude Desktop, Gemini CLI, ChatGPT desktop, Cursor, VS Code, and more — so an AI can:

  • Read: list courses, inspect course contents, see enrolled students, quizzes, grades, quiz results, activity completion, notifications, and competencies.
  • Build: create courses, users, categories, groups, enrolments, and actual content: pages, books, labels, URLs, forums, assignments, quizzes, and six quiz question types — or a whole course from one JSON outline with build_course.
  • Protect: back any course up to a real .mbz file on your disk and restore it later.
  • Safely: every write operation is off by default and only enabled with an explicit flag.

How it works (two pieces)

Moodle's built-in Web Services API can create courses and users, but it has no core function to create an activity (a Page, Book, Quiz…). So this project ships two parts that work together:

┌────────────────┐     MCP tools      ┌──────────────────┐    REST + token    ┌─────────────────┐
│  AI client     │ ◄────────────────► │   moodle-mcp     │ ◄────────────────► │   Moodle site   │
│ (Claude, etc.) │                    │  (Python server) │                    │  + local plugin │
└────────────────┘                    └──────────────────┘                    └─────────────────┘
Piece Path Role
Moodle plugin local/mcpbridge/ Adds the activity-creation web service functions Moodle core is missing, using Moodle's official add_moduleinfo() helper, so it's upgrade-safe (no raw DB writes).
MCP server moodle-mcp/ Wraps Moodle's read/write API, core and the plugin's new functions, as typed MCP tools for an AI client.

Compatibility & authentication

Works with any Moodle 4.2 or newer: self-hosted or institutional. There is nothing site-specific in the code.

Authentication uses a web service token, not a password. The MCP server never sends a username or password, it sends a token (a long random string) that an admin generates in Moodle. The token is tied to one user account and one service (a fixed list of allowed functions), and it can only do what that user's capabilities permit.

Because the token is a separate auth channel, it works regardless of how your users log in: Manual, LDAP, SAML/SSO (Shibboleth, ADFS), Google/Microsoft OAuth, CAS, etc. all make no difference. A university Moodle behind SSO works exactly the same: an admin just creates a token.

What you need

Requirement Why
Admin access (yours or an admin's) To install the plugin, enable web services, and create the token
Web services + REST enabled The authentication mechanism
A user account for the token The token inherits that user's capabilities

Caveats (be honest with yourself here)

  • You must be able to install a plugin: full control on self-hosted/institutional Moodle; a locked-down managed host may require the admin to do it.
  • Some managed clouds (e.g. MoodleCloud free tier) block custom plugins and full web services, activity creation won't work there.
  • Without the plugin, the MCP server's core tools (list/create courses, users, enrolment, grades) still work with a token; you only lose the plugin's activity-creation tools.

Features

  • 86 tools: reads, a student-assistant layer (deadlines, dashboards, task analysis), core writes, activity creation, quiz results, completion tracking, backup/restore, and a one-call course builder
  • Six quiz question types: multiple choice, true/false, short answer, essay, numerical (with tolerances), matching
  • Read/write split: read tools always on; write tools gated behind MOODLE_ALLOW_WRITE=true
  • Upgrade-safe plugin: uses Moodle's own add_moduleinfo(), never touches module tables directly
  • Clean error handling: detects Moodle's JSON-error-on-HTTP-200 quirk and surfaces readable messages
  • Token never logged: config from environment variables only
  • One token for everything: read, core writes, and the plugin functions in a single service

Quick start

1. Install the plugin (local_mcpbridge)

Copy the local/mcpbridge/ folder into your Moodle so it lives at {moodle}/local/mcpbridge/, then visit Site administration as an admin, Moodle will detect it and prompt you to upgrade. Confirm, and you're done.

2. Enable web services & generate a token

In Moodle as an admin:

  1. Enable web services: Site administration → Advanced features → tick Enable web services.
  2. Enable REST: Server → Web services → Manage protocols → enable REST protocol.
  3. Build the service: Server → Web services → External services. Use the ready-made MCP Bridge Service the plugin created, then click Functions and add the core read/write functions you want (list in Tool reference).
  4. Authorise a user for the service and make sure they have the needed capabilities (notably moodle/course:manageactivities in the target courses).
  5. Create a token: Server → Web services → Manage tokens → pick the user and the MCP Bridge Service. Copy it.

Verify before you wire up the AI: run the test script to confirm the plugin and token work end to end.

3. Run the MCP server

Easiest — from PyPI:

pip install moodle-mcp-bridge
MOODLE_URL=https://moodle.example.edu MOODLE_TOKEN=your_token moodle-mcp-bridge

Or from a checkout:

cd moodle-mcp
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env        # then edit .env with your URL + token
python server.py
Env var Meaning
MOODLE_URL Base URL, no trailing slash
MOODLE_TOKEN The token from step 2 (never logged)
MOODLE_ALLOW_WRITE true to enable write tools; anything else = read-only

4. Connect Claude Desktop

Add to claude_desktop_config.json (pip install):

{
  "mcpServers": {
    "moodle": {
      "command": "moodle-mcp-bridge",
      "env": {
        "MOODLE_URL": "https://moodle.example.edu",
        "MOODLE_TOKEN": "your_token_here",
        "MOODLE_ALLOW_WRITE": "true"
      }
    }
  }
}

Running from a checkout instead? Use "command": "/absolute/path/to/moodle-mcp/.venv/bin/python" with "args": ["/absolute/path/to/moodle-mcp/server.py"].

Not just Claude: any MCP client works

MCP is an open protocol, so the same server works with Gemini CLI, ChatGPT desktop (developer mode), Cursor, Windsurf, VS Code Copilot agent mode, Cline, LM Studio, and anything else that speaks MCP. The config is nearly identical everywhere — the moodle-mcp-bridge command plus the three env vars. Example for Gemini CLI (~/.gemini/settings.json):

{
  "mcpServers": {
    "moodle": {
      "command": "moodle-mcp-bridge",
      "env": {
        "MOODLE_URL": "https://moodle.example.edu",
        "MOODLE_TOKEN": "your_token_here",
        "MOODLE_ALLOW_WRITE": "true"
      }
    }
  }
}

Tool-use quality depends on the model: with 86 tools, stronger models chain calls (create course → add section → add quiz) more reliably than small local ones.

Restart Claude Desktop and the Moodle tools appear.


Tool reference

86 tools, grouped by what they touch. Access shows whether a tool is always available (read) or needs MOODLE_ALLOW_WRITE=true (write). Tools backed by the plugin are marked plugin; everything else uses Moodle core functions.

Courses & structure

Tool What it does Access
list_courses / search_courses List all courses / search by field read
get_course_content Everything inside a course (sections, activities, files) read
get_my_courses Courses the current user is enrolled in read
create_course / update_course Create or update a course write
create_category / delete_category Manage course categories write
create_section / delete_section plugin Manage course sections write
delete_courses Delete courses (irreversible) write
import_course Copy content from one course into another write

Course builder & backup

Tool What it does Access
build_course Build a whole course — sections, activities, quizzes with questions — from one JSON outline, with a per-item build log write
backup_course plugin Full course backup, saved as a real .mbz on your local disk write
restore_course plugin Restore a .mbz file into a brand-new course write

Content & activities

Tool What it does Access
create_page / update_page plugin HTML page activities write
create_book plugin Book with its first chapter write
create_label plugin Inline text/label on the course page write
create_url plugin External link resource write
create_forum / create_choice plugin Forum / poll activities write
create_assignment plugin Assignment with due date and grade write
update_activity / move_activity / delete_activity plugin Rename, hide, move or delete any activity write
upload_file / download_file Transfer files to/from Moodle write

Quizzes & questions

Tool What it does Access
list_quizzes Quizzes in given courses read
get_quiz_results A user's attempts + best grade for a quiz read
get_quiz_attempt_review Finished attempt, question by question read
create_quiz plugin Quiz container with timing/grade settings write
add_quiz_question plugin Multiple-choice question write
add_truefalse_question plugin True/false question write
add_shortanswer_question plugin Short-answer question write
add_essay_question plugin Essay (manually graded) question write
add_numerical_question plugin Numerical question with tolerances write
add_matching_question plugin Matching-pairs question write

Users, enrolment & groups

Tool What it does Access
get_enrolled_users Who is enrolled in a course read
create_user / update_user / delete_users Manage user accounts write
enrol_user / enrol_users / unenrol_user Manual enrolment (single or bulk) write
assign_role / unassign_role Role assignments write
create_group / add_group_members Course groups write
create_cohort / add_cohort_members Site-wide cohorts write

Communication

Tool What it does Access
get_course_announcements News-forum announcements read
get_notifications Unread count + recent notifications read
send_message Direct message to a user write
start_forum_discussion / reply_forum_post Post in forums write

Assignments & grading

Tool What it does Access
get_assignments / get_assignment_status Assignments and submission/grading state read
get_upcoming_deadlines / get_overdue_assignments Deadline tracking read
analyze_assignment / extract_assignment_requirements Requirements + context for one assignment read
find_relevant_materials / decompose_task / create_implementation_plan Scaffolds for working on an assignment read
grade_assignment Save a grade with feedback text to the gradebook write

Grades, progress & completion

Tool What it does Access
get_grades / get_user_grades Grade overview or per-course detail read
get_course_progress / get_course_health Progress and at-a-glance course health read
get_activity_completion Which activities a user completed read
get_course_completion_status Whole-course completion criteria read
list_course_competencies / get_learning_plans Competency framework data read
mark_activity_complete Tick your own manual completion box write
override_activity_completion Teacher: set a student's completion state write

Planning & insights

Tool What it does Access
get_upcoming_events Calendar events read
get_recent_activity Updates across courses since a time read
get_study_load Assignment distribution by week read
get_actionable_tasks Prioritized to-do list by urgency read
semester_dashboard / daily_briefing / weekly_review Combined snapshots read

Search & assist

Tool What it does Access
verify_connection Site info + available functions (start here) read
search_course_materials Search across course materials read
ask_moodle Route a natural-language question to the right data read

Quizzes: the six add_*_question tools use Moodle's Question Bank API (multiple choice, true/false, short answer, essay, numerical, matching). That API is version-sensitive — tested on Moodle 5.0; test on your version first.

Missing function? A tool whose web service function isn't in the token's service returns a clean "access control exception" — add the function to MCP Bridge Service and retry. Installing plugin 1.6.0+ registers the complete list automatically.


Testing from the shell

Confirm the plugin + token work before wiring up the AI:

cd moodle-mcp

# Read-only checks (site info + course list):
MOODLE_URL=https://moodle.example.edu MOODLE_TOKEN=xxxx ./test_rest.sh

# Full write test, creates a page, label, url, book, quiz + question in COURSEID:
MOODLE_URL=https://moodle.example.edu MOODLE_TOKEN=xxxx COURSEID=2 ./test_rest.sh --write

A successful create returns e.g. {"cmid": 47, "instanceid": 12}. A Moodle error (still HTTP 200) returns a JSON object with an exception field, which the server surfaces as a clean message.


Safety & write mode

For a full hardening checklist (dedicated service account, scoped role, HTTPS, token expiry), see SECURITY.md.

  • Writes hit live data. Every write tool creates or changes real records. There is no dry-run.
  • Writes are gated. If MOODLE_ALLOW_WRITE is not exactly true, the server registers read tools only: writes cannot be exposed by accident.
  • The token is the blast radius. Bind it to a dedicated service account with only the capabilities and courses you need. A site-admin token lets the AI do anything an admin can.
  • The token is never logged: read from the environment, sent only to Moodle over HTTPS.
  • Start read-only. Turn on write mode deliberately, on a test course, and confirm the shell test passes first.

Extending it

Adding a new capability (e.g. create_assignment, create_forum) is copy-paste-modify. Each plugin function follows the same three-method shape, see create_page.php as the template, and CONTRIBUTING.md for the full recipe.


Contributing

Contributions are very welcome, this is built to be extended!

  1. Fork the repo (top-right Fork button).
  2. Create a branch: git checkout -b feature/my-thing.
  3. Make your change and test it (php -l, py_compile, ideally against a real Moodle).
  4. Push and open a Pull Request to main.

See CONTRIBUTING.md for the full workflow, coding standards, and the pattern for adding a new function. Please also read our Code of Conduct. Found a bug or want a feature? Open an issue.


License

MIT, free to use, modify, and distribute.

Built for educators, admins, and anyone who wants to talk to Moodle instead of clicking through it.

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

moodle_mcp_bridge-1.6.2.tar.gz (28.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

moodle_mcp_bridge-1.6.2-py3-none-any.whl (29.7 kB view details)

Uploaded Python 3

File details

Details for the file moodle_mcp_bridge-1.6.2.tar.gz.

File metadata

  • Download URL: moodle_mcp_bridge-1.6.2.tar.gz
  • Upload date:
  • Size: 28.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for moodle_mcp_bridge-1.6.2.tar.gz
Algorithm Hash digest
SHA256 438b43d821f6072a4fceb0b1fb8990b3b35e18c6d04af9e69e1f2fdaf3208271
MD5 62b063544674022cbfe10745a96385db
BLAKE2b-256 7de6d2267b0a6b228e24d6a02e13f190f497fd5f72c0e1f36242167a1e559cf4

See more details on using hashes here.

Provenance

The following attestation bundles were made for moodle_mcp_bridge-1.6.2.tar.gz:

Publisher: publish.yml on NmaaAlhawary/MCP-Moodle

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moodle_mcp_bridge-1.6.2-py3-none-any.whl.

File metadata

File hashes

Hashes for moodle_mcp_bridge-1.6.2-py3-none-any.whl
Algorithm Hash digest
SHA256 adb8fef6f57f8133e1f8ff9070fc7a6f7290e78e89f7e8943ef8e82008a28157
MD5 47e2f33f563e7a961440310d0d572c53
BLAKE2b-256 b89849682f9bc2f3f4444b4b35ccd88827dd90631a77a41d64a8ebf58b52ad82

See more details on using hashes here.

Provenance

The following attestation bundles were made for moodle_mcp_bridge-1.6.2-py3-none-any.whl:

Publisher: publish.yml on NmaaAlhawary/MCP-Moodle

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page