본문 바로가기

MCP

[MCP 서버] PDF 문서에서 답을 찾는 Claude AI 만들기

안녕하세요,

최근 AI 모델의 고도화로 인해, 단순한 대화형 응답을 넘어 더 정확하고 정밀한 정보 제공의 중요성이 커지고 있습니다. 특히 사용자 맞춤형 정보를 제공해야 하는 상황에서는, AI가 지정된 문서를 직접 참고하여 답변을 생성하는 방식이 큰 주목을 받고 있습니다.
이러한 요구를 충족시키기 위한 대표적인 기술이 바로 RAG(Retrieval-Augmented Generation)입니다. RAG는 외부 문서에서 관련 정보를 검색한 뒤, 이를 기반으로 생성형 AI가 응답을 생성하는 방식입니다.

 

이번 글에서는 이 RAG 시스템을 MCP 서버 기반으로 구현하고, Claude에 질문을 전달하여 내 문서를 바탕으로 답변을 생성하는 방법에 대해 알아보겠습니다.


반응형

MCP 기능

이번 프로젝트에서는 내가 가지고 있는 PDF 문서를 읽고, 그 내용을 바탕으로 AI가 질문에 답할 수 있는 시스템을 만들어봅니다. 이 시스템은 RAG(Retrieval-Augmented Generation)이라는 방식으로, AI가 미리 저장된 문서에서 필요한 정보를 찾아내고, 그것을 이용해 답변하는 구조입니다.

사용자가 Claude에게 질문을 하면, Claude는 내 컴퓨터에 있는 PDF 문서들을 확인하고, 거기서 관련된 내용을 찾아 질문에 대한 답을 만들어냅니다. 이때 중요한 역할을 하는 것이 바로 MCP 서버입니다. MCP 서버는 Claude가 내 문서를 직접 열어보지 않아도, 대신 내용을 정리해서 전달해주는 중간 역할을 합니다. 이렇게 하면 AI가 내 문서를 바탕으로 더 정확하고 자세한 답변을 해줄 수 있게 되고, 나만의 문서를 이해하는 AI 도우미를 만들 수 있게 됩니다.

 

[전체 구성 흐름]

  1. uv 설치 및 가상 환경 생성
  2. MCP 서버 코드 작성
  3. Claude 환경 설정
  4. MCP 서버 실행

 

 

사전 준비 사항

이번 포스팅에서는 데스크톱용 Claude를 활용하여 MCP 서버를 구성하는 방법을 소개할 예정입니다. 따라서 먼저 데스크톱 Claude 프로그램를 설치해야 합니다. 아래에 안내된 Anthropic 공식 페이지에서 사용 중인 운영체제에 맞는 버전을 다운로드하여 설치합니다.

출처: Anthropic (클릭시 페이지 이동)


1. 실행 환경

  • 운영체제 : Windows 11
  • uv : 0.6.14
  • python : 3.10.17

 

 

2. MCP 서버 구성

MCP 서버를 통해 구현할 기능은 간단한 예시로, Claude가 내 컴퓨터에 저장된 PDF 문서를 바탕으로 질문에 답변하는 시스템입니다. 이 기능은 문서를 불러와 내용을 분할하고, 의미를 벡터화한 뒤 질문과 관련된 내용을 검색하여 Claude에게 전달하는 방식으로 동작합니다. Claude는 전달받은 문서 내용을 참고해 질문에 대한 답변을 생성하며, 사용자는 마치 AI가 문서를 직접 읽은 것처럼 자연스러운 응답을 받을 수 있습니다.

 

1) uv 설치 및 가상 환경 생성

MCP 서버를 Python 환경에서 구성하기 위해서는, 먼저 패키지 및 가상환경 관리를 위한 도구인 "uv"를 설치해야 합니다. uv는 pip과 venv를 대체할 수 있는 빠르고 효율적인 Python 패키지 관리 도구입니다. 아래 명령어를 통해 설치할 수 있습니다

# Windows PowerShell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

 

uv 설치가 완료되면, 프로젝트를 초기화하고 가상환경을 설정한 뒤, 필요한 패키지를 설치합니다.
다음 명령어를 순서대로 실행해줍니다.

# Windows PowerShell
cd \path\to\MCP                    # 1. 원하는 위치로 이동 (예: D:\MCP-server)
uv init docReader                  # 2. 'docReader'라는 이름의 uv 프로젝트 초기화
cd docReader                       # 3. 생성된 프로젝트 폴더로 이동
New-Item -ItemType Directory -Name docs     # 4. docs 폴더 생성
uv venv --python=python3.10        # 5. Python 3.10 기반 가상환경 생성 (.venv 폴더)
.venv\Scripts\activate             # 6. 가상환경 활성화
uv add mcp[cli] PyMuPDF faiss-cpu sentence_transformers  # 7. 필요한 패키지 설치

 

2) MCP 서버 코드 작성

위에서 정의한 기능을 실행하기 위해 Python 코드를 작성해야 합니다. Python 파일을 처음 만들어보는 분이라면, 아래 명령어로 파일을 생성한 후 코드를 붙여 넣어 수정하시면 됩니다.

 

[Python 파일 생성]

# Windows PowerShell
New-Item docReader.py

 

[MCP 코드]

from mcp.server.fastmcp import FastMCP
import traceback
from sentence_transformers import SentenceTransformer
import os
import fitz  # PyMuPDF
import faiss
import numpy as np

mcp = FastMCP("docreader")

# 벡터DB
def build_or_load_index(chunks):
    vectors = get_embeddings(chunks)
    dim = len(vectors[0])
    index = faiss.IndexFlatL2(dim)
    index.add(np.array(vectors))
    return index, chunks

def search_similar_chunks(query, index, chunks, top_k=5):
    q_vec = get_embeddings([query])
    _, idxs = index.search(np.array(q_vec), top_k)
    return [chunks[i] for i in idxs[0]]

# 텍스트 추출
def extract_text_from_pdf(file_path):
    doc = fitz.open(file_path)
    return "\n".join([page.get_text() for page in doc])

def split_into_chunks(text, chunk_size=300):
    sentences = text.split("\n")
    chunks, chunk = [], ""
    for sentence in sentences:
        if len(chunk) + len(sentence) < chunk_size:
            chunk += sentence + "\n"
        else:
            chunks.append(chunk.strip())
            chunk = sentence + "\n"
    if chunk:
        chunks.append(chunk.strip())
    return chunks

def load_and_chunk_documents(doc_dir):
    all_chunks = []
    for file in os.listdir(doc_dir):
        if file.endswith(".pdf"):
            full_path = os.path.join(doc_dir, file)
            raw_text = extract_text_from_pdf(full_path)
            chunks = split_into_chunks(raw_text)
            all_chunks.extend(chunks)
    return all_chunks

# 임베딩
model = SentenceTransformer("all-MiniLM-L6-v2")  # 허깅페이스에서 제공하는 임베딩 모델
                                                 # 다른 모델로 변경 가능
def get_embeddings(chunks):
    return model.encode(chunks)

# Tool 등록
@mcp.tool(name="query_documents", description="PDF 문서를 검색하고 Claude에 질문을 전달합니다.")
def query_documents(query: str) -> str:
    try:
        print(f"[질문] {query}")
        docs = load_and_chunk_documents("docs/")  
        index, chunks = build_or_load_index(docs)
        results = search_similar_chunks(query, index, chunks)
        
        prompt_response = "\n".join([
            "다음 문단을 참고하여 질문에 답해주세요:\n",
            *[f"- {chunk}" for chunk in results],
            f"\n질문: {query}"
        ])
        #print("반환 타입 확인:", type(prompt_response))
        return prompt_response
    
    except Exception as e:
        print("Tool 실행 중 오류 발생:", e)
        traceback.print_exc()
        return "오류 발생: 파일을 찾을 수 없습니다."

if __name__ == "__main__":
    mcp.run()

 

3) Claude 환경 설정

코드 작성을 완료했다면, 이제 Claude가 MCP 서버에 접근할 수 있도록 환경을 설정해주어야 합니다. 아래 절차에 따라 설정을 진행해줍니다.

  • 데스크톱 Claude 실행 (사전 준비 사항)
  • 왼쪽 상단의 ≡ (메뉴) 버튼 클릭 → 파일설정 메뉴로 이동 (아래 왼쪽 이미지 참고)
  • 개발자 모드 버튼 클릭 → 설정 편집 버튼 클릭 (아래 가운데 이미지 참고)
  • 열리는 폴더에서 "claude_desktop_config.json" 파일을 찾아 수정 (아래 오른쪽 이미지 참고)

[claude_desktop_config.json 코드]

{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": [
        "--directory",
        "D:\\Programs\\MCP\\mcp-test-uv\\weather", <- 위에서 생성한 weather 폴더 경로 지정
        "run",
        "docReader.py"
      ]
    }
  }
}

 

Claude 환경 설정 - 참고 이미지 (클릭시 이미지 확대)

 

4) MCP 서버 실행

이제 앞선 모든 과정을 완료했다면, Claude 데스크톱 앱을 한 번 종료한 뒤 다시 실행해 주세요. 설정이 제대로 적용되었다면, Claude 화면에 아래와 같이 "MCP Tools" 버튼이 활성화됩니다. 이 버튼을 클릭하면 현재 등록된 MCP 서버의 도구 목록과, 각 도구가 어떤 기능을 수행하는지 확인할 수 있습니다.

만약 MCP Tools 버튼이 보이지 않는다면, Claude 설정 파일 내 MCP 서버의 경로가 잘못 입력되었을 가능성이 있습니다. 이 경우, 설정 파일을 다시 열어 정확한 경로로 수정한 뒤 재실행해 주세요.

MCP 서버 실행 - 예시 이미지 (클릭시 이미지 확대)

 

아래 이미지는 MCP 서버 기능 테스트 결과를 보여줍니다.

 

  • 왼쪽 이미지 : Claude에게 등록된 PDF 파일을 기반으로 질문하고, 그에 대한 답변을 받은 결과입니다.
  • 오른쪽 이미지 : 사용자가 제공한 PDF 파일 중 일부 내용입니다.

 

MCP 서버 기능 테스트 결과

 

위 결과를 통해 MCP 서버가 정상적으로 작동하고 있으며, Claude가 문서 내용을 바탕으로 사용자 질문에 응답할 수 있음을 확인할 수 있습니다. Claude는 PDF에 담긴 정보를 분석한 뒤, 이를 사용자가 이해하기 쉬운 형태로 재구성하여 답변합니다. 실제로 문서 기반 질문에 대해 의미 있는 응답을 생성하는 모습을 확인할 수 있었습니다.

 

다만, 몇 가지 개선이 필요한 부분도 있었습니다. 예를 들어 "첫 번째 페이지 내용 알려줘."와 같은 단순한 요청에 대해서는, 전혀 무관한 답변이 출력되는 경우도 있었습니다. 이는 Claude가 전달받은 문서 내용을 정확히 인식하지 못했거나, MCP 서버의 문서 분할 방식이나 검색 로직에 보완이 필요한 상황일 수 있습니다.

 

따라서 향후에는 보다 정교한 문단 분할 방식, 검색 정확도 향상을 위한 알고리즘 개선, Claude와의 프롬프트 전달 방식 개선 등을 통해 더욱 정확하고 일관된 응답을 얻을 수 있을 것입니다.


 

이번 글에서는 Claude와 MCP 서버를 연동하여, 내 문서를 기반으로 AI가 질문에 답변하는 시스템을 구성하는 과정을 단계별로 살펴보았습니다. RAG 방식으로 구현된 이 시스템은, 사용자가 보유한 PDF 파일을 직접 분석하고 필요한 정보를 찾아 응답하는 구조로, AI 활용의 폭을 한층 넓혀줍니다.

 

물론 아직은 개선의 여지가 있고, 더 정교한 검색 및 응답 품질을 위해 코드를 지속적으로 다듬는 작업이 필요합니다. 하지만 이번 실습을 통해, 나만의 AI 비서 시스템을 구축하는 기초를 다졌다고 볼 수 있습니다. 앞으로 이 시스템을 기반으로 다양한 문서 형식 확장, 요약 기능 추가, 음성 응답 연동 등 더 발전된 기능들을 실험해보며 나만의 맞춤형 AI 도구로 발전시켜 보시기 바랍니다.

 

 

감사합니다. 😊

 

반응형