Skip to main content
Glama
islamweb-mcp

islamweb-mcp

by EngDawood

islamweb-mcp

An MCP (Model Context Protocol) server, written in TypeScript, for fetching and extracting content from islamweb.net's digital library. It ships with a ready-made, resumable crawler for all five Arabic dictionaries under islamweb's library subject 73 ("معاجم اللغة") — see src/books.ts:

key

title

bookId

ids

lisan-al-arab

لسان العرب (ابن منظور)

122

1..9305

al-qamus-al-muhit

القاموس المحيط (الفيروزآبادي)

123

1..8553

al-nihaya-fi-gharib-al-hadith

النهاية في غريب الحديث والأثر (ابن الأثير)

121

1..4338

maqayis-al-lugha

معجم مقاييس اللغة (ابن فارس)

124

1..5102

mukhtar-al-sihah

مختار الصحاح (الرازي)

125

1..3509

Each is extracted to JSON so it can feed a downstream tool for looking up word definitions. A scheduled GitHub Action runs the crawl every 6 hours, resuming and committing new data automatically — see "Keeping the data fresh" below.

For a hosted, remote version of this (no local server to run) see worker/ — the same 5 dictionaries served as a Streamable HTTP MCP server from a Cloudflare Worker + D1, deployable to your own Cloudflare account.

How the site works (reverse-engineered)

Each dictionary page lives at https://www.islamweb.net/ar/library/content/{bookId}/{id} (the trailing Arabic slug is decorative — the server resolves the page from the numeric id alone). Every page's HTML contains:

  • <div id="pagebody"> — the entry text without diacritics.

  • <div id="pagebody_thaskeel"> — the same text fully vocalized (tashkeel).

  • ol#topPath — a breadcrumb (لسان العرب › chapter, e.g. حرف الهمزة › the current headword, e.g. أبأ).

  • <title> — contains the part/volume number (الجزء رقم N).

  • a.topnextbutton / a.topprevbutton — links to the neighboring ids, absent at the very first/last page of the book.

islamwebClient.ts fetches and parses one page into a LibraryEntry:

{
  bookId, id, url, title, part,
  chapter, chapterId, lemma, breadcrumb,
  printedPage,       // the "[ ص: NN ]" printed page marker, if present
  text,              // plain text
  textTashkeel,      // fully vocalized text
  author, nextId, prevId, fetchedAt
}

Each page is one lexical section, which may cover one root or several related words — it is not pre-split into individual dictionary entries. That finer-grained segmentation (splitting a page's text into per-word definitions) is left to whatever tool consumes this JSON, since it needs real Arabic morphological logic to do well.

Related MCP server: hadith-mcp

Tools exposed over MCP

Tool

Purpose

islamweb_fetch_entry

Fetch + parse a single {bookId, id} page.

islamweb_lisan_al_arab_info

Returns the known bookId/id-range for Lisan al-Arab and this server's default output paths.

islamweb_list_dictionaries

Lists all 5 known dictionaries (bookId, key, title, author, id range).

islamweb_start_crawl

Starts a background, resumable crawl over an id range; returns a jobId immediately.

islamweb_crawl_status

Poll a jobId (or list all jobs from this server process).

islamweb_crawl_stats

Inspect a JSONL output file on disk (entry count, highest id) — works even after a server restart.

islamweb_compile_json

Compile the JSONL file into one sorted, pretty-printed JSON array.

islamweb_search

Substring-search a JSONL file's lemma/text and return snippets.

Why JSONL + a compile step

The crawler appends one JSON object per line to a .jsonl file as soon as each page is fetched, instead of holding everything in memory. That makes a 9305-page crawl resumable: if it's interrupted, re-running with the same outFile reads back the ids already present and only fetches what's missing. islamweb_compile_json / compileJsonlToJson turns that JSONL file into a single .json array once you want a normal JSON file.

Running an extraction

You don't have to drive this through an MCP client — there's a standalone CLI that does the same thing directly. To crawl one dictionary:

npm install
npm run build
node dist/cli.js crawl-book --key=al-qamus-al-muhit --concurrency=6 --delay=100

(key is any key from the table above, or a raw bookId.) To crawl all five, time-boxed so it fits in e.g. a CI job:

node dist/cli.js crawl-all-dictionaries --minutes=320 --concurrency=6 --delay=100

This prints progress, retries transient failures with exponential backoff (skipping immediately on a 404), and writes data/<key>.jsonl + data/<key>.json (sorted by id) for each book. Re-running the same command resumes where it left off — it skips ids already present in that book's .jsonl file, and crawl-all-dictionaries skips whole books that are already fully fetched. --minutes stops dispatching new fetches once the budget is spent (in-flight ones still finish) so a later run can pick up the rest.

Keeping the data fresh: the scheduled GitHub Action

.github/workflows/crawl-dictionaries.yml runs crawl-all-dictionaries every 6 hours (also triggerable by hand via "Run workflow"), then commits and pushes any new/changed files under data/ back to this branch. Because the crawl is resumable and file-based:

  • The first several runs make real progress (fetching whatever's still missing across all 5 dictionaries — roughly 31,000 pages total).

  • Once everything has been fetched, later runs finish in well under a minute (they just confirm every id is already present) and push nothing.

  • If islamweb adds pages to a book (a larger idto on the bookslist page), bump that book's endId in src/books.ts and the next scheduled run picks up the new ids automatically.

The job is time-boxed (--minutes=320 inside a 350-minute job timeout) so it always has room to compile and commit before GitHub's own runner limits kick in, and concurrency: group: crawl-dictionaries makes sure two runs never crawl the same files at once.

Using it as an MCP server

npm run build
npm start   # speaks MCP over stdio

Point any MCP client (Claude Desktop, Claude Code, etc.) at node /path/to/islamweb-mcp/dist/index.js. Example claude_desktop_config.json entry:

{
  "mcpServers": {
    "islamweb": {
      "command": "node",
      "args": ["/absolute/path/to/islamweb-mcp/dist/index.js"]
    }
  }
}

Set ISLAMWEB_DATA_DIR to change where the default Lisan al-Arab .jsonl/.json files live (defaults to ./data).

Notes on politeness

robots.txt on islamweb.net only disallows /newislamweb/, and /ar/library/content/... is not restricted. The crawler still defaults to a modest concurrency (3) and a per-request delay (250ms) to avoid hammering the site; both are configurable.

Available Tools

8 tools
islamweb_compile_jsonCompile JSONL crawl output into one JSON arrayA

Reads a JSONL dataset file (one entry per line) and writes it out as a single sorted, pretty-printed JSON array file. Run this once a crawl has finished (or whenever you want a fresh snapshot).

Inputs: jsonFile, jsonlFile.

islamweb_crawl_statsInspect an output JSONL file on diskA

Reads a JSONL dataset file directly from disk (independent of any in-memory job) and reports how many entries it has and the highest id fetched so far. Useful after restarting the MCP server to see how far a previous crawl got.

Inputs: outFile.

islamweb_crawl_statusCheck crawl job statusA

Returns progress (done/total/failed) for a crawl job started with islamweb_start_crawl.

Inputs: jobId.

islamweb_fetch_entryFetch one islamweb library pageA

Fetches a single content page from islamweb.net's library (https://www.islamweb.net/ar/library/content/{bookId}/{id}) and returns it parsed as JSON: title, chapter/lemma breadcrumb, plain text, fully-vocalized (tashkeel) text, and next/prev ids.

Inputs: id (required), bookId (required).

islamweb_lisan_al_arab_infoLisan al-Arab crawl coordinatesA

Returns the known bookId and id range (1..9305) for لسان العرب لابن منظور on islamweb.net, plus the paths this server uses for its extracted JSON/JSONL dataset.

Inputs: no named parameters.

islamweb_list_dictionariesList known islamweb dictionariesA

Returns every dictionary this server knows about under islamweb's library subject 73 (معاجم اللغة): bookId, key, title, author, and id range. This is the registry the GitHub Actions crawl workflow and the crawl-all-dictionaries CLI command iterate over.

Inputs: no named parameters.

islamweb_start_crawlStart a background crawlA

Starts crawling a contiguous range of content ids from one islamweb library book in the background (this call returns immediately with a jobId; poll islamweb_crawl_status with it). Each fetched page is appended as one JSON line to outFile as soon as it is parsed, so the crawl is resumable: re-running with the same outFile skips ids already present in it. Defaults are set up for لسان العرب لابن منظور (bookId 122, ids 1..9305) — omit bookId/startId/endId/outFile to crawl the whole dictionary.

Inputs: endId, bookId, delayMs, outFile, +2 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 8 tools

    Disambiguation4/5

    Most tools have clearly distinct roles, but islamweb_crawl_status and islamweb_crawl_stats could be confused at first glance since both relate to crawl progress. The descriptions clarify that one tracks an in-memory job and the other reads a file, so the ambiguity is minor.

    Naming Consistency4/5

    All tools share the consistent islamweb_ prefix and snake_case convention, and most follow a verb_noun pattern (fetch_entry, start_crawl, compile_json). A few names deviate by leading with a noun (crawl_status, crawl_stats, lisan_al_arab_info), which is a slight inconsistency but still readable and predictable.

    Tool Count5/5

    With 8 tools, the set is well-scoped for the server's purpose: discover dictionaries, fetch entries, crawl in the background, monitor progress, inspect datasets, compile, and search. No tool feels redundant or unnecessary, and the count is squarely in the ideal 3-15 range.

    Completeness4/5

    The tool surface covers the full crawl workflow—listing, fetching, starting, monitoring, compiling, and searching—which covers the stated purpose well. Minor gaps exist such as no explicit cancel-job or list-running-jobs tool, but these are workaround-able and don't create dead ends for the core pipeline.

    Maintenance

    ActivitySlowing
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables fetching and searching canonical hadith texts (Arabic and English) with cross-references and citation-safe URLs for assistants, built on FastMCP.
      3
      GPL 3.0
    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP server to search and retrieve passages from a corpus of 7,872 classical Islamic books via the Sahifah API, with full citations and mu'tabar filtering.
      21 npm
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP server that gives AI clients fast, accurate access to turath.io's books and resources, with tools for author biographies, book metadata, full texts, parsed pages, and catalog search over stdio or HTTP.
      21 npm
      1
      MIT