openemr-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@openemr-mcpCheck for drug interactions in Jane Doe's medication list"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
openemr-mcp
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 |
|
Appointments |
|
Medications |
|
Providers |
|
FDA Safety |
|
Symptom Lookup |
|
Drug Safety Flags |
|
Clinical Trends |
|
Health Trajectory |
|
Visit Prep |
|
All tools work in mock mode out of the box — no OpenEMR installation required for evaluation.
Related MCP server: FHIR MCP Server
Quick Start
Install
pip install openemr-mcp
# or with uv:
uv add openemr-mcpRun (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-mcpClaude 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 |
| Built-in curated demo data — 24 patients, no network required |
| Direct MySQL connection to OpenEMR database |
| OpenEMR FHIR R4 REST API (recommended for production) |
Drug Interactions (DRUG_INTERACTION_SOURCE)
Value | Description |
| 10 built-in drug pairs — always works, no network |
| 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. |
| ⚠️ DEPRECATED/UNAVAILABLE — RxNorm interaction API endpoints retired (returns 404) |
Symptom Checker (SYMPTOM_SOURCE)
Value | Description |
| Curated local dataset — 10 clinical groups |
| Infermedica Symptom Checker API (register here) — free tier 100 calls/day |
FDA Data (OPENFDA_SOURCE)
Value | Description |
| Built-in mock data for 6 common drugs |
| 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-mcpArchitecture
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.
Available Tools
17 toolsopenemr_appointment_listC
List upcoming appointments for a patient.
| Name | Required | Description | Default |
|---|---|---|---|
| patient_id | Yes | OpenEMR patient ID (e.g., 'p001') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description bears full burden. It indicates a read operation but does not disclose behavior for edge cases (no appointments, invalid patient ID, permissions) or whether it includes cancelled appointments.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no fluff. Slightly improved by adding context about what 'upcoming' means (e.g., within a certain timeframe) but remains efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequate for a simple list tool with one parameter and no output schema, but lacks details on return format or behavior when no appointments exist.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single parameter (patient_id already described). The description adds no extra meaning beyond the schema, achieving baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists upcoming appointments for a patient, using specific verb 'list' and resource 'appointments'. It is distinct from sibling tools that handle medications, labs, etc.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs alternatives, such as openemr_visit_prep or openemr_patient_search. Context signals show many siblings, but description does not help selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_drug_interaction_checkA
Check a list of medications for known drug-drug interactions. Returns severity-classified interactions.
| Name | Required | Description | Default |
|---|---|---|---|
| medications | Yes | List of drug names to check for interactions |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description mentions returning severity-classified interactions but lacks details on read-only nature, error handling, or potential limitations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no filler. Front-loaded with purpose and result description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema; description only vaguely states 'severity-classified interactions'. Lacks detail on result structure, error conditions, or usage context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers the single parameter 'medications' with description. Description adds no extra meaning beyond what schema provides, but is consistent with it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states verb 'Check', resource 'medications', and outcome 'returns severity-classified interactions'. Distinguishes from sibling tools like drug safety flags or FDA adverse events.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use vs. alternatives. Does not mention prerequisites or exclusion criteria for specific scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_drug_safety_flag_createB
Create a drug safety flag for a patient (adverse event, recall, warning, contraindication, or custom note).
| Name | Required | Description | Default |
|---|---|---|---|
| patient_id | Yes | OpenEMR patient ID | |
| drug_name | Yes | Name of the drug being flagged | |
| description | Yes | Clinical description of the safety concern | |
| flag_type | No | adverse_event | |
| severity | No | MODERATE | |
| source | No | AGENT |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavioral traits. It only states the basic creation action without explaining side effects, idempotency, permissions, or duplicate handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the action and resource. No unnecessary words or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 6 parameters and no output schema, yet the description omits return value information, constraints (e.g., patient_id must exist), and any post-creation behavior. Significant gaps remain for correct tool invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaning for flag_type by listing its enum values, but does not explain severity or source. Schema coverage is 50%, so the description partially compensates but is insufficient for all parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Create'), the resource ('drug safety flag for a patient'), and explicitly lists the flag types. The verb 'Create' distinguishes it from sibling tools like delete, update, and list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives (e.g., drug interaction check). It does not mention prerequisites or exclusions, leaving the agent without context for appropriate selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_drug_safety_flag_deleteB
Delete a drug safety flag by ID.
| Name | Required | Description | Default |
|---|---|---|---|
| flag_id | Yes | UUID of the flag to delete |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description only states 'delete' with no details on behavioral traits like irreversibility, cascading effects, or authorization needs. Since annotations are absent, the description carries the full burden but provides minimal transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence with no unnecessary words. It is front-loaded with the action and resource.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a deletion tool with no output schema and no annotations, the description lacks completeness. It does not mention error cases, idempotency, or what happens if the flag does not exist. This information would be valuable for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers the single parameter 'flag_id' with a clear description. The tool description adds no additional meaning beyond the schema, so a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (delete) and the resource (drug safety flag) and specifies the means (by ID). This distinguishes it from sibling tools like create, update, and list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives, such as when to delete versus update or when deletion is irreversible. The description lacks any context about prerequisites or scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_drug_safety_flag_listA
List all drug safety flags for a patient, optionally filtered by status.
| Name | Required | Description | Default |
|---|---|---|---|
| patient_id | Yes | OpenEMR patient ID | |
| status_filter | No | Filter by flag status (optional) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It states it lists flags but does not disclose ordering, pagination, or behavior for missing patient. Adequate for a simple list but lacks detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no wasted words, perfectly concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with two parameters and no output schema, the description is adequate. It covers the core functionality but could mention return format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions. The description restates the filtering capability already present in schema, adding no new meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'list all drug safety flags for a patient' with optional filtering, specifying verb, resource, and scope. It distinguishes itself from sibling tools like create, update, delete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use vs alternatives. While listing is implied, there is no mention of when not to use or comparison to sibling list tools like openemr_medication_list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_drug_safety_flag_updateB
Update a drug safety flag's severity, description, or status.
| Name | Required | Description | Default |
|---|---|---|---|
| flag_id | Yes | UUID of the flag to update | |
| severity | No | ||
| description | No | ||
| status | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden, but it only states that the tool updates fields. It does not disclose behavior such as whether omitted fields remain unchanged, if the update is atomic, or what the response contains. The mutation intent is clear but insufficient detail for safe use.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence of 8 words, which is efficient. However, it sacrifices important behavioral details that could be added without significant bloat. It scores high for conciseness but not for completeness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 4 parameters (1 required), no output schema, and no annotations, the description is incomplete. It fails to clarify update semantics (partial vs full), error conditions, or response format. Compared to sibling mutation tools, it lacks necessary context for an agent to use it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 25% (flag_id only). The description adds by listing the updatable fields (severity, description, status) but does not explain enum values or the meaning of the description field. It provides marginal value over the schema, but does not fully compensate for low coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Update' and the resource 'drug safety flag', and lists the specific fields (severity, description, status) that can be updated. This distinguishes it from sibling tools like create, delete, and list, providing a clear purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. It does not mention prerequisites (e.g., flag must exist), nor does it explain whether updates are partial or full replacements. Context like 'to update only specific fields, omit others' is missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_fda_adverse_eventsB
Query FDA FAERS database for adverse event reports on a drug.
| Name | Required | Description | Default |
|---|---|---|---|
| drug_name | Yes | Generic or brand name of the drug | |
| limit | No | Max number of top reactions to return (default 5) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavioral traits. It only states 'Query' (implying read-only) but does not mention rate limits, data freshness, pagination, or whether results are limited to top reactions. The description lacks depth for safety-critical adverse event data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and to the point, using a single clear sentence. No redundant information. It is appropriately front-loaded and efficient, though it could be slightly more informative without losing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (simple query with two parameters) and lack of output schema/annotations, the description is too minimal. It does not explain what the returned data looks like (e.g., structure of top reactions), pagination, or error handling. A more complete description would include typical fields or behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema coverage is 100%, so parameters are well-defined. The description does not add extra meaning beyond the schema; 'drug_name' and 'limit' are adequately explained in schema properties. Baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Query' and the specific resource 'FDA FAERS database for adverse event reports on a drug.' It distinguishes from sibling tools like openemr_fda_drug_label and openemr_drug_safety_flag_* by focusing on adverse events.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It does not mention exclusions, prerequisites, or compare with siblings such as openemr_fda_drug_label. The usage context is implied but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_fda_drug_labelA
Retrieve official FDA drug label including boxed warnings, contraindications, and indications.
| Name | Required | Description | Default |
|---|---|---|---|
| drug_name | Yes | Generic or brand name of the drug |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description bears full responsibility for disclosing behavior. It describes the operation as 'Retrieve', implying a safe read operation, but does not mention potential issues like missing data for certain drugs, API rate limits, or return format. The description is adequate but minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single 14-word sentence that clearly states the action and scope. Every word serves a purpose, and it is front-loaded with the main action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool (single parameter, no output schema), the description covers the key purpose and contents of the label. It is mostly complete, though it could mention that the response includes the full label text or structure, but this is not a significant omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with a description for 'drug_name' ('Generic or brand name of the drug'). The tool description adds no further detail about the parameter beyond what the schema already provides, so a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Retrieve' and clearly identifies the resource as 'official FDA drug label', with explicit mention of contents (boxed warnings, contraindications, indications). This distinguishes it from sibling tools like drug interaction check (openemr_drug_interaction_check) and adverse events (openemr_fda_adverse_events).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided about when to use this tool versus alternatives (e.g., for drug interactions or adverse events). The description simply states what it does without any conditional or contextual advice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_health_trajectoryA
Aggregate all metric trajectories (labs, vitals, questionnaires) and compute clinical drift alerts for a patient.
| Name | Required | Description | Default |
|---|---|---|---|
| patient_id | Yes | OpenEMR patient ID | |
| window_months | No | Lookback window in months (default 24) | |
| metrics | No | Subset of metrics to include (default: all) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds behavioral context by mentioning aggregation and alerts, but no annotations provided and does not disclose read-only nature or any side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, concise, front-loaded with purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Description covers purpose but lacks output format details and prerequisites; no output schema to compensate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and description adds no additional parameter meaning beyond what schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States it aggregates metric trajectories and computes clinical drift alerts for a patient, clearly differentiating from sibling trend-specific tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies use for aggregated overview and alerts, but lacks explicit guidance on when to use vs individual trend tools or when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_lab_trendsC
Return longitudinal lab trajectories for a patient (A1c, LDL, eGFR).
| Name | Required | Description | Default |
|---|---|---|---|
| patient_id | Yes | OpenEMR patient ID | |
| metrics | No | Metrics to return (default: all) | |
| window_months | No | Lookback window in months (default 24) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It only mentions returning trajectories, but does not explain behavior for missing patients, empty data, or error handling. No read-only hint is given.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence (8 words) that is front-loaded with the key purpose. It is not verbose, but could benefit from slight expansion without losing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description is insufficiently complete. It does not mention the format of returned trajectories, pagination, or edge cases, leaving the agent without critical operational context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, so the description adds no extra meaning beyond what the schema already provides. The baseline score of 3 is appropriate as the schema effectively documents parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns longitudinal lab trajectories for a patient, listing specific metrics (A1c, LDL, eGFR). It distinguishes from siblings like 'openemr_vital_trends' by focusing on labs, but does not explicitly contrast with other similar tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives, nor any prerequisites or contraindications. The description lacks context for appropriate usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_medication_listA
Return the current medication list for a patient.
| Name | Required | Description | Default |
|---|---|---|---|
| patient_id | Yes | OpenEMR patient ID (e.g., 'p001') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavior. It only states the return value but omits details like read-only nature, permissions, or side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no filler, front-loaded with the core purpose. Efficiently communicates the tool's function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple retrieval tool with one parameter and no output schema, the description is adequate but could mention output format or example to compensate for missing schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a descriptive example for patient_id. The description adds no further meaning beyond the schema, earning a baseline score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Return') and the resource ('current medication list for a patient'), making it distinct from sibling tools. No ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context (needs a patient_id) but provides no explicit guidance on when to use this tool over siblings or any prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_patient_searchA
Search OpenEMR patients by name. Returns matching patient records with ID, DOB, sex, and city.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Patient name or partial name to search for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It indicates the tool performs a read operation and returns specific fields, but does not disclose limitations like pagination or case sensitivity. Adequate for a simple search tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no extraneous information. Front-loaded with purpose and return fields. Efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, description adequately documents return fields (ID, DOB, sex, city). Covers purpose and output comprehensively for a simple patient search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with one parameter 'query' described as 'Patient name or partial name'. Description adds value by specifying partial matching, beyond the schema's basic description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the verb (search), resource (OpenEMR patients), and returns specific fields (ID, DOB, sex, city). Differentiates from siblings like openemr_provider_search (search providers) and openemr_appointment_list (list appointments).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implied usage for searching patients by name, but no explicit guidance on when to use this vs alternatives (e.g., openemr_provider_search). No exclusions or conditions provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_provider_searchA
Search for healthcare providers by specialty and/or location.
| Name | Required | Description | Default |
|---|---|---|---|
| specialty | No | Medical specialty (e.g., 'Cardiology') | |
| location | No | City or facility name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full burden. It states 'search' (read-only behavior) but does not explicitly confirm read-only nature, or mention any potential side effects, rate limits, or performance considerations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single, concise sentence of 10 words that immediately conveys the tool's purpose. No extraneous information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequate for a simple search tool with optional parameters. However, lacks details on result format, pagination, or matching behavior. With no output schema, some additional context would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with built-in parameter descriptions. The tool description adds no additional meaning beyond schema definitions. Baseline 3 is appropriate as per guidelines for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly specifies the action (search), resource (healthcare providers), and filters (specialty and/or location). It distinguishes from sibling tools like 'patient_search' which targets patients, and other tools focus on different resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description implies usage via search by specialty or location but provides no explicit guidance on when to use this vs alternatives like 'patient_search'. No context on exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_questionnaire_trendsA
Return longitudinal questionnaire score trajectories for a patient (PHQ-9 depression screening).
| Name | Required | Description | Default |
|---|---|---|---|
| patient_id | Yes | OpenEMR patient ID | |
| instrument | No | Questionnaire name (default 'PHQ-9') | PHQ-9 |
| window_months | No | Lookback window in months (default 24) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility. It does not disclose behavioral traits such as read-only nature, output format, rate limits, or required permissions. Only the basic retrieval function is implied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence of 10 words, directly stating the core function. No extraneous information; perfectly concise and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains the purpose and gives an example but lacks details about the return format (e.g., array of scores with timestamps). Since there is no output schema, the description should provide more context about what 'trajectories' means. Adequate but incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with clear descriptions for all three parameters. The description adds minimal extra value (e.g., PHQ-9 context) but is not necessary for understanding the parameters. Baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'Return' and resource 'longitudinal questionnaire score trajectories' with specific example 'PHQ-9 depression screening'. This distinguishes it from sibling tools like lab_trends or vital_trends, which deal with different metrics.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use or alternatives are given. Usage is implied by the tool name and description focusing on questionnaire trends, but there is no guidance on when not to use it versus other trend tools like openemr_health_trajectory.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_symptom_lookupA
Look up possible conditions for a list of symptoms. Returns ranked conditions with urgency level and medical disclaimer.
| Name | Required | Description | Default |
|---|---|---|---|
| symptoms | Yes | List of symptom descriptions (e.g., ['chest pain', 'shortness of breath']) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It describes the tool as a lookup (non-destructive) and mentions a medical disclaimer, which adds transparency. However, it does not disclose other behavioral traits like authentication needs or rate limits, which would be expected for a medical lookup tool. The description is honest but could be more comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the main action, and no extraneous information. Every sentence earns its place: first sentence states purpose, second states returns. No waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one required parameter, no output schema, and clear purpose), the description is complete. It specifies input format with example, expected returns (ranked conditions, urgency, disclaimer), and the context among sibling tools is clear. No additional details are needed for an agent to use it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage, the baseline is 3. The tool description adds no additional parameter meaning beyond what the schema already provides (the schema already describes the 'symptoms' parameter with an example). The description does not compensate further, so a 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Look up' and resource 'possible conditions for a list of symptoms'. It distinguishes itself from other sibling tools (e.g., appointment, drug) by focusing on symptom-based condition lookup, and it specifies output includes ranked conditions with urgency and disclaimer, leaving no ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context: for obtaining possible conditions from symptoms. However, it lacks explicit when-to-use or when-not-to-use guidance, and no alternatives are mentioned. Given it's the only symptom tool among siblings, the purpose is self-evident, so a 3 for implied usage is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_visit_prepA
Generate a pre-visit clinical brief for a patient: top risks, medication safety, care gaps, and suggested agenda. Evidence-linked, no hallucination.
| Name | Required | Description | Default |
|---|---|---|---|
| patient_id | Yes | OpenEMR patient ID | |
| window_months | No | Clinical data lookback window in months (default 24) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations; description claims evidence-linking and no hallucination but does not disclose side effects, whether it modifies data, or if it's read-only.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence with clear front-loading of purpose and key output components; effectively concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Missing output format details (e.g., text vs. JSON); with no output schema, description should clarify what the brief looks like and any additional context needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers both parameters fully; description adds no additional meaning beyond the schema, though it mentions output components not linked to parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool generates a pre-visit clinical brief listing top risks, medication safety, care gaps, and agenda. It differentiates from sibling tools which focus on specific data retrieval or actions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies use for pre-visit planning but lacks explicit when/when-not guidance or comparison to sibling tools like medication list or drug interaction check.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openemr_vital_trendsB
Return longitudinal vital sign trajectories for a patient (weight, BP systolic/diastolic).
| Name | Required | Description | Default |
|---|---|---|---|
| patient_id | Yes | OpenEMR patient ID | |
| metrics | No | Metrics to return (default: all) | |
| window_months | No | Lookback window in months (default 24) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It implies a read operation but lacks details on output format, sorting, or handling of missing data. Some transparency is present (returns trajectories), but more depth would be beneficial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that is front-loaded. Every word adds value; no waste. Could be slightly more structured, but already efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a straightforward data retrieval tool with no output schema, the description covers the core purpose. However, it lacks details on output format or usage context, making it adequate but not complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with each parameter described. The description adds minimal extra value by listing the metrics, but does not enhance meaning beyond the schema. Baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns longitudinal vital sign trajectories for a patient, specifying the metrics (weight, BP systolic/diastolic). It effectively distinguishes from sibling tools like openemr_lab_trends or openemr_health_trajectory, which focus on other data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide guidance on when to use this tool versus alternatives, such as openemr_health_trajectory or openemr_lab_trends. No exclusions or prerequisites are mentioned, leaving the agent to infer usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
17 tool updates
v0.1.0- First observed
openemr_appointment_list - First observed
openemr_drug_interaction_check - First observed
openemr_drug_safety_flag_create - First observed
openemr_drug_safety_flag_delete - First observed
openemr_drug_safety_flag_list - First observed
openemr_drug_safety_flag_update - First observed
openemr_fda_adverse_events - First observed
openemr_fda_drug_label - First observed
openemr_health_trajectory - First observed
openemr_lab_trends - First observed
openemr_medication_list - First observed
openemr_patient_search - First observed
openemr_provider_search - First observed
openemr_questionnaire_trends - First observed
openemr_symptom_lookup - First observed
openemr_visit_prep - First observed
openemr_vital_trends
TDQS
Scored across 17 tools
Most tools target clearly distinct resources: patient lookup, medications, appointments, drug label/adverse events, symptom lookup, and safety flag CRUD. The only mild overlap is between health_trajectory and the three specific trend tools, but their descriptions make the aggregate-vs-specific distinction clear enough for a capable agent.
Naming is inconsistent: CRUD operations use an object_action pattern (drug_safety_flag_create, drug_safety_flag_update) while most reads use noun phrases like medication_list, provider_search, and vital_trends. All names share the openemr_ prefix and snake_case, but the placement of the action is not predictable across the toolset.
17 tools is slightly above the typical 3-15 range, but the count is defensible for a clinical workflow server that combines EHR data, FDA lookups, and medication safety. Each tool covers a distinct resource or operation, so none feel like filler.
The toolset forms a coherent clinical pre-visit and drug-safety workflow: patient search, medication/appointment review, interaction checks, symptom lookup, trend tracking, and visit prep. Gaps like patient creation or appointment scheduling exist, but the apparent focus on read-side analysis and safety flagging is well covered.
Maintenance
Related MCP Connectors
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
Hosted MCP server for Cliniko — patients, appointments, availability, and invoices for AI agents.
Hosted MCP server exposing US hospital procedure cost data to AI assistants
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceA production-grade MCP server that enables AI assistants to securely manage healthcare data through clinical tools for patient vitals, lab results, and medication ordering. It prioritizes security and compliance with features like HIPAA-ready audit logging, PII redaction, and role-based access control.-
- FlicenseNot gradedqualityDmaintenanceA comprehensive MCP server that bridges AI applications with FHIR healthcare data systems, enabling patient data access, clinical data retrieval, and data quality assessment.4-
- AlicenseAqualityAmaintenanceMCP server for Tebra practice management that gives AI agents access to 45 tools for patients, appointments, billing, documents, and clinical data via SOAP and FHIR APIs.33231 npm1MIT

LangCare MCP FHIR Serverofficial
AlicenseNot gradedqualityDmaintenanceEnterprise-grade MCP Server for FHIR-based EMRs. Enables AI agents to read, search, create, and update any FHIR R4 resource across major EHR systems like EPIC, Cerner, and OpenEMR.147 npm54MIT