Skip to main content
Glama
fayna-digital

fayna-rag-mcp

Official

fayna-rag-mcp — lokale Wissensdatenbank mit RAG und MCP

Python License Status

Entwickelt von Fayna Digital Autor: Volodymyr Shevchenko


Problem: Das Team sammelt Dokumentation (Richtlinien, Handbücher, Notizen) in Dateien und verliert schnell den Zugriff darauf in natürlicher Sprache — die Suche nach Dateinamen oder Strg+F skaliert nicht, und das Senden interner Dokumente an einen Cloud-LLM-Dienst ist datenschutzrechtlich nicht immer akzeptabel.

Lösung: lokale RAG-Pipeline (FAISS + mehrsprachige Embeddings) auf Basis eines lokalen LLM (Ollama) — derselbe Sucher/Q&A wird als MCP-Server bereitgestellt, damit jeder MCP-Client (Claude Desktop/Code usw.) oder ein externer automatisierter Workflow über einfache REST-Routen darauf zugreifen kann. Keine Daten verlassen die Maschine, auf der dies läuft.

Ergebnis: fünf MCP-Werkzeuge und vier REST-Routen für semantische Suche, RAG-Q&A mit Quellenangaben, Dokumentenlesen und Offline-Katalogisierung — in wenigen Minuten an Claude oder n8n anschließbar, ohne Cloud-Abhängigkeiten.

Funktionen

Werkzeug (MCP)

Zweck

read_document(file_path)

liest die vollständige Datei aus der Wissensdatenbank (mit Schutz gegen Path-Traversal innerhalb von DOCUMENTS_DIR)

list_documents()

Liste aller Dokumente (.txt, .md, .pdf, .docx)

search_documents(query)

semantische FAISS-Suche → Top-relevante Chunks

ask_knowledge_base(question)

RAG-Antwort: FAISS-Retrieve + Ollama-LLM, mit Quellenangaben

show_catalog()

Read-only-Katalog der Dokumenten-Tags (Thema/Typ/Sprache/Zielgruppe)

REST-Route

Body

Funktion

POST /search

{"query": …}

FAISS-Retrieve → {results:[{source,text}]}

POST /ask

{"question": …}

RAG-Antwort → {answer, sources}

POST /find

{"query": …}

exakte Teilstringsuche über .md/.txt im Korpus

POST /hybrid

{"query": …}

Hybrid: Transliteration Kyrillisch↔Lateinisch + Token-Match, Auswahl per Semantik

Related MCP server: Nümtema Private Knowledge MCP

Stack

Python 3.10+ · FAISS (faiss-cpu) · sentence-transformers · tiktoken · Ollama · FastMCP · Tesseract/poppler/Whisper für Multi-Format-Ingest · Docker.

RAG-Pipeline

docs/ → load (.txt/.md/.pdf/.docx) → chunk (tiktoken) → embed (mpnet) → FAISS → retrieve → Ollama → answer + sources
  • Chunking – nach tiktoken-Tokens (cl100k_base), nicht nach Zeichen. Standardmäßig CHUNK_SIZE=700 Tokens, CHUNK_OVERLAP=100 Tokens.

  • Embeddings: paraphrase-multilingual-mpnet-base-v2 – ein mehrsprachiges Modell (UA/PL/EN/RU u. a.), damit die Suche unabhängig von der Abfragesprache funktioniert.

  • LLM: ein beliebiges Ollama-Modell, standardmäßig qwen2.5:7b.

  • Index: FAISS IndexFlatIP (Kosinus-Ähnlichkeit), TOP_K=5.

Schnellstart

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

Tests:

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

Docker

docker compose up -d

Die Standardwerte in docker-compose.yml/Dockerfile sind für Ollama auf dem Host ausgelegt (über host.docker.internal); passe OLLAMA_URL an dein eigenes Netzwerk an (Bridge-Adresse unter Linux, separater Ollama-Container usw.).

Konfiguration (src/config.py, alles über env)

Env

Standard

Beschreibung

DOCUMENTS_DIR

./docs

Wurzel der Wissensdatenbank

EMBEDDING_MODEL

paraphrase-multilingual-mpnet-base-v2

Embedding-Modell

OLLAMA_MODEL

qwen2.5:7b

LLM für RAG-Antworten

OLLAMA_URL

http://localhost:11434/api/generate

Ollama-Endpunkt

CHUNK_SIZE / CHUNK_OVERLAP

700 / 100

Tokens (tiktoken), nicht Zeichen

TOP_K

5

wie viele Chunks der Retrieve zurückgibt

MCP_TRANSPORT

stdio

stdio (für lokale MCP-Clients) oder http → FastMCP streamable-http

MCP_HOST / MCP_PORT

0.0.0.0 / 8765

Adresse bei MCP_TRANSPORT=http

Anbindung an einen MCP-Client (z. B. Claude Code) — über dessen MCP-Server-Konfiguration, per Befehl python -m src.mcp.server (stdio) oder die Container-URL (http).

Struktur

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)

Multi-Format-Ingest (OCR von Scans per Tesseract, Beschreibung von Zeichnungen/Schemata per Vision-Modell, Transkription von Audio/Video per Whisper) — ein separater, abhängigkeitsreicherer Pfad, der für den oben genannten Basistextkorpus nicht nötig ist.

Lizenz

MIT — siehe LICENSE. © Fayna Digital.

Related MCP Connectors

Related MCP Servers