Skip to content

Releases: G36maid/moodle-mcp

moodle-mcp v0.2.1

Choose a tag to compare

@github-actions github-actions released this 19 Oct 23:19

Added

  • the tool surface is verified against a self-hosted Moodle 5.2.4 as
    well — the supported range is now live-checked at both ends (3.7 and
    4.5 on live sites, 5.2 self-hosted)
  • capped list tools report has_more (notifications, conversations) —
    the model can tell "all of them" from "the newest N"
  • releases ship .mcpb bundles alongside the platform archives —
    one-click installs for MCP-bundle clients (Claude Desktop/Claude Code),
    with MOODLE_URL/MOODLE_TOKEN declared in the manifest

Changed

  • the 429/503 cooldown is per web-service function: one throttled
    function no longer disables every tool for the window — other endpoints
    (and other tools' writes) keep working
  • the escape hatch fails closed: when the token's enabled-function list
    cannot be loaded (site info failed), call_ws_function refuses the
    call instead of sending it unverified
  • the Moodle timezone probe runs alongside serving instead of delaying
    the MCP initialize handshake — a slow site no longer looks like a
    dead server; timestamps render in UTC until the probe lands

moodle-mcp v0.2.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 20:05

Added

  • auth follows whole-site redirects — schools that migrate hosts
    (moodle.example.edu → moodle3.example.edu) answer the old origin with a
    bare 303, and every later request would land on the homepage instead of
    the page asked for
  • token acquisition failures name the fix: every login/token.php error
    code now maps to a plain-language hint (web services disabled, missing
    create-token capability, IP-restricted mobile access, SSO-only
    accounts…)
  • a landing page and a documentation book, published at
    https://moodle.ntnu.cc (mdBook sources in docs/, built and deployed
    by CI on every push)
  • file tools accept only same-site Moodle URLs — external links belong to the
    agent's own web tooling (MOODLE_ALLOW_EXTERNAL_FETCH=true opts out)
  • MOODLE_ENABLE_WS_FUNCTION opts in to the call_ws_function escape hatch
    (hidden by default — a write-capable raw call is a conscious choice;
    MOODLE_READ_ONLY hides it regardless)
  • MOODLE_ALLOW_HTTP=true / auth --allow-http allow plain-http sites (local
    test instances on loopback hosts need no flags)
  • MOODLE_UA overrides the User-Agent on both HTTP clients (default stays
    moodle-mcp/{version})
  • MOODLE_LOG_LEVEL sets the log level (error|warn|info|debug|trace,
    default info); RUST_LOG remains the advanced escape hatch
  • a download_file overwrite parameter (false by default) for
    intentional re-downloads
  • a cargo-audit CI job failing the build on RustSec advisory matches
  • security-review hardening: redirects that originate from the Moodle
    site may never drop to plain http (the token-bearing chain), an SSO
    driver's callback POST gets the same https guard as the password POST,
    the export line auth prints is quote-safe against hostile tokens,
    and MOODLE_TIMEOUT_SECS typos fail at startup instead of silently
    becoming the default
  • per-school SSO drivers under src/sso/ (one file, one PR): auth
    dispatches by host — a school with a maintained driver replays its own
    login chain over plain HTTP (no browser, no token paste) and the token
    is validated before it is shown; every other school uses the
    credentials mode (verified live against NTUST's IdentityServer portal)

Removed

  • the auth --open flag: the Security-keys-page flow did not work at any
    surveyed school (the page was blocked by the web server or empty), and
    both verified schools are covered without a browser — NTNU by the
    credentials mode, NTUST by the SSO driver

Changed

  • list_functions is renamed to list_ws_functions — it pairs with
    call_ws_function and says what it lists (web-service functions)
  • the whole escape hatch pair (list_ws_functions, call_ws_function) is
    out of the default tool surface: the server
    now lists 20 tools until MOODLE_ENABLE_WS_FUNCTION=true opts in
  • boolean env switches (MOODLE_READ_ONLY, MOODLE_ALLOW_HTTP,
    MOODLE_ALLOW_EXTERNAL_FETCH, MOODLE_ENABLE_WS_FUNCTION) accept
    true/false (also 1/0, yes/no, on/off, case-insensitive)
    and reject any other value at startup instead of silently falling back —
    a typo'd MOODLE_READ_ONLY=ture used to disable the safety switch
  • MOODLE_URL without a scheme now defaults to https://, and plain
    http:// is rejected unless the host is loopback or the escape hatch is
    set — the token (and on auth, the password) would otherwise travel in
    cleartext

Fixed

  • timestamps render in the timezone Moodle itself uses for the user: the
    site's forced timezone, then the user's profile timezone if the site
    shows it, then the site default (the site-level values need Moodle 4.2+).
    The 0.1.2 detection read a user preference, but Moodle keeps the timezone
    in the user record, so without MOODLE_TIMEZONE stock sites fell back to
    UTC (#8, fix by @thc1006)
  • fetch_file no longer writes a predictable temp file for document
    conversion (a symlink/TOCTOU hazard on multi-user machines) — documents
    are converted fully in memory, with one less disk round-trip

moodle-mcp v0.1.4

Choose a tag to compare

@github-actions github-actions released this 14 Oct 17:17

Fixed

  • get_course_overview missed the content teachers put in section
    summaries or module descriptions instead of modules; that content is
    included now (#13)
  • get_course_overview surfaces section and module availability
    restrictions and hidden states — a restricted item is no longer listed
    as if freely available

moodle-mcp v0.1.3

Choose a tag to compare

@github-actions github-actions released this 14 Oct 14:33

Changed

  • download_file no longer creates missing save_to parent directories
    (introduced in 0.1.2). Following the explicit-action convention of the
    official filesystem server, the download fails with an error naming the
    missing directory and suggesting to create it first or save to an existing
    one — no directory structure is created on the agent's behalf (#1)

moodle-mcp v0.1.2

Choose a tag to compare

@github-actions github-actions released this 14 Oct 13:54

Fixed

  • download_file creates missing save_to parent directories instead of
    failing with No such file or directory, and rejects a blank save_to up
    front with a message that suggests the fix (#1)
  • get_notifications defaults to returning both read and unread
    notifications — the previous default silently returned only already-read
    ones (#2)
  • get_assignment prefers gradefordisplay for the grade and hides Moodle's
    -1.00000 no-grade sentinel, so gradebook grades display instead of a
    bogus -1 (#3)
  • search_users sends the parameters core_message_message_search_users
    actually requires and merges contacts/noncontacts into one list; blank
    queries are rejected client-side instead of hanging until timeout (#4)
  • download_file and fetch_file rewrite pluginfile.php URLs into
    token-authenticated ones and detect login-page or error-JSON responses, so
    an HTML login page is no longer saved as the file (#5)
  • get_discussion_posts reads attachment URLs from the url field,
    restoring attachment links on Moodle 4.5 and later (#6)
  • parallel fetch_file calls can no longer return another file's content —
    the Moodle fetch ticket is now derived from an atomic counter (#7)
  • upload_file surfaces upload.php per-file error records instead of
    reporting success when the upload was rejected (#9)
  • online-text submissions and teacher feedback comments render as markdown
    instead of raw <p>/<span>/<br> tags (#12)

Added

  • MOODLE_READ_ONLY=1 hides all write/upload tools for cautious setups;
    MOODLE_DISABLE_TOOLS hides additional tools by name, warning on unknown
    names at startup (#10)
  • MOODLE_TIMEZONE overrides the timezone used to render timestamps; the
    default auto-detects the Moodle user's timezone preference and falls back
    to UTC (#8)
  • whoami reports the active timezone, whether read-only mode is on, and the
    server's own version
  • limit: 0 on get_notifications, get_conversations and search_users
    now means the default (20) instead of a single item
  • published on crates.io — cargo install moodle-mcp

Changed

  • tool descriptions restructured as concise prose with MCP capability
    annotations (read-only / non-destructive hints)
  • all localized READMEs document every environment variable, including the
    two new ones

moodle-mcp v0.1.1

Choose a tag to compare

@github-actions github-actions released this 13 Oct 15:51

Full Changelog: v0.1.0...v0.1.1

moodle-mcp v0.1.0

Choose a tag to compare

@github-actions github-actions released this 13 Oct 11:19

First public release. 🎓

moodle-mcp lets AI agents (Claude Code, Codex, OpenCode, pi, any MCP client) operate your Moodle: browse courses, read assignments and forum threads, fetch PDFs/DOCX/PPTX as markdown, track grades and deadlines, and submit homework — all through 22 focused tools.

Highlights

  • 🧭 Agent-native design — navigation-shaped tools (list_courses → get_course_overview → per-item), dual-channel output (markdown documents + machine-readable JSON), errors that tell the model how to fix itself
  • 📄 Files as markdown — PDF/DOCX/PPTX/XLSX/ODT/EPUB/CSV/HTML converted inline via anydoc + htmd; binaries stream to disk, never into the conversation
  • 🔗 Moodle 3.7 → 5.x — version-adaptive function selection, tested against a live campus 3.7 site (18 courses, all 22 tools)
  • 🛡️ Safety by construction — token only ever sent to your Moodle host (scrubbed from errors, redirects confined), write tools require your confirmation, upload/download caps
  • 🧰 Escape hatch — call_ws_function + list_functions reach any of the ~350 web-service functions the token allows
  • ⚡ Single ~8MB static binary, no runtime deps, stdio transport

Install

# grab the archive for your platform from the assets below, then:
export MOODLE_URL=https://your-moodle.example MOODLE_TOKEN=<token>
./moodle-mcp            # serve MCP over stdio
./moodle-mcp token --url https://your-moodle.example   # obtain a token first

Client configs for Claude Code / Codex / OpenCode / pi are in the README.

Platforms

Asset Platform
x86_64-unknown-linux-gnu Linux (most PCs/servers)
aarch64-unknown-linux-gnu Linux ARM (Raspberry Pi, ARM cloud)
x86_64-apple-darwin macOS Intel
aarch64-apple-darwin macOS Apple Silicon
x86_64-pc-windows-msvc Windows

39 offline tests · clippy clean · CI on every push