Coaching institutes in India live in spreadsheets, WhatsApp groups and question PDFs. A teacher preparing SSC students might spend an evening writing 25 Time and Work questions, then another hour working out which students have gone quiet.
We build Mocxam at CeptorLabs, a mock-test and student-analytics platform for coaching institutes. This post is about the newest thing we shipped: a remote MCP server, so teachers can use Mocxam from inside Claude or ChatGPT.
TL;DR
- Mocxam now exposes an MCP server at
https://api.mocxam.com/mcp - Teachers connect with their own Mocxam login (OAuth), and can disconnect any time
- They can generate questions in bulk, query student performance and, if they're admins, manage portal settings, all in plain language
- AI-generated questions land in the Question Bank, not in live tests
- It works with Claude today and with ChatGPT through its custom MCP server option
Why MCP?
The usual way to add "AI" to a product is to embed a chatbot in it. We went the other way: teachers already use an AI assistant for lesson plans, emails and explanations, so why make them open yet another chat window?
The Model Context Protocol is an open standard for connecting AI apps to external tools and data. You write one server that exposes tools, and any MCP-capable client can use them. That "build once, work in several assistants" property is what convinced us. We didn't want to maintain a separate integration per assistant.
What teachers can actually do
These are real prompts from our connector page:
- "Make 25 Medium Quant questions for SSC CGL on Time and Work, with explanations."
- "Who are my 10 best students this month?"
- "Which students have not taken a test in 2 weeks?"
- "Give me a profile of roll number R014: strong and weak sections."
And for admins:
- "Make my student portal use our logo colours and rewrite the hero for SSC aspirants."
- "Add priya@ourinstitute.in as faculty who can manage questions and mocks."
The interesting part isn't any single prompt. It's that the assistant can chain them: find the weak section, generate targeted practice questions for it, then drop them in the Question Bank.
Design decisions we care about
1. Per-teacher OAuth, not a shared API key
Each teacher signs in with their own Mocxam account when they add the connector. The assistant acts as that person, so it can only see and do what that person can. Revoking access is a single "disconnect" on their side.
[ADD: one or two sentences on your OAuth setup, e.g. provider, scopes, token lifetime.]
2. Roles still apply
Mocxam already has faculty roles and permissions. The MCP layer doesn't bypass them: the admin-style requests above are for admins, and a faculty member shouldn't be able to rebrand the portal because a chatbot asked nicely.
[ADD: how you enforce this, e.g. same authorization layer as the web app.]
3. Human in the loop for anything students see
This was the decision we debated most. AI-generated questions can be wrong, and a wrong answer key in a mock test hurts real students.
So generated questions go straight into the Question Bank, and students only see them after a teacher adds them to a mock. There's a review step by design. We tell teachers in the docs to check answer keys first, and we'd rather say that than pretend the model never makes mistakes.
4. Tenant isolation
Each institute gets its own portal and data. The MCP server resolves everything from the authenticated user's institute, so a prompt can't wander into another institute's students.
[ADD: how tenant scoping is enforced in your tool handlers.]
A sketch of the server side
This is a simplified illustration with the TypeScript SDK, not our production code:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
const server = new McpServer({ name: "mocxam", version: "1.0.0" });
server.registerTool(
"create_questions",
{
title: "Create questions",
description: "Create questions in the teacher's Question Bank",
inputSchema: {
exam: z.string(),
topic: z.string(),
difficulty: z.enum(["Easy", "Medium", "Hard"]),
count: z.number().int().min(1).max(50),
},
},
async ({ exam, topic, difficulty, count }) => {
// [ADD: authorize user, generate/validate, save to Question Bank]
return {
content: [{ type: "text", text: `Added ${count} ${difficulty} ${topic} questions to your Question Bank.` }],
};
}
);
How to connect it
Claude: Settings → Customize → Connectors → Add custom connector. Name it Mocxam, paste your connector address from the AI Connector page in your Mocxam dashboard, then sign in with your Mocxam account.
ChatGPT: Plugins → Add → Add custom MCP server. Name it Mocxam, paste the same address, choose OAuth, continue and sign in. ChatGPT access currently needs a Plus plan or higher, and we'll open it up as Mocxam gets listed in the app directory.
Try it
If you run or teach at a coaching institute, the connector is in your Mocxam dashboard under AI Connector. If you're building your own MCP server and want to compare notes on auth or multi-tenancy, I'd love to hear from you in the comments.
Built by CeptorLabs.
Top comments (1)
This is a really smart architectural choice. Going "the other way" — building an MCP server instead of a generic in-app chatbot — is exactly the kind of composability that saves a product from AI-fatigue.
The "Human in the loop" decision (section 3) is the most critical part of this post. For an exam prep platform in India, a wrong answer key is a brand-killer. Pushing generated content to the Question Bank rather than live tests is the right safety default.
Since you asked for notes on multi-tenancy and auth, here are a few thoughts based on what's worked well for similar B2B setups:
Tenant isolation: Resolve the tenant strictly from the OAuth token context (e.g., institute_id in the claims), never from tool arguments. If an admin passes an institute_id parameter in a prompt, ignore it and cross-check against the session. This prevents "confused deputy" attacks where a malicious prompt tries to query another tenant's data.
OAuth Scopes: Since a teacher can chain prompts (find weak section → generate questions → add to bank), consider implementing incremental scopes. Give the read-only student analytics scope by default, but require an elevated scope (or a re-auth prompt) for tools that mutate data, like create_questions or add_faculty.
Token Lifetime: Keep access tokens short (e.g., 1 hour) and use refresh tokens, so if a teacher's laptop is compromised, the blast radius is limited.
One quick question on the student side: when the AI generates those 25 questions, do you keep a record of the exact prompt that generated them in your database? For auditability, it would be incredibly useful to track "Prompt X generated these questions at Time Y" so you can trace back if a batch of questions turns out to be flawed.
Great write-up, and I love the transparency of the [ADD: ...] placeholders. It shows you're actually building this in the open.