knowledge-hub-mcp
by edunavajas
README.md
# knowledge-hub-mcp
Servidor [MCP](https://modelcontextprotocol.io) **stdio** de un solo fichero Python que
conecta cualquier cliente MCP (Claude Code, Codex, Cursor, OpenCode…) con tu sistema de
conocimiento autoalojado: los **webhooks RAG de n8n** y la **API de Outline**.
Forma parte de la infraestructura que se levanta con Coolify en la serie self-hosted de
YouTube: en lugar de pegar documentación en el chat, el agente consulta directamente tu
base de conocimiento indexada.
No necesita `pip install`: es Python puro con la librería estándar.
## Arquitectura
```
cliente MCP ──stdio──▶ knowledge-hub-mcp ──curl──▶ webhooks RAG de n8n
(Claude Code, ──curl──▶ API de Outline
Codex, Cursor,
OpenCode…)
```
- El servidor habla **JSON-RPC sobre stdio** (el transporte MCP estándar para procesos locales).
- Las llamadas HTTP se hacen con **`curl` vía `subprocess`** de forma deliberada: las claves
de API y los cuerpos JSON grandes **nunca aparecen en `argv`** (se pasan por `--config` y
por el `stdin`), evitando fugas por la tabla de procesos.
- **El servidor no lleva credenciales.** Se leen en arranque de un fichero de entorno.
## Herramientas
Expone **5 herramientas**:
| Herramienta | Argumentos | Backend | Qué hace |
| --- | --- | --- | --- |
| `knowledge_search` | `query`, `limit` (1–20, por defecto 5), `source_type` (`outline`\|`repo`\|`all`) | n8n `POST /webhook/rag-search` | Búsqueda semántica sobre conocimiento curado y documentación del repositorio. |
| `knowledge_read` | `document_id` | Outline `POST /api/documents.info` | Lee el Markdown completo de un documento por su ID. |
| `knowledge_health` | — | n8n `GET /webhook/rag-health` | Recuentos y estado del índice, sin contenido ni vectores. |
| `knowledge_index` | — | n8n `POST /webhook/rag-index` | Lanza un reindexado asíncrono de la colección de Outline. |
| `knowledge_index_repository` | — | n8n `POST /webhook/rag-index-repo` | Escanea el Markdown del workspace y lo indexa como conocimiento técnico del repo. |
## Requisitos
- **python3** (3.9+). Sin dependencias: solo la librería estándar.
- **curl** (se usa para todas las llamadas HTTP).
- **git** — solo para `install.sh`.
- **Node.js 18+** — solo para la ruta de instalación vía npm.
## Instalación
### Opción A — npm global (sin clonar)
El repositorio es público:
```sh
npm install -g github:edunavajas/knowledge-hub-mcp-server
knowledge-hub-mcp --version
```
### Opción B — install.sh
```sh
git clone https://github.com/edunavajas/knowledge-hub-mcp-server.git "$HOME/.local/share/knowledge-hub-mcp"
sh "$HOME/.local/share/knowledge-hub-mcp/install.sh"
```
`install.sh` es idempotente: clona en `${KNOWLEDGE_HUB_HOME:-$HOME/.local/share/knowledge-hub-mcp}`,
crea un symlink `${KNOWLEDGE_HUB_BIN:-$HOME/.local/bin}/knowledge-hub-mcp` al fichero Python, lo
marca como ejecutable e imprime las rutas resueltas. Si lo vuelves a lanzar, actualiza el checkout
con `git pull --ff-only`.
## Configuración
Las credenciales viven en un **fichero de entorno**. La ruta por defecto es
`~/.config/knowledge-hub/knowledge.env`; se parsea al arrancar y cada `KEY=value` se aplica
**solo si esa clave no está ya definida** en el entorno del proceso (el entorno manda).
Empieza copiando la plantilla:
```sh
mkdir -p ~/.config/knowledge-hub
cp .env.example ~/.config/knowledge-hub/knowledge.env
$EDITOR ~/.config/knowledge-hub/knowledge.env
```
Contenido:
```
N8N_URL=https://n8n.tu-dominio.com
RAG_SEARCH_API_KEY=tu-clave-rag
OUTLINE_URL=https://outline.tu-dominio.com
OUTLINE_API_KEY=tu-clave-outline
KNOWLEDGE_HUB_ENV_FILE=
KNOWLEDGE_HUB_WORKSPACE=
KNOWLEDGE_HUB_PROJECT=
```
Todas las variables que leen el servidor y el instalador:
| Variable | Usada por | Por defecto | Propósito |
| --- | --- | --- | --- |
| `KNOWLEDGE_HUB_ENV_FILE` | servidor | `~/.config/knowledge-hub/knowledge.env` | Fichero de entorno desde el que cargar credenciales. |
| `KNOWLEDGE_HUB_WORKSPACE` | servidor | directorio actual (`$PWD`) | Raíz que escanea `knowledge_index_repository`. |
| `KNOWLEDGE_HUB_PROJECT` | servidor | basename del workspace | Slug usado en `collection`, `canonical_url` y `metadata.repository`. |
| `KNOWLEDGE_HUB_PYTHON` | shim npm | `python3`, luego `python` | Intérprete de Python que arranca el shim de Node. |
| `N8N_URL` | servidor | *(vacío)* | URL base de los webhooks RAG. |
| `OUTLINE_URL` | servidor | *(vacío)* | URL base de la instancia de Outline. |
| `RAG_SEARCH_API_KEY` | servidor | *(vacío)* | Se envía como `X-RAG-API-Key` a n8n. |
| `OUTLINE_API_KEY` | servidor | *(vacío)* | Se envía como `Authorization: Bearer` a Outline. |
| `KNOWLEDGE_HUB_REPO` | install.sh | `https://github.com/edunavajas/knowledge-hub-mcp-server.git` | Remoto git a clonar. |
| `KNOWLEDGE_HUB_HOME` | install.sh | `$HOME/.local/share/knowledge-hub-mcp` | Ubicación del checkout. |
| `KNOWLEDGE_HUB_BIN` | install.sh | `$HOME/.local/bin` | Dónde se crea el symlink `knowledge-hub-mcp`. |
> **El servidor no lleva credenciales embebidas.** Todo secreto se configura en el env file.
## Configuración para clientes MCP
Aviso general: los clientes con interfaz gráfica (Cursor, Claude Desktop) arrancan los
servidores MCP con un `PATH` mínimo, que normalmente **no incluye** `~/.local/bin` ni el bin
global de npm. Usa siempre una **ruta absoluta** al comando.
### Claude Code
Usa el comando `claude mcp add`. El `--` separa las opciones de Claude de la orden y sus
argumentos; las variables van con `--env`:
```sh
claude mcp add --transport stdio knowledge_hub \
--env KNOWLEDGE_HUB_WORKSPACE="$PWD" \
-- /ruta/absoluta/.local/bin/knowledge-hub-mcp
```
También puedes declararlo en `.mcp.json` (ámbito de proyecto):
```json
{
"mcpServers": {
"knowledge_hub": {
"type": "stdio",
"command": "/ruta/absoluta/.local/bin/knowledge-hub-mcp",
"args": [],
"env": {
"KNOWLEDGE_HUB_WORKSPACE": "/ruta/absoluta/a/tu/repo"
}
}
}
}
```
Comprueba el estado con `claude mcp list` o `/mcp`.
### Codex
Codex usa TOML en `~/.codex/config.toml` (o `.codex/config.toml` a nivel de proyecto). La
tabla es `[mcp_servers.<nombre>]`, con `command`, `args` y `env`:
```toml
[mcp_servers.knowledge_hub]
command = "/ruta/absoluta/.local/bin/knowledge-hub-mcp"
args = []
enabled = true
cwd = "/ruta/absoluta/a/tu/repo"
[mcp_servers.knowledge_hub.env]
KNOWLEDGE_HUB_WORKSPACE = "/ruta/absoluta/a/tu/repo"
```
### Cursor
Cursor usa JSON en `~/.cursor/mcp.json` con la clave contenedora `mcpServers`:
```json
{
"mcpServers": {
"knowledge_hub": {
"command": "/Users/<tu-usuario>/.local/bin/knowledge-hub-mcp",
"env": {
"KNOWLEDGE_HUB_WORKSPACE": "/Users/<tu-usuario>/repos/mi-proyecto"
}
}
}
}
```
Si `python3` no es resoluble desde el entorno de Cursor, llama al intérprete directamente:
`"command": "/usr/bin/python3"` con
`"args": ["/Users/<tu-usuario>/.local/share/knowledge-hub-mcp/knowledge_hub_mcp.py"]`.
### OpenCode
OpenCode usa `opencode.json` con la clave contenedora **`mcp`** (no `mcpServers`), `type`
`"local"` y el comando como **array**; las variables van en **`environment`**:
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"knowledge_hub": {
"type": "local",
"command": ["knowledge-hub-mcp"],
"enabled": true,
"environment": {
"KNOWLEDGE_HUB_WORKSPACE": "/ruta/absoluta/a/tu/repo"
}
}
}
}
```
Si el bin no está en el `PATH` de OpenCode, usa la ruta absoluta dentro del array:
`"command": ["/ruta/absoluta/.local/bin/knowledge-hub-mcp"]`.
## Ejemplos de uso
Una vez conectado, pídeselo en lenguaje natural al agente:
- **Buscar**: «Busca en la base de conocimiento cómo configuramos Coolify.»
→ `knowledge_search` con `{"query": "configuración de Coolify", "limit": 5, "source_type": "all"}`
- **Leer**: «Lee el documento `abc123` y resúmelo.»
→ `knowledge_read` con `{"document_id": "abc123"}`
- **Estado**: «¿Cuántos documentos hay indexados?»
→ `knowledge_health` sin argumentos
- **Indexar Outline**: «Reindexa la colección de Outline.»
→ `knowledge_index` sin argumentos
- **Indexar el repo**: «Indexa la documentación de este repositorio.»
→ `knowledge_index_repository` sin argumentos
## `--print-config`
Imprime la configuración resuelta **redactando los secretos** (útil para depurar y para
enseñarlo en cámara sin exponer claves):
```sh
knowledge-hub-mcp --print-config
```
Ejemplo de salida:
```
version: 0.1.0
env_file: /home/tu/.config/knowledge-hub/knowledge.env
env_file_exists: true
workspace_root: /home/tu/repos/mi-proyecto
project_slug: mi-proyecto
n8n_url: https://n8n.tu-dominio.com
outline_url: https://outline.tu-dominio.com
rag_search_api_key: <REDACTED>
outline_api_key: <REDACTED>
```
Si `env_file_exists: false`, el fichero no está donde el servidor lo busca: créalo en
`~/.config/knowledge-hub/knowledge.env` o apunta `KNOWLEDGE_HUB_ENV_FILE` a su ruta real.
## Problemas frecuentes
- **`RAG bridge is not configured` / `Outline bridge is not configured`.** El env file falta o
las claves están vacías. Compruébalo con `knowledge-hub-mcp --print-config`.
- **`command not found` en el cliente.** Los clientes con GUI usan un `PATH` mínimo: usa la
ruta absoluta al binario (ver arriba).
## Licencia
MIT — ver [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues