Skip to main content

moodle-mcp-connector

An MCP server that connects AI agents to a Moodle site through Moodle's REST web services.

It exposes Moodle as typed tools an agent can call: list and search courses, read course structure, read the full text of Pages, Books, Labels and Lessons, look at quizzes, grades, deadlines and completion, and, when explicitly enabled, create and edit course content.

  • Read-only by default. Write tools are only registered when MOODLE_ALLOW_WRITE=true.
  • Content tool set. MOODLE_TOOLSET=content reduces the server to the tools needed to read and author course content.
  • Token stays private. The token is read from the environment and is never logged or returned by any tool.

This project is not affiliated with, endorsed by, or supported by Moodle HQ or Moodle Pty Ltd. Moodle™ is a registered trademark of Moodle Pty Ltd.

It is based on the MIT-licensed moodle-mcp-bridge project (version 1.7.0); see LICENSE.

Requirements

  • Python 3.11 or newer
  • A Moodle site with web services enabled and the REST protocol turned on
  • A web service token for a dedicated Moodle account (see Security)
  • For the write tools that create and edit pages, books, labels, URLs, sections and activities: the companion Moodle plugin local_mcpconnector (repository: moodle-local_mcpconnector), release 0.1.0 (version 2026102123) or later, which has been tested on Moodle 5.3. server_info reports the installed plugin version and whether it is compatible. Read tools and the core-Moodle write tools (courses, users, enrolments, grading and so on) work without it.

Installation

This is release 0.1.1. Its plugin write tools need local_mcpconnector 0.1.0 (version 2026102123) or newer on the Moodle site; get it from moodle-local_mcpconnector.

Install it from PyPI with pip, ideally into a virtual environment:

pip install moodle-mcp-connector

Or run it without installing anything, with uv:

uvx moodle-mcp-connector

To stay on this release, pin it: pip install "moodle-mcp-connector==0.1.1" or uvx moodle-mcp-connector@0.1.1. To install straight from GitHub instead, use the release tag:

pip install "git+https://github.com/Teci-AI/moodle-mcp-connector.git@v0.1.1"

pip installs the moodle-mcp-connector command. Both of these start the server:

moodle-mcp-connector
python -m moodle_mcp_connector

The server talks MCP over stdio. Started by hand, it waits silently for an MCP client; that is expected. Stop it with Ctrl+C. To upgrade, run pip install --upgrade moodle-mcp-connector; uv picks up a new release with uvx moodle-mcp-connector@latest.

Configuration

All configuration comes from environment variables. The server also loads a .env file if one exists next to the package, in the repository root, or in the working directory; variables already set in the environment take precedence.

Variable Required Description
MOODLE_URL yes Base URL of the site, e.g. https://moodle.example.edu (no trailing slash needed).
MOODLE_TOKEN yes Web service token. Never commit it.
MOODLE_ALLOW_WRITE no true registers the write tools. Anything else, or unset, means read-only.
MOODLE_TOOLSET no content registers only the content-focused tools (marked in the tool table). Unset or all registers every tool. Any other value stops the server with an error.

Example .env (already listed in .gitignore):

MOODLE_URL=https://moodle.example.edu
MOODLE_TOKEN=replace-me
MOODLE_ALLOW_WRITE=false
MOODLE_TOOLSET=content

Setting up Moodle

First, on any site:

  1. Site administration → General → Advanced features: enable web services.
  2. Site administration → Server → Web services → Manage protocols: enable REST.
  3. Create a dedicated user for the agent (see Security). Give it only the roles it needs, in the courses it should work on, and make sure it has the webservice/rest:use capability.

Content tool set: use the plugin's ready-made service

The local_mcpconnector plugin ships a web service called MCP Connector Service (short name mcpconnector). It contains every local_mcpconnector_* function plus the 8 core read functions the content tool set uses, with file downloads allowed:

core_webservice_get_site_info
core_course_get_courses
core_course_get_courses_by_field
core_course_get_contents
core_enrol_get_users_courses
mod_quiz_get_quizzes_by_courses
mod_lesson_get_lessons_by_courses
mod_lesson_get_pages

It is disabled by default and limited to authorised users. To use it:

  1. Install the plugin, downloaded from moodle-local_mcpconnector (Site administration → Plugins → Install plugins, or unpack it into local/mcpconnector) and complete the upgrade.
  2. Site administration → Server → Web services → External services: edit MCP Connector Service, tick Enabled, and save.
  3. On the same page, open Authorised users for that service and add the dedicated user.
  4. Site administration → Server → Web services → Manage tokens: create a token for the dedicated user and MCP Connector Service. Put it in MOODLE_TOKEN, and set MOODLE_TOOLSET=content.

Other tools: use a custom service

The tools outside the content set (users, enrolments, grades, course creation, assignments, forums, messages and so on) call core functions that the ready-made service does not include. To use them, create your own service instead:

  1. Site administration → Server → Web services → External services: add a custom service, add only the functions your tools need (see the tool tables), and authorise the dedicated user. If you also want the plugin's write tools, add the local_mcpconnector_* functions you need.
  2. Tick Can download files on the service if you use read_activity or download_file.
  3. Manage tokens: create a token for the dedicated user and that service.

A token belongs to exactly one service, so a token for the ready-made service can only reach the content tools, whatever MOODLE_TOOLSET says.

OpenCode configuration

Add the server to opencode.json (project) or ~/.config/opencode/opencode.json (global). {env:MOODLE_TOKEN} reads the token from your shell environment so it never lands in the config file:

With the command installed by pip:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "moodle": {
      "type": "local",
      "command": ["moodle-mcp-connector"],
      "enabled": true,
      "environment": {
        "MOODLE_URL": "https://moodle.example.edu",
        "MOODLE_TOKEN": "{env:MOODLE_TOKEN}",
        "MOODLE_TOOLSET": "content",
        "MOODLE_ALLOW_WRITE": "false"
      }
    }
  }
}

If moodle-mcp-connector is not on OpenCode's PATH (for example because it lives in a virtual environment), use the full path to the executable, such as ["C:/Users/you/moodle-mcp/.venv/Scripts/moodle-mcp-connector.exe"] or ["/home/you/moodle-mcp/.venv/bin/moodle-mcp-connector"].

Or let uv fetch and run it from PyPI, with nothing installed beforehand. The first start takes a little longer while uv downloads it; after that it runs from uv's cache. Use "moodle-mcp-connector@0.1.1" instead to pin this release:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "moodle": {
      "type": "local",
      "command": ["uvx", "moodle-mcp-connector"],
      "enabled": true,
      "environment": {
        "MOODLE_URL": "https://moodle.example.edu",
        "MOODLE_TOKEN": "{env:MOODLE_TOKEN}",
        "MOODLE_TOOLSET": "content",
        "MOODLE_ALLOW_WRITE": "false"
      }
    }
  }
}

Tools

The Content column marks the tools registered when MOODLE_TOOLSET=content. Write tools are only registered when MOODLE_ALLOW_WRITE=true, in either tool set.

Many read tools work on "the current user", meaning the user the token belongs to. They look up that user's id once with core_webservice_get_site_info and cache it. When an optional courseid/courseids argument is omitted, they use core_enrol_get_users_courses to find that user's courses.

Read tools

Tool Content Moodle web service functions
server_info ✓ core_webservice_get_site_info; when plugin functions are present also local_mcpconnector_get_info
verify_connection ✓ core_webservice_get_site_info
list_courses ✓ core_course_get_courses
search_courses ✓ core_course_get_courses_by_field
get_my_courses ✓ core_webservice_get_site_info, core_enrol_get_users_courses
get_course_content ✓ core_course_get_contents
list_quizzes ✓ mod_quiz_get_quizzes_by_courses
search_course_materials ✓ core_course_get_contents; without courseid also core_webservice_get_site_info, core_enrol_get_users_courses
read_activity ✓ core_course_get_contents, then downloads the activity's .html files from webservice/pluginfile.php (needs Can download files)
read_lesson ✓ mod_lesson_get_lessons_by_courses, mod_lesson_get_pages
get_enrolled_users core_enrol_get_enrolled_users
get_user_grades gradereport_user_get_grade_items
get_course_announcements mod_forum_get_forums_by_courses, mod_forum_get_forum_discussions; without courseid also core_webservice_get_site_info, core_enrol_get_users_courses
get_recent_activity core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments, mod_forum_get_forums_by_courses, mod_forum_get_forum_discussions
get_assignments mod_assign_get_assignments; without courseids also core_webservice_get_site_info, core_enrol_get_users_courses
get_assignment_status core_webservice_get_site_info, mod_assign_get_submission_status
get_upcoming_deadlines core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments, mod_assign_get_submission_status
get_overdue_assignments core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments, mod_assign_get_submission_status
get_actionable_tasks core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments, mod_assign_get_submission_status
analyze_assignment core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments, mod_assign_get_submission_status, core_course_get_contents
extract_assignment_requirements core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments
find_relevant_materials core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments, core_course_get_contents
decompose_task core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments, mod_assign_get_submission_status, core_course_get_contents
create_implementation_plan core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments, mod_assign_get_submission_status, core_course_get_contents
get_grades without courseid: gradereport_overview_get_course_grades; with courseid: core_webservice_get_site_info, gradereport_user_get_grade_items
get_course_progress core_webservice_get_site_info, core_completion_get_activities_completion_status; without courseid also core_enrol_get_users_courses
get_course_health core_webservice_get_site_info, core_completion_get_activities_completion_status, mod_assign_get_assignments, mod_assign_get_submission_status, gradereport_overview_get_course_grades
get_study_load core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments, mod_assign_get_submission_status
get_upcoming_events core_calendar_get_action_events_by_timesort
semester_dashboard core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments, mod_assign_get_submission_status, gradereport_overview_get_course_grades
daily_briefing core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments, mod_assign_get_submission_status, core_calendar_get_action_events_by_timesort, gradereport_overview_get_course_grades
weekly_review core_webservice_get_site_info, core_enrol_get_users_courses, mod_assign_get_assignments, mod_assign_get_submission_status, core_completion_get_activities_completion_status
ask_moodle Routes the question to one of get_overdue_assignments, get_upcoming_deadlines, get_grades (overview), get_course_progress, get_course_announcements, get_upcoming_events, get_actionable_tasks, get_my_courses or daily_briefing, and calls that tool's functions
get_quiz_results mod_quiz_get_user_attempts, mod_quiz_get_user_best_grade
get_quiz_attempt_review mod_quiz_get_attempt_review
get_quiz_report core_enrol_get_enrolled_users, mod_quiz_get_user_best_grade, mod_quiz_get_user_attempts, mod_quiz_get_attempt_review
get_activity_completion core_completion_get_activities_completion_status; with userid 0 also core_webservice_get_site_info
get_course_completion_status core_completion_get_course_completion_status; with userid 0 also core_webservice_get_site_info
get_notifications core_webservice_get_site_info, message_popup_get_unread_popup_notification_count, message_popup_get_popup_notifications
list_course_competencies core_competency_list_course_competencies
get_learning_plans core_competency_list_user_plans; with userid 0 also core_webservice_get_site_info

Write tools (MOODLE_ALLOW_WRITE=true)

Tools marked plugin need the companion plugin moodle-local_mcpconnector, which provides the local_mcpconnector_* functions.

Plugin version 2026102123 provides every function below. If the site runs an older plugin, or the token's service leaves a function out, the tool fails with a message naming the missing function rather than a raw Moodle error, and build_course checks every function an outline needs before it writes anything, rejecting the outline if any is missing.

Tool Content Moodle web service functions
create_page ✓ local_mcpconnector_create_page (plugin)
update_page ✓ local_mcpconnector_update_page (plugin)
create_book ✓ local_mcpconnector_create_book (plugin)
create_label ✓ local_mcpconnector_create_label (plugin)
create_url ✓ local_mcpconnector_create_url (plugin)
create_quiz ✓ local_mcpconnector_create_quiz (plugin)
add_quiz_question ✓ local_mcpconnector_add_quiz_question (plugin)
add_truefalse_question ✓ local_mcpconnector_add_truefalse_question (plugin)
add_shortanswer_question ✓ local_mcpconnector_add_shortanswer_question (plugin)
add_essay_question ✓ local_mcpconnector_add_essay_question (plugin)
add_numerical_question ✓ local_mcpconnector_add_numerical_question (plugin)
add_matching_question ✓ local_mcpconnector_add_matching_question (plugin)
create_section ✓ local_mcpconnector_create_section (plugin)
delete_section ✓ local_mcpconnector_delete_section (plugin)
update_activity ✓ local_mcpconnector_update_activity (plugin)
move_activity ✓ local_mcpconnector_move_activity (plugin)
delete_activity ✓ local_mcpconnector_delete_activity (plugin)
create_forum local_mcpconnector_create_forum (plugin)
create_choice local_mcpconnector_create_choice (plugin)
create_assignment local_mcpconnector_create_assignment (plugin)
backup_course local_mcpconnector_backup_course (plugin)
restore_course local_mcpconnector_restore_course (plugin)
build_course core_webservice_get_site_info (to check every needed function first), core_course_create_courses, local_mcpconnector_create_section, local_mcpconnector_create_page, local_mcpconnector_create_label, local_mcpconnector_create_url, local_mcpconnector_create_forum, local_mcpconnector_create_assignment, local_mcpconnector_create_choice, local_mcpconnector_create_quiz, the six local_mcpconnector_add_*_question functions (plugin); with rollback=True also core_course_delete_courses
create_course core_course_create_courses
update_course core_course_update_courses
delete_courses core_course_delete_courses
import_course core_course_import_course
create_category core_course_create_categories
delete_category core_course_delete_categories
create_user core_user_create_users
update_user core_user_update_users
delete_users core_user_delete_users
enrol_user enrol_manual_enrol_users
enrol_users enrol_manual_enrol_users
unenrol_user enrol_manual_unenrol_users
assign_role core_role_assign_roles
unassign_role core_role_unassign_roles
create_group core_group_create_groups
add_group_members core_group_add_group_members
create_cohort core_cohort_create_cohorts
add_cohort_members core_cohort_add_cohort_members
grade_assignment mod_assign_save_grade
start_forum_discussion mod_forum_add_discussion
reply_forum_post mod_forum_add_discussion_post
send_message core_message_send_instant_messages
mark_activity_complete core_completion_update_activity_completion_status_manually
override_activity_completion core_completion_override_activity_completion_status
upload_file core_files_upload
download_file None; downloads a file from webservice/pluginfile.php (needs Can download files)

Security

  • Use a dedicated Moodle account for the agent, never a site administrator or your personal login. Give it only the roles it needs, and only in the courses it should touch.
  • Give the web service the minimum functions. Add only the functions in the table above that your enabled tools actually call. A tool whose function is missing fails with a clear Moodle error; it cannot reach anything the service does not allow.
  • Keep write mode off unless you need it. Without MOODLE_ALLOW_WRITE=true no write tool is registered at all. Combine write mode with MOODLE_TOOLSET=content to limit an authoring agent to course content.
  • Never commit tokens. Keep MOODLE_TOKEN in your environment or in a .env file (ignored by git). In client configs, reference the environment (for example {env:MOODLE_TOKEN} in OpenCode) rather than pasting the token. If a token leaks, revoke it in Manage tokens and issue a new one.
  • The token is sent as a POST field for web service calls. File downloads (read_activity, download_file) have to put it in the URL, so request URLs are kept out of logs and error messages, and both tools refuse any URL outside the MOODLE_URL site. An agent cannot get the token sent to another host.

Development

To work on the server itself, clone the repository and install it in editable mode with the development tools:

git clone git@github.com:Teci-AI/moodle-mcp-connector.git
cd moodle-mcp-connector
python -m venv .venv
# Windows:      .venv\Scripts\activate
# macOS/Linux:  source .venv/bin/activate
pip install -e ".[dev]"
pytest

Contributing

See CONTRIBUTING.md for how to add a new tool, build the package and run the live integration tests.

License

MIT; see LICENSE.

Metadata

Release files for moodle-mcp-connector 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for moodle-mcp-connector 0.1.1
File Size Uploaded Provenance Actions
moodle_mcp_connector-0.1.1.tar.gz 64.1 kB With provenance Details for moodle_mcp_connector-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for moodle-mcp-connector 0.1.1
File Interpreter ABI Platform Actions
moodle_mcp_connector-0.1.1-py3-none-any.whl Python 3 none any Details for moodle_mcp_connector-0.1.1-py3-none-any.whl

Total release size: 102.8 kB

Release files / moodle_mcp_connector-0.1.1.tar.gz

Download URL moodle_mcp_connector-0.1.1.tar.gz
Size 64.1 kB
Tags Source
SHA-256 checksum
How to use checksums
3bd64af3ac23977ba14ab5440ff3cb0e2877bcb36101bc29f488981b9a4b69e1
BLAKE2b-256 checksum
How to use checksums
076ddfd9b1f7a6a33e490b17d70dde43d71f731ec410c9f1594c01731c0b4b5f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / moodle_mcp_connector-0.1.1-py3-none-any.whl

Download URL moodle_mcp_connector-0.1.1-py3-none-any.whl
Size 38.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ba58785f5c5ed76cbd825d1aa6ddf5fa9a9acd20da3b0f3a99f8d5ccafb9cdf7
BLAKE2b-256 checksum
How to use checksums
1d968c4b70335b6f50f83efce3fd58059844fa8170f48fa34d81f4c99e6819c2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Security for moodle-mcp-connector 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for moodle_mcp_connector-0.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page