Skip to main content
Glama
JaipuriaAILabs

Jaipuria Moodle Reports MCP

Jaipuria Moodle Reports MCP

一个面向教师、只读的模型上下文协议(MCP)服务器,使 Jaipuria 的 student-report-system 数据可以用自然语言查询。将其连接到任何 MCP 主机(仪表板、Claude.ai、ChatGPT、Claude CLI),即可询问学生成绩、出勤、科目、队列分析、纵向趋势、风险学生和报告准确性——每个已摄入的学生,都限定在调用者的校区范围内。

在线: https://moodle-mcp-f6do.onrender.com/mcp · 健康检查: /health · 工具: 27 仓库: github.com/mansigambhir-1313/Moodle-MCP · 所有者: Jaipuria AI Labs


概述

位于 moodle-agent 中的管道摄入 Moodle 数据,计算分析,并生成经过验证的学生报告到 Supabase 项目中。此 MCP 是该项目面向教师和项目办公室的读取端:它以约 27 个结构化、可自动批准的工具形式暴露原始数据和管道输出,供主机 LLM 路由使用。

它是数据优先的——主要表面是原始成绩簿和出勤(可查询每个学生,无论是否有报告);生成的报告及其双方案准确性分数是次要层。它永远只读:没有工具写入、摄入或发送电子邮件。

设计传承:采用 Rehearsal MCP 的模式(有界缓存、路由契约文档字符串、响应预算、秘密剥离、优雅降级),从该服务器的每学生 RLS 模型调整为基于角色、校区范围的教师模型。

适用位置

  • 上游: 共享的 student-report-system Supabase 项目(表 students、courses、enrolments、marks、attendance_sessions、student_reports、report_accuracy),由 moodle-agent 写入。

  • 下游: 任何 MCP 主机——教师仪表板、Claude.ai / ChatGPT 连接器、Claude CLI。


Related MCP server: VortexIQ MCP Connector

独特之处

  • 纵向而非仅快照 — 一次运行包含每个学期(T1–T6)。像 student_trajectory 和 declining_students 这样的工具能捕捉学生逐学期下滑,而点时间查询永远无法显示。

  • 单窗格视图 — student_360 和 cohort_pulse 在一次调用中返回整个学生/整个队列,适合仪表板抽屉或落地页。

  • 准确性作为一等数据 — 每个生成的报告都带有双方案验证分数(忠实度面板 + 两轮 LLM 评判)。询问*“哪些报告被标记以及为什么?”*

  • 教学与课程信号 — section_compare(A 对 B 公平性)、assessment_breakdown(测验 vs 作业 vs 项目)、subject_difficulty(课程压力点)。


工具(27)

每个工具仅执行 SELECT,限定于调用者令牌的校区,有界,并带有 WHAT / USE WHEN / DO NOT USE / RETURNS 路由文档字符串。

学生 — 原始数据(主要)

工具

返回内容

list_students

某个校区/批次(± 部分)的名册,每个已摄入的学生

get_student

单个学生的完整记录——每科目组件分数 + 出勤

student_marks

学生的扁平、组件级成绩簿行

student_attendance

学生的每科目出勤(出席 / 会话 / %)

科目 — 原始数据(主要)

工具

返回内容

list_subjects

某个范围的科目/课程,包含学期、部分、注册

subject_performance

某科目的队列分数、通过率、出勤、每组件均值

section_compare

部分对部分的均值 + 分布(教学/评分信号)

assessment_breakdown

按评估类型(测验/作业/项目…)的队列表现

subject_difficulty

科目按难度从高到低排名(通过率 + 零分)

洞察 — 纵向与单窗格(主打)

工具

返回内容

student_trajectory

学生的分数/出勤跨学期趋势 + 标签

student_360

一次调用学生视图:百分位排名、趋势、风险标志、准确性

cohort_pulse

一次调用队列 KPI:分数、出勤、通过率、风险、分布

watchlist

自动干预列表——原因 + 建议行动,按排名

declining_students

队列范围内最大的逐学期分数下降(早期预警)

分析与风险(主要)

工具

返回内容

marks_overview

队列分数快照——均值、通过率、分布、零分

attendance_overview

队列出勤——均值、低于 75% / 65% 的计数

top_performers

某个范围内总分最高的学生

cohort_compare

某个批次的校区对校区均值

at_risk_students

综合风险排名(零分 + 出勤 + 不及格分数)

attendance_watch

低于出勤阈值的学生

zero_alerts

有记录零分的学生(最紧急)

报告与准确性(次要)

工具

返回内容

get_report_accuracy

单个报告的双方案准确性分数 + 解释

accuracy_overview

队列准确性——平均 %、已验证 / 漂移 / 标记

flagged_reports

人工审查队列(验证标记的报告)

get_student_report

为某个学生生成的叙述性报告

report_pipeline_status

某个范围的就绪 / 保留 / 失败计数

whoami

调用者的主体和允许的校区

参见 docs/INNOVATION_ROADMAP.md 了解第三阶段的想法(attendance_eligibility、attendance_marks_link、anomalies、roster_health)。


快速开始

连接主机(已部署服务器)

claude mcp add moodle --transport http https://moodle-mcp-f6do.onrender.com/mcp \
  --header "Authorization: Bearer <your MCP_TOKENS value>"

然后以自然语言询问:

"cohort pulse for jaipur 2024-26" · "who's declining" · "build my watchlist" · "show JJ24PG001's full record" · "hardest subjects" · "compare sections of Wealth Management"

本地运行

cd moodle-mcp
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env            # fill in the vars below
uvicorn server:app --port 8899
curl localhost:8899/health      # {"status":"ok",...}

冒烟测试(真实 MCP 握手 + 实时查询)

MCP_URL="http://localhost:8899/mcp" MCP_TOKEN="<a token>" python test_client.py

配置

config.py(pydantic-settings,读取 .env 和环境变量)。validate_config() 是对 Supabase 变量的失败关闭启动检查。

变量

描述

获取位置

SUPABASE_URL

报告项目 URL(https://sadbfvfcmmxgtatfjfmc.supabase.co)

Supabase → 设置 → API

SUPABASE_SERVICE_ROLE_KEY

读取服务密钥(仅服务器端,永不暴露)

Supabase → 设置 → API · 也在 moodle-agent/.env 中

MCP_TOKENS

教师令牌的 JSON 映射 → {name, campuses}(见下文)

您生成

MCP_ADMIN_TOKEN

单个全校区紧急访问令牌(MCP_TOKENS 的替代)

您生成

REPORT_PUBLIC_BASE_URL

报告链接的基础(默认 https://reports.tryrehearsal.ai)

—

MCP_SERVER_BASE_URL

此服务的公共 URL(可选)

Render 仪表板

所有日志输出到 stderr;日志行从不包含令牌内容或 PII。


访问模型(基于角色,校区范围)

与学生 MCP(每用户 RLS)不同,此服务面向查看其校区机构数据的教师。承载令牌映射到具有允许校区集的主体;每个工具将请求的校区与该集相交。授权之外的校区返回 {"found": false} — 不会泄露数据。

生成每个校区的令牌块:

python3 -c "import secrets; print('mcp_'+secrets.token_urlsafe(24))"   # one per faculty
// MCP_TOKENS (single-line JSON in the env var)
{
  "mcp_...indore": {"name": "Indore TNP",       "campuses": ["indore"]},
  "mcp_...office": {"name": "Programme Office",  "campuses": null}      // null = all campuses
}

Supabase 服务角色密钥保留在服务器端,永远不会交给主机。代码库中没有写入路径。


架构

MCP host (dashboard / Claude / ChatGPT)
        │  MCP over HTTP + Bearer <faculty token>
        ▼
server.py (FastMCP /mcp, /health)
  get_authenticated_service()  → verify token → MoodleService(allowed_campuses)
        │
  tools/* (6 modules, 27 tools) — each: Params model + _impl(svc,…) + register()
        │  every query .in_("campus", allowed) ; strip_secrets ; response budgets
        ▼
Supabase (read service role) — students · courses · enrolments · marks ·
                               attendance_sessions · student_reports · report_accuracy

完整设计:docs/ARCHITECTURE.md。

关键文件

路径

用途

server.py

FastMCP 应用、whoami、/health、认证依赖、工具接线

config.py

设置 + validate_config()

supabase_client.py

只读 MoodleService、校区范围、运行解析

tools/common.py

共享辅助:courses_for、marks_for、cohort_rollup、缓存

tools/students.py · subjects.py · insights.py

主要数据工具

tools/analytics.py · at_risk.py

队列汇总

tools/accuracy.py · reports.py

次要报告层

cache.py · guardrails.py · annotations.py

TTL 缓存、预算/范围、工具提示

test_client.py

端到端 MCP 客户端冒烟测试

缓存(OOM 安全 — 仅限有界 TTLCache)

_run_cache(每个范围的最新最终运行)、_rollup_cache / _marks_cache(队列原始数据汇总)。队列工具分页超过 PostgREST 的 1000 行上限,并将结果缓存 5 分钟。


部署

  • Render(render.yaml 蓝图或 Docker):Python 3.12 / Docker,uvicorn server:app,健康检查 /health。在仪表板中设置 SUPABASE_URL、SUPABASE_SERVICE_ROLE_KEY、MCP_TOKENS。

  • Docker: docker build -t moodle-mcp . && docker run -p 8000:8000 --env-file .env moodle-mcp

  • 当前生产环境位于 Free 实例(闲置约 15 分钟后关闭 → 约 50 秒冷启动)。升级到 Starter 以保持始终在线。

环境

URL

备注

生产

https://moodle-mcp-f6do.onrender.com

Free 实例,main 自动部署

本地

http://localhost:8899

uvicorn server:app --port 8899

完整测试/部署步骤:DEPLOY.md。


运行手册

轮换访问令牌 — 重新生成 MCP_TOKENS(使用相同的生成器),更新 Render 环境变量;服务重启后旧令牌失效。向教师重新发放新令牌。

添加按校区配置的教师 — 添加一条 "mcp_...": {"name": "...", "campuses": ["<campus>"]} 条目 到 MCP_TOKENS,重新部署,将 token 交给对方。

添加新工具 — 遵循 docs/ARCHITECTURE.md §11:添加 Params 模型 + _impl(svc,…) + register(),为每个查询限定校区范围,使用 strip_secrets,编写路由文档字符串,在 server.py 中注册。复用 tools/common.py 中的原始数据辅助函数。

冷启动/首次请求缓慢 — Free 实例从空闲状态唤醒(约 50 秒)。使用 curl <url>/health 预热,或升级实例。

验证部署 — 先执行 curl <url>/health,然后执行 MCP_URL="<url>/mcp" MCP_TOKEN="<token>" python test_client.py。


安全不变量

永远只读 · 每个查询限定校区范围 · 统一返回 {"found": false} 表示未命中(不提供存在性 探测)· 秘密信息剥离(运行 ID / 存储密钥 / 哈希 / 邮箱绝不离开服务器)· 服务角色密钥仅限服务端使用 · 响应预算 + 分页 · 优雅降级(绝不让回合返回 500)· 仅使用有界缓存(防 OOM)。详见 docs/ARCHITECTURE.md §3、§11。

Related MCP Connectors

Related MCP Servers