Skip to main content
Glama
fayna-digital

fayna-rag-mcp

Official

fayna-rag-mcp — локальная база знаний с RAG и MCP

Python License Status

Разработано Fayna Digital Автор: Volodymyr Shevchenko


Проблема: команда накапливает документацию (политики, руководства, заметки) в файлах и быстро теряет доступ к ней на естественном языке — поиск по названию файла или Ctrl+F не масштабируется, а отправка внутренних документов в облачный LLM-сервис не всегда приемлема с точки зрения конфиденциальности.

Решение: локальный пайплайн RAG (FAISS + мультиязычные эмбеддинги) на базе локального LLM (Ollama) — а тот же поисковик/Q&A предоставляется как сервер MCP, чтобы им мог воспользоваться любой MCP-клиент (Claude Desktop/Code и т. п.) или внешний автоматизированный workflow через простые REST-маршруты. Никакие данные не покидают машину, на которой это работает.

Результат: пять инструментов MCP и четыре REST-маршрута для семантического поиска, RAG Q&A с источниками, чтения документов и офлайн-каталогизации — готовые к подключению к Claude или n8n за несколько минут, без облачных зависимостей.

Возможности

Инструмент (MCP)

Назначение

read_document(file_path)

чтение полного файла из базы (с защитой от path-traversal в пределах DOCUMENTS_DIR)

list_documents()

список всех документов (.txt, .md, .pdf, .docx)

search_documents(query)

семантический поиск FAISS → топ-релевантные чанки

ask_knowledge_base(question)

ответ RAG: FAISS-retrieve + Ollama LLM, с источниками

show_catalog()

read-only каталог тегов документов (тема/тип/язык/аудитория)

REST-маршрут

Body

Что делает

POST /search

{"query": …}

FAISS-поиск → {results:[{source,text}]}

POST /ask

{"question": …}

ответ RAG → {answer, sources}

POST /find

{"query": …}

точный поиск подстроки по .md/.txt в корпусе

POST /hybrid

{"query": …}

гибрид: транслитерация кириллица↔латиница + token-match, отбор по семантике

Related MCP server: Nümtema Private Knowledge MCP

Стек

Python 3.10+ · FAISS (faiss-cpu) · sentence-transformers · tiktoken · Ollama · FastMCP · Tesseract/poppler/Whisper для мультиформатного ингеста · Docker.

Пайплайн RAG

docs/ → load (.txt/.md/.pdf/.docx) → chunk (tiktoken) → embed (mpnet) → FAISS → retrieve → Ollama → answer + sources
  • Чанкинг — по токенам tiktoken (cl100k_base), не по символам. По умолчанию CHUNK_SIZE=700 токенов, CHUNK_OVERLAP=100 токенов.

  • Эмбеддинги: paraphrase-multilingual-mpnet-base-v2 — мультиязычная модель (UA/PL/EN/RU и другие), чтобы поиск работал независимо от языка запроса.

  • LLM: любая модель Ollama, по умолчанию qwen2.5:7b.

  • Индекс: FAISS IndexFlatIP (косинусная близость), TOP_K=5.

Быстрый старт

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

Тесты:

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

Docker

docker compose up -d

Значения по умолчанию в docker-compose.yml/Dockerfile рассчитаны на Ollama, работающую на хосте (через host.docker.internal); настройте OLLAMA_URL под свою сеть (bridge-адрес на Linux, отдельный контейнер Ollama и т.п.).

Конфигурация (src/config.py, всё через env)

Env

По умолчанию

Описание

DOCUMENTS_DIR

./docs

корень базы знаний

EMBEDDING_MODEL

paraphrase-multilingual-mpnet-base-v2

модель эмбеддингов

OLLAMA_MODEL

qwen2.5:7b

LLM для ответов RAG

OLLAMA_URL

http://localhost:11434/api/generate

конечная точка Ollama

CHUNK_SIZE / CHUNK_OVERLAP

700 / 100

токены (tiktoken), не символы

TOP_K

5

сколько чанков возвращает retrieve

MCP_TRANSPORT

stdio

stdio (для локального MCP-клиента) или http → FastMCP streamable-http

MCP_HOST / MCP_PORT

0.0.0.0 / 8765

адрес при MCP_TRANSPORT=http

Подключение к MCP-клиенту (например, Claude Desktop) — через его конфигурацию MCP-серверов, командой python -m src.mcp.server (stdio) или URL контейнера (http).

Структура

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)

Мультиформатный ингест (OCR сканов через Tesseract, описание рисунков/схем через vision-модель, транскрипция аудио/видео через Whisper) — отдельный, более тяжёлый по зависимостям путь, который не требуется для базового текстового корпуса выше.

Лицензия

MIT — см. LICENSE. © Fayna Digital.

Related MCP Connectors

Related MCP Servers