DEV Community

Cover image for I built a self-hosted AI knowledge base on top of offline Wikipedia (and it speaks MCP)
Kuldip Satpute
Kuldip Satpute

Posted on AI-assisted

I built a self-hosted AI knowledge base on top of offline Wikipedia (and it speaks MCP)

On my home server I have a folder containing ZIM files: these are offline versions of Wikipedia, Stack Exchange, DevDocs and iFixit, all drawn from the Kiwix catalog. This collection amounts to tens of gigabytes of knowledge and functions without the need for an internet connection.

The problem was that kiwix-serve only allows you to read it. What I wanted to do was:

  • ask it questions and get answers I could verify,
  • keep the books updated without checking for new releases by hand, — have my other AI tools (Claude, the local LLMs) use it as a source.

That is how I created Zim Pro, a drop-in substitute for kiwix-serve which does all three things.

What it does

  • Read and carry out a search: perform a full-text search either within a single book or throughout the entire library.
  • Ask AI: this will provide answers that are based solely on your books, including numbered citations referring back to the original articles, together with the images and videos from those pages.
  • Fully offline: just point it at Ollama, LM Studio, or llama.cpp and nothing will leave your network. Any API compatible with OpenAI can be used, whether it's hosted or local.
  • MCP server: Claude together with other LLM applications is able to search and read the library.
  • Auto-updates: for each book it is compared with the Kiwix catalog; the downloads make use of multiple connections, are checksummed in parts, and can be resumed if there is a crash.
  • Make your own ZIMs: based on websites, PDFs, EPUBs, Kindle books and RSS feeds.
  • The article's Markdown export.

The interesting part: retrieval

A vector search covering all of Wikipedia wasn't possible since embedding millions of articles locally is slow and uses up a lot of disk space. Instead, Zim Pro makes use of the full-text index that is already contained in each ZIM file and places the intelligence around that index:

  1. Plan: the model looks at the list of books and then forms a number of brief questions from various perspectives, includes additional keywords, and selects the books that are most likely to be of assistance.
  2. Deep search: when carrying out each query, the selected books together with the main encyclopedia are searched.
  3. Light search: the main queries are applied to every other book, ensuring that nothing obvious is overlooked.
  4. Rank: The results are combined using a method known as reciprocal rank fusion. The top 24 articles are examined and evaluated based on how well a single passage addresses the subject, and only those passages which are suitable are passed on to the model.

The model receives articles in the form of cleaned Markdown, not HTML. Any navigation links, reference lists, "See also" sections, citation markers and licence footers are removed, and each passage is then given its section heading. This arrangement means that the amount of context window used is reserved for the prose.

Small local models frequently generate incorrect Markdown, for example with unclosed code blocks, malformed tables or leaked reasoning. All answers undergo a repair stage before they are displayed.

Using it from Claude via MCP

claude mcp add --transport http zim-pro http://localhost:8083/mcp
Enter fullscreen mode Exit fullscreen mode

The available tools are list_books, search, suggest, get_article, get_article_outline and list_updates. You have the option of locking the /mcp interface using per-app API keys, with only the SHA-256 fingerprint of each key being stored and allowing any key to be revoked individually.

Try it

mkdir -p zims state
docker run -d --name zim-pro \
  --user "$(id -u):$(id -g)" \
  -p 8083:8080 \
  -v "$PWD/zims:/data" \
  -v "$PWD/state:/state" \
  --add-host host.docker.internal:host-gateway \
  ghcr.io/magicstack-llp/zim-pro:latest
Enter fullscreen mode Exit fullscreen mode

Just open http://localhost:8083, drop some .zim files into the zims/ folder (or add them using the built-in catalog), and then make your request. When you first start up, two free AI services are set up, so Ask AI will work even if you haven't configured anything.

There is also a standalone Linux binary, or else you can enter the command 'pip install zim-pro'.

Stack

The backend uses Python 3.13, FastAPI, the python-libzim library and SQLite, while the UI is built with React, Vite and Tailwind. Images are available for the amd64 and arm64 architectures.

Known limitations

Since libzim does not provide relevance scores, when carrying out a cross-book search it groups the results by book rather than ranking them.
Since libzim holds onto Python's Global Interpreter Lock, other requests are briefly delayed when a full-text search is carried out.
The articles are served from the same source as the admin UI (just as with kiwix-serve). Set the KIWIX_ADMIN_TOKEN if you are loading untrusted ZIMs or if you need to expose the server beyond your local area network.

AI involvement

Developed with Claude.


You can find the code on GitHub at magicstack-llp/zim-pro. Suggestions, reports of issues and pull requests are all welcome, in particular those from people who are using large libraries or small local models.

Top comments (0)