Medical Research Intelligence Assistant
An agentic RAG system for answering medical questions with PubMed citations. It combines Adaptive RAG (query routing) and Self-RAG (relevance grading, query rewriting, hallucination checks) in a LangGraph pipeline.
Data source: PubMed abstracts
LLM: Mistral API
Embeddings: HuggingFace BAAI/bge-small-en-v1.5 (local, CPU)
Vector store: ChromaDB (local)
Features
- Answers medical questions with inline
[PMID]citations and confidence scores - Fetches literature from PubMed on demand (and supports optional bulk ingest)
- Three retrieval strategies based on query complexity:
- Vector — simple factual questions
- Hybrid — BM25 + dense search (complex queries)
- Iterative — sub-query decomposition (multi-hop questions)
- Self-RAG loop: relevance grading, query rewrite, hallucination check, regeneration
- CLI for single questions, interactive chat, and ingestion
- MCP server for Cursor, Claude Desktop, VS Code Copilot, and other MCP clients
Architecture

Visualize the graph:
python visualize_graph.py
Project structure
medical_rag/
├── main.py # CLI entry point
├── requirements.txt
├── rag_graph.mmd # Mermaid graph definition
├── visualize_graph.py
├── data/ # ChromaDB persistence (gitignored)
└── src/
├── graph/
│ ├── graph.py # LangGraph definition
│ └── nodes.py # Pipeline nodes
├── rag/
│ ├── pubmed_fetcher.py
│ ├── vector_store.py
│ ├── retriever.py
│ ├── graders.py
│ └── generator.py
├── mcp/
│ └── server.py # MCP tools (SSE)
└── utils/
├── config.py
├── llm.py
├── ingest.py
├── state.py
└── http_ssl.py
Setup
1. Clone and create a virtual environment
python -m venv venv
# Windows
venv\Scripts\activate
# macOS / Linux
source venv/bin/activate
2. Install dependencies
pip install -r requirements.txt
3. Configure environment variables
Create a .env file in the project root:
# Required
MISTRAL_API_KEY=your_mistral_api_key
[email protected]
# Optional
MISTRAL_MODEL=mistral-small-latest
EMBEDDING_MODEL=BAAI/bge-small-en-v1.5
CHROMA_PERSIST_DIR=./data/chroma_db
PUBMED_MAX_RESULTS=10
RELEVANCE_THRESHOLD=0.6
MAX_REWRITE_ATTEMPTS=2
MAX_REGEN_ATTEMPTS=2
MCP_HOST=0.0.0.0
MCP_PORT=8000
Get a Mistral API key at console.mistral.ai.
NCBI requires a contact email for PubMed API access (PUBMED_EMAIL).
Usage
Ask a single question
python main.py ask "What are the first-line treatments for type 2 diabetes?"
JSON output:
python main.py ask "What is metformin?" --json
Interactive chat
python main.py chat
Pre-ingest PubMed articles (optional)
Speeds up cold-start by loading seed topics into ChromaDB. The pipeline also fetches papers automatically when the store has fewer than 20 documents.
python main.py ingest
python main.py ingest --topics "diabetes,hypertension" --max 15
MCP server
Expose the RAG pipeline as MCP tools for AI agents.
Start the server
python main.py serve
The server listens at http://localhost:8000/sse (SSE transport).
Available tools
Connect from Cursor
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"medical-rag": {
"url": "http://localhost:8000/sse"
}
}
}
Connect from VS Code (GitHub Copilot)
Create .vscode/mcp.json:
{
"servers": {
"medical-rag": {
"type": "sse",
"url": "http://localhost:8000/sse"
}
}
}
Use Copilot Agent mode and keep python main.py serve running in a terminal.
Connect from Claude Desktop
{
"mcpServers": {
"medical-rag": {
"url": "http://localhost:8000/sse"
}
}
}
Configuration reference
How it works
- Ingest — PubMed abstracts are fetched via Biopython Entrez, embedded, and stored in ChromaDB (on demand or via
ingest). - Classify — Mistral routes the query as
simple,complex, ormulti_hop. - Retrieve — The matching strategy searches ChromaDB for relevant abstracts.
- Grade — Each chunk is scored for relevance (vector score + LLM judgment).
- Rewrite — If too few docs pass, the query is rephrased and more PubMed results are fetched.
- Generate — Mistral produces an answer using only the retrieved abstracts, with
[PMID]citations. - Verify — A hallucination grader checks grounding; the answer is regenerated if needed.
Limitations
- Answers are based on PubMed abstracts only (not full papers or clinical guidelines sites).
- Not a substitute for professional medical advice.
- First run downloads the embedding model (~33 MB) and may take a minute on CPU.
- Each question triggers multiple Mistral API calls (classification, grading, generation, verification).