File size: 2,148 Bytes
5922680
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import os
import pickle
from mcp.server.fastmcp import FastMCP
from langchain_community.retrievers import BM25Retriever
from config import LOCAL_STORE_PATH
from data_processing import SessionDocStore
from rag_engine import run_advanced_rag

# Initialize the MCP Server
mcp = FastMCP("PDF-QA-Server", host="0.0.0.0", port=int(os.environ.get("PORT", 8000)))

# Global variables to hold the retrievers
_bm25_retriever = None
_doc_store = None

def load_local_stores():
    global _bm25_retriever, _doc_store
    
    if _bm25_retriever is not None and _doc_store is not None:
        return
    
    if not os.path.exists(LOCAL_STORE_PATH):
        raise FileNotFoundError(f"Local store {LOCAL_STORE_PATH} not found. Did you run ingest.py first?")
        
    print(f"Loading local stores from {LOCAL_STORE_PATH}...")
    with open(LOCAL_STORE_PATH, "rb") as f:
        local_data = pickle.load(f)
        
    _doc_store = SessionDocStore()
    _doc_store.store = local_data["doc_store"]
    
    documents = local_data["bm25_docs"]
    _bm25_retriever = BM25Retriever.from_documents(documents)
    _bm25_retriever.k = 3
    print("✅ Local stores loaded successfully.")

@mcp.tool()
def query_pdf(query: str, openai_api_key: str = "") -> str:
    """
    Query the ingested PDF document to extract information and answer questions.
    Uses Hybrid Search (BM25 + Pinecone) and GPT-5 to return a robust answer.
    """
    try:
        load_local_stores()
        
        if not openai_api_key:
            return "Error: openai_api_key must be provided to query the PDF."
            
        # Execute RAG pipeline
        answer = run_advanced_rag(query, _bm25_retriever, _doc_store, openai_api_key)
        return answer
        
    except Exception as e:
        return f"Error executing RAG pipeline: {str(e)}"

if __name__ == "__main__":
    # Preload the models on startup
    try:
        load_local_stores()
    except Exception as e:
        print(f"Warning during startup: {e}")
        print("You must run ingest.py before the server can query the PDF.")
        
    # Render sets PORT, default to 8001
    mcp.run(transport='sse')