Skip to content

Repository files navigation

moodle-mcp

Model Context Protocol server for Moodle development. Plug into Claude Desktop, Cursor, Continue, Cline, or any MCP-capable assistant — get live moodledev.io documentation lookups right in your editor.

License: MIT Python 3.10+ MCP

Companion to claude-moodle-dev — that plugin teaches AI assistants the Moodle conventions; this server gives them live access to the canonical docs.

What you get

Ten MCP tools, hardened to survive site redesigns:

Tool Purpose
search_moodle_docs(query, limit=5, offset=0, version?) Search moodledev.io. Synonym expansion, quoted-phrase boost, BM25 + trigram-cosine rerank, pagination, optional version filter (4.4, 4.5, …). Optional Algolia DocSearch fast-path.
fetch_moodle_page(url) Pull a single page in full — body text + headings. Rejects off-host URLs, non-http schemes, and path traversal.
get_hooks_api_listeners() Surface the core Hooks API index + detected hook classes.
get_capability_docs(component?) Access API lookup with a RISK_* quick-reference card; optional component scope.
lookup_db_xmldb(query) Focused XMLDB / database schema search.
list_plugin_types() Table of every Moodle plugin type with one-line hints + docs URL.
get_version_info() Current Moodle versions parsed from /general/releases.
search_tracker(query, limit=5, affects_version?, fix_version?) Issue search against tracker.moodle.org (Jira), now with version filters.
list_ws_functions() List Moodle Web Services functions available to the configured instance token. Requires MOODLE_URL + MOODLE_TOKEN.
call_ws_function(function, args) Invoke a Moodle WS function against a real instance. SSRF-guarded, function-name allowlisted, refuses private/loopback hosts unless explicitly overridden.

Plus MCP resources (moodle://docs/apis/... for one-click page reads), prompts (moodle-plugin-skeleton, moodle-capability-review, moodle-hooks-migration, explain-capability, find-endpoint, explain-plugin-type, xmldb-upgrade, diagnose-mdl), tool annotations (readOnlyHint, destructiveHint) for client safety, and progress notifications during multi-fetch searches.

No API keys required for docs. Pulls the public sitemap, caches it on disk (~/.cache/moodle-mcp/), scores against your query, fetches top pages concurrently with retry + conditional GET + Retry-After header respect.

Optional environment variables

Variable Purpose
MOODLE_URL Base URL of a real Moodle instance (https). Enables WS tools.
MOODLE_TOKEN WS token for that instance.
MOODLE_WS_ALLOW_INSECURE Set to 1 to permit http:// or private/loopback hosts (local dev only).
MOODLE_DOCS_ALGOLIA_APP_ID Algolia DocSearch app ID. Enables higher-precision recall over sitemap BM25.
MOODLE_DOCS_ALGOLIA_API_KEY Algolia public search key.
MOODLE_DOCS_ALGOLIA_INDEX Index name (default: moodledev).

CLI

moodle-mcp --version
moodle-mcp --check        # diagnostic: fetch sitemap + sample page, exit
moodle-mcp --log-level DEBUG

Docker

docker build -t moodle-mcp .
docker run --rm -i moodle-mcp

Install

From PyPI (once published)

pipx install moodle-mcp

From source

git clone https://github.com/SaadRahman01/moodle-mcp
cd moodle-mcp
pipx install .

Wire it up to your assistant

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "moodle": {
      "command": "moodle-mcp"
    }
  }
}

Restart Claude Desktop. Ask: "Search the Moodle docs for how to add a capability."

Claude Code

claude mcp add moodle moodle-mcp

Cursor

~/.cursor/mcp.json:

{
  "mcpServers": {
    "moodle": { "command": "moodle-mcp" }
  }
}

Continue.dev

~/.continue/config.yaml:

mcpServers:
  - name: moodle
    command: moodle-mcp

Cline / Windsurf / any MCP client

Spawn moodle-mcp as a stdio MCP server. No extra arguments required.

How it works

   query
     │
     ▼
┌─────────────────────────────────────────┐
│  fetch sitemap.xml  (cached per session)│
└─────────────────────────────────────────┘
     │
     ▼
┌─────────────────────────────────────────┐
│  score URLs by slug-token overlap       │
└─────────────────────────────────────────┘
     │
     ▼
┌─────────────────────────────────────────┐
│  fetch top N pages → extract main text  │
└─────────────────────────────────────────┘
     │
     ▼
   markdown bundle (title, URL, excerpt)

No external search index. No API key. The only network dependency is https://moodledev.io being reachable.

Roadmap

  • lookup_capability(name) — resolve capability → metadata + risk bitmask
  • lookup_hook(name) — Hooks API 4.4+ listener signatures
  • validate_version_php(path) — local lint
  • lookup_db_field(table, column) — XMLDB metadata
  • Algolia DocSearch fast-path (when available)

Vote / request: open an issue.

Development

python3.11 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest
ruff check .

Contributing

PRs welcome. Add a new tool by:

  1. Implementing the backend in src/moodle_mcp/<your_module>.py.
  2. Registering the tool in src/moodle_mcp/server.py.
  3. Adding tests in tests/.

License

MIT.

Credits

Built by Saad Rahman. Companion of claude-moodle-dev. Powered by the Model Context Protocol and the Moodle Developer Documentation.

About

Model Context Protocol server giving AI assistants live access to moodledev.io docs, Hooks API, capabilities, XMLDB, and the Moodle Jira tracker.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages