# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Epic Patient API MCP Server - A fake Epic MCP server simulating patient APIs using file-based YAML storage with LLM-powered natural language search capabilities.
## Development Commands
**Install dependencies:**
```bash
uv pip install -e .
```
**Install with dev dependencies:**
```bash
uv pip install -e ".[dev]"
```
**Run the MCP server:**
```bash
python -m epic_mcp.server
```
**Run all tests:**
```bash
pytest
```
**Run specific test file:**
```bash
pytest tests/test_data_loader.py
```
**Run specific test:**
```bash
pytest tests/test_tools.py::test_get_allergies
```
## Architecture
### MCP Server (`src/epic_mcp/server.py`)
- Main entry point defining 15 MCP tools (list + detail pairs for each data type)
- Two-tier access pattern: List tools return IDs/summaries, detail tools return full data
- Routes tool calls to appropriate handlers in `src/epic_mcp/tools/`
- Logs requests to stderr (doesn't interfere with MCP stdio protocol)
### Data Layer (`src/epic_mcp/data/loader.py`)
- `PatientDataLoader` reads YAML files from `patients/{patient_id}/` directories
- Each patient has separate YAML files: demographics, allergies, medications, conditions, clinical_notes, labs, vitals, procedures
- Clinical note attachments stored as `.txt` files in `patients/{patient_id}/attachments/`
- Uses Pydantic models from `types.py` for validation
### LLM Integration (`src/epic_mcp/llm/`)
- Pluggable LLM architecture with `base.py` defining `LLMClient` interface
- `factory.py` creates clients based on `LLM_PROVIDER` env var (gemini or openrouter)
- Used by `search_patient_data` tool to enable natural language queries across all patient data
- Loads all patient data as JSON context and prompts LLM to answer queries
### Tool Handlers (`src/epic_mcp/tools/`)
- Each data type has list and detail handlers (e.g., `handle_list_allergies`, `handle_get_allergy_details`)
- List handlers return IDs and key metadata only
- Detail handlers require an ID and return full data
- `search.py` implements LLM-powered natural language search
- All handlers return JSON strings (including errors)
## Configuration
Requires `.env` file with LLM provider credentials:
- **Gemini** (default): `GEMINI_API_KEY` from https://aistudio.google.com/app/apikey
- **OpenRouter**: `OPENROUTER_API_KEY` from https://openrouter.ai/keys, `OPENROUTER_MODEL`
See `.env.example` for template.
## Adding New Patients
Create directory `patients/patient_XXX/` with YAML files matching the structure of existing patients (patient_001, patient_002).