sentra-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. sentra_mcp-0.1.0/.github/workflows/publish.yml +18 -0
  2. sentra_mcp-0.1.0/.gitignore +22 -0
  3. sentra_mcp-0.1.0/.python-version +1 -0
  4. sentra_mcp-0.1.0/LICENSE +21 -0
  5. sentra_mcp-0.1.0/OS-Course/lectures/.gitkeep +0 -0
  6. sentra_mcp-0.1.0/OS-Course/output/.gitkeep +0 -0
  7. sentra_mcp-0.1.0/OS-Course/past_exams/.gitkeep +0 -0
  8. sentra_mcp-0.1.0/PKG-INFO +196 -0
  9. sentra_mcp-0.1.0/README.md +172 -0
  10. sentra_mcp-0.1.0/landing/.gitignore +24 -0
  11. sentra_mcp-0.1.0/landing/README.md +24 -0
  12. sentra_mcp-0.1.0/landing/index.html +30 -0
  13. sentra_mcp-0.1.0/landing/package-lock.json +1820 -0
  14. sentra_mcp-0.1.0/landing/package.json +28 -0
  15. sentra_mcp-0.1.0/landing/public/favicon.svg +8 -0
  16. sentra_mcp-0.1.0/landing/src/App.tsx +31 -0
  17. sentra_mcp-0.1.0/landing/src/components/Closing.tsx +82 -0
  18. sentra_mcp-0.1.0/landing/src/components/CodeBlock.tsx +66 -0
  19. sentra_mcp-0.1.0/landing/src/components/DemoChat.tsx +124 -0
  20. sentra_mcp-0.1.0/landing/src/components/Faq.tsx +57 -0
  21. sentra_mcp-0.1.0/landing/src/components/Features.tsx +64 -0
  22. sentra_mcp-0.1.0/landing/src/components/Hero.tsx +133 -0
  23. sentra_mcp-0.1.0/landing/src/components/HowItWorks.tsx +58 -0
  24. sentra_mcp-0.1.0/landing/src/components/Install.tsx +167 -0
  25. sentra_mcp-0.1.0/landing/src/components/Navbar.tsx +127 -0
  26. sentra_mcp-0.1.0/landing/src/components/QuickStart.tsx +39 -0
  27. sentra_mcp-0.1.0/landing/src/components/Section.tsx +57 -0
  28. sentra_mcp-0.1.0/landing/src/components/WhatIs.tsx +50 -0
  29. sentra_mcp-0.1.0/landing/src/config.ts +46 -0
  30. sentra_mcp-0.1.0/landing/src/i18n/ar.ts +166 -0
  31. sentra_mcp-0.1.0/landing/src/i18n/en.ts +166 -0
  32. sentra_mcp-0.1.0/landing/src/i18n/index.tsx +41 -0
  33. sentra_mcp-0.1.0/landing/src/index.css +71 -0
  34. sentra_mcp-0.1.0/landing/src/main.tsx +10 -0
  35. sentra_mcp-0.1.0/landing/src/motion/variants.ts +20 -0
  36. sentra_mcp-0.1.0/landing/tsconfig.json +25 -0
  37. sentra_mcp-0.1.0/landing/vite.config.ts +7 -0
  38. sentra_mcp-0.1.0/opencode.jsonc.example +14 -0
  39. sentra_mcp-0.1.0/prompts/Extracting_Text_from_PDF.md +95 -0
  40. sentra_mcp-0.1.0/prompts/exam_targets_prompt.md +313 -0
  41. sentra_mcp-0.1.0/prompts/knowledge_base_prompt.md +298 -0
  42. sentra_mcp-0.1.0/prompts/predicted_exam_prompt.md +176 -0
  43. sentra_mcp-0.1.0/prompts/professor_dna_prompt.md +369 -0
  44. sentra_mcp-0.1.0/pyproject.toml +48 -0
  45. sentra_mcp-0.1.0/src/sentra/__init__.py +3 -0
  46. sentra_mcp-0.1.0/src/sentra/analysis_prep.py +180 -0
  47. sentra_mcp-0.1.0/src/sentra/course_store.py +74 -0
  48. sentra_mcp-0.1.0/src/sentra/exam_files.py +80 -0
  49. sentra_mcp-0.1.0/src/sentra/exam_spec.py +112 -0
  50. sentra_mcp-0.1.0/src/sentra/init_cmd.py +136 -0
  51. sentra_mcp-0.1.0/src/sentra/pdf_reader.py +101 -0
  52. sentra_mcp-0.1.0/src/sentra/server.py +154 -0
  53. sentra_mcp-0.1.0/src/sentra/settings.py +31 -0
  54. sentra_mcp-0.1.0/tests/__init__.py +0 -0
  55. sentra_mcp-0.1.0/tests/conftest.py +55 -0
  56. sentra_mcp-0.1.0/tests/test_analysis.py +56 -0
  57. sentra_mcp-0.1.0/tests/test_course_store.py +39 -0
  58. sentra_mcp-0.1.0/tests/test_exam_output.py +118 -0
  59. sentra_mcp-0.1.0/tests/test_init.py +62 -0
  60. sentra_mcp-0.1.0/tests/test_pdf_reader.py +49 -0
  61. sentra_mcp-0.1.0/tests/test_tools.py +74 -0
  62. sentra_mcp-0.1.0/uv.lock +743 -0
@@ -0,0 +1,18 @@
1
+ name: publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ id-token: write
9
+ contents: read
10
+
11
+ jobs:
12
+ publish:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: astral-sh/setup-uv@v5
17
+ - run: uv build
18
+ - run: uv publish
@@ -0,0 +1,22 @@
1
+ # Python
2
+ .venv/
3
+ dist/
4
+ build/
5
+ __pycache__/
6
+ *.pyc
7
+ *.pyo
8
+ .pytest_cache/
9
+
10
+ # Student materials — never commit private PDFs
11
+ OS-Course/**/*.pdf
12
+ OS-Course/**/*.PDF
13
+
14
+ # Frontend
15
+ landing/node_modules/
16
+ landing/dist/
17
+
18
+ # OS / editors
19
+ .DS_Store
20
+ Thumbs.db
21
+ .vscode/
22
+ .idea/
@@ -0,0 +1 @@
1
+ 3.11
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 mo22zy2
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
File without changes
File without changes
File without changes
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.5
2
+ Name: sentra-mcp
3
+ Version: 0.1.0
4
+ Summary: Sentra — local-first MCP server for mock exam generation
5
+ Project-URL: Homepage, https://github.com/mo22zy2/Sentra-MCP
6
+ Project-URL: Issues, https://github.com/mo22zy2/Sentra-MCP/issues
7
+ Author: mo22zy2
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Keywords: education,mcp,mock-exam,opencode,study
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Education
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Requires-Python: <3.14,>=3.11
19
+ Requires-Dist: anyio>=4.9
20
+ Requires-Dist: mcp<3,>=2
21
+ Requires-Dist: pydantic>=2.12
22
+ Requires-Dist: pymupdf>=1.26
23
+ Description-Content-Type: text/markdown
24
+
25
+ # Sentra — AI-Powered Mock Exam Generator (local-first MCP server)
26
+
27
+ Sentra is a local-first **MCP server** for university students. It lets you
28
+ generate realistic mock exams from your lecture PDFs and previous exams.
29
+
30
+ **OpenCode is the AI client, Sentra is the tool it calls.** The MCP server
31
+ does document extraction, validation, analysis prep, and local file
32
+ operations. Your configured AI model (via OpenCode) does the reasoning and
33
+ writes the questions. Model inference costs depend on your chosen provider —
34
+ Sentra itself makes no model calls and costs nothing.
35
+
36
+ No hosted backend, no cloud database, no file storage, no auth service.
37
+ Everything runs on your machine. Nothing you study is uploaded anywhere
38
+ by Sentra.
39
+
40
+ Bilingual product site + docs: [`landing/`](landing/) (English / Egyptian Arabic).
41
+
42
+ ## Fastest start: two commands, OpenCode does the rest
43
+
44
+ Prerequisite (once): install `uv` — Windows: `winget install -e --id astral-sh.uv`,
45
+ macOS/Linux or any Python: `pip install uv`.
46
+
47
+ ```bash
48
+ uvx sentra-mcp init
49
+ ```
50
+
51
+ `init` creates your course folder, adds Sentra to your `opencode.json`
52
+ (backing it up first, never deleting your other settings), and tells you
53
+ where to drop PDFs — in plain words. Then open OpenCode and paste:
54
+
55
+ ```text
56
+ Verify the 5 sentra tools work, then analyze my past exams and summarize the professor's question patterns.
57
+ ```
58
+
59
+ Or skip the terminal entirely: paste this into OpenCode and the agent will
60
+ run the setup for you:
61
+
62
+ ```text
63
+ 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.
64
+ ```
65
+
66
+ Then drop lecture PDFs into `lectures/`, past exams into `past_exams/`, and ask:
67
+
68
+ - "Analyze the previous exams and summarize the professor's question patterns."
69
+ - "Generate a two-hour Operating Systems mock exam with an answer key."
70
+
71
+ You get `output/<name>_exam.md` + `output/<name>_answers.md`, saved locally.
72
+
73
+ ## Manual install (developers)
74
+
75
+ Requires: Miniconda/Anaconda, Python 3.11.
76
+
77
+ ```bash
78
+ git clone https://github.com/mo22zy2/Sentra-MCP.git
79
+ cd Sentra-MCP
80
+ conda create -n mcp python=3.11 -y
81
+ conda activate mcp
82
+ pip install uv
83
+ uv sync --python "$CONDA_PREFIX/bin/python" # Windows: uv sync --python %CONDA_PREFIX%\python.exe
84
+ ```
85
+
86
+ Verify (tested on Python 3.11.17, MCP SDK 2.3.0, PyMuPDF 1.28.2):
87
+
88
+ ```bash
89
+ uv run python -c "from mcp.server import MCPServer; import pymupdf; print('ok')"
90
+ uv run pytest -q # expect: 30 passed
91
+ ```
92
+
93
+ ### OpenCode configuration
94
+
95
+ 1. Install OpenCode per https://opencode.ai/docs and configure any
96
+ compatible provider/model. That provider bills you if paid.
97
+ 2. Copy `opencode.jsonc.example` into your OpenCode config (`opencode.json`),
98
+ replacing `<ABSOLUTE_PATH_TO_SENTRA_REPO>` and
99
+ `<ABSOLUTE_PATH_TO_COURSE_FOLDER>` with real absolute paths:
100
+
101
+ ```jsonc
102
+ {
103
+ "$schema": "https://opencode.ai/config.json",
104
+ "mcp": {
105
+ "sentra": {
106
+ "type": "local",
107
+ "command": ["uvx", "sentra-mcp"],
108
+ "environment": { "SENTRA_COURSE_DIR": "<ABSOLUTE_PATH_TO_COURSE_FOLDER>" },
109
+ "enabled": true,
110
+ "timeout": 30000
111
+ }
112
+ }
113
+ }
114
+ ```
115
+
116
+ (`uvx` fetches `sentra-mcp` from PyPI on first run — no clone needed.
117
+ Developers running from source can use
118
+ `["uv", "--directory", "<ABSOLUTE_PATH_TO_SENTRA_REPO>", "run", "sentra"]`
119
+ instead.)
120
+
121
+ Verified against https://opencode.ai/docs/mcp-servers: `type: "local"`
122
+ + `command[]` array, absolute `--directory`, `environment` for the course dir
123
+ (not secrets), `enabled`, `timeout`. Never put API keys here.
124
+
125
+ ### Course folder
126
+
127
+ ```
128
+ OS-Course/
129
+ ├── lectures/ # lecture PDFs (primary content source)
130
+ ├── past_exams/ # previous exam PDFs (style evidence)
131
+ └── output/ # generated *_exam.md + *_answers.md (auto-created)
132
+ ```
133
+
134
+ Flat subfolders only — no reorganization needed. Supported format:
135
+ **PDF only** in this version (`.txt`/`.docx` are rejected with a clear error).
136
+
137
+ ## Tools (5, all local)
138
+
139
+ | Tool | What it does |
140
+ |---|---|
141
+ | `list_course_pdfs` | Lists `lectures/` + `past_exams/` PDFs, reports unreadable files. Never leaves the course dir. |
142
+ | `extract_pdf_text` | Page-preserving text extraction (50 pages / 60k chars per call). Flags scanned PDFs instead of returning silent empties. No OCR. |
143
+ | `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. |
144
+ | `prepare_exam_brief` | Validates your exam spec, returns a grounded brief + warnings for unsupported topics. The agent writes the questions. |
145
+ | `save_exam_files` | Validates exam/answer-key separation and saves `output/<name>_exam.md` + `<name>_answers.md`. Refuses silent overwrites. |
146
+
147
+ `prompts/` holds the 5 agent workflow prompts (extract → knowledge base →
148
+ professor DNA → targets → predicted exam).
149
+
150
+ ## Privacy
151
+
152
+ - Sentra processes and saves everything on your machine and uploads nothing.
153
+ - If your OpenCode model is cloud-hosted, the content you ask about is sent
154
+ to that provider — local processing does not guarantee content stays local.
155
+ - Scanned/image PDFs are flagged `insufficient_text: true`. OCR is out of scope.
156
+
157
+ ## Limits & safety
158
+
159
+ - 50 MB per file; 50 pages / 60 000 chars per `extract_pdf_text` call;
160
+ 12 000-char lecture budget per brief.
161
+ - All paths resolve inside the course dir (`../` escapes rejected).
162
+ - PDFs are treated as untrusted data (never executed). Corrupt/empty PDFs
163
+ return clear errors. No secrets in logs or config.
164
+
165
+ ## Troubleshooting
166
+
167
+ | Symptom | Fix |
168
+ |---|---|
169
+ | `Course directory does not exist` | Create it or set `SENTRA_COURSE_DIR` to an existing absolute folder. |
170
+ | `Access denied ... escapes the course directory` | Use `lectures/x.pdf`-style relative paths only. |
171
+ | Tools missing in OpenCode | `opencode mcp list`; check absolute `--directory`; re-run `uv sync`; restart OpenCode; bump `timeout` to 30000. |
172
+ | `... must sum to 100` | Difficulty `{easy,medium,hard}` must total exactly 100. |
173
+ | `Refusing to overwrite` | New `basename` or `overwrite: true`. |
174
+ | `Unsupported file type` | This version reads PDFs only. |
175
+ | `insufficient_text: true` | Scanned PDF — use a text-based export. |
176
+ | `Unknown question types` | Allowed: MCQ, True/False, Short Answer, Essay, Numerical, Comparison, Diagram, Case Study, Application, Analysis, Problem Solving. |
177
+
178
+ ## Tests
179
+
180
+ ```bash
181
+ conda activate mcp
182
+ uv run pytest -q
183
+ ```
184
+
185
+ Covers extraction, empty/corrupt PDFs, page refs, dir validation, traversal
186
+ blocks, input/spec/output validation, key separation, filename collisions,
187
+ `init` config merge + backups, and MCP registration via in-memory `Client(mcp)`.
188
+ Fixtures are synthetic — never commit private materials (see `.gitignore`:
189
+ course PDFs are excluded).
190
+
191
+ ## Contributing
192
+
193
+ Open an issue or pull request at
194
+ https://github.com/mo22zy2/Sentra-MCP with your OS, Python version, the
195
+ command you ran, and the full error message. Never attach private course
196
+ materials.
@@ -0,0 +1,172 @@
1
+ # Sentra — AI-Powered Mock Exam Generator (local-first MCP server)
2
+
3
+ Sentra is a local-first **MCP server** for university students. It lets you
4
+ generate realistic mock exams from your lecture PDFs and previous exams.
5
+
6
+ **OpenCode is the AI client, Sentra is the tool it calls.** The MCP server
7
+ does document extraction, validation, analysis prep, and local file
8
+ operations. Your configured AI model (via OpenCode) does the reasoning and
9
+ writes the questions. Model inference costs depend on your chosen provider —
10
+ Sentra itself makes no model calls and costs nothing.
11
+
12
+ No hosted backend, no cloud database, no file storage, no auth service.
13
+ Everything runs on your machine. Nothing you study is uploaded anywhere
14
+ by Sentra.
15
+
16
+ Bilingual product site + docs: [`landing/`](landing/) (English / Egyptian Arabic).
17
+
18
+ ## Fastest start: two commands, OpenCode does the rest
19
+
20
+ Prerequisite (once): install `uv` — Windows: `winget install -e --id astral-sh.uv`,
21
+ macOS/Linux or any Python: `pip install uv`.
22
+
23
+ ```bash
24
+ uvx sentra-mcp init
25
+ ```
26
+
27
+ `init` creates your course folder, adds Sentra to your `opencode.json`
28
+ (backing it up first, never deleting your other settings), and tells you
29
+ where to drop PDFs — in plain words. Then open OpenCode and paste:
30
+
31
+ ```text
32
+ Verify the 5 sentra tools work, then analyze my past exams and summarize the professor's question patterns.
33
+ ```
34
+
35
+ Or skip the terminal entirely: paste this into OpenCode and the agent will
36
+ run the setup for you:
37
+
38
+ ```text
39
+ 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.
40
+ ```
41
+
42
+ Then drop lecture PDFs into `lectures/`, past exams into `past_exams/`, and ask:
43
+
44
+ - "Analyze the previous exams and summarize the professor's question patterns."
45
+ - "Generate a two-hour Operating Systems mock exam with an answer key."
46
+
47
+ You get `output/<name>_exam.md` + `output/<name>_answers.md`, saved locally.
48
+
49
+ ## Manual install (developers)
50
+
51
+ Requires: Miniconda/Anaconda, Python 3.11.
52
+
53
+ ```bash
54
+ git clone https://github.com/mo22zy2/Sentra-MCP.git
55
+ cd Sentra-MCP
56
+ conda create -n mcp python=3.11 -y
57
+ conda activate mcp
58
+ pip install uv
59
+ uv sync --python "$CONDA_PREFIX/bin/python" # Windows: uv sync --python %CONDA_PREFIX%\python.exe
60
+ ```
61
+
62
+ Verify (tested on Python 3.11.17, MCP SDK 2.3.0, PyMuPDF 1.28.2):
63
+
64
+ ```bash
65
+ uv run python -c "from mcp.server import MCPServer; import pymupdf; print('ok')"
66
+ uv run pytest -q # expect: 30 passed
67
+ ```
68
+
69
+ ### OpenCode configuration
70
+
71
+ 1. Install OpenCode per https://opencode.ai/docs and configure any
72
+ compatible provider/model. That provider bills you if paid.
73
+ 2. Copy `opencode.jsonc.example` into your OpenCode config (`opencode.json`),
74
+ replacing `<ABSOLUTE_PATH_TO_SENTRA_REPO>` and
75
+ `<ABSOLUTE_PATH_TO_COURSE_FOLDER>` with real absolute paths:
76
+
77
+ ```jsonc
78
+ {
79
+ "$schema": "https://opencode.ai/config.json",
80
+ "mcp": {
81
+ "sentra": {
82
+ "type": "local",
83
+ "command": ["uvx", "sentra-mcp"],
84
+ "environment": { "SENTRA_COURSE_DIR": "<ABSOLUTE_PATH_TO_COURSE_FOLDER>" },
85
+ "enabled": true,
86
+ "timeout": 30000
87
+ }
88
+ }
89
+ }
90
+ ```
91
+
92
+ (`uvx` fetches `sentra-mcp` from PyPI on first run — no clone needed.
93
+ Developers running from source can use
94
+ `["uv", "--directory", "<ABSOLUTE_PATH_TO_SENTRA_REPO>", "run", "sentra"]`
95
+ instead.)
96
+
97
+ Verified against https://opencode.ai/docs/mcp-servers: `type: "local"`
98
+ + `command[]` array, absolute `--directory`, `environment` for the course dir
99
+ (not secrets), `enabled`, `timeout`. Never put API keys here.
100
+
101
+ ### Course folder
102
+
103
+ ```
104
+ OS-Course/
105
+ ├── lectures/ # lecture PDFs (primary content source)
106
+ ├── past_exams/ # previous exam PDFs (style evidence)
107
+ └── output/ # generated *_exam.md + *_answers.md (auto-created)
108
+ ```
109
+
110
+ Flat subfolders only — no reorganization needed. Supported format:
111
+ **PDF only** in this version (`.txt`/`.docx` are rejected with a clear error).
112
+
113
+ ## Tools (5, all local)
114
+
115
+ | Tool | What it does |
116
+ |---|---|
117
+ | `list_course_pdfs` | Lists `lectures/` + `past_exams/` PDFs, reports unreadable files. Never leaves the course dir. |
118
+ | `extract_pdf_text` | Page-preserving text extraction (50 pages / 60k chars per call). Flags scanned PDFs instead of returning silent empties. No OCR. |
119
+ | `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. |
120
+ | `prepare_exam_brief` | Validates your exam spec, returns a grounded brief + warnings for unsupported topics. The agent writes the questions. |
121
+ | `save_exam_files` | Validates exam/answer-key separation and saves `output/<name>_exam.md` + `<name>_answers.md`. Refuses silent overwrites. |
122
+
123
+ `prompts/` holds the 5 agent workflow prompts (extract → knowledge base →
124
+ professor DNA → targets → predicted exam).
125
+
126
+ ## Privacy
127
+
128
+ - Sentra processes and saves everything on your machine and uploads nothing.
129
+ - If your OpenCode model is cloud-hosted, the content you ask about is sent
130
+ to that provider — local processing does not guarantee content stays local.
131
+ - Scanned/image PDFs are flagged `insufficient_text: true`. OCR is out of scope.
132
+
133
+ ## Limits & safety
134
+
135
+ - 50 MB per file; 50 pages / 60 000 chars per `extract_pdf_text` call;
136
+ 12 000-char lecture budget per brief.
137
+ - All paths resolve inside the course dir (`../` escapes rejected).
138
+ - PDFs are treated as untrusted data (never executed). Corrupt/empty PDFs
139
+ return clear errors. No secrets in logs or config.
140
+
141
+ ## Troubleshooting
142
+
143
+ | Symptom | Fix |
144
+ |---|---|
145
+ | `Course directory does not exist` | Create it or set `SENTRA_COURSE_DIR` to an existing absolute folder. |
146
+ | `Access denied ... escapes the course directory` | Use `lectures/x.pdf`-style relative paths only. |
147
+ | Tools missing in OpenCode | `opencode mcp list`; check absolute `--directory`; re-run `uv sync`; restart OpenCode; bump `timeout` to 30000. |
148
+ | `... must sum to 100` | Difficulty `{easy,medium,hard}` must total exactly 100. |
149
+ | `Refusing to overwrite` | New `basename` or `overwrite: true`. |
150
+ | `Unsupported file type` | This version reads PDFs only. |
151
+ | `insufficient_text: true` | Scanned PDF — use a text-based export. |
152
+ | `Unknown question types` | Allowed: MCQ, True/False, Short Answer, Essay, Numerical, Comparison, Diagram, Case Study, Application, Analysis, Problem Solving. |
153
+
154
+ ## Tests
155
+
156
+ ```bash
157
+ conda activate mcp
158
+ uv run pytest -q
159
+ ```
160
+
161
+ Covers extraction, empty/corrupt PDFs, page refs, dir validation, traversal
162
+ blocks, input/spec/output validation, key separation, filename collisions,
163
+ `init` config merge + backups, and MCP registration via in-memory `Client(mcp)`.
164
+ Fixtures are synthetic — never commit private materials (see `.gitignore`:
165
+ course PDFs are excluded).
166
+
167
+ ## Contributing
168
+
169
+ Open an issue or pull request at
170
+ https://github.com/mo22zy2/Sentra-MCP with your OS, Python version, the
171
+ command you ran, and the full error message. Never attach private course
172
+ materials.
@@ -0,0 +1,24 @@
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ node_modules
11
+ dist
12
+ dist-ssr
13
+ *.local
14
+
15
+ # Editor directories and files
16
+ .vscode/*
17
+ !.vscode/extensions.json
18
+ .idea
19
+ .DS_Store
20
+ *.suo
21
+ *.ntvs*
22
+ *.njsproj
23
+ *.sln
24
+ *.sw?
@@ -0,0 +1,24 @@
1
+ # Sentra landing page (public site, not the exam app)
2
+
3
+ Bilingual (EN / Egyptian Arabic) product + docs site for the Sentra MCP server.
4
+ Lives in `landing/` so the Python MCP project at the repo root stays untouched.
5
+
6
+ ## Run
7
+
8
+ ```bash
9
+ cd landing
10
+ npm install
11
+ npm run dev # local preview
12
+ npm run build # production build → dist/
13
+ ```
14
+
15
+ ## Notes
16
+
17
+ - `src/config.ts` — `GITHUB_URL` is the single source of truth for the repo
18
+ link (currently `https://github.com/mo22zy2/Sentra-MCP`). The bootstrap
19
+ prompt (`BOOTSTRAP_PROMPT`) injects it automatically. Never hardcode the
20
+ URL elsewhere.
21
+ - Install commands and the OpenCode JSON mirror the root `README.md` and
22
+ `opencode.jsonc.example` verbatim. If those change, update `src/config.ts`.
23
+ - Stack: React + TypeScript + Tailwind v4 (`@tailwindcss/vite`) + motion +
24
+ lucide-react. No router (anchor navigation, single page).
@@ -0,0 +1,30 @@
1
+ <!doctype html>
2
+ <html lang="en" dir="ltr">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Sentra — Study smarter. Practice with purpose.</title>
8
+ <meta
9
+ name="description"
10
+ content="Sentra is a local-first MCP server that turns your lecture PDFs and previous exams into focused mock exams through AI agents like OpenCode."
11
+ />
12
+ <meta property="og:title" content="Sentra — Study smarter. Practice with purpose." />
13
+ <meta
14
+ property="og:description"
15
+ content="Turn lecture PDFs and past exams into focused practice with a local-first MCP server built for AI-powered studying."
16
+ />
17
+ <meta property="og:type" content="website" />
18
+ <meta name="twitter:card" content="summary" />
19
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
20
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
21
+ <link
22
+ href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=IBM+Plex+Sans+Arabic:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap"
23
+ rel="stylesheet"
24
+ />
25
+ </head>
26
+ <body>
27
+ <div id="root"></div>
28
+ <script type="module" src="/src/main.tsx"></script>
29
+ </body>
30
+ </html>