openemr-mcp

openemr-mcp

An MCP server that connects AI assistants to OpenEMR instances to manage patient records, clinical trends, and medication safety. It provides 17 tools for tasks such as patient search, drug interaction checks, and generating comprehensive health trajectories and visit preparations.

Category
Visit Server

README

openemr-mcp

PyPI Python 3.10+ License: MIT

Model Context Protocol (MCP) server for OpenEMR — connect any MCP-compatible AI assistant (Claude Desktop, Cursor, VS Code Copilot) directly to your OpenEMR instance.

Features

17 MCP tools covering:

Category Tools
Patients openemr_patient_search
Appointments openemr_appointment_list
Medications openemr_medication_list, openemr_drug_interaction_check
Providers openemr_provider_search
FDA Safety openemr_fda_adverse_events, openemr_fda_drug_label
Symptom Lookup openemr_symptom_lookup
Drug Safety Flags openemr_drug_safety_flag_create/list/update/delete
Clinical Trends openemr_lab_trends, openemr_vital_trends, openemr_questionnaire_trends
Health Trajectory openemr_health_trajectory
Visit Prep openemr_visit_prep

All tools work in mock mode out of the box — no OpenEMR installation required for evaluation.

Quick Start

Install

pip install openemr-mcp
# or with uv:
uv add openemr-mcp

Run (stdio transport)

# Mock mode — no OpenEMR needed
OPENEMR_DATA_SOURCE=mock openemr-mcp

# Against a live OpenEMR FHIR API
OPENEMR_DATA_SOURCE=api \
  OPENEMR_API_BASE_URL=https://your-openemr/apis/default \
  OPENEMR_OAUTH_SITE=default \
  OPENEMR_OAUTH_CLIENT_ID=... \
  OPENEMR_OAUTH_CLIENT_SECRET=... \
  OPENEMR_OAUTH_USERNAME=admin \
  OPENEMR_OAUTH_PASSWORD=... \
  openemr-mcp

Claude Desktop Configuration

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "openemr": {
      "command": "uvx",
      "args": ["openemr-mcp"],
      "env": {
        "OPENEMR_DATA_SOURCE": "api",
        "OPENEMR_API_BASE_URL": "https://your-openemr.example.com/apis/default",
        "OPENEMR_OAUTH_SITE": "default",
        "OPENEMR_OAUTH_CLIENT_ID": "your_client_id",
        "OPENEMR_OAUTH_CLIENT_SECRET": "your_client_secret",
        "OPENEMR_OAUTH_USERNAME": "admin",
        "OPENEMR_OAUTH_PASSWORD": "your_password"
      }
    }
  }
}

For mock mode (demo / evaluation):

{
  "mcpServers": {
    "openemr": {
      "command": "uvx",
      "args": ["openemr-mcp"],
      "env": {
        "OPENEMR_DATA_SOURCE": "mock"
      }
    }
  }
}

Data Sources

Patient / Clinical Data (OPENEMR_DATA_SOURCE)

Value Description
mock (default) Built-in curated demo data — 24 patients, no network required
db Direct MySQL connection to OpenEMR database
api OpenEMR FHIR R4 REST API (recommended for production)

Drug Interactions (DRUG_INTERACTION_SOURCE)

Value Description
mock (default) 10 built-in drug pairs — always works, no network
openfda OpenFDA FAERS co-reporting heuristic — free, no API key required. Severity based on co-report volume (HIGH ≥ 50, MODERATE ≥ 5). Note: Co-reporting indicates correlation, not definitive causation.
rxnorm ⚠️ DEPRECATED/UNAVAILABLE — RxNorm interaction API endpoints retired (returns 404)

Symptom Checker (SYMPTOM_SOURCE)

Value Description
mock (default) Curated local dataset — 10 clinical groups
infermedica Infermedica Symptom Checker API (register here) — free tier 100 calls/day

FDA Data (OPENFDA_SOURCE)

Value Description
mock (default) Built-in mock data for 6 common drugs
live Live OpenFDA API — free, optional key for higher rate limits

Environment Variables

See .env.example for the full list with comments.

Key variables:

# Data source
OPENEMR_DATA_SOURCE=mock        # mock | db | api

# MySQL (when OPENEMR_DATA_SOURCE=db)
OPENEMR_DB_HOST=localhost
OPENEMR_DB_PORT=3306
OPENEMR_DB_USER=openemr
OPENEMR_DB_PASSWORD=openemr
OPENEMR_DB_NAME=openemr

# FHIR API (when OPENEMR_DATA_SOURCE=api)
OPENEMR_API_BASE_URL=https://your-openemr/apis/default
OPENEMR_OAUTH_SITE=default
OPENEMR_OAUTH_CLIENT_ID=...
OPENEMR_OAUTH_CLIENT_SECRET=...
OPENEMR_OAUTH_USERNAME=admin
OPENEMR_OAUTH_PASSWORD=...

# Optional external APIs
DRUG_INTERACTION_SOURCE=mock    # mock | openfda | rxnorm (deprecated)
SYMPTOM_SOURCE=mock             # mock | infermedica
INFERMEDICA_APP_ID=
INFERMEDICA_APP_KEY=
OPENFDA_SOURCE=mock             # mock | live
OPENFDA_API_KEY=

Tool Reference

openemr_patient_search

Search patients by name. Returns patient ID, DOB, sex, city.

{ "query": "Jane" }

openemr_appointment_list

List upcoming appointments for a patient.

{ "patient_id": "p001" }

openemr_medication_list

Return the current medication list for a patient.

{ "patient_id": "p001" }

openemr_drug_interaction_check

Check a list of medications for known drug-drug interactions.

{ "medications": ["warfarin", "aspirin", "metformin"] }

openemr_provider_search

Search healthcare providers by specialty and/or location.

{ "specialty": "Cardiology", "location": "Boston" }

openemr_fda_adverse_events

Query FDA FAERS database for adverse event reports on a drug.

{ "drug_name": "metformin", "limit": 5 }

openemr_fda_drug_label

Retrieve official FDA drug label including boxed warnings and contraindications.

{ "drug_name": "warfarin" }

openemr_symptom_lookup

Look up possible conditions for a list of symptoms.

{ "symptoms": ["chest pain", "shortness of breath"] }

openemr_drug_safety_flag_create

Create a drug safety flag for a patient.

{
  "patient_id": "p001",
  "drug_name": "warfarin",
  "description": "Patient reported unusual bruising",
  "flag_type": "adverse_event",
  "severity": "HIGH"
}

openemr_drug_safety_flag_list

List all drug safety flags for a patient.

{ "patient_id": "p001", "status_filter": "active" }

openemr_drug_safety_flag_update

Update a drug safety flag's severity, description, or status.

{ "flag_id": "uuid-...", "severity": "MODERATE", "status": "resolved" }

openemr_drug_safety_flag_delete

Delete a drug safety flag by ID.

{ "flag_id": "uuid-..." }

openemr_lab_trends

Return longitudinal lab trajectories (A1c, LDL, eGFR).

{ "patient_id": "p001", "metrics": ["a1c", "ldl"], "window_months": 24 }

openemr_vital_trends

Return longitudinal vital sign trajectories (weight, BP).

{ "patient_id": "p001", "metrics": ["weight", "bp_systolic", "bp_diastolic"] }

openemr_questionnaire_trends

Return longitudinal questionnaire score trajectories (PHQ-9).

{ "patient_id": "p001", "instrument": "PHQ-9", "window_months": 24 }

openemr_health_trajectory

Aggregate all metric trajectories and compute clinical drift alerts.

{ "patient_id": "p001", "window_months": 24 }

openemr_visit_prep

Generate a pre-visit clinical brief: top risks, medication safety, care gaps, and suggested agenda.

{ "patient_id": "p001", "window_months": 24 }

Development

# Clone and install in editable mode
git clone https://github.com/shruti-jn/openemr-mcp
cd openemr-mcp
pip install -e ".[dev]"

# Run tests (mock mode, no external dependencies)
pytest

# Start server locally
OPENEMR_DATA_SOURCE=mock openemr-mcp

Architecture

src/openemr_mcp/
├── server.py              # MCP server — registers all 17 tools
├── config.py              # Pydantic-settings configuration
├── schemas.py             # All Pydantic response schemas
├── auth.py                # OpenEMR OAuth2 token manager
├── data_source.py         # Data source resolver
├── tools/                 # 13 tool modules (17 MCP tools)
├── repositories/          # Data access (MySQL, FHIR R4, SQLite)
└── services/              # Business logic (OpenFDA, trajectory alerts, visit prep)

Drug safety flags are persisted in a local SQLite database at ~/.openemr_mcp/drug_safety_flags.db.

License

MIT — see LICENSE.

Contributing

Pull requests welcome. Please open an issue first for major changes.

This project is part of the AgentForge OpenEMR AI toolkit.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured