diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..5ecfe46
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,1873 @@
+# Novion - Medical Research and Analysis Platform
+
+[Generated from codebase reconnaissance on 2025-02-08]
+
+## Quick Reference
+**Tech Stack**: Python | TypeScript | FastAPI | Next.js 15 | React 18 | LangChain | Cornerstone.js
+**Backend Dev Server**: `cd backend && python server.py` (→ http://localhost:8000)
+**Frontend Dev Server**: `cd frontend && npm run dev` (→ http://localhost:3000)
+**Run Tests**: `python test_client.py` (backend) | `npm test` (frontend)
+**Documentation**: `/docs` endpoint (FastAPI auto-generated)
+
+---
+
+## Table of Contents
+1. [Project Overview](#project-overview)
+2. [Core Commands](#core-commands)
+3. [Project Structure](#project-structure)
+4. [Development Patterns & Conventions](#development-patterns--conventions)
+5. [Safety and Permissions](#safety-and-permissions)
+6. [Code Examples](#code-examples)
+7. [API Documentation](#api-documentation)
+8. [Database](#database)
+9. [Environment Configuration](#environment-configuration)
+10. [Testing Strategy](#testing-strategy)
+11. [Troubleshooting](#troubleshooting)
+
+---
+
+## Project Overview
+
+Novion is a comprehensive medical research and analysis platform with specialized agent-based reasoning capabilities. It combines AI-powered medical agents (Pharmacist, Researcher, Medical Analyst) with advanced DICOM/FHIR medical imaging support and BiomedParse GPU-accelerated medical image segmentation.
+
+**Type**: Monorepo (Python backend + Next.js frontend)
+**Status**: Active Development
+**Primary Languages**: Python 3.8+ | TypeScript 5.3
+**Key Features**:
+- Multi-agent AI system with chain-of-thought reasoning (LangChain/LangGraph)
+- DICOM/NIfTI medical image viewing and analysis (Cornerstone3D)
+- BiomedParse 3D medical image segmentation
+- FHIR healthcare data integration via MCP (Model Context Protocol)
+- Real-time streaming chat interface
+- GPU-accelerated inference support
+
+**Target Deployment**:
+- Frontend: Vercel/local (Next.js)
+- Backend: Docker with CUDA (GPU) or local Python
+
+---
+
+## Core Commands
+
+### Backend (Python/FastAPI)
+
+#### Development
+- **Start backend server**: `cd backend && python server.py`
+ - Runs on http://localhost:8000
+ - API docs at http://localhost:8000/docs
+- **Simplified demo server** (no external dependencies): `python tests/simple_server.py`
+- **Test client** (comprehensive API testing): `python tests/test_client.py`
+
+#### Testing
+**File-scoped (PREFERRED - faster feedback):**
+- Run specific test module: `python -m pytest backend/tests/test_heatmap_validation.py`
+- Run test with pattern: `python -m pytest -k "test_pattern_name"`
+- Test MCP integration: `python backend/test_mcp_integration.py`
+
+**API testing (using test_client.py):**
+- Test tools endpoint: `python tests/test_client.py tools`
+- Test basic chat: `python tests/test_client.py chat "Hello"`
+- Test specialized agent: `python tests/test_client.py ask pharmacist "What are common side effects of ibuprofen?"`
+- Test specific tool: `python tests/test_client.py tool list_fhir_resources`
+
+**Project-wide:**
+- Run all backend tests: `python -m pytest backend/tests/`
+- Run with coverage: `python -m pytest --cov=backend backend/tests/`
+
+#### Code Quality
+**File-scoped (PREFERRED):**
+- Format single file: `black backend/server.py`
+- Lint single file: `ruff check backend/server.py`
+- Type check: Python is dynamically typed (no mypy config found)
+
+**Project-wide:**
+- Format all: `black backend/`
+- Lint all: `ruff check backend/`
+
+### Frontend (Next.js/TypeScript)
+
+#### Development
+- **Start dev server**: `cd frontend && npm run dev`
+ - Runs on http://localhost:3000
+ - Hot-reload enabled
+- **Verified startup** (with type-check and build validation): `cd frontend && ./start-dev.sh`
+ - Checks dependencies, runs type-check, validates build, then starts dev server
+
+#### Building
+- Build for production: `npm run build`
+- Start production server: `npm run start`
+- Analyze bundle: `npm run analyze:bundle`
+
+#### Testing
+**File-scoped (PREFERRED):**
+- Run single test file: `npm test -- path/to/file.test.tsx`
+- Run tests in directory: `npm test -- components/`
+- Run specific test: `npm test -- -t "should validate user input"`
+
+**Project-wide:**
+- Run all tests: `npm test`
+- Run with coverage: `npm test -- --coverage`
+
+#### Code Quality
+**File-scoped (PREFERRED):**
+- Lint file: `npx eslint --fix app/page.tsx`
+- Format file: `npx prettier --write app/page.tsx`
+- Type check file: `npx tsc --noEmit app/page.tsx`
+
+**Project-wide:**
+- Lint all: `npm run lint`
+- Format all: `npm run format`
+- Format check: `npm run format:check`
+- Type check all: `npm run type-check`
+
+#### Code Analysis
+- Analyze unused exports: `npm run analyze:unused`
+- Cleanup unused code: `npm run cleanup:unused`
+
+### Environment Setup
+
+#### Backend
+1. Create virtual environment: `python -m venv .venv`
+2. Activate: `source .venv/bin/activate` (Linux/Mac) or `.venv\Scripts\activate` (Windows)
+3. Install dependencies: `pip install -r backend/requirements.txt`
+4. Create `.env.local` with required API keys (see [Environment Configuration](#environment-configuration))
+
+#### Frontend
+1. Ensure Node.js 20+ installed (check `.nvmrc`: `node >= 20.0.0`)
+2. Install dependencies: `cd frontend && npm install`
+3. Create `frontend/.env.local` with required variables (see [Environment Configuration](#environment-configuration))
+
+### GPU Backend Deployment (Docker)
+
+For GPU-accelerated BiomedParse inference:
+
+```bash
+# Build GPU image
+docker build -t novion-backend:gpu -f backend/Dockerfile .
+
+# Run with GPU support
+docker run --gpus all -p 8000:8000 \
+ -e BP3D_CKPT=/weights/biomedparse_3D_AllData_MultiView_edge.ckpt \
+ -e BP_TMP_TTL=7200 -e BP_TMP_SWEEP=1800 -e BP_VALIDATE_HEATMAP=1 \
+ -v /opt/weights:/weights \
+ novion-backend:gpu
+
+# Verify health
+curl http://localhost:8000/api/biomedparse/v1/health
+```
+
+See `DEPLOY_GPU.md` and `DEPLOY_LOCAL.md` for detailed deployment instructions.
+
+---
+
+## Project Structure
+
+```
+/
+├── backend/ # Python FastAPI backend
+│ ├── server.py # ⭐ Main FastAPI server with all endpoints
+│ ├── chat_interface.py # ⭐ Chat interface with LLM integration and specialized agents
+│ ├── biomedparse_api.py # BiomedParse 3D medical image segmentation
+│ ├── novion.py # Legacy/alternative server implementation
+│ ├── mcp/ # Model Context Protocol integration
+│ │ ├── client.py # ⭐ MCP client implementation
+│ │ ├── fhir_server.py # FHIR MCP server for healthcare data
+│ │ ├── installer.py # MCP server installation management
+│ │ └── agent_integration.py # Agent-MCP integration layer
+│ ├── tools/ # Specialized agent tools
+│ │ ├── medical_info.py # Medical information retrieval
+│ │ ├── researcher.py # Research and clinical trials
+│ │ └── medications.py # Medication and drug interaction tools
+│ ├── models_utils/ # Model utilities and helpers
+│ ├── tests/ # Backend tests
+│ │ └── test_heatmap_validation.py
+│ ├── requirements.txt # ⭐ Python dependencies
+│ ├── langgraph.json # LangGraph configuration
+│ └── test_mcp_integration.py # MCP integration tests
+├── frontend/ # Next.js 15 frontend
+│ ├── app/ # Next.js App Router
+│ │ ├── layout.tsx # Root layout with providers
+│ │ ├── page.tsx # ⭐ Main application page
+│ │ └── api/ # Next.js API routes
+│ ├── components/ # React components
+│ │ ├── DicomViewer.tsx # ⭐ DICOM medical image viewer wrapper
+│ │ ├── AdvancedViewer.tsx # Advanced viewing features
+│ │ ├── novionAgents.tsx # ⭐ AI agents interface
+│ │ ├── core/ # Core viewer components
+│ │ │ └── CoreViewer.tsx # Cornerstone3D integration
+│ │ ├── ui/ # UI components (buttons, panels, etc.)
+│ │ ├── viewer/ # Viewer-specific components
+│ │ ├── modals/ # Modal dialogs
+│ │ ├── toolbars/ # Toolbar components
+│ │ ├── layouts/ # Layout components
+│ │ └── providers/ # Context providers
+│ ├── lib/ # Shared utilities and configurations
+│ │ ├── api.ts # ⭐ API client for backend communication
+│ │ ├── utils.ts # Utility functions
+│ │ ├── db.ts # Database client (Prisma)
+│ │ ├── env.ts # Environment variable validation
+│ │ ├── cornerstone/ # Cornerstone3D setup and utilities
+│ │ ├── api/ # API client modules
+│ │ ├── hooks/ # Custom React hooks
+│ │ ├── services/ # Frontend services
+│ │ ├── types/ # TypeScript type definitions
+│ │ └── utils/ # Utility modules
+│ ├── hooks/ # Global custom hooks
+│ ├── types/ # Global TypeScript types
+│ ├── styles/ # Global styles and CSS
+│ ├── package.json # ⭐ Frontend dependencies
+│ ├── tsconfig.json # TypeScript configuration
+│ ├── tailwind.config.ts # ⭐ Tailwind CSS configuration
+│ ├── .eslintrc.json # ESLint configuration
+│ ├── schema.prisma # Prisma database schema
+│ ├── next.config.js # Next.js configuration
+│ └── start-dev.sh # Development startup script with validation
+├── tests/ # Top-level tests
+│ ├── test_client.py # ⭐ Comprehensive API test client
+│ └── simple_server.py # Simplified test server
+├── dicom-test-files/ # DICOM test data
+├── ideas-inspo/ # Project ideas and inspiration
+├── related-papers/ # Research papers and references
+├── README.md # Project documentation
+├── DEPLOY_LOCAL.md # ⭐ Local development deployment guide
+├── DEPLOY_GPU.md # ⭐ GPU cloud deployment guide
+└── .gitignore # Git ignore rules
+```
+
+**Key Files**:
+- `backend/server.py` - Main FastAPI application with all API endpoints
+- `backend/chat_interface.py` - Chat interface with specialized medical agents (Pharmacist, Researcher, Medical Analyst)
+- `backend/mcp/client.py` - MCP client for FHIR and other healthcare data integration
+- `frontend/app/page.tsx` - Main application entry point with DICOM viewer and AI agents
+- `frontend/components/DicomViewer.tsx` - DICOM medical image viewer component
+- `frontend/lib/api.ts` - Centralized API client for backend communication
+- `frontend/tailwind.config.ts` - Design system tokens and Tailwind configuration
+
+---
+
+## Development Patterns & Conventions
+
+### Backend (Python/FastAPI)
+
+#### Code Style
+- **Language**: Python 3.8+
+- **Indentation**: 4 spaces (PEP 8)
+- **Quotes**: Double quotes preferred
+- **Line length**: 88 characters (Black default)
+- **Type hints**: Encouraged but not enforced
+- **Async/await**: Use for all I/O operations (FastAPI endpoints, database queries, LLM calls)
+
+#### Naming Conventions
+- **Files**: snake_case (`chat_interface.py`, `mcp_client.py`)
+- **Classes**: PascalCase (`ChatInterface`, `RadSysXMCPClient`, `FHIRMCPServer`)
+- **Functions/Methods**: snake_case (`get_response`, `install_mcp_server`)
+- **Constants**: UPPER_SNAKE_CASE (`API_BASE_URL`, `DEFAULT_MODEL`)
+- **Private**: Leading underscore (`_internal_helper`)
+
+#### FastAPI Patterns
+
+✅ **GOOD - Async endpoints with proper error handling**:
+```python
+from fastapi import FastAPI, HTTPException
+from pydantic import BaseModel
+
+app = FastAPI()
+
+class ChatRequest(BaseModel):
+ message: str
+ model: str = "gpt-4"
+
+@app.post("/chat")
+async def chat_endpoint(request: ChatRequest):
+ try:
+ response = await chat_interface.get_response(
+ request.message,
+ model=request.model
+ )
+ return {"response": response}
+ except Exception as e:
+ raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
+```
+
+✅ **GOOD - Streaming responses**:
+```python
+from fastapi.responses import StreamingResponse
+
+@app.post("/chat/stream")
+async def chat_stream(request: ChatRequest):
+ async def generate():
+ async for chunk in chat_interface.stream_response(request.message):
+ yield f"data: {chunk}\n\n"
+
+ return StreamingResponse(generate(), media_type="text/event-stream")
+```
+
+❌ **BAD - Synchronous blocking operations**:
+```python
+@app.post("/chat")
+def chat_endpoint(request: ChatRequest): # Missing async
+ response = requests.post(...) # Blocking I/O - use httpx with async instead
+ return response.json()
+```
+
+#### LangChain/LangGraph Patterns
+
+✅ **GOOD - Use chat_interface.py singleton pattern**:
+```python
+from chat_interface import ChatInterface
+
+# Get singleton instance
+chat_interface = ChatInterface.get_instance()
+
+# Use specialized agents
+response = await chat_interface.ask_agent(
+ agent_type="pharmacist",
+ query="What are the side effects of aspirin?",
+ model="gpt-4"
+)
+```
+
+✅ **GOOD - Specialized agent with chain-of-thought**:
+```python
+# Agents show reasoning in tags before final answer
+# Example agent types: "pharmacist", "researcher", "medical_analyst"
+response = await chat_interface.ask_agent(
+ agent_type="researcher",
+ query="Latest clinical trials for diabetes treatment",
+ model="gpt-4"
+)
+# Response includes: reasoning process + final recommendation
+```
+
+#### MCP Integration Patterns
+
+✅ **GOOD - Use MCP client for FHIR operations**:
+```python
+from mcp.client import RadSysXMCPClient
+
+mcp_client = RadSysXMCPClient()
+await mcp_client.initialize()
+
+# List available FHIR resources
+resources = await mcp_client.call_tool("list_fhir_resources", {})
+
+# Query FHIR data
+patients = await mcp_client.call_tool("query_fhir", {
+ "resource_type": "Patient",
+ "search_params": {"name": "John"}
+})
+```
+
+✅ **GOOD - Install MCP servers dynamically**:
+```python
+from mcp.installer import MCPInstaller
+
+installer = MCPInstaller()
+result = await installer.install_server(
+ server_name="custom-fhir-server",
+ package="@example/fhir-mcp",
+ args=["--port", "9000"],
+ env={"FHIR_BASE_URL": "https://fhir.example.com"}
+)
+```
+
+### Frontend (Next.js/TypeScript)
+
+#### Code Style
+- **Language**: TypeScript strict mode enabled
+- **Indentation**: 2 spaces
+- **Quotes**: Double quotes (enforced by Prettier)
+- **Semicolons**: Required
+- **Line length**: 100 characters
+- **Trailing commas**: Always in multiline
+
+#### Naming Conventions
+- **Files**: kebab-case for components (`dicom-viewer.tsx`), PascalCase for component files when standard (`DicomViewer.tsx`)
+- **Components**: PascalCase (`DicomViewer`, `AdvancedViewer`, `CoreViewer`)
+- **Functions/Hooks**: camelCase (`useViewportManager`, `loadDicomImage`)
+- **Constants**: UPPER_SNAKE_CASE (`API_BASE_URL`, `MAX_FILE_SIZE`)
+- **Types/Interfaces**: PascalCase (`ViewerProps`, `DicomImage`, `ToolType`)
+- **CSS Classes**: kebab-case (`viewer-container`, `tool-button`)
+
+#### TypeScript Configuration
+
+Key `tsconfig.json` settings:
+- Strict mode: enabled
+- Module resolution: bundler (Next.js 15)
+- Path aliases: `@/*` maps to `frontend/*`
+- JSX: preserve (handled by Next.js)
+
+#### Component Patterns (Functional Only)
+
+✅ **GOOD - Functional components with TypeScript**:
+```tsx
+"use client"; // For components using hooks/interactivity
+
+import React from 'react';
+import type { UiToolType } from '@/lib/utils/cornerstoneInit';
+
+interface DicomViewerProps {
+ imageIds?: string[];
+ viewportType: 'AXIAL' | 'SAGITTAL' | 'CORONAL';
+ isActive?: boolean;
+ isExpanded?: boolean;
+ onActivate?: () => void;
+ onToggleExpand?: () => void;
+ onImageLoaded?: (success: boolean) => void;
+ activeTool?: UiToolType;
+ viewportId: string;
+ loadSignal: boolean;
+ onReady: (viewportId: string) => void;
+}
+
+export function DicomViewer({
+ imageIds,
+ viewportType,
+ isActive = false,
+ isExpanded = false,
+ onActivate,
+ onToggleExpand,
+ onImageLoaded,
+ activeTool = null,
+ viewportId,
+ loadSignal,
+ onReady
+}: DicomViewerProps) {
+ // Use hooks for state management
+ const [isLoading, setIsLoading] = React.useState(false);
+
+ // Component logic
+ return (
+
+ {/* JSX content */}
+
+ );
+}
+```
+
+✅ **GOOD - Consistent type imports**:
+```tsx
+// Use type imports for types only (enforced by ESLint)
+import type { DicomImage, ViewerConfig } from '@/lib/types';
+import { CoreViewer } from '@/components/core/CoreViewer';
+```
+
+❌ **BAD - Class components**:
+```tsx
+class DicomViewer extends React.Component {
+ // Legacy pattern - DO NOT USE
+}
+```
+
+❌ **BAD - Mixing type and value imports**:
+```tsx
+// Don't mix when importing types
+import { DicomImage, CoreViewer } from '@/lib/types'; // BAD
+// Instead:
+import type { DicomImage } from '@/lib/types';
+import { CoreViewer } from '@/components/core/CoreViewer';
+```
+
+#### State Management
+
+- **Local component state**: `useState` for component-specific state
+- **Server state**: `@tanstack/react-query` for API data fetching and caching
+- **Global UI state**: React Context or Zustand (if needed)
+- **Form state**: Controlled components with `useState` or `react-hook-form` for complex forms
+
+✅ **GOOD - React Query for API data**:
+```tsx
+import { useQuery } from '@tanstack/react-query';
+import { api } from '@/lib/api';
+
+export function PatientList() {
+ const { data, isLoading, error } = useQuery({
+ queryKey: ['patients'],
+ queryFn: () => api.getPatients()
+ });
+
+ if (isLoading) return
Loading...
;
+ if (error) return
Error: {error.message}
;
+
+ return (
+
+ {data?.map(patient => (
+
{patient.name}
+ ))}
+
+ );
+}
+```
+
+#### API Integration
+
+✅ **GOOD - Use centralized API client from `lib/api.ts`**:
+```tsx
+import { api } from '@/lib/api';
+
+// GET request
+const response = await api.get('/api/patients', {
+ params: { page: 1, limit: 20 }
+});
+
+// POST request
+const result = await api.post('/api/chat', {
+ message: 'Hello',
+ model: 'gpt-4'
+});
+
+// Streaming chat
+const stream = await api.streamChat({
+ message: 'Analyze this medical image',
+ model: 'gpt-4'
+});
+
+for await (const chunk of stream) {
+ console.log(chunk);
+}
+```
+
+❌ **BAD - Direct fetch calls**:
+```tsx
+const response = await fetch('/api/patients'); // Don't do this
+const data = await response.json();
+```
+
+#### Styling with Tailwind CSS
+
+✅ **GOOD - Use Tailwind utility classes**:
+```tsx
+export function Button({ variant = 'primary', children }: ButtonProps) {
+ return (
+
+ );
+}
+```
+
+✅ **GOOD - Use CSS variables from Tailwind config**:
+```tsx
+// Always use design tokens from tailwind.config.ts
+// Colors: border, background, foreground, primary, secondary, muted, accent, card, destructive
+