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サービスに送信することはプライバシーの観点から必ずしも許容できない。

解決策: ローカルLLM(Ollama)をベースとしたローカルRAGパイプライン(FAISS + 多言語埋め込み)——そして同じ検索/QA機能を MCPサーバー として公開し、任意のMCPクライアント(Claude Desktop/Codeなど)や外部の自動化ワークフローがシンプルなRESTルート経由で利用できるようにする。実行中のマシンからデータが外部に出ることはない。

結果: セマンティック検索、ソース付きRAG QA、ドキュメント読み取り、オフラインカタログ化のための5つのMCPツールと4つのRESTルート——クラウド依存なしで、数分でClaudeやn8nに接続できる。

機能

ツール(MCP)

用途

read_document(file_path)

データベースからのファイル全体の読み取り(DOCUMENTS_DIR 内のパストラバーサルガード付き)

list_documents()

全ドキュメントの一覧(.txt、.md、.pdf、.docx)

search_documents(query)

FAISSによるセマンティック検索 → 関連性の高いチャンク

ask_knowledge_base(question)

RAG回答:FAISS取得 + Ollama LLM、ソース付き

show_catalog()

ドキュメントタグの読み取り専用カタログ(トピック/タイプ/言語/対象者)

RESTルート

Body

処理内容

POST /search

{"query": …}

FAISS取得 → {results:[{source,text}]}

POST /ask

{"question": …}

RAG回答 → {answer, sources}

POST /find

{"query": …}

コーパス内の .md/.txt に対する完全な部分文字列検索

POST /hybrid

{"query": …}

ハイブリッド:キリル↔ラテン文字の翻字 + トークンマッチ、セマンティクスによる選定

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 はご自身のネットワークに合わせて調整してください(Linuxのブリッジアドレス、別のOllamaコンテナなど)。

設定(src/config.py、すべてenv経由)

Env

デフォルト

説明

DOCUMENTS_DIR

./docs

知識ベースのルート

EMBEDDING_MODEL

paraphrase-multilingual-mpnet-base-v2

埋め込みモデル

OLLAMA_MODEL

qwen2.5:7b

RAG回答用のLLM

OLLAMA_URL

http://localhost:11434/api/generate

Ollamaのエンドポイント

CHUNK_SIZE / CHUNK_OVERLAP

700 / 100

トークン数(tiktoken)、文字数ではない

TOP_K

5

取得が返すチャンク数

MCP_TRANSPORT

stdio

stdio(ローカルMCPクライアント用)または http → FastMCP streamable-http

MCP_HOST / MCP_PORT

0.0.0.0 / 8765

MCP_TRANSPORT=http の場合のアドレス

MCPクライアント(例:Claude Code)への接続 — 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)

マルチフォーマット取り込み(TesseractによるスキャンOCR、ビジョンモデルによる図面/図表の説明、Whisperによる音声/動画の文字起こし)— 依存関係が重い別のパスであり、上記の基本テキストコーパスには不要です。

ライセンス

MIT — LICENSE を参照。© Fayna Digital。

Related MCP Connectors

Related MCP Servers