Skip to main content
Glama
fayna-digital

fayna-rag-mcp

Official

fayna-rag-mcp — base de conocimiento local con RAG y MCP

Python License Status

Desarrollado por Fayna Digital Autor: Volodymyr Shevchenko


Problema: el equipo acumula documentación (políticas, manuales, notas) en archivos y pierde rápidamente el acceso a ella en lenguaje natural — la búsqueda por nombre de archivo o Ctrl+F no escala, y enviar documentos internos a un servicio LLM en la nube no siempre es aceptable por privacidad.

Solución: un pipeline RAG local (FAISS + embeddings multilingües) sobre un LLM local (Ollama) — y ese mismo buscador/Q&A expuesto como servidor MCP, para que pueda usarlo cualquier cliente MCP (Claude Desktop/Code, etc.) o un flujo de trabajo externo automatizado mediante rutas REST simples. Ningún dato sale de la máquina donde se ejecuta.

Resultado: cinco herramientas MCP y cuatro rutas REST para búsqueda semántica, Q&A RAG con fuentes, lectura de documentos y catalogación offline — listas para conectar a Claude o n8n en minutos, sin dependencias en la nube.

Capacidades

Herramienta (MCP)

Propósito

read_document(file_path)

lectura del archivo completo desde la base (con protección contra path-traversal dentro de DOCUMENTS_DIR)

list_documents()

lista de todos los documentos (.txt, .md, .pdf, .docx)

search_documents(query)

búsqueda semántica FAISS → fragmentos más relevantes

ask_knowledge_base(question)

respuesta RAG: recuperación FAISS + LLM Ollama, con fuentes

show_catalog()

catálogo de solo lectura de etiquetas de documentos (tema/tipo/idioma/audiencia)

Ruta REST

Body

Qué hace

POST /search

{"query": …}

recuperación FAISS → {results:[{source,text}]}

POST /ask

{"question": …}

respuesta RAG → {answer, sources}

POST /find

{"query": …}

búsqueda exacta de subcadena en .md/.txt del corpus

POST /hybrid

{"query": …}

híbrido: transliteración cirílico↔latino + coincidencia de tokens, selección por semántica

Related MCP server: Nümtema Private Knowledge MCP

Stack

Python 3.10+ · FAISS (faiss-cpu) · sentence-transformers · tiktoken · Ollama · FastMCP · Tesseract/poppler/Whisper para ingesta multi-formato · Docker.

Pipeline RAG

docs/ → load (.txt/.md/.pdf/.docx) → chunk (tiktoken) → embed (mpnet) → FAISS → retrieve → Ollama → answer + sources
  • Fragmentación — por tokens tiktoken (cl100k_base), no por caracteres. Por defecto CHUNK_SIZE=700 tokens, CHUNK_OVERLAP=100 tokens.

  • Embeddings: paraphrase-multilingual-mpnet-base-v2 — modelo multilingüe (UA/PL/EN/RU y otros), para que la búsqueda funcione independientemente del idioma de la consulta.

  • LLM: cualquier modelo de Ollama, por defecto qwen2.5:7b.

  • Índice: FAISS IndexFlatIP (similitud coseno), TOP_K=5.

Inicio rápido

pip install -r src/requirements.txt

# Przykład: demo-korpus na kilka dokumentów (sample-docs/)
export DOCUMENTS_DIR=./sample-docs
python -m src.main build-index      # → src/index/index.faiss + chunks.pkl

# Interaktywne Q&A (CLI)
python -m src.main

# Serwer MCP (transport z env MCP_TRANSPORT: stdio|http)
python -m src.mcp.server

Pruebas:

pip install -r tests/requirements-dev.txt
pytest -q

Docker

docker compose up -d

Los valores por defecto en docker-compose.yml/Dockerfile están diseñados para Ollama ejecutándose en el host (a través de host.docker.internal); ajusta OLLAMA_URL a tu propia red (dirección bridge en Linux, contenedor Ollama separado, etc.).

Configuración (src/config.py, todo mediante env)

Env

Por defecto

Descripción

DOCUMENTS_DIR

./docs

raíz de la base de conocimiento

EMBEDDING_MODEL

paraphrase-multilingual-mpnet-base-v2

modelo de embeddings

OLLAMA_MODEL

qwen2.5:7b

LLM para respuestas RAG

OLLAMA_URL

http://localhost:11434/api/generate

endpoint de Ollama

CHUNK_SIZE / CHUNK_OVERLAP

700 / 100

tokens (tiktoken), no caracteres

TOP_K

5

cuántos fragmentos devuelve la recuperación

MCP_TRANSPORT

stdio

stdio (para cliente MCP local) o http → FastMCP streamable-http

MCP_HOST / MCP_PORT

0.0.0.0 / 8765

dirección con MCP_TRANSPORT=http

Conexión a un cliente MCP (p. ej. Claude Code) — mediante su configuración de servidores MCP, con el comando python -m src.mcp.server (stdio) o la URL del contenedor (http).

Estructura

src/
├── config.py         # wszystkie env-zmienne + domyślne
├── main.py           # CLI: build-index | interaktywne Q&A
├── assistant.py       # CompanyKBAssistant (LLM decyduje czy wołać MCP-toolki)
├── catalog.py         # offline-klasyfikacja dokumentów przez Ollama → JSON+HTML
├── ingest.py           # multi-formatowy ingest: OCR skanów, vision-opis diagramów, Whisper-transkrypcja
├── rag/
│   ├── ingest.py      # load_document (.txt/.md/.pdf/.docx)
│   ├── chunk.py        # chunk_text (tiktoken cl100k_base, overlap)
│   ├── embed.py         # embed_chunks (sentence-transformers)
│   ├── build_index.py   # build_index → FAISS + pickle
│   └── query.py          # retrieve / build_prompt / ask
└── mcp/
    ├── server.py     # FastMCP: 5 MCP-toolków + 4 trasy REST
    └── client.py      # MCPClient (JSON-RPC przez subprocess)

Ingesta multi-formato (OCR de escaneos con Tesseract, descripción de dibujos/esquemas con modelo de visión, transcripción de audio/vídeo con Whisper) — una ruta separada, más pesada en dependencias, innecesaria para el corpus de texto básico anterior.

Licencia

MIT — ver LICENSE. © Fayna Digital.

Related MCP Connectors

Related MCP Servers