Skip to content

Quran Gallery MCP

by qurangallery.com · remote · no sign-in to list tools · v0.3.0 · published by com.qurangallery

Classical Islamic library (Shamela, 8,594 books): verbatim Arabic cited by volume and page. No key.

Changes · 1

14 tools: 1 change things and 13 only read.

Scanned Oct 21, 2026

No check matched anything in the tool definitions. No finding is not a safety guarantee. How the checks work.

claude mcp add --transport http qurangallery https://qurangallery.com/mcp/shamela

Tools

Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.

14 tools

Changes things 1Claude Code: ask
  • shamela_citeCitations.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Citations. mode=citation (default): build one for a book, optionally a page and quoted text — Shamela's copy format, short inline, full with death year, or BibTeX/RIS. Call it whenever you attribute a quote; it needs only the catalogue, plus the installed text for a page's printed number. Read page_resolved, components.auto_numbered and notes[] before presenting. mode=printed_page: map a printed citation («vol. 4, p. 405») to the page_ids carrying it — no arithmetic relates the two, and one printed page often spans several ids: read them all, in order, with shamela_read(unit='page'). Resolve the work with shamela_find(kind='work') first; holding a page_id already, skip this. Failures come back as `status`; citable:false = Shamela's own numbering. Error: BOOK_NOT_FOUND.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
Only reads 13Claude Code: allow
  • fetchRead one library page whole by the id `search` returned: main text, then its footnotes under their own label (the editor's words, never the author's), with book, author, printed vo…No findings

    Why it is in this group

    • The name "fetch" says "fetch": a word for reading.
    Description, as the server wrote it
    Read one library page whole by the id `search` returned: main text, then its footnotes under their own label (the editor's words, never the author's), with book, author, printed volume/page, edition data and the shamela.ws link. Use shamela_read instead to read one body part at a time (unit "page"), a run of pages (unit "range") or a whole chapter (unit "section"), and shamela_cite (mode "printed_page") to turn a printed volume and page into ids. Not a search. Long pages are cut at 4 body parts of about 4,000 characters (2 without an API key): metadata.complete false, ending with the shamela_read call that continues it. A malformed id, or a page the library does not hold, returns a tool error.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • shamela_findCatalogue lookup — which books, headings, authors and shelves exist, not page text.No findings

    Why it is in this group

    • The name "shamela_find" says "find": a word for reading.
    Description, as the server wrote it
    Catalogue lookup — which books, headings, authors and shelves exist, not page text. `kind`: - book (default): titles, authors, publication lines, subject descriptions → book_ids, installed or not. no_title_match: not proof the book is held. downloaded:false → another edition (shamela_get_details(kind='book') same_group) or catalogue metadata only. - heading: chapter/section headings, i.e. where books treat a topic; open with shamela_read(unit='section', book_id, title_id). No hits = no heading carries the words: drop words or use shamela_search(match='words'). - author: names and biographies → author_id, Hijri death year, book count; no scope. Empty is not absence: retry kunya, nisba or shuhra (ابن قدامة / الموفق / المقدسي). - category: the 41 flat shelves with catalogue and installed counts → scope.category_ids. A subject spans ids (Qur'anic studies 3 tafsir, 4 Qur'anic sciences/usul al-tafsir, 5 tajwid/qira'at; fiqh 14–17 by madhab): pass all that apply. downloaded_only:true when choosing shelves to search or read. - work: verify a cited title (optional author, edition); refuses rather than guesses; catalogue only, text need not be installed. - name: fuzzy best guess over book/author names, for an id; always answers, so never use it to verify a citation. - period: books by Hijri window, bounds ANDed (scope.period_* on searches unions them). Rules: a parameter of another kind is refused; book/heading/author/period page with limit/offset until has_more is false. Instead: page text → shamela_search; a printed page → shamela_cite(mode='printed_page'); one book's headings → shamela_read(unit='toc').

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • shamela_get_briefReturn this server's machine-readable capability handshake: capabilities, numeric limits, retired tool names with their replacements, and traps (ways a result misleads, each with t…No findings

    Why it is in this group

    • The name "shamela_get_brief" says "get": a word for reading.
    Description, as the server wrote it
    Return this server's machine-readable capability handshake: capabilities, numeric limits, retired tool names with their replacements, and traps (ways a result misleads, each with the response field that proves it fired). Call it first from a programmatic client: inputs are strict, so an argument an older build lacks (e.g. `shape`, response_format:'none') is a hard validation error that fails the whole call, and tools/list cannot reveal argument support — gate each new argument on its capability string. Cache by brief_hash and re-fetch only when it changes. Constants only: needs no library access and does not fail. Example: {} or {response_format:'json'}.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • shamela_get_detailsCatalogue record for one book (kind=book, default) or one author (kind=author), installed or not.No findings

    Why it is in this group

    • The name "shamela_get_details" says "get": a word for reading.
    Description, as the server wrote it
    Catalogue record for one book (kind=book, default) or one author (kind=author), installed or not. - book: authors, category, type, printed-edition flag, whether the text is installed here, the scanned printing and the other editions of the same work (same_group). When a reader tool says BOOK_NOT_DOWNLOADED, pick an installed entry from same_group or answer from this record. Read book_date, edition, editor and publisher per their field notes: never supply a missing one. - author: name, Hijri death year (null = unknown or living) and every catalogued book they wrote or co-wrote, each flagged installed or not. Volumes → shamela_read(unit='parts'); a book by title or subject → shamela_find(kind='book'). Errors: BOOK_NOT_FOUND, AUTHOR_NOT_FOUND.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • shamela_lookup_hadithHadith.No findings

    Why it is in this group

    • The name "shamela_lookup_hadith" says "lookup": a word for reading.
    Description, as the server wrote it
    Hadith. mode=search (default): find a hadith by its wording and trace its takhrij — searches the hadith shelves (Sunnah collections, commentaries, takhrij, hadith sciences) in matn and footnotes, reads hadith keys off the matching pages and lists every collection indexing the same hadith. No offset; if the full text matches nothing, one word is dropped and named in `relaxed`. Takhrij covers only key_index_books, so few rows is not proof of a weak or rare hadith. mode=sources: every book recording one hadith_key, with its page_id, one row per book in index order. A downloaded:false book is catalogued but not installed: use another edition (shamela_get_details(kind='book') same_group). Narrator chains → shamela_lookup_rijal(mode='isnad_search'); general text → shamela_search(match='words').

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • shamela_lookup_quranQur'an text.No findings

    Why it is in this group

    • The name "shamela_lookup_quran" says "lookup": a word for reading.
    Description, as the server wrote it
    Qur'an text. mode=search (default): find verses by Arabic words, typed in إملائي spelling or pasted in Uthmani rasm; words ANDed, results in mushaf order (aya_id 1–6236), not relevance. Zero hits usually means a misspelling: drop a word or use options.wildcards. mode=aya: fetch verses you can already cite, by aya_id OR surah + aya (never both or neither: BAD_ARG); `count` gives a run that continues across surahs and stops at the last verse. Each verse in three renderings (body = the spelling search matches, amiri for display). AYA_NOT_FOUND names the valid range. Commentary → shamela_lookup_tafsir; the words inside books → shamela_search(match='words').

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • shamela_lookup_rijalHadith narrators and isnad chains, from Shamela's rijal register and isnad index.No findings

    Why it is in this group

    • The name "shamela_lookup_rijal" says "lookup": a word for reading.
    Description, as the server wrote it
    Hadith narrators and isnad chains, from Shamela's rijal register and isnad index. `mode`: - narrators (default): a narrator by name → narrator_id, most-documented first, then earliest death year. Names collide: confirm the death year before using an id. - narrator: one dossier by narrator_id — lineage, death year, tabaqa, Ibn Hajar's and al-Dhahabi's grades, critics' jarh wa-ta'dil verdicts verbatim with source (the only paged part), hadith_notes on audition and irsal; include_network adds isnad-index counts per book and top teachers/students. Quote verdicts as worded; never synthesize a grade. - isnad_search: chains by the narrators in them — `contains` (anywhere) or `transmission` [teacher_id, student_id] pairs that must be adjacent (direct audition, the stronger test) — each hit with book, page, hadeeth_key and the chain. - isnad: the chain(s) printed on one page (book_id/page_id from a search hit) with names and death years, plus the same hadith's other routes — one thread or many. Rules: a parameter of another mode is refused. Chains run ascending (Companion first, collector last). Only ten hadith books are isnad-indexed (see scope_book_ids): an empty isnad_search means no such chain in those ten, not in all literature; most pages answer no_isnad_indexed:true with a no_isnad_reason, not an error. Errors: RIJAL_UNAVAILABLE (register not installed), NARRATOR_NOT_FOUND (search the name again), BOOK_NOT_FOUND, PAGE_NOT_FOUND, BOOK_NOT_DOWNLOADED (try shamela_get_details(kind='book') same_group). Instead: book authors → shamela_find(kind='author'); a hadith by its text → shamela_lookup_hadith(mode='search').

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • shamela_lookup_tafsirTafsir on one verse (aya_id OR surah + aya, else BAD_ARG).No findings

    Why it is in this group

    • The name "shamela_lookup_tafsir" says "lookup": a word for reading.
    Description, as the server wrote it
    Tafsir on one verse (aya_id OR surah + aya, else BAD_ARG). mode=coverage (default): which tafsir books cover it, fetching no text — shelves 3 (tafsir) and 4 (Qur'anic sciences; not 5, tajwid and qira'at) crossed with Shamela's curated tafsir index, plus index hits from other shelves (in_tafsir_categories:false). Status per book: indexed_covers (with page_id), indexed_no_entry_for_this_aya, or not_indexed_coverage_unknown — NOT evidence the book is silent. mode=texts: the commentary from several books in one call, each attributed (book, author, death year, printed page), read only from pages the index maps to the verse, never a text-search guess. Each source's `note` names the next call when its text continues. Example: {surah:2, aya:255, book_ids:[1503, 639]}.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • shamela_readRead an installed book's text and structure by internal ids.No findings

    Why it is in this group

    • The name "shamela_read" says "read": a word for reading.
    Description, as the server wrote it
    Read an installed book's text and structure by internal ids. `unit`: - page (default): one page_id → body (author's matn), foot (editor's footnotes), printed page label, prev/next page ids, enclosing headings. - range: up to 20 consecutive pages from start_page_id, each with text, footnotes, printed page — to read on past a hit or through a span. - section: one chapter by title_id with its sub-headings, up to the next heading outside it. - toc: headings with their title_ids; top level by default, parent_id/depth expand, containing_page_id gives the chain enclosing a page. - parts: volumes — part label, page count, first/last page_id. - services: what one page cites (aya ids, hadith keys, isnad markers, as stored) → shamela_lookup_quran(mode='aya'), shamela_lookup_hadith(mode='sources'), shamela_lookup_rijal(mode='isnad'). Rules: a parameter of another unit is refused. page_id is not the printed page and ids have gaps: step with prev_page_id/next_page_id, not ±1; for a printed «vol./page» call shamela_cite(mode='printed_page') first. A size budget cuts long text: follow body_has_more (body_part+1) or next_start_page_id. Errors: PAGE_NOT_FOUND (also a range start past the end), TITLE_NOT_FOUND, BOOK_NOT_FOUND, BOOK_NOT_DOWNLOADED (catalogued, not installed: use an installed edition from shamela_get_details(kind='book') same_group). Instead: a heading by its words → shamela_find(kind='heading'); books of untitled «فصل» headings → shamela_search(match='words') scoped to the book; any catalogued book's metadata → shamela_get_details(kind='book').

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • shamela_search_librarySearch one named shelf of the classical Islamic library (8,594 works) for quotable passages: verbatim Arabic with book, author, printed volume/page, edition and a shamela.ws link.No findings

    Why it is in this group

    • The name "shamela_search_library" says "search": a word for reading.
    Description, as the server wrote it
    Search one named shelf of the classical Islamic library (8,594 works) for quotable passages: verbatim Arabic with book, author, printed volume/page, edition and a shamela.ws link. The default first search for hadith, tafsir, fiqh or creed. Not for isnads, narrators or diacritic-exact wording. Use shamela_search (match "words") to pin books or categories or to page past 10 results, shamela_read (unit "page") to read a whole page. Scope is one shelf per call; call again with another shelf to widen. Ranking: exact phrase first, then all the words; a madhhab scope asks that school's own books first; main text before footnote. relaxedToTokens and note flag a weaker match; no passages means absent from that scope, not from the library. A non-Arabic query or unknown scope returns a tool error naming the fix.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • shamela_survey_topicCount how much the library holds on a term and where: the exact matching-page total plus its distribution by category, Hijri century, book and author (top 15 each).No findings

    Why it is in this group

    • The description's first verb is "count": a word for reading.
    Description, as the server wrote it
    Count how much the library holds on a term and where: the exact matching-page total plus its distribution by category, Hijri century, book and author (top 15 each). Statistics only, never passages — use shamela_search(match='words') instead to retrieve and read the pages. Run it before searching to size a topic and pick scope.category_ids (map by_category names to ids with shamela_find(kind='category')). mode 'literal' (default, 6–9 ms) counts the word as written; 'morphological' counts every derived form of its root (seconds) and is often far broader. coverage_capped:true means the breakdown is a top-5,000 sample whose counts are floors; total_hits stays exact. No match = total_hits 0; EMPTY_SCOPE when scope matches no book. Example: {term:'الاستصناع', scope:{category_ids:[14,15,16,17]}}; {term:'التيمم', scope:{citable_only:true}}.

    Annotations the server declares

    • readOnlyHint: true
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Install

Pinned to version 0.3.0. Values in angle brackets are yours to fill in.

claude mcp add --transport http qurangallery https://qurangallery.com/mcp/shamela

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__qurangallery__shamela_search_library",
      "mcp__qurangallery__search",
      "mcp__qurangallery__fetch",
      "mcp__qurangallery__shamela_search",
      "mcp__qurangallery__shamela_find",
      "mcp__qurangallery__shamela_read",
      "mcp__qurangallery__shamela_get_details",
      "mcp__qurangallery__shamela_lookup_quran",
      "mcp__qurangallery__shamela_lookup_tafsir",
      "mcp__qurangallery__shamela_lookup_hadith",
      "mcp__qurangallery__shamela_lookup_rijal",
      "mcp__qurangallery__shamela_survey_topic",
      "mcp__qurangallery__shamela_get_brief"
    ],
    "ask": [
      "mcp__qurangallery__shamela_cite"
    ],
    "deny": []
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as qurangallery. Review it before you use it.