Quran Recitation Validator
مُدَقِّق التِّلاوة القُرآنية — Quran Recitation Validator v2.2
Validates Arabic Quran recitations — single verse, full surah, juz, page, or any consecutive verse range. Supports standard Arabic, Uthmani script, and full tashkeel (harakat) validation.
Features
Feature | Detail |
Single-verse | Finds + validates any of the 6,236 Quran verses |
Multi-verse | Full surah, juz, page, or arbitrary consecutive range |
Tashkeel | Per-word harakat comparison (فتحة، ضمة، كسرة، مدة، شدة، سكون) |
Uthmani input | Paste directly from Mushaf — normalizes |
4-layer search | Exact → Linguistic (roots/morphology) → Relaxed → Fuzzy |
WER scoring | Word Error Rate = (subs + dels + ins) / reference words |
Arabic feedback | Human-readable result in Arabic |
Folder Structure
validator/
│
├── 📄 server.py FastMCP 2.0 server (port 3001)
├── 📄 validator_mcp.py Main routing: auto single ↔ multi-verse
├── 📄 normalizer.py Arabic normalizer pipeline (7 steps)
├── 📄 quran_db.py O(1) indexed DB (gid / sura / juz / page)
├── 📄 quran_search.py 4-layer verse search engine
├── 📄 multi_verse.py Forward alignment for multi-verse recitation
├── 📄 tashkeel.py Per-word harakat validation
│
├── 📂 data/
│ ├── quran.json 6,236 verses — gid, uthmani, standard, standard_full, ... (5.1 MB)
│ ├── uthmani_standard_map.json 2,017 Uthmani→standard word pairs, corpus-derived (70 KB) ★
│ ├── word-map.json Arabic word → root + morphological forms (877 KB)
│ └── morphology.json Root index + verb/noun patterns (2.5 MB)
│
├── 📂 tests/
│ ├── test_all.py 124 tests across 12 categories — 123/124 pass (99.2%)
│ ├── dataset_gen.py Auto-generates 63 test cases from quran.json
│ └── dataset.json Generated test cases (gitignored)
│
├── 🖼️ architecture.svg System architecture diagram (this file)
├── 📄 README.md This file
├── 📄 Dockerfile
└── 📄 .env.exampleArchitecture
The system has 6 pipeline stages (see architecture.svg):
Input Text
↓
[Mode Detection] → single (≤8 words) or multi (>8 words)
↓
[Normalizer] — 7 steps:
① NFC unicode
② Word-level map (2017 Uthmani→standard pairs) ← NEW v2.2
③ Remove tashkeel / Quranic marks
④ U+0670 contextual fallback (ٰ → ا unless ى/ذ/ه/ل)
⑤ Alef variants → ا Hamza variants → ء
⑥ word-initial ءا → ا ى → ي
⑦ Remove non-Arabic, collapse whitespace
↓
[Search / Alignment]
Single: 4-layer search (exact AND → linguistic → relaxed → fuzzy)
Multi: detect start verse → word-by-word boundary scan → forward align
↓
[Word Diff] — SequenceMatcher opcodes → substitutions / deletions / insertions → WER
↓
[Tashkeel Check] — if user provided harakat: per-word harakat comparison
↓
JSON Result: {is_correct, verse_key, wer, corrections, tashkeel_errors, feedback, ...}Normalizer — Uthmani Script Handling
The key innovation of v2.2 is the word-level corpus map:
# uthmani_standard_map.json — built by aligning all 6,236 verses
{
"الرحمٰن": "الرحمن", # ← Bismillah fix (was "الرحمان" in v2.1)
"الكتٰب": "الكتاب",
"الخٰسرون": "الخاسرون",
"أولٰئك": "أولئك",
"ذٰلك": "ذلك",
"هٰذا": "هذا",
"علىٰ": "على",
... # 2,017 total entries
}Result: 100% accuracy on all 8,107 ٰ-containing words in the Quran corpus.
Run
MCP Server (production)
uv run python server.py
# Port 3001 / SSE endpoint at /sseTests
cd servers/validator
python3 tests/dataset_gen.py # regenerate 63 test cases
python3 tests/test_all.py # run all 124 testsAPI
Exposed as the MCP tool validate_recitation(text) (SSE at :3001/sse).
The tool returns the Arabic feedback string; the internal
validate_recitation() in validator_mcp.py produces the full result dict
below (single- and multi-verse shapes):
Input:
{ "text": "بسم الله الرحمن الرحيم" }Single-verse result:
{
"mode": "single",
"is_correct": true,
"verse_key": "1:1",
"surah_name": "الفاتحة",
"wer": 0.0,
"corrections": [],
"matched_verse": "بِسۡمِ ٱللَّهِ ٱلرَّحۡمَٰنِ ٱلرَّحِیمِ",
"feedback": "ممتاز! تلاوتك صحيحة تماماً.",
"has_tashkeel": false
}Multi-verse result (7-verse Fatiha):
{
"mode": "multi",
"is_correct": true,
"total_verses": 7,
"correct_verses": 7,
"total_wer": 0.0,
"verses": [ {"verse_key":"1:1","is_correct":true,"wer":0.0}, ... ],
"range": "من الفاتحة (1:1) إلى (1:7)"
}Test Results — v2.2
Category | Tests | Pass |
Normalizer unit tests | 11 | 11 ✅ |
QuranDB unit tests | 7 | 7 ✅ |
Single-verse perfect | 10 | 10 ✅ |
Single-verse substitution | 4 | 3 ✅ 1 ❌¹ |
Single-verse deletion | 3 | 3 ✅ |
Single-verse tashkeel | 6 | 6 ✅ |
Multi-verse full surahs | 7 | 7 ✅ |
Multi-verse with errors | 3 | 3 ✅ |
Multi-verse consecutive | 6 | 6 ✅ |
Multi-verse full pages | 5 | 5 ✅ |
Edge cases | 5 | 5 ✅ |
Dataset-driven | 62 | 62 ✅ |
Total | 124 | 123 (99.2%) |
¹ SS03: واحد → finds 6:19 instead of 112:1 — wrong root in word-map.json source data.
Known Limitations
# | Issue | Cause | Affects |
1 |
| Wrong root in | Ikhlas v1 detection |
2 | Huruf muqatta'at (الم، الر) | Not searchable | Start-verse detection |
3 | Identical verse openings | Lower GID always wins | 2:63 vs 2:93 |
4 |
| 1 Uthmani word = 2 standard words | 338 verses w/ يا أيها |
Changelog
v2.2 (2026-03-09)
NEW
data/uthmani_standard_map.json— 2,017 corpus-derived Uthmani→standard word pairsFIX
الرحمٰن→الرحمن(wasالرحمانin v2.1)FIX All 8,107 ٰ-containing Quranic words now normalize with 100% accuracy
Architecture SVG diagram added
v2.1 (2026-03-09)
FIX U+0670 contextual rule:
ٰ→اexcept after ى/ذ/ه/لFIX
ءَاتَ(Uthmani initial ءا) → standardاتَVerse 2:121 Uthmani input now validates correctly (0 errors, was 3 errors)
v2.0 (2026-03-09)
Multi-verse alignment engine (
multi_verse.py)Tashkeel validation (
tashkeel.py)Complete Arabic normalizer (
normalizer.py)O(1) QuranDB (
quran_db.py)4-layer search (
quran_search.py)Test suite: 123/124 (99.2%)
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/NightPrinceY/validator-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server