MCP server for OpenEMR — patient, medication, FDA drug safety, and clinical trajectory tools for Claude Desktop, Cursor, and any MCP-compatible AI client
OpenEMR MCP has 17 well-named tools with generally clear descriptions and complete input schemas. Naming follows verb_noun patterns (search, list, create, update, delete), which is excellent. Descriptions are substantive (80-200 chars typical) and explain intent well. All 17 tools have documented input schemas with typed parameters. However, critical gaps exist: (1) NO output schemas are documented, LLMs cannot infer what fields to expect from responses, forcing manual parsing; (2) No error handling guidance, tools lack recovery instructions or classification (retryable vs user-fixable); (3) Missing parameter descriptions for optional params in some tools (e.g., openemr_lab_trends metrics/window_months have descriptions, but semantic clarity on defaults could be stronger); (4) No tool annotations (readOnlyHint, destructiveHint, idempotentHint), destructive tools (delete, update) do not declare their risk profile via metadata; (5) No evidence of parameter validation rules or constraints beyond enums where present; (6) Some tools accept open-ended arrays without documented limits (e.g., openemr_drug_interaction_check accepts unbounded medication array). Overall structure is solid but lacks the production-grade robustness of A-tier tools.
List upcoming appointments for a patient.
Check a list of medications for known drug-drug interactions. Returns severity-classified interactions.
Create a drug safety flag for a patient (adverse event, recall, warning, contraindication, or custom note).
Delete a drug safety flag by ID.
List all drug safety flags for a patient, optionally filtered by status.
Update a drug safety flag's severity, description, or status.
No output schemas documented for any of the 17 tools. LLMs cannot infer response structure, field names, or types. This forces manual parsing and increases hallucination risk.
No error handling guidance. Tools do not document what errors can occur, whether they are retryable, or what the LLM should do next (e.g., search_first, ask_user, abort). This violates the recovery-guide pattern.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 66 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 48 | - | v1 |
Query FDA FAERS database for adverse event reports on a drug.
Retrieve official FDA drug label including boxed warnings, contraindications, and indications.
Synthesize a patient's clinical health trajectory: demographics, current vitals, lab trends, active medications, recent appointments, and key alerts.
Return longitudinal lab trajectories for a patient (A1c, LDL, eGFR).
Return the current medication list for a patient.
Search OpenEMR patients by name. Returns matching patient records with ID, DOB, sex, and city.
Search for healthcare providers by specialty and/or location.
Return longitudinal questionnaire score trajectories for a patient (PHQ-9 depression screening).
Look up possible conditions for a list of symptoms. Returns ranked conditions with urgency level and medical disclaimer.
Prepare for an upcoming patient visit: patient overview, current problems, recent labs, medications, allergies, and active safety flags.
Return longitudinal vital sign trajectories for a patient (weight, BP systolic/diastolic).
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) present. Destructive tools (openemr_drug_safety_flag_delete, openemr_drug_safety_flag_update) do not declare their risk profile, forcing LLMs to infer from names alone.
openemr_drug_interaction_check accepts unbounded array of medications with no documented size limit. An LLM could pass 1000+ drugs, causing performance or API degradation. Missing constraint documentation.
openemr_provider_search has two optional parameters (specialty, location) with no guidance on mutual exclusivity or combined behavior. Description does not explain: are both required? Can one be omitted? What is the result if both are omitted?
Several tools return data with no pagination support (openemr_medication_list, openemr_fda_adverse_events, openemr_symptom_lookup). If results exceed context window, LLM cannot navigate them. Missing limit/offset or cursor parameters and total count in responses.
No evidence of input validation or parameter constraints in tool implementations (based on code review). Type checking exists (string, integer), but no length limits, regex patterns, or format validation documented or visible in schemas.