MCP server using SMART on FHIR (Public Client) via Bun to search/query patient EHR data.
The Health Record MCP server demonstrates solid definition quality with well-documented tools for healthcare EHR data access. All 5 tools have explicit descriptions and input schemas. Strengths: clear action verbs (grep_, query_, eval_, read_), detailed parameter descriptions with context and examples, comprehensive input schemas with proper typing. Weaknesses: missing output schema documentation (critical for LLM planning), no error handling guidance, no tool annotations (readonly hints), and eval_record exposes code execution which needs security documentation. The parameter descriptions are verbose (50-300 chars) and contextual, which is good for EHR domain specificity but occasionally buries key constraints. Composition is clean, each tool has one responsibility. However, the lack of visible output schema definitions and error recovery patterns prevents a higher score.
A string containing the body of an async JavaScript function. This function receives the following arguments: 1. 'fullEhr': An object containing the patient's EHR data (ClientFullEHR format) with 'fullEhr.fhir' (FHIR resource types mapped to arrays) and 'fullEhr.attachments' (processed attachment objects). 2. 'console': A limited console object with 'log', 'warn', and 'error' methods. 3. '_': The Lodash library (v4). 4. 'Buffer': The Node.js Buffer class. The function MUST conclude with a 'return' statement specifying the JSON-serializable value to send back.
The text string or JavaScript-style regular expression to search for (case-insensitive). Example: 'heart attack|myocardial infarction|mi'. Best for finding specific text/keywords or variations across *all* record parts (FHIR+notes). Use regex with `|` for related terms (e.g., `'diabetes|diabetic'`).
The read-only SQL SELECT statement to execute against the in-memory FHIR data. FHIR resources are stored in the 'fhir_resources' table with columns 'resource_type', 'resource_id', and 'json'. For example, 'SELECT json FROM fhir_resources WHERE resource_type = "Patient"' or 'SELECT json FROM fhir_resources WHERE resource_type = "Observation" AND json LIKE "%diabetes%"'. Best for precisely selecting specific FHIR resources or fields using known structure (e.g., Observations by LOINC). Limited to structured FHIR data.
Read the content of an attachment from a DocumentReference or similar resource. Returns plaintext or base64-encoded binary content.
Output schemas are completely undocumented across all 5 tools. LLMs cannot plan downstream operations without knowing the response structure (fields, types, pagination). This violates pattern:tool and pattern:response-shaper.
query_record exposes direct SQL interface without input validation constraints documented. No mention of sanitization, allowed keywords, injection prevention, or SQL dialect restrictions. Violates pattern:tool-gateway and pattern:secret-injection (SQL queries could leak sensitive data).
eval_record allows arbitrary JavaScript code execution. Description lacks explicit warnings about execution timeouts, resource limits, sandboxing, or code safety constraints. This is a critical security and operational boundary that must be documented. Violates pattern:tool-gateway.
Inferred effective spec: 2025-06-18+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 63 | 2025-06-18+ | v2 |
| 2026-03-09 | F | 30 | - | v1 |
Read a specific FHIR resource by type and ID. Returns the resource in the requested format (plaintext or JSON).
No error handling guidance across any tool. Descriptions do not explain how to recover from 'resource not found', 'invalid regex', 'malformed attachment', or 'SQL syntax error'. Violates pattern:recovery-guide and pattern:error-classification.
No tool annotations (readonly, destructive, idempotent hints) in the schema. All 5 tools are read-only but this is not formally declared. Tools should have readOnlyHint=true in their definitions per current MCP spec. Violates pattern:tool-annotation.
Parameter descriptions occasionally include example values (e.g., grep_record query param shows 'heart attack|myocardial infarction|mi', read_attachment shows 'content[0].attachment'). LLMs tend to reuse example values literally. Should replace with formal constraints (enum, pattern, format). Violates pattern:constrained-input.
read_resource and read_attachment parameters use generic strings (resource_type, resource_id) but descriptions don't clarify expected format. For resource_type, should suggest that only valid FHIR types are accepted (and list common ones). For resource_id, should clarify format (UUID, alphanumeric, etc.). Violates pattern:tool-description.
grep_record has complex conditional behavior for resource_types parameter (omitted=search all, array of FHIR types=filtered, ["Attachment"]=attachments only, mixed list=FHIR+all attachments). This conditional dependency is explained in the description but is error-prone. Should simplify or add explicit enum-style options. Violates pattern:tool-description (undocumented conditional logic).