isu-moodle-mcp
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只有兩個:requests 和 mcp。
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 | 做什麼 |
| 連線體檢。接不上先跑這個 |
| 進行中的課 |
| 所有還看得到的課(注意下面的已知限制) |
| 用關鍵字找自己的課 |
| 課程有幾個單元、幾份教材、幾份作業 |
| 教材清單(含下載網址) |
| 作業清單 |
| 全班繳交狀況 |
| 修課名單(姓名 / email / 角色) |
| 成績矩陣:每位學生 × 每個評分項目 |
| 活動完成度 |
| 下載教材檔案 |
| 直接呼叫任意 Moodle 函式(探索用) |
| 繳交報表:含繳交時間、遲交、重繳次數 |
| 單一學生的逐項成績 |
| 查某位學生的 email |
| 一門課的教材+作業+名單+成績,整包抓下來 |
| 所有看得到的課,整批抓 |
CDP 層(要先跑 python start_debug_chrome_moodle.py 並在那個視窗登入)
Tool | 做什麼 |
| debug Chrome 通不通、登入了沒 |
| 這門課我還進不進得去——API 回答不了的那題 |
| 每一筆選課的狀態、方法、加選時間、起訖日 |
| 掃描找出「存在、但你已經看不到」的課 |
| 哪個服務綁了哪些函式、誰能自己領 token |
| 角色的 capability 矩陣(300+ 條,API 拿不到) |
舊系統層(學校換過平台時用)
需要在 .env 加一行 MOODLE_LEGACY_URL=https://舊站網址。
Tool | 做什麼 |
| 舊站活著嗎、走 API 還是走 CDP。挖資料前先跑這支 |
| 舊站儀表板上看得到的課 |
| 舊站版的「這門課我還進不進得去」 |
| 舊站某門課的單元與教材連結 |
這一版故意不含任何寫入工具(例如改成績的 mod_assign_save_grade)。
唯讀的東西弄錯了頂多是資料不對;寫入弄錯了是真的改到學生成績。
真的需要再自己加,但請先在測試站練過。
已知限制(請務必讀完這一節)
🔴 舊課會安靜地消失——但條件比你想的窄
core_enrol_get_users_courses 只回「你目前還有選課關係」的課。
2026-08-20 用兩台本機 Moodle 4.1.18 實測,逐項驗過:
學校做了什麼 | 課還在你的清單裡嗎 |
課程設成隱藏( | 照樣看得到 |
課程結束日已經過了 | 照樣看得到 |
老師的選課關係被設為「已停用」 | 消失。而且完全不會報錯 |
這張表推翻了一個很常見的說法(也包括本 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 失敗
錯誤 | 意思 | 怎麼辦 |
| 帳密不對 | Moodle 帳號未必等於你的 email |
| 站台沒開行動裝置服務 | 請管理員開 |
| 你的帳號沒有自建 token 的權限 | 學校改過預設權限,需請管理員發 token |
| 站台維護中 | 等一下再試 |
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。拿去改成你自己學校的版本,不用問。
This server cannot be installed
Maintenance
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
- AlicenseNot gradedqualityDmaintenanceEnables 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.14MIT
- AlicenseNot gradedqualityDmaintenanceEnables interaction with Moodle learning management systems through the REST API. Supports course management, user enrollment, assignment handling, and forum operations through natural language.14MIT
- AlicenseNot gradedqualityCmaintenanceProvides 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.1416MIT
- FlicenseAqualityCmaintenanceEnables read-only querying of Moodle as a student, including courses, assignments, grades, forums, and files, using a personal web services token.11
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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