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 + 다국어 임베딩) — 그리고 동일한 검색기/Q&A를 MCP 서버로 노출하여 모든 MCP 클라이언트(Claude Desktop/Code 등) 또는 간단한 REST 경로를 통한 외부 자동화 워크플로우에서 사용할 수 있게 합니다. 어떤 데이터도 실행 중인 머신을 벗어나지 않습니다.

결과: 의미 검색, 출처 포함 RAG Q&A, 문서 읽기, 오프라인 카탈로그링을 위한 5개의 MCP 도구와 4개의 REST 경로 — 클라우드 의존성 없이 몇 분 안에 Claude 또는 n8n에 연결할 준비가 완료됩니다.

기능

도구 (MCP)

용도

read_document(file_path)

데이터베이스에서 전체 파일 읽기 (DOCUMENTS_DIR 내 path-traversal 가드 포함)

list_documents()

모든 문서 목록 (.txt, .md, .pdf, .docx)

search_documents(query)

FAISS 의미 검색 → 상위 관련 청크

ask_knowledge_base(question)

RAG 응답: FAISS-retrieve + Ollama LLM, 출처 포함

show_catalog()

문서 태그의 읽기 전용 카탈로그 (주제/유형/언어/대상)

REST 경로

Body

기능

POST /search

{"query": …}

FAISS-retrieve → {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의 bridge 주소, 별도 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

retrieve가 반환하는 청크 수

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, vision 모델을 통한 그림/도표 설명, Whisper를 통한 오디오/비디오 전사) — 위의 기본 텍스트 코퍼스에는 필요 없는, 의존성이 더 무거운 별도 경로입니다.

라이선스

MIT — LICENSE 참조. © Fayna Digital.

Related MCP Connectors

Related MCP Servers