Skip to main content

Sentra — AI-Powered Mock Exam Generator (local-first MCP server)

Sentra is a local-first MCP server for university students. It lets you generate realistic mock exams from your lecture PDFs and previous exams.

OpenCode is the AI client, Sentra is the tool it calls. The MCP server does document extraction, validation, analysis prep, and local file operations. Your configured AI model (via OpenCode) does the reasoning and writes the questions. Model inference costs depend on your chosen provider — Sentra itself makes no model calls and costs nothing.

No hosted backend, no cloud database, no file storage, no auth service. Everything runs on your machine. Nothing you study is uploaded anywhere by Sentra.

Bilingual product site + docs: landing/ (English / Egyptian Arabic).

The user wants Sentra installed and running. Do everything below yourself. Never ask the student to run commands or edit files. Everything stays on this machine — NEVER upload their files anywhere.

  1. Install: if uvx sentra-mcp init works, use it. Otherwise git clone this repo, then uv sync inside it (install uv first via pip install uv if missing; create a Python 3.11 environment if no Python 3.11+ exists). Verify with uv run pytest -q (expect 30 passed).
  2. Configure: add the sentra block from opencode.jsonc.example under mcp in the user's opencode.json (create mcp if missing, keep every other key). Prefer command ["uvx", "sentra-mcp"]; from source use ["uv", "--directory", "<ABSOLUTE_REPO_PATH>", "run", "sentra"]. Set SENTRA_COURSE_DIR to an absolute course path.
  3. Course folder: create OS-Course/{lectures,past_exams,output} if init didn't (default: next to the repo or under Documents).
  4. Verify the 5 tools respond: list_course_pdfs, extract_pdf_text, analyze_past_exams, prepare_exam_brief, save_exam_files.
  5. Tell the user (simply, in their language): the exact folder to drop PDFs into, and that they must RESTART OpenCode for the tools to appear.
  6. Making exams: for EACH exam requested, call prepare_exam_brief with its spec, write original questions (never copy past exams), then save_exam_files with a DIFFERENT basename per exam (e.g. mock1, mock2). Never reuse a basename unless the user says overwrite. Every answer key stays in its separate *_answers.md file.
  1. Copy this repo link: \https://github.com/mo22zy2/Sentra-MCP2. In OpenCode, paste it and say: \download and run this mcp3. Restart OpenCode so the sentra tools appear.
  2. Drop lecture PDFs into \lectures/\ and past exams into \past_exams/.
  3. Say: \make me 2 exams using the sentra mcp\ — collect both exams and both answer keys from \output/.

Prefer to run it yourself?

Prerequisite (once): install uv — Windows: winget install -e --id astral-sh.uv, macOS/Linux or any Python: pip install uv.

uvx sentra-mcp init

init creates your course folder, adds Sentra to your opencode.json (backing it up first, never deleting your other settings), and tells you where to drop PDFs — in plain words. Then open OpenCode and paste:

Verify the 5 sentra tools work, then analyze my past exams and summarize the professor's question patterns.

Or skip the terminal entirely: paste this into OpenCode and the agent will run the setup for you:

Install Sentra on this computer: make sure `uv` is installed (install it if missing), then run `uvx sentra-mcp init` to configure OpenCode and create my course folder. Verify the 5 sentra tools are available, then tell me where to drop my lecture PDFs and past exams, in simple words. Never upload my files anywhere.

Then drop lecture PDFs into lectures/, past exams into past_exams/, and ask:

  • "Analyze the previous exams and summarize the professor's question patterns."
  • "Generate a two-hour Operating Systems mock exam with an answer key."

You get output/<name>_exam.md + output/<name>_answers.md, saved locally.

Manual install (developers)

Requires: Miniconda/Anaconda, Python 3.11.

git clone https://github.com/mo22zy2/Sentra-MCP.git
cd Sentra-MCP
conda create -n mcp python=3.11 -y
conda activate mcp
pip install uv
uv sync --python "$CONDA_PREFIX/bin/python"   # Windows: uv sync --python %CONDA_PREFIX%\python.exe

Verify (tested on Python 3.11.17, MCP SDK 2.3.0, PyMuPDF 1.28.2):

uv run python -c "from mcp.server import MCPServer; import pymupdf; print('ok')"
uv run pytest -q               # expect: 30 passed

OpenCode configuration

  1. Install OpenCode per https://opencode.ai/docs and configure any compatible provider/model. That provider bills you if paid.
  2. Copy opencode.jsonc.example into your OpenCode config (opencode.json), replacing <ABSOLUTE_PATH_TO_SENTRA_REPO> and <ABSOLUTE_PATH_TO_COURSE_FOLDER> with real absolute paths:
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "sentra": {
      "type": "local",
      "command": ["uvx", "sentra-mcp"],
      "environment": { "SENTRA_COURSE_DIR": "<ABSOLUTE_PATH_TO_COURSE_FOLDER>" },
      "enabled": true,
      "timeout": 30000
    }
  }
}

(uvx fetches sentra-mcp from PyPI on first run — no clone needed. Developers running from source can use ["uv", "--directory", "<ABSOLUTE_PATH_TO_SENTRA_REPO>", "run", "sentra"] instead.)

Verified against https://opencode.ai/docs/mcp-servers: type: "local"

  • command[] array, absolute --directory, environment for the course dir (not secrets), enabled, timeout. Never put API keys here.

Course folder

OS-Course/
├── lectures/     # lecture PDFs (primary content source)
├── past_exams/   # previous exam PDFs (style evidence)
└── output/       # generated *_exam.md + *_answers.md (auto-created)

Flat subfolders only — no reorganization needed. Supported format: PDF only in this version (.txt/.docx are rejected with a clear error).

Tools (5, all local)

Tool What it does
list_course_pdfs Lists lectures/ + past_exams/ PDFs, reports unreadable files. Never leaves the course dir.
extract_pdf_text Page-preserving text extraction (50 pages / 60k chars per call). Flags scanned PDFs instead of returning silent empties. No OCR.
analyze_past_exams Question types, wording templates, approx difficulty, marks — every finding cites file:page. Past patterns only; never claims to predict the real exam.
prepare_exam_brief Validates your exam spec, returns a grounded brief + warnings for unsupported topics. The agent writes the questions.
save_exam_files Validates exam/answer-key separation and saves output/<name>_exam.md + <name>_answers.md. Refuses silent overwrites.

prompts/ holds the 5 agent workflow prompts (extract → knowledge base → professor DNA → targets → predicted exam).

Privacy

  • Sentra processes and saves everything on your machine and uploads nothing.
  • If your OpenCode model is cloud-hosted, the content you ask about is sent to that provider — local processing does not guarantee content stays local.
  • Scanned/image PDFs are flagged insufficient_text: true. OCR is out of scope.

Limits & safety

  • 50 MB per file; 50 pages / 60 000 chars per extract_pdf_text call; 12 000-char lecture budget per brief.
  • All paths resolve inside the course dir (../ escapes rejected).
  • PDFs are treated as untrusted data (never executed). Corrupt/empty PDFs return clear errors. No secrets in logs or config.

Troubleshooting

Symptom Fix
Course directory does not exist Create it or set SENTRA_COURSE_DIR to an existing absolute folder.
Access denied ... escapes the course directory Use lectures/x.pdf-style relative paths only.
Tools missing in OpenCode opencode mcp list; check absolute --directory; re-run uv sync; restart OpenCode; bump timeout to 30000.
... must sum to 100 Difficulty {easy,medium,hard} must total exactly 100.
Refusing to overwrite New basename or overwrite: true.
Unsupported file type This version reads PDFs only.
insufficient_text: true Scanned PDF — use a text-based export.
Unknown question types Allowed: MCQ, True/False, Short Answer, Essay, Numerical, Comparison, Diagram, Case Study, Application, Analysis, Problem Solving.

Tests

conda activate mcp
uv run pytest -q

Covers extraction, empty/corrupt PDFs, page refs, dir validation, traversal blocks, input/spec/output validation, key separation, filename collisions, init config merge + backups, and MCP registration via in-memory Client(mcp). Fixtures are synthetic — never commit private materials (see .gitignore: course PDFs are excluded).

Contributing

Open an issue or pull request at https://github.com/mo22zy2/Sentra-MCP with your OS, Python version, the command you ran, and the full error message. Never attach private course materials.

Metadata

Release files for sentra-mcp 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sentra-mcp 1.0.0
File Size Uploaded
sentra_mcp-1.0.0.tar.gz 94.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sentra-mcp 1.0.0
File Interpreter ABI Platform
sentra_mcp-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 114.7 kB

Release files / sentra_mcp-1.0.0.tar.gz

Download URL sentra_mcp-1.0.0.tar.gz
Size 94.1 kB
Tags Source
SHA-256 checksum
How to use checksums
88c72a66504c5ae54e27e1ef6d6386cbf41b4b5076a2833f4509932caa953177
BLAKE2b-256 checksum
How to use checksums
6623529f7706a8a5862b2c12e54fea6558fe970056ef86c16589f29758e81893
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / sentra_mcp-1.0.0-py3-none-any.whl

Download URL sentra_mcp-1.0.0-py3-none-any.whl
Size 20.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b0e10f1cfc1524a60123d86b512c3ee6c5275d392f81a22397490bdcc0875edd
BLAKE2b-256 checksum
How to use checksums
1d3c0d9da405d28be2e70ba0404dc50fd2e61d026114049f31cab9920d4544f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page