Skip to main content
Glama

isu-moodle-mcp

把 Moodle 接進 Claude 的 MCP server。分兩層

  • API 層(18 支,主力):官方 Web Service REST API。不爬 HTML、不用開瀏覽器。

  • CDP 層(6 支,補洞)+舊系統層(4 支):只在 API 真的拿不到的時候才用 debug Chrome。 最重要的一支是 probe_course_access() —— 它是唯一能發現「有一門課你已經看不到了」的辦法。

平常只用 API 層就夠。CDP 層是給「我教過的課都在清單裡嗎」這種問題準備的。

給義守大學 AIEA「課程設計 AI 實務」工作坊(2026-08-21)單元 3 使用。 直接 pull 下來改成你自己的,不需要 GitHub 帳號。


這是什麼

課堂上示範的 flipclass-mcp 是南臺科大 FlipClass 的 MCP server。那套系統沒有 API, 所以它靠兩件事拿資料:爬 HTML(32 處 xpath)+ debug Chrome(成績矩陣、成員名單這些 純 HTTP 讀不到的頁面)。那是「系統再封閉,有帳密就能完整逆向」的示範。

這一套是同一件事的另一半:當對方有 API 的時候,同一組 MCP tool 契約可以整個抽換後端。

flipclass-mcp

moodle-mcp

取資料

爬 HTML + lxml xpath

官方 REST API

認證

帳密 + anticsrf token + cookie 快取

一組 token,無狀態

多重登入互踢

會(已知問題)

不會

成員名單 / 成績矩陣

要開 debug Chrome 走 CDP

一般 API 就有

學生 email

用學號拼字串推導

名單直接給

認證相關程式碼

約 247 行

約 15 行

debug Chrome

每次都要開(沒它就沒成績矩陣)

只在查選課關係時才要

tool 名稱與 docstring 兩邊刻意保持一致,這樣你可以直接對照,看同一個需求在 「有 API」和「沒 API」兩種情況下分別長什麼樣。


Related MCP server: Moodle MCP Server

快速開始

1. 拿到程式

git clone https://github.com/scatjay/isu-moodle-mcp.git

沒有 git 也可以在 GitHub 頁面按 Code → Download ZIP

2. 裝相依套件

pip install -r requirements.txt

只有兩個:requestsmcp

3. 換一組 token

python get_token.py https://moodle.你的學校.edu.tw

它會問你的 Moodle 帳號密碼,成功就把 token 寫進 .env

請在你自己的終端機跑這一步,不要在 AI 對話裡跑。 對話逐字稿可能被保存或備份,密碼和 token 一旦出現在裡面就等於外洩。

為什麼是 token 不是帳密? token 可以撤銷、只綁你自己的權限、而且不會像密碼那樣 一洩就全盤皆輸。Moodle 的 token 預設 12 週到期——學期中工具突然壞掉、說 invalidtoken,回來重跑這支就好。

4. 接到 Claude

在 Claude Desktop 的設定檔(claude_desktop_config.json)加:

{
  "mcpServers": {
    "moodle": {
      "command": "python",
      "args": ["C:/你的路徑/isu-moodle-mcp/server.py"],
      "env": {
        "MOODLE_URL": "https://moodle.你的學校.edu.tw",
        "MOODLE_TOKEN": "貼上 .env 裡那一串",
        "MOODLE_LEGACY_URL": "https://舊站網址(沒有舊站就整行刪掉)"
      }
    }
  }
}

5. 先跑體檢

接好之後,第一句先叫 Claude 跑 diagnose()。它會告訴你 token 有沒有效、 你實際能呼叫哪些函式、缺了什麼。接不上的時候第一個該跑的就是這支。


有哪些工具

Tool

做什麼

diagnose()

連線體檢。接不上先跑這個

list_current_courses()

進行中的課

list_history_courses()

所有還看得到的課(注意下面的已知限制

search_courses(keyword)

用關鍵字找自己的課

get_course_overview(course_id)

課程有幾個單元、幾份教材、幾份作業

list_materials(course_id)

教材清單(含下載網址)

list_homework(course_id)

作業清單

list_submissions(assignment_id)

全班繳交狀況

read_members(course_id)

修課名單(姓名 / email / 角色)

read_score_matrix(course_id)

成績矩陣:每位學生 × 每個評分項目

get_completion_status(course_id)

活動完成度

download_file(fileurl, dest_path)

下載教材檔案

raw_call(wsfunction, params_json)

直接呼叫任意 Moodle 函式(探索用)

get_submission_report(assignment_id)

繳交報表:含繳交時間、遲交、重繳次數

get_student_grade_record(course_id, uid)

單一學生的逐項成績

get_student_email(course_id, uid)

查某位學生的 email

fetch_course_bundle(course_id, dest)

一門課的教材+作業+名單+成績,整包抓下來

fetch_all_courses_bundle(dest)

所有看得到的課,整批抓

CDP 層(要先跑 python start_debug_chrome_moodle.py 並在那個視窗登入)

Tool

做什麼

cdp_status()

debug Chrome 通不通、登入了沒

probe_course_access(course_id)

這門課我還進不進得去——API 回答不了的那題

enrolment_details(course_id)

每一筆選課的狀態、方法、加選時間、起訖日

find_hidden_courses()

掃描找出「存在、但你已經看不到」的課

webservice_overview()

哪個服務綁了哪些函式、誰能自己領 token

role_capabilities(role_id)

角色的 capability 矩陣(300+ 條,API 拿不到)

舊系統層(學校換過平台時用)

需要在 .env 加一行 MOODLE_LEGACY_URL=https://舊站網址

Tool

做什麼

legacy_status()

舊站活著嗎、走 API 還是走 CDP。挖資料前先跑這支

legacy_list_courses()

舊站儀表板上看得到的課

legacy_probe_course(course_id)

舊站版的「這門課我還進不進得去」

legacy_course_contents(course_id)

舊站某門課的單元與教材連結

這一版故意不含任何寫入工具(例如改成績的 mod_assign_save_grade)。 唯讀的東西弄錯了頂多是資料不對;寫入弄錯了是真的改到學生成績。 真的需要再自己加,但請先在測試站練過。


已知限制(請務必讀完這一節)

🔴 舊課會安靜地消失——但條件比你想的窄

core_enrol_get_users_courses 只回「你目前還有選課關係」的課

2026-08-20 用兩台本機 Moodle 4.1.18 實測,逐項驗過:

學校做了什麼

課還在你的清單裡嗎

課程設成隱藏(visible=0

照樣看得到

課程結束日已經過了

照樣看得到

老師的選課關係被設為「已停用」

消失。而且完全不會報錯

這張表推翻了一個很常見的說法(也包括本 README 的前一版): 「隱藏或封存舊課會讓它消失」。實測不成立。 真正會讓課消失的只有最後那一列。 寫在這裡是因為:一個被實測推翻的說法留在文件裡,比沒寫還糟—— 你會照著它去跟管理員要錯的東西。

課程、學生、作業都還在資料庫裡,只是你看不到。而 API 不會告訴你 「有一門課你看不到了」,它只是不提。

所以要做長時段分析之前,先跑 find_hidden_courses()probe_course_access(course_id) 逐一探測,不要只信 list_history_courses() 的清單。 那支一定會回一個 caveat 欄位提醒你,請不要忽略它。

Moodle 的錯誤是 HTTP 200

Moodle 回錯誤時 HTTP 狀態碼仍然是 200,錯誤藏在 body 的 exception 欄位裡。 raise_for_status() 完全抓不到。本 server 已經處理,但你自己寫程式打 Moodle 時要記得。

accessexception 很難查

官方列出的成因有七八種,而除非管理員把 debug 開到 NORMAL 以上, 錯誤訊息不會告訴你是哪一種。本 server 會把它翻成白話並給出最可能的三個原因, 但真正要確定是哪一個,還是得跑 diagnose() 看你的 token 到底含哪些函式。

你只看得到自己的課

這是 Moodle 內建的保證,不是本工具的限制。token 完全繼承你本人的權限, 每次呼叫都會做 context 層級的權限檢查。這同時是安全保證也是限制。

陣列參數不能用 JSON

Moodle REST 用 PHP 的 $_POST 解析,陣列必須寫成 courseids[0]=5&courseids[1]=7。 丟 JSON 字串會被當成單一字串而報 invalidparameter。本 server 已自動攤平。

檔案下載的參數名不一樣

REST 端點用 wstoken,但 webservice/pluginfile.php 用的是 token。 移植時最容易漏掉這一點。而且服務的 downloadfiles 必須是開的。


如果 get_token.py 失敗

錯誤

意思

怎麼辦

invalidlogin

帳密不對

Moodle 帳號未必等於你的 email

servicenotavailable

站台沒開行動裝置服務

請管理員開 enablemobilewebservice

cannotcreatetoken

你的帳號沒有自建 token 的權限

學校改過預設權限,需請管理員發 token

sitemaintenance

站台維護中

等一下再試

Moodle 原廠預設把 moodle/webservice:createmobiletoken所有已登入使用者, 所以老師通常不需要管理員就能自己換 token。但學校可以改這個預設值—— 如果改過,只會在你實際去換的時候才發現,從外面探測不出來。


開發筆記

這支是從 flipclass-mcp 移植過來的。移植時砍掉的是最痛的那一半、留下的是最有價值的那一半:

  • 砍掉(約 247 行):_login、anticsrf 處理、cookie 快取、checkMultiLogin 多重登入處理、32 處 lxml xpath 解析、CDP(debug Chrome)連線

  • 保留:FastMCP 骨架、每個 @mcp.tool() 的簽名與 docstring ——這才是真正的資產,因為那是 LLM 看到的契約

會這樣做,是因為現成的 Moodle Python 套件沒有一個能用:moodlepy 停更近兩年 且把相依鎖在 attrs<23(2022 年的版本);moodle_api.py 停更三年且不在 PyPI; python-moodle 還在維護但根本是爬 HTML,不是 REST client。 Moodle REST 簡單到十幾行就寫完,引入停更套件只是多背一份技術債。


授權

MIT。拿去改成你自己學校的版本,不用問。

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables interaction with Moodle learning management systems through the Moodle REST API. Supports course management, user enrollment, assignments, forums, quizzes, and file operations through natural language.
    14
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables interaction with Moodle learning management systems through the REST API. Supports course management, user enrollment, assignment handling, and forum operations through natural language.
    14
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides Claude with full access to Moodle learning management systems, enabling interaction with courses, files, assignments, grades, and calendar events. It also supports building Obsidian study vaults from course materials through automated knowledge graph creation.
    14
    16
    MIT

View all related MCP servers

Related MCP Connectors

  • Read-only MCP server for ClassQuill, a tutoring-business-management platform.

  • WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.

  • Read-only tools over the Safer Agentic AI framework: 238 patterns + 14 heuristics.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/scatjay/isu-moodle-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server