Skip to main content
Glama

UNNC Moodle MCP + Codex skill

在 Codex 中说“同步我的 Moodle 课件”,把已选择课程的讲义保存到电脑,更新时保留旧版本。一个共享 MCP 核心、首次设置向导和薄的 Codex skill;个人课程、路径和会话在仓库外,不维护个人专属代码分叉。

支持范围:UNNC 使用的 Nottingham Moodle、macOS + Google Chrome、Node.js 24+。 非官方项目。只读访问学校数据,第一版仅手动同步。Windows、Edge、其他学校和其他 agent 客户端尚未验证。

新手开始

  1. 安装 Node.js 24 或更新版本(包含 npm)与 Google Chrome。

  2. 下载本仓库 ZIP 并解压,双击 scripts/setup.command。它检查环境,经你确认后安装本项目依赖、编译并打开设置向导;不会修改全局 Codex 配置。macOS 如果阻止脚本运行,可以采用下方终端方式,无需关闭系统安全功能。

  3. 向导中选择资料根目录,在专用 Chrome 中亲自登录和完成 MFA,从真实课程名称列表中选课,再确认摘要。不要把密码、验证码或 Cookie 发给 AI。

  4. 按下方说明接入 Codex,安装附带 skill,重启客户端后检查工具是否出现。

终端方式:打开项目目录,运行:

npm run doctor
npm ci
npm run build
npm run setup

向导不会自动下载。设置完成后运行 npm run sync,或在接入后的 Codex 中说“检查 Moodle 登录状态,然后同步我已选择的课程”。无需输入课程 ID;向导用课程序号选择。默认资料根目录 ~/Documents/MoodleSync,可以改用其他绝对路径。

环境检查针对默认 /Applications 中的 Chrome;不是 Chrome 安装器。项目不自动安装 Node/Chrome,也不自动授权 Codex 修改配置。

Related MCP server: smu-elearn

接入 Codex

运行 npm run codex-config 可以打印已填好本机 Node 和服务路径的配置区块(复制从 [mcp_servers.moodle_local] 开始的部分,不包含 npm 提示);它不会修改任何配置。仓库也提供 codex-mcp.example.toml。用 command -v node 找到 Node 绝对路径,填写它以及本项目 dist/src/server.js 的绝对路径。经你确认后将该区块加入自己的 Codex MCP 配置;先备份并保留其他服务。不要把凭据写进配置。重启客户端后调用 get_sync_settings 与 check_connection,核对实际目录、课程和登录状态。

安装 skill:把仓库里的 skills/unnc-moodle 整个目录复制到 ~/.codex/skills/unnc-moodle(自定义 CODEX_HOME 时用其 skills 目录)。已有同名 skill 时先比较,不静默覆盖。重启后可以说:

使用 $unnc-moodle 帮我设置 Moodle,之后同步我选择的课件。

skill 负责引导,MCP 负责硬性检查。未确认目录或名单为空时,下载与同步返回 SETUP_REQUIRED;检查连接、发现课程仍然可用。 安装 skill 不等于安装/连接 MCP,也不能绕过设置门槛。

服务入口为 node /absolute/project/dist/src/server.js,使用标准 MCP stdio,stdout 只用于协议。官方 MCP Client 已测试工具发现与调用;没有实测 Claude/Cursor 等客户端,因此不承诺直接兼容。

工具与常用命令

工具

用途

get_sync_settings

显示目录、课程、setupConfirmed、readyToSync 和下一步

check_connection

验证专用会话,不返回凭据

list_courses

从 My Modules 发现课程,包括隐藏课程

select_courses(courseIds)

经用户批准替换名单,拒绝未观察到的 ID;空数组清空名单

confirm_setup(dataDir,confirmed:true)

经用户确认当前根目录和名单后保存设置;不是迁移工具

list_resources(courseId)

列出已选课程资源及类型

download_resource(courseId,moduleId)

下载指定已发现文件/文件夹模块

sync_courses(forceContentCheck?)

对已批准名单执行一次增量同步

终端命令:npm run settings 查看设置、npm run login 重新登录、npm run courses 列课、npm run select -- COURSE_ID ... 替换名单、npm run select -- --clear 清空名单。CLI select 后其他已运行进程需重启;MCP select_courses/confirm_setup 更新当前进程。多个进程同时更改配置时,应停止旧进程并重新核对,避免旧快照继续工作。

下学期运行 npm run setup 重新选择课程即可,无需改源码。取消选择保留原有文件与历史,不再同步该课。已经登录时向导跳过重新登录。明确配置过相同设置时不用重复确认每次同步。

保存位置与迁移

持久设置默认 ~/Library/Application Support/moodle-mcp/settings.json,向导在确认后记录所选根目录和课程配置路径。根目录下:

  • materials/:资料,按 课程ID/模块ID/路径槽/v0001/文件名 保存。

  • state/:增量状态、临时文件及操作锁。

  • courses.json:课程白名单。

用 Finder 的 ⌘⇧G 粘贴 get_sync_settings 中的 materials 路径查看。路径槽避免文件重名,版本目录保留历史;内容校验不代替 Git 源码版本管理。

绝对路径环境变量可覆盖:MOODLE_DATA_DIR、MOODLE_COURSES_FILE、MOODLE_SETTINGS_FILE、MOODLE_PROFILE_DIR。名单与设置必须是各自专用的 JSON 文件,不能放入 materials、state 或浏览器 profile 内,不能指向同一文件。环境变量优先于持久设置;CLI 与 MCP 应使用一致的覆盖值。改变根目录或名单文件路径会要求重新确认,不能直接把旧确认用于新位置。MOODLE_HEADLESS=false 显示操作窗口。

改根目录不等于自动迁移。 要保留旧历史:停止 MCP/CLI、备份旧根目录,将 materials、state、courses.json 整体复制到一个新目录,保留旧目录,运行 setup 确认新根目录,重启 MCP 并回读设置。不要只复制课件而漏掉 manifest;不要在同步运行时迁移。项目没有自动迁移命令,未执行真实资料迁移测试。

从旧版本升级:已有白名单和资料不自动改动。首次运行 setup 或通过工具确认原根目录即可;不要为升级重新下载全部资料。不要上传自己的数据目录。

同步结果与可靠性

每次结果包括 added、updated、unchanged、failed、skipped、remoteMissing;失败包含阶段与下载尝试次数。必须检查业务结果,MCP 返回文本成功不代表所有资源同步成功。

  • 用资源 ID 与远端路径识别文件,用 SHA-256 比较内容。可靠 ETag 可条件请求;304 且本地校验一致才跳过。无验证器可能重复传输,但不重复保存相同内容。

  • 更新新建版本,保留旧版与用户本地编辑;远端消失不删除本地文件。只有已确认发现完整的页面才标记缺失,无法确认时报告解析失败并保留历史。

  • 下载阶段 NETWORK/PARSE_FAILED 最多三次,等待 1.5 秒、3 秒;持续失败仍报告,不猜链接。retryable 表示后续手动调用可能有意义,不表示自动无限重试。

  • 任意阶段 429 立即停止整批,保留已成功项;登录过期也停止。权限不足或404只报告对应项/课程。LOCAL_IO 提示先解决磁盘或权限,INTERNAL 不冒充网络故障。

  • 临时下载完成后才提交;成功摘要在状态保存成功后写入,失败清理临时状态文件。状态损坏停止,不重置历史。崩溃残留 operation.lock 仅在确认对应 PID 已停止后移除,不自动偷取锁。

  • 显式导航和下载请求串行、间隔至少 1.5 秒;浏览器自身页面子资源/AJAX 不是所有请求均经过该间隔。下载上限 100 MiB,响应体缓存,不是严格流式内存限制。

文件与已发布文件夹可下载;论坛、测验、作业、反馈等非文件活动跳过。特殊插件、真实文件夹隐藏子树、视频、ZIP 展开不保证支持。HTML 讲义按文件保存,同步不执行脚本、不镜像外部资产;离线用浏览器打开后可能执行其原脚本并加载外部资源。

登录与数据边界

专用浏览器位于 ~/Library/Application Support/moodle-mcp/browser-profile,不读取或复制日常 Chrome。目录700、会话600权限,只额外保存 Moodle 域 Cookie;整个专用 profile 可能有正常 SSO 缓存,应视为敏感。文件权限不等于加密。

NEEDS_LOGIN 时停止操作,运行 npm run login 亲自认证。关闭异常或 Chrome 缺失应结合 doctor 排查,PROFILE_BUSY 不能保证就是另一个进程占用。撤销时停止服务/专用窗口,删除本项目专用 profile,并按学校方式注销学校会话;删除本机文件不能保证撤销其他副本。不要删除个人 Chrome。

仅访问已选择、账户有权限的课程,不提交作业、发消息或修改学校内容。外链只报告,不携带学校凭据访问;登录窗口允许学校正常 SSO。访问会被网站正常记录。不要把 profile、会话、课程名单、课件或私有验证记录提交 GitHub。

验证与发布

运行 npm test。测试范围、真实证据和未验证项见 docs/TESTING.md。公开导出与审查步骤见 docs/RELEASE.md。发布包包含同一套核心、向导、skill、测试与许可证,不包含个人仓库旧 Git 历史。

MIT 许可只覆盖本项目代码,不授予学校课件、品牌或第三方内容的权利。

参考:MCP SDK、Playwright、Codex MCP。

Available Tools

8 tools
check_connectionB
Read-onlyIdempotent

Check Moodle connection and dedicated login session; never return credentials.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered structurally. The description adds one genuinely useful behavioral fact beyond that: credentials are never returned, which tells the agent the output is safe to surface. It says nothing about failure behavior or what a failed connection check looks like, so it adds context but not rich detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence with the credential-safety clause placed after the core purpose, so the operation is front-loaded. No filler, though "dedicated login session" is slightly vague phrasing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no parameters, the description is the only place a caller could learn what a successful or failed check returns (status, error signaling). It covers scope and the credential guarantee but leaves the return contract unstated, which is a real gap for a diagnostic tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the schema carries no semantic burden and there is nothing for the description to disambiguate. Baseline of 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ("Check") and resource ("Moodle connection and dedicated login session"), which is a diagnostic/health-check operation distinct from the sibling tools (list_courses, download_resource, sync_courses), none of which perform connectivity checks. It is clear what the tool does, though it never explicitly contrasts itself with those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to call this versus other tools, no prerequisites, and no exclusions. The only hint is the implied 'verify before acting' role, which the agent must infer from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

confirm_setupA
Idempotent

After explicit user confirmation of the displayed course list and current data root, persist setup approval. dataDir must match current settings. For a different root use npm run setup; this tool never migrates data.

ParametersJSON Schema
NameRequiredDescriptionDefault
dataDirYes
confirmedYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the write/idempotent/non-destructive profile, and the description adds genuinely new context: it requires prior explicit user confirmation and it never migrates data, which is a meaningful scope boundary for an approval-persisting write. It does not describe failure behavior if dataDir mismatches, but that is a minor gap given annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the precondition, then the constraint, then the exclusion. Every sentence adds distinct information with no repetition of the tool name or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter mutation with no output schema, the description supplies the precondition, the constraint on dataDir, and the alternative tool. The only omission is what happens on a mismatched dataDir (error vs. no-op), which is not essential for selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the burden. It does clarify dataDir semantics ('must match current settings'), which is valuable, but the 'confirmed' parameter is only implicit in the prose and its const:true constraint is left to the schema. Partial compensation warrants a baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource ('persist setup approval') and clarifies the boundary ('never migrates data'), which separates it from a full setup/migration flow. It is clear but does not explicitly position itself against the sibling tools (list_courses, sync_courses, etc.), which are read/selection oriented.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the precondition precisely ('After explicit user confirmation of the displayed course list and current data root') and names the alternative path for a different root ('use npm run setup'). Both when-to-use and when-not-to-use are covered with the routing condition spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

download_resourceA
Idempotent

Download a discovered file/folder module in an approved course to the approved materials directory. Keep old versions.

ParametersJSON Schema
NameRequiredDescriptionDefault
courseIdYes
moduleIdYes

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, idempotentHint=true and destructiveHint=false; the description adds the non-obvious behavioral fact that existing versions are retained ('Keep old versions'), which explains the non-destructive profile. It does not describe overwrite semantics, required permissions, or failure handling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, zero filler, with the action and destination front-loaded and the versioning caveat placed last. Every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter write tool with no output schema and no parameter documentation, the description covers the operation and its non-destructive behavior but omits where ids originate, what the 'approved materials directory' resolves to, and what happens on re-download of an existing module. Adequate but with visible gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description supplies no parameter information at all. The names courseId and moduleId are largely self-explanatory, but the description never clarifies accepted id forms (they come from list_courses/list_resources) or what a 'module' scope means for a file/folder download.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb (Download) plus the exact resource (a discovered file/folder module in an approved course) and destination (the approved materials directory). This clearly separates it from read-only siblings like list_resources, but it never names an alternative tool to complete the routing decision.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrases 'discovered' and 'approved course' imply prerequisites (discovery/selection must have happened first), which is useful implicit guidance. However, there is no explicit when-to-use versus sync_courses or list_resources, and no stated exclusions or preconditions for the call itself.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_sync_settingsB
Read-onlyIdempotent

Show approved course IDs and local output directories without authentication data.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds a useful disclosure that authentication data is excluded from the response, but says nothing about return format or completeness of the settings view.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single compact sentence with the main content front-loaded. The trailing 'without authentication data' qualifier is slightly awkward but earns its place as a scoping disclosure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of explaining returns and only partially does so: it names course IDs and output directories but omits other settings fields an agent might expect. Adequate but incomplete for a settings-reading tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. The description correctly implies no inputs are needed and instead spends its words describing the output content.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Show) and a specific resource (sync settings, realized as approved course IDs and local output directories). It is clear what the tool returns, though it never names or contrasts with siblings such as list_courses or check_connection.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance and no alternatives are named. The phrase 'without authentication data' hints that this is a scoped/redacted variant of a settings view, but the agent is left to infer when to prefer it over the other seven siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_coursesB
Read-onlyIdempotent

List enrolled My Modules courses including hidden courses. Only explicitly approved IDs may be synchronized.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint, so the safety profile is covered. The description usefully adds that hidden courses are included, but the 'only explicitly approved IDs may be synchronized' sentence is ambiguous about whether it constrains this read call at all.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the core capability front-loaded and no padding. The trailing sentence about approved IDs is terse but does not clearly belong to a list operation, which slightly weakens the structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters, no output schema and full annotation coverage, the description only needs to convey what is enumerated and the scope. It does that, though the cryptic sync/approval sentence leaves a small ambiguity unresolved.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so per the rubric the baseline is 4. There is nothing parameter-level for the description to clarify, and it does not mislead about inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (list enrolled My Modules courses) and adds a scope detail (including hidden courses) that an agent could not infer from the name. It does not, however, distinguish this list tool from siblings like list_resources or sync_courses.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use or when-not-to-use guidance, and no alternative is named. The second sentence hints at a sync-approval workflow but never says how it relates to calling this tool versus sync_courses or select_courses.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_resourcesB
Read-onlyIdempotent

List visible resources for an approved course, with observed IDs, titles, types and available format metadata.

ParametersJSON Schema
NameRequiredDescriptionDefault
courseIdYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive and openWorld behavior, so the safety profile is covered. The description usefully adds the 'visible'/'approved' scoping qualifier and the shape of the returned fields, but says nothing about pagination, result size, or auth requirements beyond the annotation hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence that front-loads the action and scope, with no filler. Slightly awkward phrasing ('observed IDs') costs it nothing materially.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 1-parameter read-only list tool with annotations covering safety and no output schema, the description tells the agent what it gets back and the scope. Gaps around pagination and how 'visible' is determined remain, so it is adequate but not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden, and it only weakly compensates: 'for an approved course' implies courseId must reference an approved course but gives no format or validation detail. The parameter name courseId is self-evident, so meaning is not lost, but no real added semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (resources) scoped to an approved course, and even enumerates the returned fields (IDs, titles, types, format metadata). It is clearly separable from list_courses and download_resource by resource type, though it never names a sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'for an approved course' implies the context in which this applies, so usage is inferable. However, there is no explicit when-to-use guidance and no mention of the obvious alternative (download_resource) for actually fetching content, leaving the agent to infer routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

select_coursesA
Idempotent

After user approval, replace the local course selection with observed My Modules IDs. Empty courseIds clears selection without deleting files. Local change only.

ParametersJSON Schema
NameRequiredDescriptionDefault
courseIdsYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes meaningfully beyond the annotations: it discloses that the operation is a replacement, that an empty array clears without deleting files, that it is a local-only change, and that user approval is required. The annotations already cover idempotency and destructiveHint=false; the only unexplained point is openWorldHint=true, which sits in mild tension with 'Local change only' but reasonably reads as 'no remote mutation' rather than a true conflict.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, each carrying a distinct fact (precondition, effect, edge case, scope), with the primary action front-loaded. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter, no-output-schema tool with annotations present, the description covers precondition, mutation semantics, empty-input behavior, and scope. It leaves unaddressed what happens with invalid or unmatched IDs and whether the new selection is returned, which would be the only remaining gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, yet the description explains what courseIds contains ('observed My Modules IDs') and what an empty array means, which is the key semantic the schema cannot convey. It stops short of noting constraints like the 200-item cap or positive-integer requirement, but those are already in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and target state: 'replace the local course selection with observed My Modules IDs'. The phrases 'Local change only' and 'without deleting files' distinguish it behaviorally from write/transfer siblings like sync_courses and download_resource, so an agent can tell what this mutates without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear precondition ('After user approval') and an explicit edge-case usage ('Empty courseIds clears selection'). It does not, however, name an alternative tool or state when to prefer this over sync_courses, so the routing guidance is incomplete rather than absent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sync_coursesA
Idempotent

Perform one manual incremental sync for the locally approved courses. forceContentCheck bypasses ETag validation.

ParametersJSON Schema
NameRequiredDescriptionDefault
forceContentCheckNo

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnly=false, idempotent=true, destructive=false, openWorld=true). The description adds real behavioral context beyond that: the sync is incremental (not full), is manual/one-shot, and operates on locally approved courses. The ETag bypass detail is the kind of hidden behavior an agent could not infer from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler, and the core action is front-loaded ahead of the parameter detail. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-required-parameter, single-boolean tool with no output schema and annotations already declaring safety and idempotency, the description covers the essentials: what runs, on what scope, and what the flag does. Only the default behavior of forceContentCheck and any result semantics are unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the single boolean parameter has no schema description, so the description carries the burden. 'forceContentCheck bypasses ETag validation' fully explains the parameter's effect, which is the key semantic an agent needs. It does not state the default when omitted, keeping it short of a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('sync') and resource ('courses'), scoped to 'locally approved courses' with 'one manual incremental sync'. This distinguishes it from list/select siblings by making clear it performs an actual sync rather than a listing or selection, though it never explicitly names the alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'Perform one manual incremental sync' implies this is an on-demand trigger rather than a scheduled/automatic sync, which gives some usage context. However, it does not say when an agent should invoke it versus check_connection, get_sync_settings, or confirm_setup, nor any prerequisite state.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv0.3.0
    • First observedcheck_connection
    • First observedconfirm_setup
    • First observeddownload_resource
    • First observedget_sync_settings
    • First observedlist_courses
    • First observedlist_resources
    • First observedselect_courses
    • First observedsync_courses

TDQS

A3.8/5.0

Scored across 8 tools

Disambiguation4/5

Each tool targets a fairly distinct action: connectivity check, course/resource discovery, single download, bulk sync, settings read, course selection, and setup confirmation. Minor overlap exists between sync_courses and download_resource (both fetch content) and between select_courses and confirm_setup (both touch setup state), but descriptions clarify the boundaries.

Naming Consistency5/5

All eight tools follow a consistent snake_case verb_noun pattern (check_connection, list_courses, download_resource, sync_courses, select_courses, confirm_setup, etc.). No mixing of conventions or vague verbs.

Tool Count5/5

Eight tools is well-scoped for a Moodle course-sync server, with each tool earning its place across connection, discovery, sync, and setup concerns. No redundant or trivial tools pad the set.

Completeness4/5

The surface covers connection, discovery, download, sync, settings, and setup lifecycle well. Minor gaps like cleanup of old versions or removing downloaded materials exist, but core workflows are covered.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers