Openemr Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Openemr Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Model Context Protocol (MCP) server for OpenEMR — connect any MCP-compatible AI assistant (Claude Desktop, Cursor, VS Code Copilot) directly to your OpenEMR instance.
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.
pip install openemr-mcp
# or with uv:
uv add openemr-mcp# 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-mcpAdd 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"
}
}
}
}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_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_SOURCE)| Value | Description |
|---|---|
mock (default) | Curated local dataset — 10 clinical groups |
infermedica | Infermedica Symptom Checker API (register here) — free tier 100 calls/day |
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 |
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=openemr_patient_searchSearch patients by name. Returns patient ID, DOB, sex, city.
{ "query": "Jane" }openemr_appointment_listList upcoming appointments for a patient.
{ "patient_id": "p001" }openemr_medication_listReturn the current medication list for a patient.
{ "patient_id": "p001" }openemr_drug_interaction_checkCheck a list of medications for known drug-drug interactions.
{ "medications": ["warfarin", "aspirin", "metformin"] }openemr_provider_searchSearch healthcare providers by specialty and/or location.
{ "specialty": "Cardiology", "location": "Boston" }openemr_fda_adverse_eventsQuery FDA FAERS database for adverse event reports on a drug.
{ "drug_name": "metformin", "limit": 5 }openemr_fda_drug_labelRetrieve official FDA drug label including boxed warnings and contraindications.
{ "drug_name": "warfarin" }openemr_symptom_lookupLook up possible conditions for a list of symptoms.
{ "symptoms": ["chest pain", "shortness of breath"] }openemr_drug_safety_flag_createCreate 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_listList all drug safety flags for a patient.
{ "patient_id": "p001", "status_filter": "active" }openemr_drug_safety_flag_updateUpdate a drug safety flag's severity, description, or status.
{ "flag_id": "uuid-...", "severity": "MODERATE", "status": "resolved" }openemr_drug_safety_flag_deleteDelete a drug safety flag by ID.
{ "flag_id": "uuid-..." }openemr_lab_trendsReturn longitudinal lab trajectories (A1c, LDL, eGFR).
{ "patient_id": "p001", "metrics": ["a1c", "ldl"], "window_months": 24 }openemr_vital_trendsReturn longitudinal vital sign trajectories (weight, BP).
{ "patient_id": "p001", "metrics": ["weight", "bp_systolic", "bp_diastolic"] }openemr_questionnaire_trendsReturn longitudinal questionnaire score trajectories (PHQ-9).
{ "patient_id": "p001", "instrument": "PHQ-9", "window_months": 24 }openemr_health_trajectoryAggregate all metric trajectories and compute clinical drift alerts.
{ "patient_id": "p001", "window_months": 24 }openemr_visit_prepGenerate a pre-visit clinical brief: top risks, medication safety, care gaps, and suggested agenda.
{ "patient_id": "p001", "window_months": 24 }# 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-mcpsrc/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.
MIT — see LICENSE.
Pull requests welcome. Please open an issue first for major changes.
This project is part of the AgentForge OpenEMR AI toolkit.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.