# OOREP MCP Server [![npm version](https://img.shields.io/npm/v/oorep-mcp.svg)](https://www.npmjs.com/package/oorep-mcp) [![CI](https://github.com/Dhi13man/oorep-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/Dhi13man/oorep-mcp/actions/workflows/ci.yml) [![CodeQL](https://github.com/Dhi13man/oorep-mcp/actions/workflows/codeql.yml/badge.svg)](https://github.com/Dhi13man/oorep-mcp/actions/workflows/codeql.yml) [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/Dhi13man/oorep-mcp/badge)](https://scorecard.dev/viewer/?uri=github.com/Dhi13man/oorep-mcp) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) An MCP server and TypeScript client SDK that gives AI assistants access to OOREP's homeopathic repertory and materia medica reference data. ## TL;DR ```bash # Install and run (no setup required) npx -y oorep-mcp ``` ```typescript // Or use programmatically import { createOOREPClient } from 'oorep-mcp'; const client = createOOREPClient(); const results = await client.searchRepertory({ symptom: 'headache worse motion' }); console.log(results.rubrics); client.destroy(); ``` **Ask your AI assistant:** *"Search OOREP for remedies for throbbing headache worse from light"* ## What is OOREP? **OOREP (Open Online Repertory)** is an open-source homeopathic database containing: - **12+ Repertories** - Systematic indexes of symptoms mapped to remedies (Kent, Boger, Boericke, etc.) - **Multiple Materia Medicas** - Detailed remedy descriptions and therapeutic indications - **600+ Remedies** - Comprehensive remedy database with names, abbreviations, and alternates ### How Homeopathic Data is Structured ```mermaid graph TB subgraph Repertory[Repertory Structure] Chapter[Chapter
e.g. Head] Rubric[Rubric
e.g. Pain - Throbbing] R1[Belladonna - 4] R2[Glonoine - 3] R3[Natrum mur - 2] Chapter --> Rubric Rubric --> R1 Rubric --> R2 Rubric --> R3 end subgraph MateriaMedica[Materia Medica Structure] Remedy[Remedy
e.g. Belladonna] S1[Mind: Sudden onset...] S2[Head: Throbbing pain...] S3[...] Remedy --> S1 Remedy --> S2 Remedy --> S3 end ``` This MCP server enables AI assistants to query this data programmatically. ## Features | Feature | Description | |---------|-------------| | **Search Repertories** | Query symptoms across 12+ repertories, get matching rubrics with weighted remedies | | **Search Materia Medicas** | Find remedy descriptions and indications from multiple sources | | **Remedy Information** | Get comprehensive details for 600+ remedies | | **List Resources** | Browse available repertories, materia medicas, and remedies | | **Guided Workflows** | Prompts for symptom analysis, remedy comparison, case repertorization | | **Structured Responses** | MCP 2025-06-18 compliant with outputSchema and structuredContent | | **Performance** | Built-in caching (5min TTL), request deduplication, automatic retries | | **Type Safety** | Full TypeScript with Zod validation on all inputs | | **Security** | Input sanitization, error message sanitization, no credentials required | | **SDK Adapters** | Direct integration with OpenAI, Vercel AI SDK, LangChain, Google Gemini | ## Quick Start Requires [Node.js 22.12 or newer](https://nodejs.org/) with npm/npx. ### 1. Add to Claude Desktop **macOS:** Edit `~/Library/Application Support/Claude/claude_desktop_config.json` **Windows:** Edit `%APPDATA%\Claude\claude_desktop_config.json` ```json { "mcpServers": { "oorep": { "command": "npx", "args": ["-y", "oorep-mcp"] } } } ``` ### 2. Restart Claude Desktop Quit completely (Cmd+Q / Alt+F4), then reopen. ### 3. Start Using **You:** "Search OOREP for remedies for headache worse at night" **Claude will:** 1. Call `search_repertory` with symptom "headache worse night" 2. Return matching rubrics with remedies and their weights 3. Explain the results in context ## Installation ### NPX (Recommended) No installation required: ```bash npx -y oorep-mcp ``` ### npm Global ```bash npm install -g oorep-mcp oorep-mcp ``` ### npm Local (for SDK usage) ```bash npm install oorep-mcp ``` ## Platform Configuration ### Claude Code #### Option A: CLI ```bash claude mcp add oorep -- npx -y oorep-mcp ``` #### Option B: Config file (`~/.claude.json`) ```json { "mcpServers": { "oorep": { "command": "npx", "args": ["-y", "oorep-mcp"], "env": { "OOREP_MCP_BASE_URL": "https://www.oorep.com", "OOREP_MCP_LOG_LEVEL": "info" } } } } ``` Verify: Run `/mcp` in Claude Code ### Claude Desktop **Config locations:** - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json` - Windows: `%APPDATA%\Claude\claude_desktop_config.json` ```json { "mcpServers": { "oorep": { "command": "npx", "args": ["-y", "oorep-mcp"], "env": { "OOREP_MCP_BASE_URL": "https://www.oorep.com", "OOREP_MCP_LOG_LEVEL": "info" } } } } ``` **Important:** Quit completely (Cmd+Q), not just close window. ### Codex CLI **Config:** `~/.codex/config.toml` (macOS/Linux) or `C:\Users\\.codex\config.toml` (Windows) ```toml [mcp_servers.oorep] command = "npx" args = ["-y", "oorep-mcp"] startup_timeout_sec = 15.0 tool_timeout_sec = 60.0 [mcp_servers.oorep.env] OOREP_MCP_BASE_URL = "https://www.oorep.com" OOREP_MCP_LOG_LEVEL = "info" ``` Or via CLI: ```bash codex mcp add oorep --env OOREP_MCP_BASE_URL=https://www.oorep.com --env OOREP_MCP_LOG_LEVEL=info -- npx -y oorep-mcp ``` Verify: Run `codex mcp list` ### Gemini CLI **Config:** `~/.gemini/settings.json` ```json { "mcpServers": { "oorep": { "command": "npx", "args": ["-y", "oorep-mcp"], "env": { "OOREP_MCP_BASE_URL": "https://www.oorep.com", "OOREP_MCP_LOG_LEVEL": "info" }, "timeout": 30000 } } } ``` ## Usage Examples Once installed, you can interact with OOREP through Claude naturally: ### Searching for Remedies **You:** "Can you search OOREP for remedies for headache that's worse at night?" **Claude will:** 1. Use the `search_repertory` tool 2. Search for "headache worse night" in the default repertory 3. Return matching rubrics with remedy recommendations and their weights ### Getting Detailed Remedy Information **You:** "Tell me more about Aconite - what conditions is it used for?" **Claude will:** 1. Use the `get_remedy_info` tool to fetch details about Aconite 2. Provide information about its common uses, characteristics, and therapeutic applications ### Comparing Remedies **You:** "Compare Aconite and Belladonna for fever symptoms" **Claude will:** 1. Use the `remedy-comparison` prompt 2. Search materia medicas for both remedies 3. Provide a side-by-side comparison focusing on fever symptoms 4. Highlight key differentiating factors ### Case Repertorization **You:** "I want to repertorize a case with these symptoms: anxiety, palpitations, and insomnia" **Claude will:** 1. Use the `repertorization-workflow` prompt 2. Guide you through systematic symptom analysis 3. Search relevant rubrics for each symptom 4. Help synthesize results to identify well-indicated remedies ### Browsing Available Resources **You:** "What repertories are available in OOREP?" **Claude will:** 1. Use the `list_available_repertories` tool 2. Show all 12+ available repertories with their names and descriptions ## API Reference ### Tools #### `search_repertory` Search for symptoms in homeopathic repertories. **Parameters:** | Name | Type | Required | Default | Description | |------|------|----------|---------|-------------| | `symptom` | string | Yes | - | Symptom to search (3-200 chars). Supports wildcards. | | `repertory` | string | No | `publicum` | Repertory abbreviation (e.g., `kent`, `boger`) | | `minWeight` | number | No | `1` | Minimum remedy weight (1-4) | | `maxResults` | number | No | `20` | Maximum rubrics to return (1-100) | | `includeRemedyStats` | boolean | No | `true` | Include aggregated remedy statistics | **Returns:** ```typescript { totalResults: number; rubrics: Array<{ rubric: string; // Full path: "Head > Pain > Throbbing" text: string | null; // Additional rubric text repertory: string; // Repertory abbreviation remedies: Array<{ name: string; // Full name: "Belladonna" abbreviation: string; // "Bell." weight: number; // 1-4 }>; }>; remedyStats?: Array<{ // If includeRemedyStats=true name: string; abbreviation: string; count: number; // Times appearing cumulativeWeight: number; // Sum of weights }>; } ``` #### `search_materia_medica` Search materia medica texts for remedy descriptions. **Parameters:** | Name | Type | Required | Default | Description | |------|------|----------|---------|-------------| | `symptom` | string | Yes | - | Symptom to search (3-200 chars) | | `materiamedica` | string | No | `boericke` | Materia medica abbreviation | | `remedy` | string | No | - | Filter to specific remedy | | `maxResults` | number | No | `10` | Maximum results (1-50) | **Returns:** ```typescript { totalResults: number; results: Array<{ remedy: string; // "Aconitum napellus" materiaMedica: string; // "boericke" sections: Array<{ heading: string; // "Mind", "Head", etc. content: string; // Section text depth: number; // Heading depth }>; }>; } ``` #### `get_remedy_info` Get detailed information about a specific remedy. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `remedy` | string | Yes | Remedy name, abbreviation, or alternate name (1-100 chars) | **Returns:** ```typescript { id: number; nameAbbrev: string; // "Acon." nameLong: string; // "Aconitum napellus" namealt: string[]; // ["Aconite", "Monkshood"] } | null // null if not found ``` **Matching behavior:** - Exact match on abbreviation, long name, or alternate names (case-insensitive) - Partial match for queries ≥3 characters #### `list_available_repertories` List all accessible repertories. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `language` | string | No | Filter by language code (e.g., `en`, `de`) | **Returns:** ```typescript Array<{ abbreviation: string; // "kent" title: string; // "Kent Repertory" author: string; // "James Tyler Kent" language: string; // "en" }> ``` #### `list_available_materia_medicas` List all accessible materia medica texts. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `language` | string | No | Filter by language code | **Returns:** ```typescript Array<{ abbreviation: string; // "boericke" title: string; // "Boericke Materia Medica" author: string; // "William Boericke" language: string; // "en" }> ``` ### Structured Response Format All tools support the MCP 2025-06-18 specification with structured responses: **Response Structure:** ```typescript { // Text content for backwards compatibility content: [{ type: 'text', text: '{"totalResults": 42, "rubrics": [...]}' // JSON string }], // Machine-parseable structured content structuredContent: { totalResults: 42, rubrics: [...] // Actual JavaScript object } } ``` **Benefits:** - **outputSchema**: Each tool definition includes a JSON Schema defining the expected output structure - **structuredContent**: Direct access to typed results without JSON parsing - **Backwards Compatible**: Text content always included for older clients - **Error Handling**: Errors return `isError: true` for LLM self-correction ### Resources | URI | Description | Content Type | |-----|-------------|--------------| | `oorep://remedies/list` | Complete list of all 600+ remedies | JSON | | `oorep://repertories/list` | All available repertories with metadata | JSON | | `oorep://materia-medicas/list` | All available materia medicas | JSON | | `oorep://help/search-syntax` | Search syntax guide with examples | Text | ### Prompts #### `analyze-symptoms` Guided workflow for systematic symptom analysis. **Arguments:** | Name | Type | Required | Description | |------|------|----------|-------------| | `symptom_description` | string | No | Initial symptom description | **Workflow:** Guides through symptom gathering → modality analysis → repertory search → synthesis #### `remedy-comparison` Compare multiple remedies side-by-side. **Arguments:** | Name | Type | Required | Description | |------|------|----------|-------------| | `remedies` | string | Yes | Comma-separated remedy names (2-6 remedies) | **Example:** `remedies: "Aconite, Belladonna, Gelsemium"` #### `repertorization-workflow` Step-by-step case taking and repertorization. **Workflow:** 7-step process from symptom collection through remedy differentiation. ## Search Syntax ### Basic Search ```bash headache # Simple term headache night # Multiple terms (AND) ``` ### Wildcards ```bash head* # Matches: head, headache, heading *ache # Matches: headache, stomachache ``` ### Exact Phrases ```bash "worse at night" # Exact phrase match "throbbing pain" # Must appear together ``` ### Exclusions ```bash headache -migraine # Headache but not migraine fever -intermittent # Fever excluding intermittent ``` ### Combined ```bash head* pain -chronic "worse motion" ``` ### Tips - Minimum 3 characters per term - Wildcards only at word boundaries - Use repertory-specific terminology for better results ## SDK Integration For programmatic use with AI frameworks, see the **[SDK Integration Guide](docs/SDK.md)**. **Supported frameworks:** OpenAI, Vercel AI SDK, LangChain/LangGraph, Google Gemini **Quick example:** ```typescript import { createOOREPClient } from 'oorep-mcp'; const client = createOOREPClient(); const results = await client.searchRepertory({ symptom: 'headache worse motion' }); console.log(results.rubrics); client.destroy(); ``` ## Configuration All configuration via environment variables: | Variable | Default | Description | |----------|---------|-------------| | `OOREP_MCP_BASE_URL` | `https://www.oorep.com` | OOREP API base URL | | `OOREP_MCP_TIMEOUT_MS` | `30000` | Request timeout (ms) | | `OOREP_MCP_CACHE_TTL_MS` | `300000` | Cache TTL (ms), 0 to disable | | `OOREP_MCP_MAX_RESULTS` | `100` | Maximum results cap | | `OOREP_MCP_LOG_LEVEL` | `info` | `debug` \| `info` \| `warn` \| `error` | | `OOREP_MCP_DEFAULT_REPERTORY` | `publicum` | Default repertory | | `OOREP_MCP_DEFAULT_MATERIA_MEDICA` | `boericke` | Default materia medica | | `OOREP_MCP_REMOTE_USER` | *(unset)* | If set, sends `X-Remote-User` header (numeric member ID) on all upstream requests | > The MCP server maintains an anonymous OOREP session automatically. It performs a lightweight bootstrap request to fetch the required cookies and reuses them for subsequent search calls, so no additional authentication setup is necessary for public data. **Example with custom config:** ```json { "mcpServers": { "oorep": { "command": "npx", "args": ["-y", "oorep-mcp"], "env": { "OOREP_MCP_TIMEOUT_MS": "60000", "OOREP_MCP_CACHE_TTL_MS": "600000", "OOREP_MCP_LOG_LEVEL": "debug" } } } } ``` ## Architecture ```mermaid graph TB subgraph Client[MCP Client] MCPClient((Claude, Codex,
Gemini, etc.)) end subgraph Server[OOREP MCP Server] Tools[Tools] Resources[Resources] Prompts[Prompts] SDK[SDK] subgraph SDKClient[OOREPClient] Cache[(Cache)] Dedup[Deduplicator] Validators[Validators] end subgraph HTTPClient[OOREPClient - HTTP] Session[Session mgmt] Retry[Retry logic] Timeout[Timeout handling] end Tools --> SDKClient Resources --> SDKClient Prompts --> SDKClient SDK --> SDKClient SDKClient --> HTTPClient end subgraph External[OOREP API] API[https://www.oorep.com] end MCPClient -->|MCP Protocol| Server HTTPClient -->|HTTPS| API ``` **Key Components:** - **Cache**: In-memory LRU cache with configurable TTL (default 5 min) - **Deduplicator**: Prevents duplicate concurrent requests for same data - **Validators**: Zod schemas validate all inputs before API calls - **Session Management**: Automatic cookie handling for OOREP API ## Security Considerations ### Input Validation All inputs are validated using Zod schemas: - **Symptom searches**: 3-200 characters, trimmed of whitespace - **Remedy names**: 1-100 characters - **Server-side sanitization**: The OOREP API handles additional input sanitization ### Error Handling - All errors are sanitized before being returned to clients - Internal details (stack traces, file paths) are never exposed - Network errors return generic messages ### Data Privacy - No user credentials are stored or required - OOREP sessions are anonymous and cookie-based - No data is persisted to disk (memory cache only) - All inputs validated using Zod schemas - Errors are sanitized before returning to clients ## Rate Limiting The OOREP MCP Server does not implement internal rate limiting. However: ### OOREP API Limits The upstream OOREP API may have rate limits. If you exceed them, you'll receive a `RateLimitError`: ```typescript { content: [{ type: 'text', text: 'Error: Rate limit exceeded. Please try again later.' }], isError: true } ``` ### Mitigation Strategies 1. **Enable caching** (default: 5 minutes TTL) ```json "env": { "OOREP_MCP_CACHE_TTL_MS": "300000" } ``` 2. **Reduce concurrent requests** by using specific search terms 3. **Increase cache TTL** for frequently accessed data ```json "env": { "OOREP_MCP_CACHE_TTL_MS": "600000" } ``` ### Request Deduplication The SDK client automatically deduplicates concurrent identical requests, reducing API load. ## TypeScript Type Imports Import types directly from the package for type-safe development: ```typescript import type { // Tool argument types SearchRepertoryArgs, SearchMateriaMedicaArgs, GetRemedyInfoArgs, ListRepertoriesArgs, ListMateriaMedicasArgs, // Result types RepertorySearchResult, MateriaMedicaSearchResult, RemedyInfo, RepertoryMetadata, MateriaMedicaMetadata, // Supporting types Rubric, Remedy, MateriaMedicaResult, MateriaMedicaSection, // SDK Client types OOREPClient, OOREPSDKConfig, } from 'oorep-mcp'; ``` ### Schema Validation You can also import Zod schemas for runtime validation: ```typescript import { SearchRepertoryArgsSchema, RepertorySearchResultSchema, RemedyInfoSchema, } from 'oorep-mcp'; // Validate external data const validated = SearchRepertoryArgsSchema.parse(untrustedInput); ``` ## Troubleshooting ### Server Not Appearing in Claude Desktop **Problem:** The MCP indicator doesn't show up after configuration. **Solutions:** 1. **Completely quit Claude Desktop** (Cmd+Q on macOS, not just close window) 2. **Restart Claude Desktop** and wait 10-15 seconds for MCP initialization 3. **Check the configuration file** for valid JSON syntax (use a JSON validator) 4. **Check the logs:** - **macOS:** `~/Library/Logs/Claude/mcp*.log` - **Windows:** `%APPDATA%\Claude\Logs\mcp*.log` 5. **Verify npx works:** Run `npx -y oorep-mcp` in terminal to check if it starts ### Connection Timeout Errors **Problem:** "Connection timeout" or "Request timed out" errors. **Solutions:** 1. **Increase timeout** in configuration: ```json "env": { "OOREP_MCP_TIMEOUT_MS": "60000" } ``` 2. **Check network connectivity** to : ```bash curl https://www.oorep.com ``` 3. **Check for firewall/proxy issues** that might block connections ### No Results Returned **Problem:** Searches return empty results or "No results found". **Solutions:** 1. **Try broader search terms** (e.g., "headache" instead of "headache left temple worse 3pm") 2. **Remove filters** like `minWeight` or specific repertory restrictions 3. **Check if OOREP website is accessible** at 4. **Try a different repertory:** **Ask Claude:** "Search in the Kent repertory instead" ### High Memory Usage **Problem:** MCP server consuming excessive memory. **Solutions:** 1. **Reduce cache TTL** to clear cache more frequently: ```json "env": { "OOREP_MCP_CACHE_TTL_MS": "60000" } ``` 2. **Reduce max results:** ```json "env": { "OOREP_MCP_MAX_RESULTS": "50" } ``` 3. **Restart Claude Desktop** periodically to clear cache ### Permission Errors on macOS/Linux **Problem:** "Permission denied" when running the server. **Solutions:** 1. **For global install:** Ensure proper npm permissions ```bash sudo npm install -g oorep-mcp ``` 2. **For npx (recommended):** No permissions needed, use `-y` flag: ```bash npx -y oorep-mcp ``` ### Viewing Detailed Logs To see detailed debug logs for troubleshooting: 1. **Set log level to debug:** ```json "env": { "OOREP_MCP_LOG_LEVEL": "debug" } ``` 2. **Check MCP logs:** - **macOS:** `tail -f ~/Library/Logs/Claude/mcp*.log` - **Windows:** Check `%APPDATA%\Claude\Logs\` 3. **Look for specific error patterns:** - `NetworkError` - Connection issues - `TimeoutError` - Request taking too long - `ValidationError` - Invalid input - `RateLimitError` - Too many requests ### Still Having Issues? 1. **Check existing issues:** 2. **Report a new issue:** Include: - Your OS and version - Node.js version (`node --version`) - Claude Desktop version - Configuration (remove any sensitive data) - Error logs from MCP log files 3. **Join the discussion:** Share your experience and get community help ## Development ### Prerequisites - Node.js ≥ 22.12.0 - npm ≥ 10.0.0 ### Setup ```bash git clone https://github.com/Dhi13man/oorep-mcp.git cd oorep-mcp npm ci ``` ### Commands ```bash npm run build # Compile TypeScript npm run typecheck # Type checking only npm run dev # Development mode with watch npm test # Run all tests npm run test:watch # Watch mode npm run test:coverage # Coverage report npm run test:e2e # Live OOREP integration (requires network access) npm run lint # ESLint npm run format # Prettier ``` ### Test Structure ```text src/ ├── **/*.unit.test.ts # Unit tests (mocked dependencies) └── **/*.integration.test.ts # Integration tests (real implementations) ``` - **1100+ tests** with **95%+ coverage** - Unit tests use mocked dependencies - Integration tests use real implementations with mocked HTTP ## Disclaimer **This tool is for educational and informational purposes only.** - **Not medical advice** - Not a substitute for professional medical consultation - **Consult practitioners** - Always consult qualified homeopathic practitioners - **Not for diagnosis** - Not intended for diagnosing or treating medical conditions Homeopathic treatment should only be undertaken under the guidance of qualified professionals. ## License MIT License - see [LICENSE](LICENSE) file for details. ## Acknowledgments - **OOREP Team**: For creating and maintaining the open-source OOREP platform - **Anthropic**: For the Model Context Protocol and Claude - **MCP Community**: For tools, documentation, and support ## Links - **OOREP Website**: - **OOREP GitHub**: - **MCP Documentation**: - **Issue Tracker**: - **npm Package**: - **Support Development**: