MCP server exposing Arabic knowledge sources (Quran, Hadith, Arabic Wikipedia, Arabic news) to any MCP client
Strong foundation with 11 well-named, read-only tools covering Arabic knowledge domains (Quran, Hadith, news, Wikipedia). All tools have descriptions (avg 180 chars, within 10-1024 baseline) and complete input schemas with types. Parameter descriptions are present and actionable. However, output schemas are documented only in descriptions, not as formal JSON Schema; error handling lacks recovery guidance; no tool annotations (readOnlyHint); and some parameter constraints could be more explicit (e.g., language enum values, surah range validation). Composition is clean, each tool has one responsibility, but descriptions could be more LLM-optimized per pattern:tool-description.
Fetch a single hadith by collection slug and hadith number. Args: collection: One of the slugs returned by ``hadith_list_collections`` (e.g. ``"bukhari"``, ``"muslim"``, ``"nawawi40"``). number: 1-based hadith number within the collection. language: ``"both"`` (Arabic + English, default), ``"en"`` only, or ``"ar"`` only. Returns: ``{"collection", "collection_name", "hadith_number", "reference", "grades", "arabic", "english"}``. Fields for the language you didn't request will be ``null``. Examples: - ``hadith_get("bukhari", 1)`` - the famous "Actions are by intentions" hadith - ``hadith_get("nawawi40", 13, language="en")`` - Nawawi #13
List the supported Hadith collections and their identifiers. Call this first if the user asks "which collections do you have?" or before composing a query so you know which ``collection`` slugs are valid for ``hadith_get`` and ``hadith_search``. Returns: ``{"collections": [{"slug", "name"}, ...]}``. ``slug`` is the short identifier used everywhere else in this tool.
Search within a single Hadith collection for hadiths containing a keyword. The first search against a collection downloads the full edition once (a few MB) and keeps it in memory; subsequent searches are in-process substring scans. Args: query: Search term in Arabic or English. Arabic is normalized (alef variants folded, tashkeel ignored) before matching. collection: Collection slug (default ``"bukhari"``). See ``hadith_list_collections``. limit: Maximum hits to return (1-50, default 10). language: ``"auto"`` (detect from query), ``"ar"``, or ``"en"``. Returns: ``{"query", "language", "collection", "total_matches", "returned", "results": [{"hadith_number", "reference", "text", "matched_in"}]}``. Call ``hadith_get`` for the parallel translation of any hit. Examples: - ``hadith_search("intention")`` - English search in Bukhari - ``hadith_search("النية", collection="muslim")`` - Arabic search - ``hadith_search("prayer", collection="nawawi40", limit=5)``
Output schemas documented only in prose descriptions, not as formal JSON Schema. LLMs cannot parse unstructured text to infer response structure for downstream tool chaining.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). All tools are read-only but lack explicit annotation to guide agent planning and safety checks.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 61 | <=2025-11-25 | v2 |
Get the latest Arabic news headlines. Args: source: Single source slug (e.g. ``"aljazeera"``, ``"bbc"``) Omit to aggregate across **all** configured sources. limit: Maximum items returned in total (1-100, default 20). When aggregating, items are interleaved in the order each feed lists them - most outlets put newest first. Returns: ``{"sources_queried", "returned", "items": [{"source", "source_name", "title", "link", "summary", "published"}]}``. Examples: - ``news_headlines()`` - top stories across every outlet - ``news_headlines(source="aljazeera", limit=10)``
List the Arabic news outlets this server can pull RSS from. Returns: ``{"sources": [{"id", "name", "url"}]}``. ``id`` is the slug accepted by ``news_headlines`` and ``news_search``.
Search Arabic news headlines and summaries for a keyword. Searches title + summary text. Arabic normalization (alef folding, tashkeel stripping) is applied so a query for ``"الاسلام"`` will match headlines spelled ``"الإسلام"``. Args: query: Search term in Arabic or English. source: Single source slug to restrict to; omit to search all. limit: Maximum hits to return (1-100, default 20). Returns: ``{"query", "sources_queried", "total_matches", "returned", "items": [...]}``. Each item has the same shape as ``news_headlines``. Examples: - ``news_search("غزة")`` - across all outlets - ``news_search("الذكاء الاصطناعي", source="bbc")``
Get metadata for a Surah (chapter) without its verses.
Fetch a single Quran verse with both Arabic and English text. Use this when the user references a specific ayah and you need its exact wording - for tafsir-style questions, quoting in answers, or when another tool returned a reference you want to expand. Args: reference: Verse reference in ``"surah:ayah"`` form. Surah is 1-114; ayah is 1-based within the surah. Returns: A dict with ``reference``, ``surah`` metadata (Arabic + English names, revelation type, total ayah count), ``arabic`` (Uthmani script), ``english`` (Saheeh International translation), and positional metadata (``juz``, ``page``, ``sajda``). Examples: - ``quran_get_verse("2:255")`` → Ayat al-Kursi - ``quran_get_verse("1:1")`` → Bismillah - ``quran_get_verse("112:1")`` → Al-Ikhlas opening
Search the Quran for verses containing a keyword (Arabic or English). Returns matches in the searched language only - call ``quran_get_verse`` on a hit's ``reference`` to also get the parallel translation. Args: query: Search term. Arabic input searches the Uthmani text; English input searches the Saheeh International translation. limit: Maximum results to return (default 10, max 50). surah: Restrict search to a single surah (1-114). Omit to search all 114. language: ``"auto"`` (detect from query), ``"ar"`` (force Arabic search), or ``"en"`` (force English search). Returns: ``{"query": str, "language": str, "total_matches": int, "returned": int, "results": [...]}``. Each result has ``reference``, ``surah`` metadata, ``text``, and ``ayah_number_global``. Examples: - ``quran_search("mercy")`` - English search - ``quran_search("الرحمن", limit=5)`` - Arabic search - ``quran_search("light", surah=24)`` - within Surah An-Nur only
Fetch the intro/summary of an Arabic Wikipedia article by exact title. Use this after ``wikipedia_search`` returns a promising title, or when the user names a specific topic. The summary is a plain-text extract of the article lead - typically 1-3 paragraphs. Args: title: Exact Wikipedia article title. Use the ``title`` field from ``wikipedia_search`` results. Returns: ``{"title", "display_title", "description", "extract", "url", "thumbnail_url", "lang", "dir"}``. ``extract`` is the plain-text intro; ``thumbnail_url`` may be ``null``. Examples: - ``wikipedia_get_summary("ابن سينا")`` - ``wikipedia_get_summary("الجزائر")``
Search Arabic Wikipedia for article titles matching a query. Returns just titles + snippets - call ``wikipedia_get_summary`` on a hit's title to read the article intro. Args: query: Search terms. Arabic recommended (this hits the Arabic Wikipedia), but English query terms also work for entities with Arabic articles (e.g. "Python"). limit: Maximum titles to return (1-50, default 10). Returns: ``{"query", "total_hits", "returned", "results": [{"title", "snippet", "page_id", "word_count", "timestamp"}]}``. ``snippet`` is HTML with ``<span>`` highlight markers around the matched terms. Examples: - ``wikipedia_search("ابن سينا")`` - Avicenna - ``wikipedia_search("الذكاء الاصطناعي")`` - Artificial Intelligence - ``wikipedia_search("Python", limit=5)``
Parameter constraints not formalized as enums or patterns. E.g., 'language' accepts 'both'|'en'|'ar' but no enum constraint; 'surah' accepts 1-114 but no min/max bounds in schema.
Error handling lacks recovery guidance. Tools document error codes (e.g., 'not_found') but do not guide LLM on next steps (e.g., 'Try hadith_search() with a partial keyword').
quran_get_surah_info description is minimal (9 chars: 'Get metadata for a Surah (chapter) without its verses.'). Lacks context on when to call it vs. quran_get_verse.