Jaipuria Moodle Reports MCP
Provides tools to query student marks, attendance, subject performance, cohort analytics, longitudinal trends, at-risk students, and report accuracy from Moodle data, all scoped by campus and read-only.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Jaipuria Moodle Reports MCPshow me declining students in the 2024 cohort"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Jaipuria Moodle Reports MCP
A faculty-facing, read-only Model Context Protocol (MCP) server that makes the Jaipuria
student-report-system data queryable in plain language. Connect it to any MCP host (a dashboard,
Claude.ai, ChatGPT, Claude CLI) and ask about student marks, attendance, subjects, cohort
analytics, longitudinal trends, at-risk students, and report accuracy — every ingested student,
scoped to the caller's campuses.
Live: https://moodle-mcp-f6do.onrender.com/mcp · Health: /health · Tools: 27
Repo: github.com/mansigambhir-1313/Moodle-MCP · Owner: Jaipuria AI Labs
Overview
The pipeline in moodle-agent ingests Moodle data, computes analytics, and
generates validated student reports into a Supabase project. This MCP is the read side of that
project for faculty and the programme office: it exposes the raw data and the pipeline's outputs as
~27 structured, auto-approvable tools that a host LLM routes on.
It is data-first — the primary surface is the raw gradebook and attendance (queryable for every student, report or not); the generated reports and their two-scheme accuracy scores are a secondary layer. It is read-only forever: no tool writes, ingests, or emails.
Design lineage: the Rehearsal MCP patterns (bounded caches, routing-contract docstrings, response budgets, secret stripping, graceful degradation), adapted from that server's per-student RLS model to a role-based, campus-scoped faculty model.
Where it fits
Upstream: the shared
student-report-systemSupabase project (tablesstudents,courses,enrolments,marks,attendance_sessions,student_reports,report_accuracy), written bymoodle-agent.Downstream: any MCP host — a faculty dashboard, Claude.ai / ChatGPT connectors, Claude CLI.
Related MCP server: VortexIQ MCP Connector
What makes it exclusive
Longitudinal, not just snapshot — one run holds every trimester (T1–T6). Tools like
student_trajectoryanddeclining_studentscatch a student sliding term-over-term, which a point-in-time query never shows.Single-pane views —
student_360andcohort_pulsereturn a whole student / whole cohort in one call, ready for a dashboard drawer or landing screen.Accuracy as first-class data — every generated report carries a two-scheme validation score (faithfulness panel + two-turn LLM judge). Ask "which reports are flagged and why?"
Teaching & curriculum signals —
section_compare(A-vs-B fairness),assessment_breakdown(quiz vs assignment vs project),subject_difficulty(curriculum pressure points).
Tools (27)
Every tool is SELECT-only, campus-scoped to the caller's token, bounded, and carries a
WHAT / USE WHEN / DO NOT USE / RETURNS routing docstring.
Students — raw data (primary)
Tool | What it returns |
| Roster for a campus/batch (± section), every ingested student |
| One student's complete record — per-subject component marks + attendance |
| Flat, component-level gradebook rows for a student |
| Per-subject attendance (present / sessions / %) for a student |
Subjects — raw data (primary)
Tool | What it returns |
| Subjects/courses for a scope, with trimester, sections, enrolment |
| A subject's cohort marks, pass rate, attendance, per-component means |
| Section-vs-section means + spread (teaching/marking signal) |
| Cohort performance by assessment kind (quiz/assignment/project…) |
| Subjects ranked hardest-first (pass rate + zeros) |
Insights — longitudinal & single-pane (hero)
Tool | What it returns |
| A student's marks/attendance trend across trimesters + label |
| One-call student view: percentile rank, trend, risk flags, accuracy |
| One-call cohort KPIs: marks, attendance, pass rate, at-risk, distribution |
| Auto intervention list — reasons + suggested action, ranked |
| Cohort-wide biggest term-over-term mark drops (early warning) |
Analytics & at-risk (primary)
Tool | What it returns |
| Cohort marks snapshot — mean, pass rate, distribution, zeros |
| Cohort attendance — mean, counts below 75% / 65% |
| Highest overall marks in a scope |
| Campus-vs-campus means for a batch |
| Composite risk ranking (zeros + attendance + failing marks) |
| Students below an attendance threshold |
| Students with a recorded zero (most urgent) |
Reports & accuracy (secondary)
Tool | What it returns |
| One report's two-scheme accuracy score + interpretation |
| Cohort accuracy — mean %, verified / drift / flagged |
| The human-review queue (validation-flagged reports) |
| The generated narrative report for a student |
| Ready / held / failed counts for a scope |
| The caller's principal and allowed campuses |
See docs/INNOVATION_ROADMAP.md for Phase-3 ideas
(attendance_eligibility, attendance_marks_link, anomalies, roster_health).
Quickstart
Connect a host (deployed server)
claude mcp add moodle --transport http https://moodle-mcp-f6do.onrender.com/mcp \
--header "Authorization: Bearer <your MCP_TOKENS value>"Then ask, in plain language:
"cohort pulse for jaipur 2024-26" · "who's declining" · "build my watchlist" · "show JJ24PG001's full record" · "hardest subjects" · "compare sections of Wealth Management"
Run locally
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",...}Smoke test (real MCP handshake + live queries)
MCP_URL="http://localhost:8899/mcp" MCP_TOKEN="<a token>" python test_client.pyConfiguration
config.py (pydantic-settings, reads .env + env vars). validate_config() is a fail-closed
boot check on the Supabase vars.
Variable | Description | Where to get it |
| Report project URL ( | Supabase → Settings → API |
| Read service key (server-side only, never exposed) | Supabase → Settings → API · also in |
| JSON map of faculty tokens → | You generate it |
| Single all-campus break-glass token (alternative to | You generate it |
| Base for report links (default | — |
| Public URL of this service (optional) | Render dashboard |
All logging goes to stderr; log lines never contain token contents or PII.
Access model (role-based, campus-scoped)
Unlike the student MCP (per-user RLS), this serves faculty who see institutional data for their
campuses. A bearer token maps to a principal with an allowed-campus set; every tool intersects
the requested campus with that set. A campus outside the grant returns {"found": false} — no data
leaks.
Generate a per-campus token block:
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
}The Supabase service-role key stays server-side and is never handed to the host. There is no write path in the codebase.
Architecture
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_accuracyFull design: docs/ARCHITECTURE.md.
Key files
Path | Purpose |
| FastMCP app, |
| Settings + |
| Read-only |
| Shared helpers: |
| Primary data tools |
| Cohort rollups |
| Secondary report layer |
| TTL cache, budgets/scoping, tool hints |
| End-to-end MCP client smoke test |
Caches (OOM-safe — bounded TTLCache only)
_run_cache (latest final run per scope), _rollup_cache / _marks_cache (cohort raw-data
rollups). Cohort tools page past PostgREST's 1000-row cap and cache the result for 5 min.
Deployment
Render (
render.yamlblueprint or Docker): Python 3.12 / Docker,uvicorn server:app, health check/health. SetSUPABASE_URL,SUPABASE_SERVICE_ROLE_KEY,MCP_TOKENSin the dashboard.Docker:
docker build -t moodle-mcp . && docker run -p 8000:8000 --env-file .env moodle-mcpCurrent prod is on the Free instance (spins down after ~15 min idle → ~50s cold start). Upgrade to Starter for always-on.
Environment | URL | Notes |
Production |
| Free instance, |
Local |
|
|
Full test/deploy steps: DEPLOY.md.
Runbooks
Rotate access tokens — regenerate MCP_TOKENS (same generator), update the Render env var; the
service restarts and old tokens stop working. Re-issue the new tokens to faculty.
Add a per-campus faculty — add one "mcp_...": {"name": "...", "campuses": ["<campus>"]} entry
to MCP_TOKENS, redeploy, hand them their token.
Add a new tool — follow docs/ARCHITECTURE.md §11: add a Params model + _impl(svc,…) +
register(), campus-scope every query, strip_secrets, write the routing docstring, register in
server.py. Reuse the raw-data helpers in tools/common.py.
Cold start / first request slow — Free instance woke from idle (~50s). Warm it with
curl <url>/health, or upgrade the instance.
Verify a deploy — curl <url>/health, then
MCP_URL="<url>/mcp" MCP_TOKEN="<token>" python test_client.py.
Safety invariants
Read-only forever · campus-scope every query · uniform {"found": false} misses (no existence
oracle) · secret stripping (run ids / storage keys / hashes / emails never leave the server) ·
service-role key server-side only · response budgets + paging · graceful degradation (never 500 the
turn) · bounded caches only (OOM-safe). Detail in docs/ARCHITECTURE.md §3, §11.
This server cannot be installed
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
- AlicenseNot gradedqualityBmaintenanceEnables querying your team's work (stats, overdue, workload, active members, etc.) via natural language, scoped to your department with read-only signed-token access.46MIT
- AlicenseNot gradedqualityCmaintenanceEnables read-only access to VortexIQ ecommerce AI data, including store audits, KPIs, alerts, brand DNA, and reports, through natural language queries.MIT
- FlicenseNot gradedqualityBmaintenanceEnables querying of live organizational data (student records, outcomes, certifications, finances, donations, communications) via Claude using structured database queries and semantic search.
- FlicenseNot gradedqualityCmaintenanceProvides tools for querying student academic data such as subjects, marks, performance reports, timetable, exams, fees, events, holidays, and assignments via natural language.
Related MCP Connectors
Read-only access to your VortexIQ store data: audits, KPIs, alerts, Brand DNA, reports, Ask VIQ.
Official Microsoft MCP Server to query Microsoft Entra data using natural language
Ask your app anything — revenue, errors, read-cost, growth — and get rendered charts back.
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/mansigambhir-1313/Moodle-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server