mcp-usc
mcp-usc
面向圣地亚哥·德·孔波斯特拉大学(Universidade de Santiago de Compostela)Moodle 虚拟校园的本地 MCP 服务器,采用 HTTP-first 架构。可查询课程、日历、消息、论坛、资料、作业和测验,还能在 USC 官方页面和 PDF 中搜索考试日期。
0.3.0 版本将学生覆盖范围扩展至 301 项已研究的 Moodle 能力:192 项允许的读取操作和 109 项已识别的操作。只有十二项范围明确且无歧义的私有变更可通过通用接口执行;发布、可评分的活动、提交、测验和删除操作均使用上下文工具。所有会产生影响的操作都要求预览、一次性令牌和 MCP 客户端的批准。
设计原则
MCP 服务器使用 STDIO;「HTTP-first」描述的是此进程与 Moodle/USC 之间的连接。
常规查询和写入操作不自动化浏览器。
当存在合法令牌时,优先使用 Moodle 官方 REST API。
使用
MoodleSessioncookie 时,读取操作使用同源 AJAX 和直接下载/pluginfile.php。HTML 表单仅保留给已确认的测验操作。Playwright 仅打开可见浏览器以完成 Microsoft Entra/MFA 并获取初始 cookie。登录完成后即关闭。
所有远程文本——名称、消息、问题、通知和文档——均标记为不可信内容,绝不将其解释为指令。
连接器仅以已认证账户的权限运行:不提升权限,也不冒充教师或管理人员。
必须使用学生账户和最低权限令牌进行配置。Moodle 的共享 API 始终遵循有效权限,具有额外角色的账户可能比普通学生看到更多数据。
不查询邮件或 Teams。Moodle 内部消息可能根据收件人的设置生成外部通知;预览会在发送前发出警告。
Related MCP server: MCP UJI Academic Server
要求
Windows、Linux 或 macOS;
Python 3.11 或更高版本;
推荐使用
uv;需要有效的 USC 账户才能访问私有数据;
可选:暴露所需功能的 Moodle Web Services 令牌。
安装
git clone https://github.com/PabloPC05/mcp-usc.git
cd mcp-usc
uv sync --extra dev这足以使用 REST 令牌或已存储的会话运行服务器。仅当需要通过登录助手创建或续期会话时才安装 Playwright:
uv sync --extra dev --extra browser-auth
uv run playwright install chromium助手可以使用 Chromium 或已安装的 Chrome/Edge:
$env:USC_BROWSER_CHANNEL = "chrome" # también "msedge" o "chromium"认证与 HTTP 传输
连接器按以下顺序自动选择私有传输方式:
如果
USC_MOODLE_TOKEN或USC_MOODLE_TOKEN_FILE提供了令牌,则使用官方 REST。使用
keyring保存的MoodleSessioncookie 进行 HTTP 访问。
REST 令牌
仅使用 Moodle 为你的账户和服务签发的合法令牌:
$env:USC_MOODLE_TOKEN = "..."
uv run mcp-usc status也可以从受保护的本地文件中读取:
$env:USC_MOODLE_TOKEN_FILE = "C:\ruta\privada\moodle-token.txt"不要使用你的 USC 密码配合 login/token.php,也不要将其保存在 .env 中。Moodle 中存在某个函数并不意味着该函数在令牌关联的服务中已启用。
Cookie 会话
uv run mcp-usc login
uv run mcp-usc status请在可见窗口中亲自完成 Microsoft Entra 和 MFA。程序仅提取 MoodleSession,通过 HTTP 验证会话,并将 cookie 以 moodle-session 为键保存在系统安全存储中——Windows 上为凭据管理器。密码不会经过 MCP。
登录后,所有操作均使用 httpx:
/user/preferences.php提供身份信息和临时sesskey,无需打开仪表盘;/lib/ajax/service.php执行标记为 AJAX 的函数;如果 Moodle 未通过 AJAX 发布读取内容,则读取操作会以封闭方式失败;
认证下载保留 cookie,仅接受直接的
/pluginfile.php,并应用本地限制;只有某些测验操作在明确确认后才可使用 HTML 表单。
sesskey 不会被持久化或返回。由于 AJAX 协议的要求,它可能出现在 Moodle 基础设施可见的 URL 中。cookie 在有效期内等同于凭据:不要复制、记录、发布或同步它。过期后,重复执行 mcp-usc login。
兼容性矩阵
能力 | REST 令牌 | HTTP 会话 |
课程、时间线和日历 | API REST | AJAX;不回退到记录浏览次数的页面 |
对话和消息 | REST | AJAX |
论坛和讨论 | REST | 存在时使用 AJAX;无 HTML 回退 |
讨论中的帖子 | REST 需确认 | AJAX 需确认(如果该函数存在) |
发布论坛讨论/回复 | REST | 无法通过 AJAX 安全实现 |
创建/删除个人事件 | REST | 无法通过 AJAX 安全实现 |
提交/撤回 Choice 回复 | REST | 无法通过 AJAX 安全实现 |
资料和资源 | REST | AJAX 和直接下载 |
作业的读取和修改 | REST | 无法安全实现 |
提交文件 | REST + | 不操作 JavaScript |
测验 | REST | 纯读取使用 AJAX;操作确认后才使用表单 |
Moodle 的 filemanager 管理器通过 JavaScript 创建草稿,不等同于标准 multipart 字段。如果提交仅提供该管理器,则替换或删除其文件需要授权的 REST 令牌;会话模式下的公共文件工具会停止且不修改任何内容。不使用 Playwright 模拟文件管理器。
授权的本地文件
上传工具在配置 allowlist 文件夹之前处于禁用状态:
$env:USC_UPLOAD_ROOT = "C:\Users\TU_USUARIO\Documents\mcp-usc-uploads"
$env:USC_MAX_UPLOAD_BYTES = "52428800"USC_UPLOAD_ROOT 必须存在。仅接受解析到该文件夹内的常规文件;不跟随逃逸出该文件夹的路径,也不允许同一文件上传两次。预览在发出令牌之前显示相对路径、名称、大小和 SHA-256。
本地上传限制:
每次操作最多 20 个文件;
USC_MAX_UPLOAD_BYTES同时适用于单个文件和总量;默认值:50 MiB(
52428800字节);可配置范围:1 字节至 100 MiB;
在线文本另有 1 MiB 的额外限制。
replace_submission_files 替换提交的完整文件集;不会静默地向现有文件添加一个文件。在发出确认之前,会检查服务是否允许上传以及提交是否仅启用了 file 插件。同样,仅当 onlinetext 是唯一启用的插件时,REST 文本保存才会启用。Moodle 会在 mod_assign_save_submission 中处理所有插件,因此在创建草稿或修改提交之前,未知组合会被拒绝。
公开的考试来源
每个 USC 学院都发布自己的日历。配置以分号分隔的规范页面或 PDF:
$env:USC_EXAM_SOURCES = "https://www.usc.gal/gl/centro/MI_CENTRO/horarios/cursos;https://assets.usc.gal/ruta/calendario.pdf"搜索使用直接 HTTP,仅接受 usc.gal/usc.es 下的 HTTPS,最多跟随五次重定向,每个文档最多下载 15 MB。不进行大规模爬取:仅查询指定来源及其直接的考试/PDF 链接。每条证据保留 URL、适用的 PDF 页面和查询时间;不一致的来源显示为冲突。
连接 Codex
在此计算机上通过 PowerShell 执行:
codex mcp add usc-campus -- uv --directory C:\Users\pablo\mcp-usc run mcp-usc serve
codex mcp list要从 MCP 配置中包含公开来源:
codex mcp remove usc-campus
codex mcp add usc-campus --env USC_EXAM_SOURCES="https://www.usc.gal/gl/centro/MI_CENTRO/horarios/cursos" -- uv --directory C:\Users\pablo\mcp-usc run mcp-usc serve重启客户端或打开新会话以加载服务器。根据 OpenAI 官方文档,MCP 配置在 ChatGPT 应用、Codex CLI 和同一主机的 IDE 扩展之间共享。
另外,在 %USERPROFILE%\.codex\config.toml 中启用主机对所有写入操作的批准:
[mcp_servers.usc-campus]
command = "uv"
args = ["--directory", 'C:\Users\pablo\mcp-usc', "run", "mcp-usc", "serve"]
default_tools_approval_mode = "writes"MCP 注释、预览、令牌和主机批准是互补的层级;任何一层都不能替代对确切参数的人工决策。
MCP 工具
0.3.0 版本公开了 75 个工具:39 个读取操作、18 个预览操作和 18 个有影响的操作。完整能力研究解释了清单、安全边界以及 Moodle 4.5 和 5.2 之间的差异。
分组 | 读取 | 预览 | 写入 |
学生目录 |
|
|
|
校园与日程 |
| 创建或删除个人事件 | 创建或删除个人事件 |
消息与论坛 |
| 消息、帖子检查、新讨论或回复 | 发送消息、检查帖子、创建讨论或回复 |
Choice | 目录的读取函数 | 提交或撤回回答 | 提交或撤回自己的回答 |
材料与考试 |
| — | — |
作业 |
|
|
|
测验 |
| 检查活动中的尝试、开始、保存或结束 | 检查活动中的尝试、开始、保存或结束 |
call_student_read 仅接受白名单中明确包含的 192 个函数;它不是
任意的 Moodle 代理。使用 REST 令牌时,list_student_capabilities(available_only=true) 允许
查看所配置服务公布了哪些函数。使用 AJAX 会话时,完整可用性并不总是
可发现的,如果 Moodle 未公开该函数,每次调用都会封闭式失败。
十二个通用操作仅限于自身偏好、私有收藏、静音或 标记会话/通知、保留未发送的草稿以及标记问题。新的 上下文操作在发出确认之前,先通过专有 HTTP、课程、论坛、群组、受众、阶段和 选项进行解析:
创建或删除日历中的个人事件;
在论坛中发起讨论或公开回复,不含附件或私密回复;
提交或撤回自己在 Choice 活动中的回答。
这六个上下文操作要求合法的 REST 令牌公布它们。Moodle 4.5–5.2 通常不会将其函数标记为 AJAX;cookie 模式在预览之前停止,并且 不会尝试用浏览器模拟它们。
目录还会识别尚无安全执行器的学生操作。这些操作
以 generic_execution_supported=false 发布:出现在清单中并不允许
执行它们,也不意味着 USC 已启用相应的模块或插件。
消息、论坛和材料
list_messages读取已接收或已发送的消息而不将其标记为已读。list_conversations仅 为兼容性而保留,并会封闭式失败:某些 Moodle 版本在执行该所谓的读取时 可能会创建一条与自己的会话并将其标记为收藏。论坛包括所有可见的论坛,而不仅仅是公告。Moodle 在执行
mod_forum_get_discussion_posts时可能会将帖子标记为已读;因此list_discussion_posts会封闭式失败,而preview_inspect_discussion_posts/inspect_discussion_posts这一对操作在遍历 帖子和附件元数据之前要求确认。search_message_contacts会创建对收件人的临时引用。preview_message要求 最近进行过搜索,显示姓名、ID 和文本,并且绝不发送。list_course_contents列出章节、活动、页面、链接和文件。list_course_resources返回十分钟有效的不透明引用。只有最近的引用 可以与read_course_resource一起使用。read_course_resource支持 PDF、文本/HTML 和 OOXML(.docx、.pptx、.xlsx)。默认情况下 将下载限制为 25 MiB、文本限制为 100,000 个字符、PDF 限制为 100 页; 每次调用接受的最大值为 50 MiB、500,000 个字符和 300 页。在会话模式下,内容和公告要求纯 AJAX 函数,资源必须直接指向
/pluginfile.php;打开course/view.php、mod/*/view.php或论坛页面 会被拒绝,因为这可能记录访问、标记已读或改变完成状态。
作业与提交
使用公布了所需函数的 REST 令牌,可以列出作业并查询 草稿、文件、在线文本、反馈和权限。
作业的 HTML 页面会记录浏览并可能改变完成状态;因此,在会话模式下, 所有作业的读取、预览和写入都会在打开之前失败。
保存文本、替换/删除文件、提交评分或删除整个提交 是不同的写入操作,每个操作都有自己的预览。
submit_assignment可能会关闭草稿的编辑,并且必须遵守 Moodle 显示的提交声明。remove_submission使用mod_assign_remove_submission,在 Moodle 4.5 或更高版本中可用。它是 破坏性的,不等同于“重新打开”。check_submission_reopen绝不改变状态。如果提交已可编辑,它会报告该情况;如果已 关闭,标准 API 将重新打开权限保留给教师。连接器不会试图绕过该 限制:必须通过正常渠道向教师请求重新打开。
测验
可以列出测验和自己的尝试,并读取已结束尝试的允许回顾。
打开活动尝试的数据或摘要可能会导致 Moodle 处理到期并 改变其状态。因此
get_quiz_attempt_page和get_quiz_attempt_summary会封闭式失败;preview_inspect_quiz_attempt显示风险,inspect_quiz_attempt要求确认。在会话模式下,纯列表需要 AJAX。表单仅在第二次确认调用中打开, 用于检查可能具有状态的尝试、开始、保存或结束;预览不会打开
mod/quiz/view.php。start_quiz可能会立即启动计时器。save_quiz_answers修改打开的尝试但不会结束它。finish_quiz通常不可逆。问题和字段名称来自 Moodle,被视为不可信数据,连接器 从不推断答案是否正确。
每个写入操作都要求独立的预览;先前的批准 不授权尝试的下一步。
确认与写入
所有写入都遵循两次调用:
preview_*验证状态并返回可见参数以及confirmation_token。写入工具仅当操作和参数完全匹配时才使用该令牌。
令牌仅存在于内存中,五分钟后过期,且一次性使用。更改文本、
收件人、文件、回答、尝试或任何其他输入都会使确认失效。主机的
writes 批准必须保持有效,以便第二次调用要求人工干预。
每个联系人引用和确认令牌也绑定到创建它的 Moodle user_id。
如果在预览和写入之间更改了账户或会话,操作将被拒绝。
对 HTML 表单的有效响应仅确认请求已发送:当 Moodle 未提供
明确的后续条件时,返回 outcome="unknown",并且对于模糊响应,
绝不通过第二个传输方式重试。
写入期间超时或连接中断是模糊的:Moodle 可能已应用该 操作,即使客户端未收到响应。不要自动重试消息、 提交、保存或结束。重新读取会话、提交状态或尝试,并 根据该证据做出决定;在限时测验中,还要直接在 Moodle 中 检查时钟。
测试
uv run pytest
uv run ruff check .该套件用测试替身替换了 HTTP、keyring、表单、上传和下载。它不包含 令牌、cookie 或真实数据,并且不对 USC 执行任何写入。真实访问 仅通过手动和本地方式验证。
官方来源
该契约已与官方文档和代码进行核对:
Moodle 外部服务及其 安全建议。
moodlehq/moodleapp(Apache-2.0),从客户端使用 服务、内容和资源的官方参考。
已审阅的先前工作
研究了具有许可证的项目,以避免重复已解决的模式。复用了架构思路和公共契约,而非凭据或不兼容的代码:
haolamnm/moodle-mcp-srv(Apache-2.0):架构、 诊断和 REST 客户端。Snaw80/moodle-mcp(MIT):SSO 登录和移动端流程。USC 的公共移动端端点返回 404,因此使用本地获取的 cookie。GhaithAlHallak8/moodler-mcp(MIT):Moodle 会话 和同源 AJAX。1alexandrer/moodle-mcp(MIT):面向学生的工具和 可操作事件。mrcinv/moodle_api.py(MIT):通用客户端和core_course_get_contents。lmscloud-io/moodle-mcp-server(GPL-3.0): 以最小权限暴露 Moodle 函数的 MCP。
loyaniu/moodle-mcp 仅用于比较范围,因为该仓库未声明许可证;未复制其代码。
已知限制
每个 Web Service 的可用性取决于 USC 分配给令牌或会话的版本、配置和权限。
OIDC 会话和
MoodleSession会过期;需要重新执行mcp-usc login。AJAX 和测验表单可能随版本变化。如果连接器无法安全识别某个操作,将以关闭方式失败。
作业要求使用 REST:其页面会记录浏览行为,且
filemanagerJavaScript 不等同于 原生 multipart 字段。删除完整提交需要 Moodle 4.5+ 和有效权限。重新打开已关闭的提交由教师负责。
并非所有教师都使用虚拟校园;邮件或 Teams 可能包含此服务器不查询的信息。
Moodle 中的某个日期可能是持续评估,而某个公开日期可能是正式考试。两者作为不同来源保留。
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
- FlicenseAqualityCmaintenanceEnables read-only querying of Moodle as a student, including courses, assignments, grades, forums, and files, using a personal web services token.11
- AlicenseNot gradedqualityDmaintenanceEnables querying academic data such as subjects, degrees, locations, and schedules from Universitat Jaume I via MCP tools.MIT
- FlicenseNot gradedqualityBmaintenanceEnables AI assistants to read your Moodle courses, list materials, quizzes, and search content to plan exam preparation through natural language.1
- FlicenseAqualityCmaintenanceEnables AI assistants to query the UTN distance learning Moodle campus, providing tools to list courses, view content, check deadlines, see grades, and more.7
Related MCP Connectors
Read-only MCP server for Muovi, Argentina's trust-first local services marketplace (6 tools).
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
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/PabloPC05/mcp-usc'
If you have feedback or need assistance with the MCP directory API, please join our Discord server