MCP Academic RAG Server Usage Guide
Overview
The MCP Academic RAG Server is a Model Context Protocol (MCP) server that provides advanced academic document processing and querying capabilities using Retrieval-Augmented Generation (RAG). It enables users to process academic papers, extract content, and perform intelligent queries through natural language.
Architecture
MCP Client → STDIO Transport → MCP Server → RAG Pipeline → OpenAI GPT
↓ ↓ ↓
Tool Calls Server Context Document Store
↓ ↓
Document Pipeline Embeddings
Core Components
1. MCP Server (mcp_server.py)
Purpose: Main MCP server implementation with STDIO transport
Transport: Standard Input/Output for Claude Desktop integration
Tools: 4 primary tools for document processing and querying
Error Handling: Comprehensive error handling with structured logging
2. Server Context (core/server_context.py)
Purpose: Dependency injection container managing all server components
Initialization: Multi-phase setup with proper dependency ordering
Components: ConfigManager, RAGPipeline, SessionManager, DocumentPipeline
3. RAG Pipeline (rag/haystack_pipeline.py)
Purpose: Retrieval-Augmented Generation using Haystack 2.x
Capabilities: Semantic search, context building, LLM response generation
Integration: OpenAI GPT-3.5-turbo with sentence-BERT embeddings
Available Tools
process_document
Process academic documents through OCR, structure extraction, and embedding generation.
Input Schema:
{
"file_path": "string (required) - Path to document file",
"file_name": "string (optional) - Display name for document"
}
Example Usage:
{
"file_path": "/Users/researcher/papers/neural_networks.pdf",
"file_name": "Neural Networks Survey 2024"
}
Output:
{
"status": "success",
"document_id": "abc123def",
"file_name": "neural_networks.pdf",
"processing_stages": ["raw", "structured", "embedded"],
"metadata": {
"pages": 12,
"file_type": ".pdf",
"processing_time": 4.2
},
"message": "Document processed successfully"
}
query_documents
Query processed documents using RAG pipeline with natural language.
Input Schema:
{
"query": "string (required) - Research question or query",
"session_id": "string (optional) - Session ID for conversation context",
"top_k": "integer (optional) - Max documents to retrieve (default: 5)"
}
Example Usage:
{
"query": "What are the latest developments in transformer architectures?",
"session_id": "research_session_1",
"top_k": 3
}
Output:
{
"status": "success",
"session_id": "research_session_1",
"query": "What are the latest developments in transformer architectures?",
"answer": "Recent transformer developments include...",
"sources": [
{
"content": "Abstract content from relevant paper...",
"metadata": {
"document_id": "abc123",
"file_name": "transformers_survey.pdf",
"page": 3
}
}
]
}
get_document_info
Retrieve information about a processed document.
Input Schema:
{
"document_id": "string (required) - ID of processed document"
}
Example Usage:
{
"document_id": "abc123def"
}
list_sessions
List all active chat sessions with metadata.
Input Schema:
{}
Output:
{
"status": "success",
"sessions": [
{
"session_id": "research_session_1",
"created_at": "2024-01-15T10:30:00Z",
"last_active_at": "2024-01-15T11:45:00Z",
"message_count": 5,
"metadata": {}
}
],
"total_count": 1
}
Environment Setup
Required Environment Variables
The server supports multiple AI providers. Choose one:
# Option 1: OpenAI (default provider)
export OPENAI_API_KEY="sk-your-api-key-here"
# Option 2: Anthropic Claude
export ANTHROPIC_API_KEY="sk-ant-your-api-key-here"
export LLM_PROVIDER="anthropic"
export LLM_MODEL="claude-3-sonnet-20240229"
# Option 3: Google Gemini
export GOOGLE_API_KEY="your-google-ai-key-here"
export LLM_PROVIDER="google"
export LLM_MODEL="gemini-1.5-pro"
📚 For detailed model comparison and setup: Multi-Model Setup Guide
Installation Requirements
# Core MCP requirements
pip install mcp
# RAG pipeline dependencies
pip install haystack-ai sentence-transformers openai
# Document processing (optional)
pip install pypdf2 python-docx # PDF and Word support
Configuration
Basic Configuration (config/config.json)
{
"llm": {
"model": "gpt-3.5-turbo",
"temperature": 0.7,
"max_tokens": 1000
},
"rag_settings": {
"retriever_top_k": 5,
"embedding_model": "sentence-transformers/all-MiniLM-L6-v2"
},
"processors": [
{
"name": "HaystackEmbeddingProcessor",
"enabled": true
}
]
}
Claude Desktop Integration
Add to Claude Desktop configuration:
{
"mcpServers": {
"academic-rag": {
"command": "python",
"args": ["/path/to/mcp_server.py"],
"env": {
"OPENAI_API_KEY": "your-api-key"
}
}
}
}
Usage Workflows
1. Document Processing Workflow
graph LR
A[Upload Document] --> B[process_document]
B --> C[OCR/Extraction]
C --> D[Structure Analysis]
D --> E[Embedding Generation]
E --> F[Document Indexed]
Steps:
Call
process_documentwith file pathServer processes through OCR and structure extraction
Content is embedded using sentence-BERT
Document becomes searchable via RAG pipeline
2. Query Workflow
graph LR
A[Natural Language Query] --> B[query_documents]
B --> C[Query Embedding]
C --> D[Semantic Retrieval]
D --> E[Context Building]
E --> F[LLM Generation]
F --> G[Response with Sources]
Steps:
Submit natural language query via
query_documentsQuery is embedded and matched against document store
Relevant passages are retrieved and formatted
LLM generates contextual response with citations
3. Session Management
# Create session for research project
session_result = await query_documents({
"query": "What is machine learning?",
"session_id": "ml_research_2024"
})
# Continue conversation with context
followup_result = await query_documents({
"query": "How does it relate to deep learning?",
"session_id": "ml_research_2024" # Same session maintains context
})
Error Handling
Common Error Types
Authentication Errors:
{
"status": "error",
"message": "RAG pipeline not initialized",
"context_status": {
"rag_enabled": false,
"error_reason": "No OpenAI API key found"
}
}
File Processing Errors:
{
"status": "error",
"message": "File not found: /invalid/path.pdf"
}
Query Processing Errors:
{
"status": "error",
"message": "Error querying documents: Rate limit exceeded"
}
Error Recovery Strategies
Missing API Key: Set
OPENAI_API_KEYenvironment variableFile Access: Verify file path and permissions
Rate Limits: Implement exponential backoff in client
Pipeline Errors: Check server logs in stderr output
Performance Characteristics
Operation |
Typical Time |
Memory Usage |
Rate Limits |
|---|---|---|---|
Document Processing |
5-30 seconds |
~200MB peak |
File size dependent |
Query Execution |
3-5 seconds |
~50MB |
OpenAI API limits |
Session Management |
<100ms |
~10MB per session |
Memory bounded |
Embedding Generation |
1-3 seconds |
~100MB |
CPU dependent |
Advanced Configuration
Custom Embedding Models
{
"rag_settings": {
"embedding_model": "sentence-transformers/all-mpnet-base-v2",
"retriever_top_k": 10
}
}
Available Models:
all-MiniLM-L6-v2: Fast, 384-dim (default)all-mpnet-base-v2: Accurate, 768-dimmulti-qa-MiniLM-L6-cos-v1: Optimized for Q&A
Custom LLM Configuration
{
"llm": {
"model": "gpt-4",
"temperature": 0.3,
"max_tokens": 2000,
"presence_penalty": 0.1
}
}
Document Processing Customization
{
"processors": [
{
"name": "HaystackEmbeddingProcessor",
"enabled": true,
"chunk_size": 500,
"chunk_overlap": 50
}
]
}
Security Considerations
API Key Management
Store API keys in environment variables, not configuration files
Use different API keys for development and production
Monitor API usage and implement rate limiting
File Access
Validate file paths to prevent directory traversal
Implement file size limits to prevent resource exhaustion
Consider sandboxing for untrusted documents
Network Security
Use HTTPS for all external API calls
Implement timeout and retry mechanisms
Monitor for unusual API usage patterns
Troubleshooting
Server Won’t Start
# Check Python path and dependencies
python -c "import mcp; print('MCP available')"
python -c "from haystack import Pipeline; print('Haystack available')"
# Verify environment
echo $OPENAI_API_KEY
RAG Pipeline Issues
# Debug document store
print(f"Documents indexed: {rag_pipeline.document_store.count_documents()}")
# Test query embedding
embedder = SentenceTransformersTextEmbedder()
result = embedder.run("test query")
print(f"Embedding shape: {result['embedding'].shape}")
Performance Optimization
Use faster embedding models for development
Implement document caching for frequently accessed files
Monitor memory usage with large document collections
Consider batch processing for multiple documents
Integration Examples
Python Client
import asyncio
from mcp.client.stdio import stdio_client
async def process_and_query():
async with stdio_client("python", ["mcp_server.py"]) as client:
# Process document
process_result = await client.call_tool(
"process_document",
{"file_path": "/path/to/paper.pdf"}
)
# Query document
query_result = await client.call_tool(
"query_documents",
{"query": "What is the main contribution of this paper?"}
)
print(query_result)
asyncio.run(process_and_query())
REST API Wrapper
from fastapi import FastAPI
from mcp.client.stdio import stdio_client
app = FastAPI()
@app.post("/process")
async def process_document(file_path: str):
async with stdio_client("python", ["mcp_server.py"]) as client:
return await client.call_tool("process_document", {"file_path": file_path})
@app.post("/query")
async def query_documents(query: str):
async with stdio_client("python", ["mcp_server.py"]) as client:
return await client.call_tool("query_documents", {"query": query})
Best Practices
Initialization: Always call server initialization once during startup
Error Handling: Check tool response status before processing results
Session Management: Use consistent session IDs for related queries
Resource Management: Monitor memory usage with large document collections
API Limits: Implement rate limiting and exponential backoff
Logging: Monitor stderr output for server logs and diagnostics
Testing: Test with sample documents before processing important files
Validation: Validate file paths and query parameters before API calls
Support and Monitoring
Logging Configuration
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
Health Check
async def health_check():
try:
result = await client.call_tool("list_sessions", {})
return {"status": "healthy", "server_responsive": True}
except Exception as e:
return {"status": "unhealthy", "error": str(e)}
Performance Monitoring
Monitor API response times
Track document processing success rates
Monitor memory and CPU usage
Set up alerting for API rate limit issues