Skip to main content
Glama

corpus-mcp

Ein lokaler Server für MCP, der einem Agenten einen sauberen, effizienten Zugriff auf eine lokale Wissensbasis aus Offline-ZIM-Archiven bietet — Wikipedia, medizinische Dokumentation (MDWiki), Entwicklerdokumentation (DevDocs) und Stack Exchange — über eine einheitliche Schnittstelle. Kein Internet, keine Embeddings, keine Vektor-Datenbank: libzim-Volltextsuche plus deterministische, serverseitige Inhaltsbereinigung.

Die öffentliche MCP-Oberfläche besteht aus genau zwei Werkzeugen:

search(query, limit?)
fetch(ref, sections?)

Das konfigurierte Korpus ist eine Betreiber-Angelegenheit, keine Agenten-Angelegenheit. Der Agent darf ausschließlich Folgendes verwenden:

discover  →  search()
select    →  fetch()

Korpus-Familien

Korpus

kind

Dokument

Abschnittsmodell

Wikipedia, MDWiki

article

Artikel

Überschriftenbaum (h2+), Einleitungsabschnitt mit der ID ""

DevDocs (C, CMake, Python)

documentation

Dokumentationsseite

Überschriftenbaum; In-Page-Inhaltsverzeichnisse und Navigationsrahmen entfernt

Stack Exchange

thread

Frage + Antworten

synthetische Abschnitte: question, accepted-answer, answer-<id>

Die gesamte Korpusidentifikation, das Routing, der ZIM-Zugriff, die HTML-Interpretation, die Bereinigung, das Ranking, die Redirect-Behandlung und die Normalisierung liegen in der Verantwortung des Servers. Der Agent muss weder HTML parsen noch Redirects auflösen, keine Referenzen erzeugen oder parsen und auch nichts über libzim, ZIM-Namensräume oder die Interna der Korpus-Speicherung wissen.

Related MCP server: mcpzim

Referenzen

search()-Ergebnisse enthalten eine opake ref (z. B. corpus://Wikipedia/Bell_test); fetch() konsumiert sie. Der Agent darf eine ref niemals erzeugen, parsen oder verändern und er darf das Korpus nicht aus einer ref ableiten.

search() produces ref      fetch() consumes ref

Architektur

Local agent
    │  MCP / Streamable HTTP  →  http://127.0.0.1:8000/mcp
    ▼
┌──────────────────────────────────────────────┐
│ Corpus MCP Server                            │
│  search()  fetch()                           │
│  ├─ CorpusManager (routing, cache,          │
│  │   bounded-concurrency fan-out)           │
│  ├─ federated ranking (RRF + lexical title  │
│  │   reranking + diversity)                 │
│  ├─ adapters: mediawiki / devdocs /         │
│  │   stackexchange                           │
│  ├─ HTML cleaner → Markdown, section trees  │
│  └─ GlobalRef codec (opaque refs)           │
└─────────────┬────────────────────────────────┘
              ▼
      per-library ZIM service (only libzim touchpoint,
      one search lock per archive)
              ▼
      corpus/  (read-only volume, N .zim archives)
      corpus.toml  (manifest: name, adapter, path)

Die MCP-Ebene macht keinerlei libzim-Konzepte sichtbar: keine Namensräume, keine Cluster-IDs, keine Roheinträge, keine MIME-Typen und kein reines HTML.

Voraussetzungen

  • Docker + Docker Compose

  • ZIM-Archive (siehe unten)

  • Für den lokalen Lauf der Testsuite: Python 3.12 und uv (oder pip)

Korpus-Struktur

Der Server lädt niemals selbst Archive herunter – die Beschaffung des Korpus ist bewusst vom Start der Anwendung entkoppelt. Standardstruktur:

corpus/
  wikipedia/wikipedia_en_all_nopic_*.zim
  medical/mdwiki_en_all_maxi_*.zim
  devdocs/devdocs_en_cpp_*.zim
  devdocs/devdocs_en_cmake_*.zim
  devdocs/devdocs_en_python_*.zim
  stackexchange/stackoverflow.com_en_all_*.zim
  stackexchange/security.stackexchange.com_en_all_*.zim
  stackexchange/softwareengineering.stackexchange.com_en_all_*.zim
corpus.toml

corpus.toml benennt jede Bibliothek, ihren Adapter und ihren Pfad (relativ zum Korpus-Wurzelverzeichnis):

version = 1

[[library]]
name = "Wikipedia"
path = "wikipedia/wikipedia_en_all_nopic_2026-06.zim"
adapter = "mediawiki"

[[library]]
name = "CMake-Docs"
path = "devdocs/devdocs_en_cmake_2026-08.zim"
adapter = "devdocs"

Validierungsregeln: Namen müssen eindeutig sein, Adapter müssen bekannt sein, Pfade müssen innerhalb des Korpus-Wurzelverzeichnisses bleiben. Verifizieren Sie ein Korpus, bevor Sie den Server starten:

make validate-corpus   # opens every archive, reports metadata
make corpus-list       # list configured libraries

Start / Herunterfahren

make start           # build + start (docker compose, detached)
make logs            # tail logs
make ps              # container status
make stop            # stop (keep containers)
make down            # stop + remove
make restart
make build

Der MCP-Endpunkt ist anschließend unter http://127.0.0.1:8000/mcp (Streamable HTTP) erreichbar. Der Host-Port ist standardmäßig nur an Loopback gebunden; der Container lauscht intern auf 0.0.0.0:8000.

Wenn ein konfiguriertes ZIM-Archiv nicht geöffnet werden kann, schlägt der Serverstart fehl und die betreffende Bibliothek wird benannt – es gibt keinen Modus eingeschränkter Funktion.

Tool-Schemata

search(query: str, limit?: int)

Durchsucht den Volltextindex jeder konfigurierten Bibliothek (begrenzte Parallelität, ein Worker pro Archiv), führt die Ranking-Listen mit der Reciprocal-Rank-Fusion zusammen, bewertet gleichwertige korpusübergreifende Kandidaten anhand der lexikalischen Titelabdeckung neu, wendet einen deterministischen Diversitätsdurchlauf an und liefert bereinigte Ergebnisse. limit ist standardmäßig 5; der Server erzwingt eine harte Obergrenze (SEARCH_MAX_LIMIT, Standardwert 10).

{
  "results": [
    {
      "ref": "corpus://Wikipedia/Bell_test",
      "library": "Wikipedia",
      "kind": "article",
      "title": "Bell test",
      "snapshot": "2026-06",
      "snippet": "To close the detection loophole, an apparatus with a high detection efficiency is needed.",
      "relevant_sections": [
        { "id": "Notable_experiments", "title": "Notable experiments" },
        { "id": "Loopholes", "title": "Loopholes" }
      ]
    }
  ]
}
  • ref – opake globale Kennung; sie an fetch() zurückgeben.

  • library / kind / snapshot – Herkunft: welches Archiv, welche Dokumentart und welcher Korpus-Snapshot (abgeleitet aus den Archiv-Metadaten).

  • relevant_sections – 0–3 deterministische lexikalische Hinweise (leer, wenn kein Abschnitt klar übereinstimmt). Die Abschnitts-IDs werden vom Server abgeleitet; der Agent darf rekonstruieren.

Eine ausfallende Bibliothek verschlechtert die Quelle höchstens (die übrigen Lieferanten weiterhin Ergebnisse); sie stoppt sie jedoch nie.

fetch(ref: str, sections?: list[str])

Gibt das bereinigte Dokument als strukturiertes Markdown zurück.

  • Ohne sections: das gesamte Dokument (begrenzt durch MAX_FETCH_CHARS; truncated: true, falls an einer Abschnittsgrenze abgeschnitten).

  • Mit sections: nur diese Abschnitte (einschließlich Unterbäume). Die Abschnitts-IDs stammen aus den search()-Hinweisen oder aus available_sections. Die Einleitung/Intro besitzt die ID "". Bei Threads sind die Abschnitte question, accepted-answer und answer-<id>; deren metadata trägt Bewertung, Annahmestatus und Tags.

{
  "ref": "corpus://Wikipedia/Bell_test",
  "library": "Wikipedia",
  "kind": "article",
  "title": "Bell test",
  "snapshot": "2026-06",
  "sections": [
    { "id": "Loopholes", "title": "Loopholes", "content": "## Loopholes\n\n..." }
  ],
  "available_sections": [
    { "id": "", "title": "Bell test" },
    { "id": "Background", "title": "Background" },
    { "id": "Loopholes", "title": "Loopholes" }
  ],
  "truncated": false
}

Fehler sind präzise und direkt umsetzbar:

{ "error": "invalid_ref", "message": "invalid reference: ..." }
{ "error": "not_found", "message": "Document not found in Wikipedia: Foo_bar" }
{
  "error": "section_not_found",
  "missing_sections": ["Experiments"],
  "available_sections": [ { "id": "Loopholes", "title": "Loopholes" }, "..." ]
}

Beispiel-Workflow für Agenten

search("Bell experiment loopholes")
    ↓
fetch("corpus://Wikipedia/Bell_test", ["Notable_experiments", "Loopholes"])

Konfiguration

Standardwerte der Umgebungsvariablen für Container (angezeigt):

Variable

Standard

Bedeutung

CORPUS_ROOT

/corpus

Korpus-Wurzelverzeichnis innerhalb des Containers (erforderlich)

CORPUS_CONFIG

/config/corpus.toml

Pfad zum Manifest im Container (erforderlich)

MCP_HOST

0.0.0.0

Liste Adresse innerhalb des Containers

MCP_PORT

8000

Liste Port innerhalb des Containers

SEARCH_LIMIT

5

Standardwert für limit bei search()

SEARCH_MAX_LIMIT

10

Hartes Maximum für search(limit=…)

MAX_FETCH_CHARS

100000

Ausgabebudget für abgerufene Inhalte

SEARCH_WORKERS

8

Nummer der neuzeitlichen Archivsuchläufe während des Fan-out

SEARCH_MAX_CONSECUTIVE

2

Diversitätsdurchlauf: max. aufeinanderfolgende Ergebnisse aus derselben bibliothek

LOG_QUERIES

true

Produktionsnamen diese Option – suchanfrageteent protokollieren (Datenschutz)

ZIM_CHECK

false

Führt beim Start libzims vollständige Checksummenprüfung aus (liest das gesamte Korpus; Opt-in; langsam bei großen Archiven)

Host-seitige Compose-Variablen: CORPUS_ROOT (Standard ./corpus) und CORPUS_CONFIG (Standard ./corpus.toml).

Der Server bricht bei ungültiger Konfiguration sofort ab (Fail Fast).

Tests

make test     # unit + integration + MCP surface tests (needs .venv)
make lint
make format

Vorbereitung für einen lokalen Testlauf:

uv venv .venv --python 3.12
uv pip install -e . --python .venv/bin/python
uv pip install --python .venv/bin/python pytest pytest-asyncio ruff
make test

Die Tests erzeugen mit dem Writer von libzim eigene kleine ZIM-Fixtures(ein je Korpus-Familie); ein Korpus ist nicht erforderlich. Der Regressionstest für der die. Die MCP-Oberfläche prüft, dass der Server genau die beiden Tools search und fetch verfügbar macht und weder Prompts noch Ressourcen an- bieten.

Sicherheitsposture

Lokaler Dienst durch Design: Die Host-Bindung erfolgt standardmäßig ausschließlich über Loopback, die Korpus-Volumes Are read- sind – read-only, der Container läuft als Benutzer ohne Root-Rechte, kein privilegierter Modus, kein – keine Docker-Socket, kein beliebiger Dateisystemzugriff, kein Abruf von URLs und keine Shell-Ausführung. Keines der Tools akzeptiert Dateisystempfade, URLs, Befehle oder direkt ausführbaren Inhalt – ref ist ausschließlich eine opake Korpus-Kennung.

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Enables AI models to access and search offline Wikipedia and other knowledge bases stored in ZIM format files. Provides intelligent content retrieval, structured browsing, advanced search capabilities, and metadata extraction for comprehensive offline knowledge access.
    1
    118
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    An MCP server that provides offline access to ZIM file archives, including Wikipedia, medical knowledge, and maps. It dynamically exposes tools like search, article retrieval, and driving route planning based on available ZIM files.
    4
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables large language models to directly access and search content in ZIM files, allowing offline question answering and information retrieval from resources like Wikipedia.
    19
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables offline CRUD and semantic search on Wikipedia ZIM archives via MCP tools for reading, writing, editing, deleting, and searching articles.
    1
    MIT

View all related MCP servers

Related MCP Connectors

  • Shared, peer-validated knowledge archive for AI agents — search, contribute, and validate via MCP

  • Agentic search over your Dewey document collections from any MCP-compatible client.

  • Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.

View all MCP Connectors

Latest Blog Posts

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/MagoDelBlocco/mcp-wiki'

If you have feedback or need assistance with the MCP directory API, please join our Discord server