Skip to content

imagry/mp_mcp

Repository files navigation

RAG MCP Server

A production-ready Retrieval-Augmented Generation (RAG) server that implements the Model Context Protocol (MCP) for seamless integration with AI assistants like Cursor, Claude, and other MCP-compatible clients.

Features

  • MCP Protocol: Full implementation of Anthropic's Model Context Protocol (JSON-RPC 2.0)
  • RAG Pipeline: Vector-based document retrieval using LlamaIndex + ChromaDB
  • Multi-Source Ingestion: Automatic data collection from GitHub and OneDrive
  • Dockerized: Complete containerization with persistent storage
  • Local Embeddings: Self-contained using sentence-transformers (no API keys needed)
  • Document Processing: Supports .md, .pdf, .docx, and .pptx files

Architecture

┌─────────────┐
│ AI Client   │ (Cursor, Claude, etc.)
│  (MCP)      │
└──────┬──────┘
       │ HTTP/JSON-RPC 2.0
       ▼
┌─────────────────────────────┐
│  FastAPI Server             │
│  - /mcp endpoint            │
│  - tools/list, tools/call   │
└──────────┬──────────────────┘
           │
           ▼
┌──────────────────────────────┐
│ RAG Pipeline                 │
│  - LlamaIndex                │
│  - ChromaDB (persistent)     │
│  - HuggingFace Embeddings    │
└──────────────────────────────┘

Quick Start

Prerequisites

  • Docker & Docker Compose
  • GitHub Personal Access Token (for private repo access)
  • OneDrive rclone configuration (see below)

1. Clone This Repository

git clone <your-repo>
cd rag-mcp-server

2. Configure Secrets

Create a .env file:

# GitHub Configuration
GITHUB_REPO_URL=https://github.com/your-org/your-docs-repo.git
GITHUB_TOKEN=ghp_your_github_personal_access_token

# OneDrive Configuration
ONE_DRIVE_REMOTE_PATH=my-onedrive:Engineering/Technical Docs
RCLONE_CONFIG=<see below>

3. Set Up OneDrive Access (rclone)

Get rclone Config:

# Install rclone (if not already installed)
curl https://rclone.org/install.sh | sudo bash

# Configure OneDrive
rclone config

# Follow prompts:
# - Name: my-onedrive
# - Storage: onedrive
# - Follow OAuth flow

Extract Config for Docker:

# View your rclone config
cat ~/.config/rclone/rclone.conf

# Copy the ENTIRE output and set it as RCLONE_CONFIG in .env
# Example format:
# [my-onedrive]
# type = onedrive
# token = {"access_token":"..."}
# drive_id = ...
# drive_type = business

Important: The RCLONE_CONFIG should be the entire multi-line config block. In your .env file, you can use:

RCLONE_CONFIG='[my-onedrive]
type = onedrive
token = {"access_token":"eyJ0..."}
drive_id = b!abc123
drive_type = business'

4. Build and Start the Server

# Build the Docker image
docker-compose build

# Start the server
docker-compose up -d

# Check logs
docker-compose logs -f

5. Ingest Data

# Run the ingestion script inside the container
docker-compose exec rag-mcp-server python ingest.py

# This will:
# 1. Clone your GitHub repo
# 2. Download files from OneDrive
# 3. Convert documents to text
# 4. Build vector index

6. Verify It's Working

# Check health
curl http://localhost:8000/health

# Check index stats
curl http://localhost:8000/stats

# Test search (non-MCP endpoint)
curl -X POST "http://localhost:8000/search?query=authentication&top_k=3"

Using with MCP Clients

Configuration for Cursor / Claude Code

Add to your MCP client configuration:

{
  "mcpServers": {
    "rag-docs": {
      "url": "http://localhost:8000/mcp",
      "transport": "http"
    }
  }
}

Available MCP Tools

Tool: search_docs

Description: Search internal documentation using vector similarity

Parameters:

  • query (string, required): The search query
  • top_k (integer, optional): Number of results (1-20, default: 5)

Example MCP Request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_docs",
    "arguments": {
      "query": "How do I configure authentication?",
      "top_k": 5
    }
  }
}

Project Structure

.
├── main.py              # FastAPI server + MCP protocol
├── rag_pipeline.py      # RAG logic (LlamaIndex + ChromaDB)
├── ingest.py            # Data ingestion script
├── requirements.txt     # Python dependencies
├── Dockerfile           # Container definition
├── docker-compose.yml   # Service orchestration
└── README.md           # This file

# Generated at runtime:
├── db/                 # Persistent vector database
│   └── chroma/        # ChromaDB storage
├── staging/           # Temporary ingestion files
    ├── repo/          # GitHub clone
    ├── onedrive/      # OneDrive downloads
    └── processed/     # Converted documents

API Endpoints

MCP Protocol Endpoint

POST /mcp

Handles MCP JSON-RPC 2.0 requests:

  • initialize: Server capabilities
  • tools/list: Available tools
  • tools/call: Execute search

Utility Endpoints

GET /

  • Server information

GET /health

  • Health check + index stats

GET /stats

  • Detailed index statistics

POST /search?query=...&top_k=5

  • Simple search endpoint (non-MCP, for testing)

Maintenance

Re-ingesting Data

# Re-run ingestion to update the index
docker-compose exec rag-mcp-server python ingest.py

Viewing Logs

docker-compose logs -f rag-mcp-server

Resetting the Database

# Stop the server
docker-compose down

# Remove the persistent volume
docker volume rm rag-db-data

# Restart and re-ingest
docker-compose up -d
docker-compose exec rag-mcp-server python ingest.py

Updating Code

# Rebuild after code changes
docker-compose build
docker-compose up -d

Troubleshooting

Issue: "No documents found"

Solution: Run the ingestion script:

docker-compose exec rag-mcp-server python ingest.py

Issue: GitHub clone fails

Cause: Invalid or expired GITHUB_TOKEN

Solution:

  1. Generate a new Personal Access Token at https://github.com/settings/tokens
  2. Ensure it has repo scope
  3. Update .env and restart: docker-compose restart

Issue: OneDrive sync fails

Cause: Expired rclone OAuth token

Solution:

  1. Run rclone config reconnect my-onedrive on your local machine
  2. Copy updated config from ~/.config/rclone/rclone.conf
  3. Update RCLONE_CONFIG in .env
  4. Restart: docker-compose restart

Issue: Container won't start

Solution:

# Check logs for errors
docker-compose logs rag-mcp-server

# Common fixes:
# 1. Verify .env file exists and has all required variables
# 2. Check port 8000 is not already in use
# 3. Rebuild: docker-compose build --no-cache

Advanced Configuration

Custom Embedding Model

Edit rag_pipeline.py:

EMBEDDING_MODEL = "sentence-transformers/all-mpnet-base-v2"  # Higher quality

Chunk Size Tuning

Edit rag_pipeline.py:

CHUNK_SIZE = 1024  # Larger chunks
CHUNK_OVERLAP = 100

Adding More File Types

Edit ingest.py to add custom converters:

elif suffix == ".html":
    # Your custom conversion logic
    text = convert_html_to_text(file_path)

Security Notes

  • Never commit .env file to version control
  • Rotate GitHub tokens regularly
  • Use private networks in production (not exposed to internet)
  • Consider adding authentication middleware to /mcp endpoint

Performance

  • First ingestion: ~5-15 minutes (depends on document count)
  • Query latency: ~100-500ms (local embeddings)
  • Memory usage: ~2-4GB (includes embedding model)
  • Storage: ~100MB + (document size × 1.5)

License

MIT

Support

For issues or questions:

  1. Check the troubleshooting section above
  2. Review logs: docker-compose logs
  3. Open an issue in this repository

Built with: FastAPI • LlamaIndex • ChromaDB • Docker • MCP Protocol

About

RAG server implementing Model Context Protocol (MCP) for internal documentation search

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published