Moodle自动化工具:零配置API客户端与AI助手集成实战
1. 项目概述
如果你是一名学生或者教育工作者,正在使用Moodle作为你的学习管理系统,那么你很可能经历过这样的场景:为了下载课程资料,你需要在浏览器里一个个点击链接,手动保存文件;想要查看最新的作业截止日期,你得反复刷新日历页面;或者,当你试图通过编程方式获取课程数据时,却发现官方的Web服务API要么配置复杂,要么不支持你学校的单点登录。这些问题不仅耗时,而且打断了你专注于学习或研究本身的流程。今天要聊的这个工具,moodle-connector,就是为了解决这些痛点而生的。它是一个功能全面的Moodle REST API客户端,集成了批量下载功能,并且原生支持MCP协议,能够无缝接入像Claude Code、OpenCode这样的现代AI编程助手。简单来说,它让你能用命令行、Python脚本或者直接通过AI对话,来高效地管理你的Moodle学习数据。
这个工具的核心价值在于它的“无侵入性”和“自动化”。它不需要你的Moodle管理员进行任何特殊的服务器端配置,尤其是对于使用了微软Azure AD、Google或其他SAML等单点登录的学校,它巧妙地复用了官方Moodle移动应用的认证流程。这意味着,即使你的学校没有为你单独开通API令牌,你也能通过一个自动化的浏览器交互流程完成登录并获取访问权限。对于开发者或技术爱好者,它提供了从CLI工具、Python库到MCP服务器三种使用模式,覆盖了从简单查询到复杂集成的各种需求。接下来,我将带你深入拆解它的设计思路、核心功能,并分享从安装配置到高级集成的完整实操经验。
2. 核心设计思路与架构解析
2.1 为什么选择“移动应用启动流”作为认证核心?
在深入代码之前,理解moodle-connector的认证机制至关重要,这也是它最巧妙的设计。传统的Moodle Web服务API需要管理员在后台手动为用户生成一个“Web服务令牌”,这个过程往往涉及权限配置,且并非所有机构都对学生开放此功能。moodle-connector绕开了这个限制,直接采用了Moodle为官方移动应用设计的“移动启动流”。
这个流程的本质是:Moodle服务器提供了一个特定的端点(/admin/tool/mobile/launch.php),当移动应用需要获取一个长期有效的API令牌时,会通过这个端点发起请求。如果用户没有有效的Web会话,Moodle会将用户重定向到配置的SSO提供商(如微软登录页面)进行认证。认证成功后,SSO回跳至Moodle,Moodle最终会响应一个特殊的重定向,其URL协议头是moodlemobile://,并在其中包含了编码后的API令牌。
moodle-connector的自动化脚本(使用Playwright无头浏览器)模拟了这一过程:
- 启动一个浏览器实例,导航到启动流URL。
- 浏览器会经历完整的SSO登录流程(包括可能的多因素认证),这一切对用户是可见的、可交互的。
- 脚本监听网络响应,专门捕获那个包含
moodlemobile://的重定向。 - 从该URL中解析出令牌,加密存储,然后自动关闭浏览器。
这个设计的优势非常明显:
- 零服务器配置:学生或教师个人即可使用,无需IT部门介入。
- 广泛的兼容性:只要你的Moodle实例支持官方移动应用(绝大多数都支持),且启用了移动服务,这个流程就能工作。它不关心后端具体是微软、Google还是其他SAML提供商。
- 用户体验一致:登录流程和你在手机上用Moodle App登录一模一样,包括MFA推送,降低了使用门槛。
注意:这个流程的成功运行,前提是你的教育机构允许使用Moodle移动应用。有些机构出于安全策略可能会禁用此功能,如果在登录时浏览器页面没有正确跳转或捕获不到令牌,这可能是首要排查点。
2.2 三层集成模式:CLI、库与MCP
moodle-connector提供了三种不同抽象层次的使用方式,以适应不同的场景和用户群体。
第一层:命令行界面这是最直接、最快捷的使用方式。通过一系列简单的python moodle_connector.py <command>命令,你可以完成大部分常见操作,比如列出课程、查看成绩、下载资料。它非常适合进行快速的数据查询和一次性任务,也方便集成到Shell脚本中实现自动化。例如,你可以写一个每日运行的Cron作业,用deadlines命令检查即将到来的截止日期,并通过邮件或消息推送提醒自己。
第二层:Python库对于需要在Python项目中深度集成Moodle数据的开发者,moodle-connector提供了完整的Python API。你可以将它作为一个模块导入,创建连接器实例,然后以编程方式调用各种方法。这为构建更复杂的应用打开了大门,比如:
- 开发一个本地的课程仪表盘,聚合所有课程信息。
- 创建一个自动化的作业提交提醒机器人。
- 将课程资料同步到你偏好的笔记软件或云存储中。
- 进行学习数据分析,生成个性化的学习报告。
库模式提供了最大的灵活性,允许你精细控制数据流和处理逻辑。
第三层:MCP服务器这是该项目最具前瞻性的特性。MCP是一种新兴的协议,旨在让AI助手(如Claude Code)能够安全、可控地调用外部工具和服务。通过将moodle-connector封装为MCP服务器,你可以在Claude Code的对话窗口中,直接使用自然语言指令来操作你的Moodle数据,例如:“帮我看看这周有哪些作业要交?”或者“把机器学习课程第三周的所有资料下载到当前目录”。
这种集成模式模糊了工具和助手的边界,将数据获取能力变成了AI工作流的一部分,极大地提升了在编程和学习过程中的效率。MCP服务器模式封装了底层的认证和API调用细节,对最终用户(通过AI助手)暴露的是一组清晰、安全的工具函数。
2.3 安全与数据持久化策略
处理教育平台的凭证和数据,安全是重中之重。moodle-connector在这方面做了几层考虑:
凭证加密存储:获取到的Moodle API令牌(相当于你的长期密码)不会以明文形式保存。它使用
cryptography库,结合PBKDF2密钥派生函数(48万次迭代)和Fernet对称加密,将令牌加密后存储在credentials.enc文件中。解密所需的密码通过环境变量MOODLE_CRED_PASSWORD传入,避免了在脚本或配置文件中硬编码密码。环境变量驱动:强制要求通过环境变量提供加密密码,这是一种良好的安全实践。它避免了密码被意外提交到版本控制系统(如Git),也便于在服务器或容器化环境中进行配置管理。
缓存机制:为了避免对Moodle API的频繁请求(可能触发速率限制或增加服务器负载),工具实现了请求缓存。API响应会被缓存在本地
cache/目录下,并有一个可配置的存活时间。这对于courses、materials这类不常变化的数据非常有效,能显著提升后续命令的响应速度。缓存文件也提供了离线查看部分数据的可能性。MCP错误净化:当作为MCP服务器运行时,工具会确保内部错误细节(如堆栈跟踪、文件路径)不会泄露给客户端(AI助手)。只返回对用户友好的错误信息,这既保护了系统隐私,也提供了更好的用户体验。
3. 从零开始的完整部署与配置指南
3.1 环境准备与依赖安装
首先,你需要一个Python环境。我强烈建议使用Python 3.10或更高版本,以确保所有依赖库的兼容性。如果你使用conda或venv管理虚拟环境,先创建并激活一个。
项目的安装流程在README中描述为通过clawhub(一个OpenClaw的技能管理器)。但对于大多数用户,更通用的方式是直接从GitHub克隆仓库:
git clone https://github.com/Jabir-Srj/moodle-connector.git cd moodle-connector接下来安装Python依赖。项目根目录下的requirements.txt文件列出了所有必要的库:
pip install -r requirements.txt这里的关键依赖包括:
requests: 用于发送HTTP请求到Moodle API。cryptography: 提供强大的加密功能,用于保护你的凭证。playwright: 用于自动化浏览器交互,实现SSO登录流程。mcp: 实现MCP服务器协议,与AI助手通信。
安装完Python包后,必须安装Playwright所需的浏览器内核。这一步很容易被忽略,导致后续登录脚本失败。
python -m playwright install chromium这里安装的是Chromium,它是一个开源的浏览器核心,Playwright用它来驱动自动化。安装过程会下载对应的浏览器二进制文件,请确保网络通畅。
3.2 核心配置文件详解
配置是使用该工具的第一步。项目提供了一个模板文件config.template.json,你需要复制它并创建自己的配置文件。
cp config.template.json config.json现在用你喜欢的文本编辑器打开config.json。它的结构非常简单,但每个字段都至关重要。
{ "moodle": { "base_url": "https://your-moodle-site.example.com", "web_service_token": "" }, "cache": { "api_ttl_seconds": 300 } }moodle.base_url: 这是你学校Moodle实例的根地址。注意,地址通常以https://开头,并且不包含尾随的斜杠。例如:https://mytimes.taylors.edu.my或https://aula.usm.cl。务必填写正确,这是所有API调用的基础。moodle.web_service_token: 这个字段通常留空。留空表示工具将使用前面介绍的自动化浏览器流程来获取令牌。如果你已经从其他途径(比如手动从Moodle个人设置中生成)获得了一个有效的Web服务令牌,可以在这里填写,工具将直接使用它而跳过登录流程。cache.api_ttl_seconds: API缓存的有效时间,单位是秒。默认300秒(5分钟)。意味着在5分钟内,重复请求同一数据会直接返回本地缓存,而不会访问网络。你可以根据数据更新频率调整这个值。对于课程列表这类不常变的数据,可以设置更长(如3600秒);对于作业或成绩,可能希望设置短一些。
实操心得:在首次配置时,我建议将
api_ttl_seconds设置为一个较小的值(比如60),以便在调试阶段能快速看到更改效果。等一切稳定后,再调整为更合理的值以提升性能。另外,务必确保你的config.json文件被添加到.gitignore中,避免将你的个人站点信息意外提交到公开仓库。
3.3 首次登录与认证流程实战
配置好base_url后,就可以进行首次登录了。这是最关键的一步。你需要设置加密密码的环境变量,然后运行登录命令。
在Linux/macOS的终端或Windows的PowerShell/CMD中:
# Linux/macOS export MOODLE_CRED_PASSWORD="your-strong-password-here" python moodle_connector.py login # Windows (PowerShell) $env:MOODLE_CRED_PASSWORD="your-strong-password-here" python moodle_connector.py login # Windows (CMD) set MOODLE_CRED_PASSWORD=your-strong-password-here python moodle_connector.py login请将your-strong-password-here替换为你自己设定的一个强密码。这个密码用于加密/解密你的Moodle令牌,请妥善保管。每次运行工具(无论是CLI、库还是MCP服务器)都需要提供相同的密码。
运行命令后,你会看到一个新的浏览器窗口(或标签页)自动打开,并导航到你Moodle站点的移动启动页面。接下来:
- 交互登录:如果尚未登录,浏览器会跳转到你学校的SSO页面(可能是微软、Google登录页)。请像平时一样输入你的学校账号和密码。
- 完成MFA:如果启用了多因素认证,按照提示完成验证(如点击手机认证App的确认、输入短信验证码等)。
- 自动捕获与关闭:登录成功后,Moodle会发起一个
moodlemobile://的重定向。moodle-connector的脚本会捕获这个请求,从中提取令牌,然后自动关闭浏览器窗口。整个过程你无需手动复制任何URL或令牌。
如果一切顺利,终端会输出类似以下的信息:
# ✅ Authentication Successful - User: 张三 (zhangsan@university.edu) - Site: https://aula.usm.cl - Moodle version: 4.3.1同时,当前目录下会生成一个credentials.enc文件,里面存储的就是加密后的令牌。请勿删除或随意分享此文件。只要令牌未过期(通常有效期很长),后续所有操作都将使用这个缓存凭证,无需再次登录。
注意事项:有时浏览器可能会被学校的登录页面额外要求确认设备或同意条款,请仔细完成所有交互步骤。如果浏览器打开后长时间停留在某个页面没有自动关闭,可能是网络问题、页面元素加载慢,或者学校的移动服务被禁用。可以按
Ctrl+C终止命令,检查终端是否有错误输出,并确认你的Moodle实例是否确实支持官方移动应用。
4. CLI工具使用详解与场景化示例
成功登录后,你就可以尽情使用命令行工具了。CLI提供了最直观的交互方式。下面我将逐一解析每个命令,并附上实际使用场景。
4.1 信息查询类命令
这些命令用于从Moodle获取各种信息,并以结构化的JSON或格式化的文本输出。
列出所有课程 (
courses)python moodle_connector.py courses这个命令会获取你当前学期(以及可能的历史学期)注册的所有课程列表。输出包括课程ID、全名、短名称、开始/结束日期等。课程ID是后续许多命令(如
materials)的关键参数。查看成绩 (
grades)python moodle_connector.py grades获取你在所有课程中的成绩概览。输出通常按课程分组,显示每个评分项目(如作业、测验、考试)的得分、满分以及百分比。这对于快速了解自己的学习进度非常有用。
查看作业与截止日期有两个相关命令:
python moodle_connector.py assignments python moodle_connector.py deadlinesassignments命令专门获取作业信息,包括作业名称、描述、截止日期、提交状态等。deadlines命令则从日历API获取所有即将到来的事件(可能包含作业、测验、其他活动)。根据README的提示,某些Moodle版本的日历API可能有参数问题,如果deadlines报错,使用assignments通常能获得相同的截止日期信息。查看课程公告 (
announcements)python moodle_connector.py announcements获取所有课程论坛中的最新公告。老师通常通过这里发布重要通知,这个命令能帮你集中查看,避免遗漏。
获取课程资料列表 (
materials)# 获取所有课程的资料 python moodle_connector.py materials # 获取特定课程的资料(需要课程ID) python moodle_connector.py materials --course-id 12345这是非常强大的功能。它会扫描课程的所有章节和模块,列出所有可用的资源:PDF文件、Word文档、视频链接、外部URL等。输出中会包含每个资源的名称、类型以及最重要的——下载URL。这个URL是后续
download命令或批量下载的输入。
4.2 文件下载与数据导出命令
单文件下载 (
download)python moodle_connector.py download "https://your-moodle-site/pluginfile.php/..." --output lecture1.pdf当你从
materials命令或网页上获得一个具体的文件URL后,可以用此命令下载它。工具内置了缓存机制和重试逻辑。--output参数可选,如果不指定,会尝试从URL或响应头中推断文件名。完整数据摘要导出 (
summary)python moodle_connector.py summary这个命令堪称“瑞士军刀”。它会一次性调用上述所有信息查询命令(课程、成绩、作业、资料、截止日期、公告),并将结果整合成一个结构化的Markdown文档输出到终端。你可以将其重定向到文件,生成一份个人学习状态的完整快照。
python moodle_connector.py summary > my_moodle_status.md生成的文件非常适合归档,或者导入到笔记软件中进行进一步整理。
4.3 场景化应用示例
场景一:每周学习启动清单你可以创建一个简单的Shell脚本(比如weekly_review.sh),在每周一早上自动运行:
#!/bin/bash export MOODLE_CRED_PASSWORD="your-password" cd /path/to/moodle-connector # 生成本周摘要 python moodle_connector.py summary > "$(date +%Y-%m-%d)_summary.md" # 检查未来7天的截止日期,并高亮显示 python moodle_connector.py assignments | jq -r '.[] | select(.duedate > now and .duedate < now+604800) | "\(.coursename): \(.name) - Due: \(.duedate_str)"' # 注意:上述jq命令需要安装jq工具,并且时间戳需要转换,此处仅为逻辑示例。场景二:快速下载特定课程的所有课件假设你已经知道“机器学习”课程的ID是44864。
- 首先,获取该课程所有资料的URL列表:
python moodle_connector.py materials --course-id 44864 > ml_materials.json - 然后,编写一个简单的Python脚本解析这个JSON,循环调用
download命令,或者更高效地,使用下一节会讲到的批量下载器。
5. 高级应用:Python库集成与批量下载
5.1 将Moodle数据集成到你的Python项目中
CLI适合交互和脚本,但如果你想构建一个图形界面、一个自动化流水线或一个数据分析程序,Python库模式提供了最大的灵活性。以下是一个更深入的使用示例:
from moodle_connector import MoodleConnector from pathlib import Path import json from datetime import datetime, timedelta # 1. 初始化连接器 # 假设你的config.json和credentials.enc在当前目录 config_path = Path('config.json') connector = MoodleConnector(config_path=config_path, password='your-encryption-password') # 注意:生产环境应从环境变量读取密码 # 2. 获取数据 print("正在获取课程信息...") all_courses = connector.courses() current_courses = [c for c in all_courses if c.get('enddate', 0) > datetime.now().timestamp()] print(f"你本学期有 {len(current_courses)} 门课程。") for course in current_courses: print(f"\n--- {course['fullname']} ---") # 获取该课程作业 assignments = connector.assignments(course_id=course['id']) upcoming = [a for a in assignments if a.get('duedate') and datetime.fromtimestamp(a['duedate']) > datetime.now()] if upcoming: print("即将截止的作业:") for a in upcoming[:3]: # 显示最近的三项 due_date = datetime.fromtimestamp(a['duedate']).strftime('%Y-%m-%d %H:%M') print(f" - {a['name']} (截止: {due_date})") # 获取该课程最新公告 announcements = connector.announcements(course_id=course['id']) if announcements: latest = announcements[0] print(f"最新公告: {latest['subject']} ({latest['timecreated_str']})") # 3. 下载特定资源 # 假设你从materials()中获得了某个文件的URL file_url = "https://.../lecture.pdf" try: file_content = connector.download(file_url) with open('downloaded_lecture.pdf', 'wb') as f: f.write(file_content) print("文件下载成功。") except Exception as e: print(f"下载失败: {e}") # 4. 导出完整数据用于分析 full_data = connector.summary() with open('full_moodle_data.json', 'w', encoding='utf-8') as f: json.dump(full_data, f, ensure_ascii=False, indent=2) print("完整数据已导出至 full_moodle_data.json")关键点解析:
MoodleConnector类是所有功能的入口。初始化时,它会自动加载配置,并使用提供的密码尝试解密本地凭证。如果凭证不存在或已过期,你需要先通过CLI的login命令完成首次认证。- 所有数据获取方法(如
courses(),assignments())返回的都是Python字典或字典列表,方便你用程序进行处理。 download(url)方法返回的是文件的二进制内容(bytes),你需要自己决定如何保存它(写入文件、存入数据库等)。summary()方法返回的是一个包含了所有类别数据的综合字典结构。
5.2 配置化批量下载器实战
手动一个个下载文件很麻烦。batch_downloader.py脚本配合一个JSON配置文件,可以实现全自动、可定制的批量下载。
第一步:准备下载清单复制示例配置文件并编辑:
cp downloads.example.json downloads.json编辑downloads.json,其结构如下:
{ "downloads": [ { "module": "机器学习基础", "course_id": 44864, "files": [ { "name": "第一周_引言与概览.pdf", "url": "https://your-moodle.com/pluginfile.php/12345/mod_resource/content/1/week1.pdf" }, { "name": "编程作业1说明.zip", "url": "https://your-moodle.com/pluginfile.php/12345/mod_resource/content/2/assignment1.zip" } ] }, { "module": "数据库系统", "course_id": 44865, "files": [ { "name": "Chapter1_SQL基础.pptx", "url": "https://your-moodle.com/pluginfile.php/67890/mod_resource/content/1/ch1.pptx" } ] } ] }module: 你自定义的模块或课程名称,用于创建本地文件夹。course_id: 课程ID,用于信息关联(下载器本身不一定需要,但有助于管理)。files: 一个列表,每个元素包含name(你希望保存的文件名)和url(从materials命令获取的完整下载链接)。
第二步:运行批量下载确保MOODLE_CRED_PASSWORD环境变量已设置,然后运行:
python batch_downloader.py脚本会:
- 读取
downloads.json配置。 - 为每个
module在downloads/目录下创建对应的文件夹(例如downloads/机器学习基础/)。 - 遍历
files列表,使用配置好的连接器(同样需要认证)下载每个URL的文件,并以指定的name保存到对应模块文件夹中。 - 显示下载进度和结果。
输出目录结构:
downloads/ ├── 机器学习基础/ │ ├── 第一周_引言与概览.pdf │ └── 编程作业1说明.zip └── 数据库系统/ └── Chapter1_SQL基础.pptx实操心得与技巧:
- 如何高效获取下载URL?最准确的方法是使用
python moodle_connector.py materials --course-id <ID> --format json命令,将输出重定向到文件,然后从JSON中提取url字段。你可以写一个小脚本来自动化这个过程,将materials的输出转换成downloads.json的格式。- 处理大量文件:如果文件非常多,批量下载可能会运行较长时间。建议在网络稳定的环境下进行。脚本内部应该有基本的错误处理和重试,但如果遇到个别文件失败,可以手动补下。
- 命名策略:在
downloads.json中精心设计name字段非常重要。建议包含周次、主题、文件类型等信息,例如W02_Linear_Regression_Slides.pdf,这样归档后一目了然。- 增量下载:当前的批量下载器是“全量”执行,每次都会重新下载列表中的所有文件。你可以通过检查本地文件是否存在、或比较文件大小/修改时间来实现简单的增量下载逻辑。
6. 无头服务器环境下的令牌获取方案
自动化浏览器登录在带有图形界面的桌面电脑上运行良好。但是,如果你想把moodle-connector部署到一台没有显示器的Linux服务器上(例如,用于定时运行的数据同步脚本),Playwright的无头浏览器可能因为缺少显示环境而失败。此时,你需要一种替代方案来获取初始的API令牌。
项目提供了一个巧妙的解决方案:Tampermonkey用户脚本辅助获取。思路是在一台有浏览器的电脑(比如你的个人笔记本)上,通过一个浏览器脚本手动获取令牌,然后将令牌复制到服务器的config.json文件中。
操作步骤:
在有浏览器的机器上:
- 安装Tampermonkey浏览器扩展。
- 打开Tampermonkey的管理面板,点击“创建新脚本”。
- 将项目中的
moodle_token_helper.user.js文件内容完全复制到编辑器中。 - 保存脚本。该脚本默认会匹配在
README中提到的已测试的Moodle站点(如*.taylors.edu.my,*.usm.cl)。如果你的学校域名不同,你需要修改脚本顶部的@match和@connect指令,将其改为你的Moodle站点地址,例如:// @match https://your-moodle-site.example.com/* // @connect your-moodle-site.example.com
获取令牌:
- 确保你已用浏览器正常登录了学校的Moodle网站。
- 访问你的Moodle站点首页。
- 此时,页面右下角会出现一个蓝色的“Get Token”按钮(由Tampermonkey脚本添加)。
- 点击这个按钮。脚本会在后台模拟移动启动流程,利用你当前的登录会话Cookie去请求令牌,并拦截
moodlemobile://重定向。 - 成功后,页面会弹出一个对话框,显示获取到的
web_service_token(一串长字符)。
部署到服务器:
- 复制弹出的令牌字符串。
- 在你的服务器上,编辑
config.json文件,将复制的令牌粘贴到"web_service_token"字段中(原来为空)。 - 确保
MOODLE_CRED_PASSWORD环境变量已设置(用于加密存储,但此时已有令牌,可能仅用于其他加密上下文或未来刷新)。 - 现在,服务器上的
moodle-connector在初始化时,会直接使用这个手动配置的令牌,而不再尝试启动浏览器登录。
重要提示:通过此方式获取的令牌与通过浏览器自动化获取的令牌具有相同的有效期。当令牌过期后,你需要重复此过程获取新令牌并更新服务器上的配置。这是一种“半自动”的解决方案,适用于无法进行交互式登录的服务器环境。
7. 与AI助手深度集成:MCP服务器配置
MCP(Model Context Protocol)是Anthropic提出的一种协议,旨在让AI模型能够安全、可控地使用外部工具。moodle-connector的MCP服务器功能,让你可以在Claude Code、OpenCode等支持MCP的编辑器中,直接通过对话来查询和操作你的Moodle数据。
7.1 配置Claude Desktop
这是最典型的集成场景。你需要编辑Claude Desktop应用的配置文件。
找到配置文件:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
- macOS:
编辑配置文件: 如果文件不存在,就创建它。在其中添加
moodle-connector服务器的配置。关键点:你需要指定MCP服务器的启动命令,并传递加密密码环境变量。同时,你需要知道mcp_server.py脚本在你电脑上的绝对路径。{ "mcpServers": { "moodle-connector": { "command": "python", "args": [ "/ABSOLUTE/PATH/TO/YOUR/moodle-connector/mcp_server.py" ], "env": { "MOODLE_CRED_PASSWORD": "your-encryption-password" } } } }- 将
/ABSOLUTE/PATH/TO/YOUR/moodle-connector/替换为你克隆项目后的实际路径。 - 将
your-encryption-password替换为你之前设置并一直使用的那个加密密码。
- 将
重启Claude Desktop: 保存配置文件后,完全关闭并重新启动Claude Desktop应用。
7.2 在Claude Code中使用Moodle工具
重启后,Claude Code应该已经连接上了moodle-connectorMCP服务器。你可以在聊天窗口中尝试以下类型的指令:
自然语言查询:
- “列出我这学期的所有课程。”
- “我这周有哪些作业要交?”
- “我在‘数据结构’这门课的成绩怎么样?”
- “把‘计算机视觉’课程第三周的资料下载到我当前目录。”
直接工具调用: 在一些支持工具选择的界面,你可能可以直接看到名为
courses,grades,download等工具。点击或调用它们,Claude会引导你完成参数输入(如需要的话)。
背后的工作原理: 当你发出指令时,Claude Code会将你的自然语言转换为对特定MCP工具的调用请求。这个请求通过标准输入/输出发送给mcp_server.py进程。MCP服务器接收到请求后:
- 使用环境变量中的密码初始化
MoodleConnector。 - 调用对应的Python方法(如
connector.courses())。 - 将返回的数据结构转换为MCP协议规定的格式。
- 通过标准输出将结果返回给Claude Code。
- Claude Code将结果格式化后展示给你。
整个过程对你来说是透明的,你感觉就像是在直接问Claude关于Moodle的事情。
7.3 安全性与错误处理
MCP集成模式特别注重安全:
- 环境隔离:Moodle凭证的加密密码通过
env配置传递,不会在聊天记录或Claude的上下文中暴露。 - 错误净化:如果MCP服务器内部发生错误(如网络问题、API变更),它会捕获异常并返回一个通用的、对用户友好的错误信息,而不会将Python堆栈跟踪等内部细节泄露给AI助手,避免了潜在的信息泄露。
- 工具范围限制:AI助手只能使用服务器暴露的这8个预定工具,无法执行任意命令或访问文件系统,提供了良好的安全边界。
8. 故障排除与经验分享
即使设计再完善的工具,在实际使用中也可能遇到各种环境或配置问题。下面是我在部署和使用过程中遇到的一些典型问题及解决方法。
8.1 登录流程相关问题
问题:浏览器打开后,停留在登录页面,长时间不自动关闭。
- 可能原因1:移动服务被禁用。这是最常见的原因。有些学校出于安全考虑,禁用了Moodle的移动应用服务。你可以尝试用手机访问你学校的Moodle网站,看是否会提示下载官方App或是否有一个移动版界面。如果完全没有,可能此路不通。
- 可能原因2:网络或页面加载问题。SSO页面可能包含复杂的JavaScript,或者网络较慢导致脚本未能及时检测到重定向。可以尝试增加Playwright的等待超时时间(需要修改
moodle_connector.py中的相关代码)。 - 可能原因3:多因素认证流程特殊。某些MFA流程(如硬件令牌)可能需要额外的用户交互,超出了脚本的自动化范围。确保你使用的是常见的MFA方式(如手机App确认、短信码)。
- 排查方法:运行登录命令时,可以尝试添加
--no-headless参数(如果脚本支持),让浏览器以非无头模式运行,观察整个流程卡在哪一步。你也可以手动完成登录后,观察地址栏是否会最终跳转到一个moodlemobile://开头的URL。
问题:登录成功,但后续命令提示“Invalid token”或“Access denied”。
- 可能原因1:令牌未正确保存。检查当前目录下是否生成了
credentials.enc文件。文件大小是否正常?可以尝试删除该文件并重新登录。 - 可能原因2:环境变量密码不一致。确保每次运行命令时,
MOODLE_CRED_PASSWORD环境变量的值与首次登录时使用的完全一致。大小写敏感。 - 可能原因3:Moodle站点权限问题。获取到的令牌可能缺少某些API功能的权限。这比较罕见,因为移动启动流通常授予了移动应用所需的全部权限。
8.2 API请求与数据获取问题
问题:deadlines命令报错“Invalid parameter value detected”。
- 解决方案:正如README所指出的,这是某些Moodle版本日历API的已知问题。直接使用
assignments命令替代,它通常包含相同的截止日期信息,且更稳定。
问题:materials命令返回的列表为空或不完整。
- 可能原因:Moodle中的课程资料可能以多种形式存在(资源、页面、URL、文件夹等)。
materials命令主要抓取可下载的文件资源。有些资料可能是嵌入的文本页面、外部链接或需要在线查看的活动,这些可能不会被识别为“文件”。此外,老师可能对某些资源设置了访问限制(如按日期开放、需完成前置活动)。 - 排查方法:在Moodle网页版中浏览该课程,看看你想获取的资料具体是什么类型。如果是PDF、PPT等文件,通常可以获取到。
问题:文件下载缓慢或失败。
- 可能原因1:网络问题或文件较大。工具内置的请求可能有默认超时时间。对于大文件,可以考虑在代码中增加超时设置。
- 可能原因2:下载链接失效或需要会话。Moodle的文件下载链接通常是临时的,并且需要有效的会话。确保你的令牌没有过期。如果过期,需要重新登录。
- 解决方案:可以尝试清除缓存目录
rm -rf cache/,然后重新运行命令。对于批量下载,建议实现简单的重试机制。
8.3 MCP服务器集成问题
问题:Claude Code中看不到Moodle工具。
- 检查1:配置文件路径和语法。确保
claude_desktop_config.json路径正确,JSON格式无误(无尾随逗号,字符串正确引号)。 - 检查2:Python路径和依赖。确保
command指定的python在系统路径中,并且moodle-connector目录下的所有依赖(特别是mcp包)已安装。可以在终端手动运行python /path/to/mcp_server.py看是否有导入错误。 - 检查3:Claude Desktop日志。查看Claude Desktop的应用日志,通常会有MCP服务器连接失败的详细信息。日志位置因操作系统而异。
- 检查4:环境变量。确保配置中
env里的MOODLE_CRED_PASSWORD值正确,且与加密credentials.enc文件的密码一致。
问题:调用工具时返回“Authentication required”或类似错误。
- 可能原因:MCP服务器启动时无法加载有效的凭证。首先确保你已通过CLI成功登录并生成了
credentials.enc文件。其次,确认配置文件中env设置的密码能正确解密该文件。
8.4 维护与更新
- 令牌过期:Moodle移动令牌通常有效期较长(数周或数月),但并非永久有效。如果所有命令突然开始返回认证错误,最可能的原因就是令牌过期。只需删除
credentials.enc文件,重新运行python moodle_connector.py login即可。 - 项目更新:关注原GitHub仓库的更新。开发者可能会修复bug、添加新功能或适配Moodle API的变更。更新后,记得重新安装依赖(
pip install -r requirements.txt)。 - 缓存管理:
cache/目录会随着使用逐渐增大。定期清理可以释放磁盘空间,但也会导致下次请求需要重新从网络获取。你可以根据需求决定是定期删除,还是设置一个较短的api_ttl_seconds。
这个工具的核心价值在于它为学生和开发者提供了一个统一、自动化的接口,将分散在Moodle网页各处的信息聚合起来。无论是通过命令行快速查询,还是通过Python脚本进行复杂的数据处理,亦或是通过与AI助手的自然语言交互,它都极大地提升了信息获取和处理的效率。它的设计充分考虑到了现实世界的复杂性,特别是对SSO登录的支持,使得它在许多严格的校园IT环境下也能工作。如果你经常与Moodle打交道,花点时间部署和配置它,很可能会成为你学习工作流中一个不可或缺的助力。
