corpus-mcp
corpus-mcp
Локальный MCP сервер, который предоставляет агенту чистый и эффективный доступ к локальному корпусу знаний из офлайн-ZIM-архивов — Википедия, медицинская вики (MDWiki), документация разработчика (DevDocs) и Stack Exchange — через единый интерфейс. Без интернета, без эмбеддингов, без векторной базы данных: полнотекстовый поиск libzim плюс детерминированная очистка контента на стороне сервера.
Публичный интерфейс MCP — ровно два инструмента:
search(query, limit?)
fetch(ref, sections?)Настроенный корпус — это забота оператора, а не агента. Агент только:
discover → search()
select → fetch()Семейства корпусов
Корпус |
| Документ | Модель секций |
Wikipedia, MDWiki |
| статья | дерево заголовков (h2+), вводная секция с id |
DevDocs (C, CMake, Python) |
| страница документации | дерево заголовков; внутристраничные оглавления и навигационные элементы удаляются |
Stack Exchange |
| вопрос + ответы | синтетические секции: |
Вся идентификация корпуса, маршрутизация, доступ к ZIM, интерпретация HTML, очистка, ранжирование, обработка редиректов и нормализация остаются обязанностями сервера. Агенту никогда не требуется разбирать HTML, обрабатывать редиректы, конструировать или разбирать ссылки, а также знать что-либо о libzim, пространства имён ZIM или внутреннем устройстве хранения корпуса.
Related MCP server: mcpzim
Ссылки
Результаты search() содержат непрозрачный ref (например, corpus://Wikipedia/Bell_test); fetch() использует его. Агент никогда не должен создавать, разбирать или изменять ref или выводить корпус из него:
search() produces ref fetch() consumes refАрхитектура
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)Слой MCP не раскрывает никаких концепций libzim: никаких пространств имён, идентификаторов кластеров, сырых записей, MIME-типов или сырого HTML.
Предварительные требования
Docker + Docker Compose
Архивы ZIM (см. ниже)
Для запуска набора тестов локально: Python 3.12 и
uv(или pip)
Расположение корпуса
Сервер никогда не скачивает архивы сам — сбор корпуса намеренно отделен от запуска приложения. Структура по умолчанию:
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.tomlcorpus.toml описывает каждую библиотеку, ее адаптер и путь (относительно корня корпуса):
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"Правила проверки: уникальные имена, известные адаптеры, пути должны оставаться внутри корня корпуса. Проверьте корпус перед запуском сервера:
make validate-corpus # opens every archive, reports metadata
make corpus-list # list configured librariesЗапуск / остановка
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После этого конечная точка MCP доступна по адресу http://127.0.0.1:8000/mcp (Streamable HTTP). Порт хоста по умолчанию привязан только к loopback; контейнер слушает адрес 0.0.0.0:8000 внутри.
Если какой-либо указанный ZIM не может быть открыт, сервер не запускается и указывает проблемную библиотеку — частично работоспособного режима не существует.
Схемы инструментов
search(query: str, limit?: int)
Ищет полнотекстовый индекс каждой настроенной библиотеки (ограниченная параллельность, один рабочий процесс на архив), объединяет ранжированные списки с помощью Reciprocal Rank Fusion, упорядочивает конкурирующих кандидатов из разных корпусов по лексическому совпадению заголовков, применяет детерминированную логику разнообразия и возвращает чистые результаты. limit по умолчанию равен 5; сервер накладывает жёсткий максимум (SEARCH_MAX_LIMIT, по умолчанию 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— непрозрачный глобальный идентификатор; передайте его обратно вfetch().library/kind/snapshot— происхождение: какой архив, какой документ, и снимок корпуса (полученный из метаданных архива).relevant_sections— 0–3 детерминированных лексических подсказки (пусто, если ни одна секция явно не соответствует). Идентификаторы секций генерируются сервером; агент не должен их восстанавливать.
Одна неисправная библиотека ухудшает качество поиска (остальные по-прежнему отвечают), но никогда не останавливает его.
fetch(ref: str, sections?: list[str])
Возвращает очищенный документ в виде структурированного Markdown.
Без параметра
sections: весь документ (ограниченMAX_FETCH_CHARS;truncated: true, если обрезан на границе секции).С параметром
sections: только указанные секции (включая вложенные). Идентификаторы секций берутся изsearch()подсказок или изavailable_sections. Вводная секция имеет идентификатор"". Для тем секции —question,accepted-answerиanswer-<id>; их полеmetadataсодержит оценку, флаг «принято» и теги.
{
"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
}Ошибки — краткие и конструктивные:
{ "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" }, "..." ]
}Пример рабочего процесса агента
search("Bell experiment loopholes")
↓
fetch("corpus://Wikipedia/Bell_test", ["Notable_experiments", "Loopholes"])Конфигурация
Переменные окружения (показаны значения по умолчанию в контейнере):
Variable | Default | Meaning |
|
| Корень корпуса внутри контейнера (обязательно) |
|
| Путь к манифесту внутри контейнера (обязательно) |
|
| Адрес прослушивания внутри контейнера |
|
| Порт прослушивания внутри контейнера |
|
| Значение |
|
| Жёсткий максимум для |
|
| Бюджет размера вывода для полученного контента |
|
| Параллельный поиск по архивам при рассылке |
|
| Логика разнообразия: максимум подряд идущих результатов из одной библиотеки |
|
| Записывать текст поискового запроса (приватность) |
|
| Выполнять полную проверку контрольных сумм libzim при старте (затрагивает весь корпус: опционально, медленно для больших архивов) |
Переменные Compose на стороне хоста: CORPUS_ROOT (по умолчанию ./corpus) и CORPUS_CONFIG (по умолчанию ./corpus.toml).
Сервер быстро завершится при недопустимой конфигурации.
Тесты
make test # unit + integration + MCP surface tests (needs .venv)
make lint
make formatНастройка для локального запуска тестов:
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Тесты создают небольшие самостоятельные ZIM-файлы с помощью writer из libzim (по одному на семейство корпусов); внешний корпус не требуется. Регрессионный тест поверхности MCP проверяет, что сервер предоставляет ровно два инструмента — search и fetch — и никаких prompts или resources.
Модель безопасности
Сервис локальен изначально: привязка к хосту по умолчанию только к loopback, тома корпуса только для чтения, контейнер запускается от непривилегированного пользователя, без привилегированного режима, без Docker-сокета, без произвольного файлового доступа, без извлечения URL, без выполнения команд оболочки. Ни один инструмент не принимает файловые пути, URL, команды или исполняемое содержимое — ref является лишь непрозрачным идентификатором корпоративной базы.
This server cannot be installed
Maintenance
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
- AlicenseAqualityAmaintenanceEnables 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.1118MIT
- AlicenseAqualityBmaintenanceAn 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.4MIT
- AlicenseNot gradedqualityDmaintenanceEnables large language models to directly access and search content in ZIM files, allowing offline question answering and information retrieval from resources like Wikipedia.19MIT
- AlicenseNot gradedqualityBmaintenanceEnables offline CRUD and semantic search on Wikipedia ZIM archives via MCP tools for reading, writing, editing, deleting, and searching articles.1MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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