Search and query patient Electronic Health Record (EHR) data using SMART on FHIR.
https://youtu.be/K0t6MRyIqZU?si=Mz4d65DcAD3i2YbO
This project acts as a specialized server providing tools for Large Language Models (LLMs) and other AI agents to interact with Electronic Health Records (EHRs). It leverages the SMART on FHIR standard for secure data access and the Model Context Protocol (MCP) to expose the tools.
Think of it as a secure gateway and toolkit enabling AI to safely access and analyze patient data from diverse EHR systems.
The system works in three main stages:
The MCP Server offers several tools for interacting with the loaded EHR data:
grep_record
: Performs text or regular expression searches across all parts of the fetched record (structured FHIR data + text from notes/attachments). Ideal for finding keywords or specific mentions (e.g., "diabetes", "aspirin").query_record
: Executes read-only SQL SELECT
queries directly against the structured FHIR data. Useful for precise lookups based on known FHIR resource structures (e.g., finding specific lab results by LOINC code).eval_record
: Executes custom JavaScript code directly on the fetched data (FHIR resources + attachments). Offers maximum flexibility for complex calculations, combining data from multiple sources, or custom formatting.This setup allows AI tools to leverage comprehensive EHR data through a standardized and secure interface.
(Developer setup and usage details can be found within the codebase and specific module documentation.)
This project offers different ways to fetch EHR data and expose it via MCP tools:
This project includes a self-contained web application that allows users to connect to their EHR via SMART on FHIR and fetch their data.
https://mcp.fhir.me/ehr-connect#deliver-to-opener:$origin
$origin
with the actual origin of the window that opens this link).?brandTags
): You can filter the list of EHR providers shown on the connection page by adding the brandTags
query parameter to the URL. Provide a comma-separated list of tags. Only brands matching all provided tags (from their configuration in brandFiles
) will be displayed.
It supports both OR (comma-separated) and AND (caret ^
separated) logic, with AND taking precedence.
?brandTags=epic,sandbox
: Shows brands tagged with epic
OR sandbox
.?brandTags=epic^dev
: Shows brands tagged with both epic
AND dev
.?brandTags=epic^dev,sandbox^prod
: Shows brands tagged with (epic
AND dev
) OR (sandbox
AND prod
).prod
..../ehr-connect?brandTags=hospital^us
: Shows brands tagged with hospital
AND us
.DocumentReference
).ClientFullEHR
): Once fetching is complete, the client gathers all the data into a ClientFullEHR
JSON object. This object contains:
fhir
: A dictionary where keys are FHIR resource types (e.g., "Patient") and values are arrays of the corresponding FHIR resources.attachments
: An array of processed attachment objects, each including metadata (source resource, path, content type) and the content itself (contentBase64
for raw data, contentPlaintext
for extracted text).#deliver-to-opener:$origin
hash, the client will prompt the user for confirmation and then send the ClientFullEHR
object back to the window that opened it using window.opener.postMessage(data, targetOrigin)
.src/cli.ts
)This mode is ideal for running the MCP server locally, often used with tools like Cursor or other command-line AI clients.
--create-db
and --db
flags. This starts a temporary web server and uses the same SMART on FHIR web client logic described above to fetch data. Instead of sending the data via postMessage
, it saves the ClientFullEHR
data into a local SQLite database file.
# Example: Fetch data and save to data/my_record.sqlite
bun run src/cli.ts --create-db --db ./data/my_record.sqlite
Follow the prompts (opening a link in your browser) to connect to your EHR.# Example: Start the MCP server using the saved data
bun run src/cli.ts --db ./data/my_record.sqlite
config.*.json
): This process relies on a configuration file (e.g., config.epicsandbox.json
) which defines available EHR brands/endpoints in a brandFiles
array. Each entry in this array specifies the brand's details, including:
url
: Path/URL to the brand definition file (like static/brands/epic-sandbox.json
).tags
: An array of strings (e.g., ["epic", "sandbox"]
) used for categorization or filtering.vendorConfig
: Contains SMART on FHIR client details (clientId
, scopes
).src/cli.ts
and the database file.
{
"mcpServers": {
"local-ehr": {
"name": "Local EHR Search",
"command": "bun", // Or the absolute path to bun
"args": [
"/home/user/projects/smart-mcp/src/cli.ts", // Absolute path to cli.ts
"--db",
"/home/user/projects/smart-mcp/data/my_record.sqlite" // Absolute path to DB file
]
}
}
}
src/sse.ts
/ index.ts
)This mode runs a persistent server suitable for scenarios where multiple clients might connect over the network. It uses Server-Sent Events (SSE) for the MCP communication channel.
/authorize
, /token
, /register
, etc.).ClientFullEHR
data during the authorization process, and keeps it in memory (or a persisted session) for the duration of the client's connection.Query your ClickHouse database server.
A Model Context Protocol Server for MongoDB
A read-only MCP server to query live Adobe Analytics data. Requires the CData JDBC Driver for Adobe Analytics.
Official MCP server for dbt (data build tool) providing integration with dbt Core/Cloud CLI, project metadata discovery, model information, and semantic layer querying capabilities.
Universal database MCP server supporting mainstream databases.
Allows Claude AI to interact directly with MySQL databases.
An MCP server for Firebird SQL databases, enabling LLMs to securely access, analyze, and manipulate database content.
An MCP-based database server with support for SQLite, MySQL, PostgreSQL, and MSSQL.
Interact with Microsoft SQL Server (MSSQL) databases. List tables, read data, and execute SQL queries with controlled access.
Interact with the microCMS headless CMS API, enabling AI assistants to manage content.