corpus-mcp
corpus-mcp
Un servidor local MCP que ofrece a un agente un acceso limpio y eficiente a un corpus de conocimiento local de archivos ZIM sin conexión — Wikipedia, artículos médicos, documentación para desarrolladores (DevDocs) y Stack Exchange — a través de una interfaz uniforme. Sin internet, sin embeddings, sin base de datos vectorial: búsqueda de texto completo con libzim y una limpieza determinista del contenido dentro del propio servidor.
La superficie pública de MCP son exactamente dos herramientas:
search(query, limit?)
fetch(ref, sections?)El corpus configurado es un asunto del operador, no del agente. El agente solo:
discover → search()
select → fetch()Familias de corpus
Corpus |
| Documento | Modelo de secciones |
Wikipedia, MDWiki |
| artículo | árbol de encabezados (h2+), sección inicial con id |
DevDocs (C, CMake, Python) |
| página de documentación | árbol de encabezados; TOC de la página y elementos de navegación eliminados |
Stack Exchange |
| pregunta + respuestas | secciones sintéticas: |
Toda la identificación del corpus, el enrutamiento, el acceso a ZIM, la interpretación del HTML, la limpieza, la clasificación, el manejo de redirecciones y la normalización siguen siendo responsabilidades del servidor. El agente nunca tiene que parsear HTML, resolver redirecciones, construir o parser alguna referencia, ni conocer nada sobre libzim, los espacios de nombres de ZIM o los detalles del almacenamiento del corpus.
Related MCP server: mcpzim
References
search() devuelve resultados con un ref opaco (p. ej., corpus://Wikipedia/Bell_test); fetch() lo consume. El agente no debe nunca construir, parsear o modificar de null, ni inde que la from derivar el corpus a partir de un ref:
search() produces ref fetch() consumes refArquitectura
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)La capa MCP no expone información de libzim: no espacios de nombres, IDs de clúster, entradas en bruto, tipos MIME ni HTML en bruto.
Prerequisitos
Docker y Docker Compose
Archivos ZIM (ver más abajo)
Para ejecutar la suite de pruebas localmente: Python 3.12 y
uv(o pip)
Estructura del corpus
El servidor nunca descarga los lugares por sí mismo — la adquisición del corpus está deliberadamente desacoplada del arranque de la aplicación. Copia las estructura por defecto:
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 names cada biblioteca, su adaptador y su ruta (relativa a la raíz del corpus):
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"Reglas de validación: nombres únicos, adaptadores conocidos, rutas que deben permanecer dentro de la raíz del corpus. Verifica un corpus antes de iniciar el servidor:
make validate-corpus # opens every archive, reports metadata
make corpus-list # list configured librariesInicio / apagado
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 buildEl endpoint MCP queda disponible en http://127.0.0.1:8000/mcp (Streamable HTTP). El puerto del host está vinculado a loopback por defecto; el contenedor escucha en 0.0.0.0:8000 internamente.
Si no se puede abrir algún ZIM configurado, el servidor falla al iniciar e indica la bibliotecaproblemática; no hay un modo parcialmente funcional.
Esquemas de las herramientas
search(query: str, limit?: int) (Busca en el índice de texto completo de todas las bibliotecas configuradas (con concurrencia acotada, un worker por archivo), fusiona las listas clasificadas con Reciprocal Rank Fusion, reordena los candidatos empatados entre corpus por la cobertura léxica de título, aplica una pasada determinista dediversidad y devuelve resultados limpios. limit se limita por defecto a 5; el servidor impone un máximo absoluto (SEARCH_MAX_LIMIT, por defecto 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: identificador global opaco; pásalo de vuelta afetch().library/kind/snapshot: procedencia — qué archivo, qué tipo de documento y la instantánea del corpus (derivada de los metadatos del archivo).relevant_sections: 0–3 and hints léxicos deterministas (vacío cuando ninguna sección coincide claramente). Los IDs de sección son determinados por el servidor; el agente no debe reconstruirlos.
Una única biblioteca con fallos degrada la búsqueda (las demás siguen respondiendo) pero nunca la matra.
fetch(ref: str, sections?: list[str])
Devuelve el documento limpio en formato Markdown estructurado.
Sin
sections: el documento completo (limitado porMAX_FETCH_CHARS;truncated: truesi se corta en el límite de una sección).Con
sections: solo esas secciones (incluidos los subárboles). Los IDs de sección provienen de los avisos desearch()o deavailable_sections. La sección inicial tiene el id"". En los hilos las secciones sonquestion,accepted-answeryanswer-<id>; sumetadatacontiene lo puntaje, aceptación y etiquetas.
{
"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
}Los errores son concursos y ofrecen una orientación:
{ "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" }, "..." ]
}Ejemplo de flujo de un payload
search("Bell experiment loopholes")
↓
fetch("corpus://Wikipedia/Bell_test", ["Notable_experiments", "Loopholes"])Configuración
Variables de entorno (valores predeterminados del contenedor):
Variable | Default | Meaning |
|
| Directorio raíz del corpus dentro del contenedor (obligatorio) |
|
| Ruta del archivo de configuración dentro del contenedor (obligatorio) (obligatorio) |
|
| Dirección de escucha dentro del contenedor |
|
| Puerto de escucha dentro del contenedor |
|
|
|
|
| Máximo absoluto para |
|
| Límite de salida para el contenido recuperado por |
|
| Búsquedas concurrentes en archivos durante el fan-out |
|
| Pasada de diversidad: máximo de resultados consecutivos de una misma biblioteca |
|
| Registrar el texto de las consultas (privacidad) |
|
| Ejecutar la verificación completa de suma de comprobación de libzim (bytes exies) al arrancar (lee todo el corpus: optativo, lento en copias grandes) |
Variables de Docker, lado central: CORPUS_ROOT (default ./corpus) y CORPUS_CONFIG (default ./corpus.toml).
El servidor falla rápido antes una configuración no válida.
Tests
make test # unit + integration + MCP surface tests (needs .venv)
make lint
make formatConfiguración para una ejecución local de pruebas:
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 testLas pruebas generan sus propios fixtures ZIM con sunergy-writer de libzim (corpus por biblioteca); no es necesario corpus real. La prueba de regresión de la superficie MCP comprueba que el servidor expone exactamente dos herramientas search y fetch, y no expone prompts ni recursos.
Postura de seguridad
Servicio local por diseño: bind del host únicamente a loopback por defecto, volúmenes introspection de corpi read-onmembers-only, el contenedor se ejecuta con un usuario no root, no tiene modo privilegiarlo, no hay socket de Docker, no hay acceso arbitrario al sistema de archivos, no se realiza fetching de URLs y no se ejecutan comandos shell. Ninguna herramienta acepta rutas de archivos, URLs, comandos ni contenido ejecutable —/tmp/reuse is no. ref es simplemente un identificador opaco y exclusivo.
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