Moodle自动化神器:开源API客户端集成MCP,实现课程资料批量下载与AI助手对话
1. 项目概述与核心价值如果你是一名学生、教师或者教育技术从业者正在为如何高效、自动化地从Moodle学习管理系统中获取课程资料、成绩和作业信息而烦恼那么今天分享的这个工具可能会成为你的得力助手。我最近在深度使用一个名为moodle-connector的开源项目它本质上是一个功能全面的Moodle REST API客户端但它的强大之处远不止于此。它集成了批量下载器并且原生支持MCP协议能够无缝接入像Claude Code、OpenCode这样的现代AI编程工具。简单来说它把Moodle从一个需要通过浏览器点点点的网站变成了一个可以通过命令行、Python脚本甚至AI助手直接对话来操控的数据源。这个工具解决的核心痛点非常明确自动化与集成。想象一下你不再需要手动登录Moodle网站一页页翻找课程资料然后一个个点击下载。你可以写一个简单的脚本或者直接在Claude Code里问一句“把我这学期所有课程的课件都下载下来”它就能自动完成。这对于需要备份资料、进行离线学习、或者开发与Moodle集成的教育应用的人来说价值巨大。它的设计思路非常清晰通过模拟官方Moodle移动应用的认证流程来绕过复杂的SSO登录提供一套完整的API封装并支持多种使用模式从命令行到编程接口再到AI工具集成覆盖了从普通用户到开发者的不同需求场景。2. 核心功能与设计思路拆解2.1 三大核心功能模块解析moodle-connector的设计可以清晰地划分为三个层次这也是它区别于简单脚本的关键。2.1.1 完整的Moodle API客户端这是项目的基石。它并非只实现一两个API而是覆盖了学生和教师日常使用的大部分核心功能课程与内容管理列出所有已注册课程、获取课程内的所有资料文件、链接、页面等。学业进度跟踪查询各门课程的成绩、获取所有作业包括截止日期和提交状态、查看课程公告。日历与日程提取即将到来的截止日期和日历事件。文件下载与缓存提供带缓存的稳健文件下载功能避免重复下载节省流量和时间。这些功能通过一个统一的MoodleConnector类暴露出来内部处理了API端点调用、参数构造、错误处理和分页逻辑。开发者不需要去翻阅Moodle那略显晦涩的Web Service文档直接调用这些高层方法即可。2.1.2 通用批量下载器这是面向普通用户的“杀手级”功能。它采用JSON驱动的配置方式意味着你不需要写任何Python代码。你只需要在一个downloads.json文件里按照“课程模块 - 文件列表”的结构填写好课程名和对应的文件URL运行一个命令它就能自动按课程文件夹结构下载所有文件。这个设计巧妙地将“配置”与“代码”分离极大降低了使用门槛。无论是想下载某一门课的全部课件还是跨多门课程收集特定类型的资料都变得非常简单。2.1.3 MCP协议服务器这是项目最前沿也最具想象力的部分。MCPModel Context Protocol是一种让AI助手如Claude安全、可控地访问外部工具和数据的协议。moodle-connector实现了一个MCP服务器将上述所有API功能暴露为AI助手可以调用的“工具”。一旦配置完成你可以在Claude Code中直接使用自然语言指令比如“查看我这周有哪些作业要交”或“把‘机器学习’课程第三周的材料发给我”AI助手就能调用背后的MCP工具获取真实数据并回答你。这实现了从“操作工具”到“与助手对话”的体验飞跃。2.2 认证机制巧妙的“移动应用流程”破解Moodle集成的最大门槛往往是认证尤其是当学校使用了微软Azure AD、Google或其他SAML等单点登录方案时。传统的API令牌方式需要管理员在Moodle后台手动生成并配置对学生而言几乎不可行。moodle-connector采用了一种非常巧妙的方案模拟官方Moodle移动应用的启动流程。这个流程是Moodle为官方App设计的通常对SSO有很好的支持。具体流程如下工具通过playwright自动化打开一个浏览器导航到Moodle站点的/admin/tool/mobile/launch.php这个特殊页面。如果用户未登录Moodle会将页面重定向到学校的SSO登录页面如微软登录页。用户此时在自动打开的浏览器窗口中像平时一样完成用户名、密码输入以及多因素认证操作。这一切都是交互式的完美解决了自动化脚本难以处理复杂SSO和MFA的问题。登录成功后Moodle会生成一个用于移动应用的令牌并以moodlemobile://token...这种自定义协议链接的形式发起重定向。playwright会拦截这个重定向从中提取出令牌然后自动关闭浏览器。至此令牌获取完成。这个方案的优点在于“通用性”。它不依赖于任何特定的SSO提供商只要你的Moodle网站支持通过浏览器进行SSO登录并且允许使用移动应用即存在launch.php页面这个流程就能走通。它把最复杂的交互式认证环节交给了浏览器和用户程序只负责流程的启动和令牌的捕获非常稳健。2.3 安全与数据持久化设计考虑到要处理敏感的登录令牌项目在安全上也做了考量加密存储获取到的令牌会使用cryptography库的Fernet对称加密进行加密并持久化保存到credentials.enc文件中。加密密钥来源于用户通过环境变量MOODLE_CRED_PASSWORD提供的密码并经过PBKDF2算法派生。这意味着令牌不会以明文形式存储。环境变量驱动强制要求通过环境变量传递加密密码避免了在脚本或配置文件中硬编码密码的风险也更适合自动化部署。缓存机制对API响应进行了基于时间的缓存TTL可配置减少对Moodle服务器的重复请求提升响应速度并尊重服务器资源。无痕运行强调不要将包含真实令牌的config.json文件提交到Git仓库符合基本的代码安全实践。3. 详细配置与实操部署指南3.1 环境准备与项目初始化假设你已经在系统上安装了Python 3.10和Git以下是部署步骤# 1. 通过OpenClaw的技能商店安装如果使用OpenClaw clawhub install moodle-connector cd ./skills/moodle-connector # 或者直接从GitHub克隆通用方式 git clone https://github.com/Jabir-Srj/moodle-connector.git cd moodle-connector # 2. 安装Python依赖 pip install -r requirements.txt # 关键依赖requests, cryptography, playwright, mcp # 3. 安装Playwright的浏览器内核 python -m playwright install chromium # 这一步很重要因为自动化登录需要浏览器环境注意playwright install chromium会下载一个独立的Chromium浏览器不会影响你系统已安装的Chrome。在服务器或无GUI环境部署时可能需要安装额外的系统库如xvfb来支持虚拟显示。3.2 核心配置文件详解项目有两个核心配置文件config.json和downloads.json。3.2.1 主配置文件 (config.json)首先复制模板文件并进行配置cp config.template.json config.json用文本编辑器打开config.json其结构如下{ moodle: { base_url: https://your-university-moodle-site.edu, web_service_token: }, cache: { api_ttl_seconds: 300 } }base_url必须修改。填写你的Moodle网站的根地址不要以斜杠结尾。例如https://moodle.uni-example.org。web_service_token首次使用时留空。留空将触发自动化的浏览器SSO登录流程来获取令牌。如果你已经通过其他方式如后文将介绍的Tampermonkey脚本获得了令牌可以手动填写在这里后续登录会直接使用它。api_ttl_secondsAPI响应缓存时间单位秒。设置为300意味着5分钟内重复请求同一数据会直接返回缓存而不访问网络。根据数据更新频率调整。3.2.2 批量下载配置文件 (downloads.json)这个文件用于定义你要批量下载的内容。复制示例文件cp downloads.example.json downloads.json其结构是一个JSON数组每个元素代表一个课程模块{ downloads: [ { module: 数据科学导论, course_id: 12345, files: [ { name: 第一讲_引言.pdf, url: https://your-moodle-site.edu/webservice/pluginfile.php/.../Lecture1.pdf }, { name: 第一次作业要求.zip, url: https://your-moodle-site.edu/webservice/pluginfile.php/.../HW1.zip } ] }, { module: 机器学习, course_id: 67890, files: [ { name: Week2_Linear_Regression.pptx, url: https://your-moodle-site.edu/webservice/pluginfile.php/.../week2.pptx } ] } ] }module自定义的文件夹名称下载的文件会放在以此命名的文件夹下。course_idMoodle内部的课程ID。这个ID可以通过运行python moodle_connector.py courses命令来获取。files一个列表包含每个文件的自定义name保存到本地的文件名和完整的url。文件的URL需要从Moodle网站获取通常可以在文件资源的右键菜单或分享链接中找到以webservice/pluginfile.php开头的地址。3.3 首次登录与认证实操这是最关键的一步将建立你与Moodle站点的连接。设置加密密码你需要设定一个密码用于加密存储即将获取的登录令牌。通过环境变量传递# Linux/macOS export MOODLE_CRED_PASSWORDyour_strong_password_here # Windows (Command Prompt) set MOODLE_CRED_PASSWORDyour_strong_password_here # Windows (PowerShell) $env:MOODLE_CRED_PASSWORDyour_strong_password_here请务必使用一个强密码并牢记它后续每次使用工具包括MCP服务器都需要提供同一个密码来解密令牌。执行登录命令python moodle_connector.py login此时程序会启动一个Chromium浏览器窗口并导航到你配置的Moodle站点的移动启动页面。完成交互式登录如果之前没有登录过浏览器会跳转到你学校的统一认证页面可能是微软、Google等。像平时一样在打开的浏览器窗口中输入你的学号/邮箱、密码并完成任何多因素认证步骤如手机验证码、认证器App确认。登录成功后Moodle会尝试跳转到moodlemobile://协议链接。playwright会拦截这个跳转从中提取令牌。一旦令牌被成功捕获浏览器窗口会自动关闭命令行会显示成功信息包括你的用户名和Moodle版本。令牌会被加密保存到credentials.enc文件。实操心得第一次运行时请确保你的桌面环境可以正常弹出浏览器窗口。如果遇到浏览器闪退或无法打开可能是playwright的浏览器安装有问题可以尝试重新运行python -m playwright install chromium。登录过程完全模拟真人操作所以如果学校SSO页面有额外的安全验证如点击“信任此设备”也需要手动完成。3.4 无头服务器环境下的令牌获取技巧如果你需要在没有图形界面的服务器如云服务器、WSL上运行此工具自动化的浏览器登录将无法进行。此时可以使用项目提供的Tampermonkey Token Helper方案。原理在一台有浏览器的电脑上比如你的个人笔记本通过一个用户脚本UserScript从已登录的Moodle会话中提取令牌然后手动将这个令牌填入服务器的config.json中。操作步骤在你的浏览器Chrome/Firefox等中安装Tampermonkey扩展。打开Tampermonkey的管理面板点击“创建新脚本”。将项目中的moodle_token_helper.user.js文件内容完全复制粘贴进去。保存脚本CtrlS。脚本默认匹配*://*/*但为了安全建议你编辑脚本开头的match行将其改为只匹配你的Moodle域名例如match https://your-moodle-site.edu/*。确保你已通过浏览器正常登录了Moodle网站。在Moodle网站的任意页面你应该能看到页面右下角出现一个“Get Token”的浮动按钮。点击该按钮。脚本会利用你当前的会话Cookie在后台调用移动启动接口并拦截返回的令牌。令牌一串长字符串会以弹窗或控制台日志的形式显示。复制它。回到你的服务器环境打开config.json将复制的令牌粘贴到web_service_token字段的值中双引号内。现在服务器上的工具就可以直接使用这个令牌进行API调用了无需再次登录。这个方案完美解决了无头环境的认证问题是自动化部署的关键。4. 多种使用模式深度体验4.1 命令行接口快速上手获取令牌后你就可以使用丰富的CLI命令了。这些命令是探索数据和进行简单操作的最快方式。# 列出你注册的所有课程并显示课程ID和全名 python moodle_connector.py courses # 查看所有课程的成绩如果老师已发布 python moodle_connector.py grades # 获取所有未完成的作业按截止日期排序显示详情 python moodle_connector.py assignments # 查看所有课程的最新公告 python moodle_connector.py announcements # 获取指定课程ID的所有学习材料资源列表 python moodle_connector.py materials --course-id 12345 # 查看未来几周内的所有截止日期和日历事件 python moodle_connector.py deadlines # 下载单个文件并指定输出文件名 python moodle_connector.py download https://.../file.pdf --output lecture.pdf # 生成一份完整的Markdown格式学习报告包含课程、成绩、作业、公告等所有信息 python moodle_connector.py summary semester_report.mdsummary命令非常实用它会生成一个结构清晰的Markdown文档适合用于定期学习进度复盘或归档。4.2 作为Python库集成到自定义脚本对于开发者将其作为库集成可以提供最大的灵活性。下面是一个示例脚本用于每周一自动检查作业截止日期并发送提醒#!/usr/bin/env python3 weekly_deadline_checker.py 每周一运行检查未来7天的作业截止日期并生成提醒摘要。 from moodle_connector import MoodleConnector from pathlib import Path from datetime import datetime, timedelta import smtplib from email.mime.text import MIMEText def main(): # 初始化连接器 connector MoodleConnector( config_pathPath(./config.json), passwordyour_encryption_password # 或者从环境变量读取 ) # 获取所有作业 all_assignments connector.assignments() # 计算日期范围 today datetime.now() next_week today timedelta(days7) upcoming [] for course_name, assignments in all_assignments.items(): for assignment in assignments: # 注意Moodle返回的时间戳通常是UTC需要根据实际情况处理 due_date datetime.fromtimestamp(assignment.get(duedate, 0)) if today due_date next_week and not assignment.get(submitted, False): upcoming.append({ course: course_name, name: assignment[name], due: due_date.strftime(%Y-%m-%d %H:%M), url: assignment.get(url, #) }) # 生成提醒内容 if upcoming: email_content f【学习提醒】未来一周内有 {len(upcoming)} 项作业待提交\n\n for item in upcoming: email_content f- **{item[course]}**: {item[name]}\n email_content f 截止时间: {item[due]}\n email_content f 链接: {item[url]}\n\n # 这里可以替换为你自己的邮件发送逻辑 print(待办作业提醒) print(email_content) # send_email_alert(email_content) # 取消注释并实现发送邮件函数 else: print(未来一周内没有待提交的作业继续保持) if __name__ __main__: main()这个例子展示了如何超越工具自带的CLI根据个人需求定制自动化工作流。4.3 配置MCP服务器与Claude Code深度集成这是最体现“现代感”的用法。通过MCP协议你可以让Claude Code直接访问你的Moodle数据。配置步骤定位Claude Code配置找到你系统的Claude Code配置文件claude_desktop_config.json。macOS:~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:%APPDATA%\Claude\claude_desktop_config.jsonLinux:~/.config/Claude/claude_desktop_config.json编辑配置文件在配置文件中添加moodle-connector作为MCP服务器。确保MOODLE_CRED_PASSWORD环境变量已设置。{ mcpServers: { moodle-connector: { command: python, args: [/ABSOLUTE/PATH/TO/moodle-connector/mcp_server.py], env: { MOODLE_CRED_PASSWORD: your_encryption_password_here } } } }重要提示args中的路径必须使用绝对路径。env里的密码必须与之前登录时设置的MOODLE_CRED_PASSWORD完全一致否则无法解密令牌。重启Claude Code保存配置文件后完全关闭并重新启动Claude Code应用程序。验证与使用重启后Claude Code会自动启动MCP服务器。你可以直接在聊天框中尝试“列出我这学期的所有课程。”“我这周有哪些作业要交”“帮我下载‘人工智能’课程的所有课件。”“给我生成一份本学期的学习情况总结报告。”Claude会识别这些指令并调用对应的Moodle工具来获取真实数据然后将结果组织成自然语言回复给你。这极大地提升了信息获取的效率和体验。4.4 运行批量下载任务当你按照3.2.2节配置好downloads.json后运行批量下载非常简单python batch_downloader.py程序会读取downloads.json配置。为每个module创建对应的文件夹在downloads/目录下。遍历每个files列表使用内置的下载器带缓存获取文件并以指定的name保存到对应模块文件夹中。在控制台输出下载进度和结果。所有下载的文件都会保存在downloads/目录下结构清晰便于管理。5. 高级技巧、问题排查与经验分享5.1 认证失败与令牌管理浏览器打开后无法自动关闭这是最常见的问题。根本原因是工具没有成功拦截到moodlemobile://的重定向。请首先确认你的Moodle站点是否启用了“移动应用”功能即存在/admin/tool/mobile/launch.php页面。有些学校可能禁用了此功能。此时只能使用Tampermonkey脚本手动获取令牌。“Invalid parameter value detected”错误在调用deadlines()函数时某些Moodle版本的日历API参数可能不兼容。解决方法是使用assignments()函数它通常也包含了作业的截止日期信息可以替代。令牌过期Moodle移动令牌通常有数小时到数天的有效期。过期后API调用会返回认证错误。解决方法很简单删除本地的credentials.enc文件然后重新运行python moodle_connector.py login进行认证。你可以将重新登录的步骤加入到你的月度或周度自动化脚本中。多Moodle账户支持如果你有多个学校的Moodle账户可以为每个账户创建独立的配置文件夹分别管理config.json和credentials.enc并通过--config参数或修改代码指定不同的配置路径。5.2 性能优化与缓存策略调整缓存时间默认的API缓存时间是300秒5分钟。对于作业、成绩等不常变动的数据可以适当延长如api_ttl_seconds: 3600。对于公告等可能更新频繁的数据可以缩短或设置为0。你可以根据不同的API端点细化缓存策略但这需要修改源代码。清理缓存如果怀疑缓存数据过期或出错可以手动删除cache/目录下的所有文件。文件下载器也使用缓存如果文件下载不完整或被破坏同样可以清理缓存目录。网络超时处理在网络不稳定的环境可以在MoodleConnector初始化时为底层的requests.Session设置更长的timeout参数避免因网络波动导致频繁失败。5.3 安全最佳实践密码管理MOODLE_CRED_PASSWORD是保护令牌的关键。避免使用简单密码。在自动化脚本中可以考虑从安全的密码管理器读取或使用操作系统提供的密钥环如keyring库。配置文件隔离永远不要将包含真实web_service_token或密码的config.json提交到版本控制系统如Git。确保.gitignore文件包含了config.json和credentials.enc。环境区分在开发、测试、生产不同环境使用不同的配置文件和密码。权限控制在服务器上运行时确保credentials.enc等敏感文件的读写权限仅限于执行进程的用户。5.4 扩展与二次开发思路这个项目提供了很好的基础框架你可以基于它进行扩展开发图形界面利用MoodleConnector类可以轻松构建一个本地的桌面或Web应用提供更友好的课程管理界面。集成到笔记软件将summary()输出的Markdown定期同步到Obsidian、Logseq等笔记软件中构建个人知识库。构建通知机器人结合上一节的Python脚本示例将作业截止提醒、新公告通知推送到Telegram、Discord或微信。数据分析定期收集成绩、作业提交时间等数据使用Pandas进行分析可视化自己的学习趋势。支持更多Moodle插件当前工具主要覆盖核心功能。你可以查阅Moodle的Web Service API文档为特定的活动模块如问卷、Wiki、数据库添加支持。5.5 我踩过的“坑”与心得SSO流程的不可预测性不同学校的SSO页面尤其是微软Azure AD可能有细微差别比如额外的“是否保持登录”选项、不同的MFA推送方式。自动化脚本虽然能处理标准流程但遇到非标界面时可能会卡住。我的经验是第一次登录时密切观察浏览器自动操作的全过程确保它能顺利走到最后一步。如果卡住可能需要调整playwright的等待逻辑或选择器。文件URL的获取batch_downloader需要你手动提供每个文件的完整URL。从Moodle页面获取这些URL有时比较麻烦特别是当资源被嵌套在文件夹或页面中时。一个技巧是先使用materials()API获取某个课程的所有材料列表里面通常会包含资源的直接URL。你可以写一个小脚本将materials()的输出转换成downloads.json所需的格式实现半自动化。MCP服务器的路径问题在配置Claude Code时args中的Python脚本路径必须使用绝对路径并且要确保该Python环境已安装所有依赖。我最初使用了相对路径导致启动失败。建议在终端中先用绝对路径直接运行python /path/to/mcp_server.py测试一下确保它能正常启动且不报错再填入配置。令牌的长期有效性不要假设令牌永远有效。在设计任何重要的自动化流程时比如每天同步作业一定要加入错误处理。当API返回认证错误时自动触发重新登录流程或至少发送一个报警通知而不是让整个流程静默失败。这个工具将Moodle从一个封闭的网站变成了一个开放的数据平台其设计理念——通过标准化协议MCP和自动化流程来提升效率——非常值得借鉴。无论你是想解放双手的学生还是希望构建教育科技应用的开发者它都提供了一个坚实且优雅的起点。