@securecloudnetworks/ehr-adapter-sdk
v1.0.2
Published
Open-source TypeScript SDK for EHR integrations with FHIR 4.0.1 compatibility. Mock adapter included for development and testing.
Maintainers
Readme
EHR Adapter SDK
Ship EHR integrations in days, not months.
Production-ready TypeScript SDK for multi-vendor FHIR R4 integration. Start free with MockAdapter — go live with Epic, Athena, Cerner, and Health Gorilla on a commercial license.
Quick Start
npm install @securecloudnetworks/ehr-adapter-sdk
```typescript
import { MockAdapter } from "@securecloudnetworks/ehr-adapter-sdk";
const adapter = new MockAdapter({
vendor: "mock",
baseUrl: "http://localhost:3001",
auth: { type: "apikey", apiKey: "dev-key" },
});
const patient = await adapter.getPatient("patient-001");
const vitals = await adapter.getVitals("patient-001");
const meds = await adapter.getMedications("patient-001");
const schedule = await adapter.getAppointments("patient-001");
console.log(`${patient.name?.[0]?.given?.[0]} ${patient.name?.[0]?.family}`);
// → "James Smith"That's it. No EHR credentials, no sandbox accounts, no NDAs — just working FHIR data in your local environment.
What's Included (MIT — Free)
Core Architecture
EHRAdapterinterface — the unified contract all adapters implementBaseAdapter— HTTP client, automatic retries, circuit breaker, audit loggingAdapterFactory— create adapters by vendor name
Single-tenant only. Multi-tenant isolation is a commercial feature — see Multi-Tenant Support below.
Authentication
ApiKeyProvider— API key auth (header, query param, or cookie)BearerTokenProvider— JWT/Bearer token auth with validation
Type System
- Complete FHIR R4 TypeScript types: Patient, Observation, Appointment, MedicationRequest, AllergyIntolerance, Condition, Procedure, Immunization, Practitioner, Organization, Bundle, CapabilityStatement
- Full error hierarchy:
AuthError,RateLimitError,ResourceNotFoundError,TenantIsolationError,FHIRValidationError, and more - Builder-pattern config types for adapters and tenants
Plugin System
TransformationPipeline— pre/post processors and validation pipeline
MockAdapter
- Full EHR simulation with realistic FHIR data (patients, vitals, labs, medications, appointments)
- Configurable delay, error rate, and dataset size for testing every scenario
- No external dependencies — works offline
Utilities
- HTTP client with retries, timeout, and circuit breaker
- Zod-based FHIR resource validator
- AES-256-GCM encryption, HMAC, key derivation
- HIPAA-compliant structured and audit logging
- HIPAA/GDPR compliance event logging with breach detection
- Environment config loader
Tests: automated suite, CI-verified on every push.
Feature Comparison
| Feature | MIT (Free) | Developer$99/mo | Professional$299/mo | Enterprise | |---|:---:|:---:|:---:|:---:| | MockAdapter | ✅ | ✅ | ✅ | ✅ | | Core SDK + Types | ✅ | ✅ | ✅ | ✅ | | Plugin System | ✅ | ✅ | ✅ | ✅ | | HIPAA Audit Logging | ✅ | ✅ | ✅ | ✅ | | Epic MyChart (FHIR R4) | ❌ | ✅ | ✅ | ✅ | | Athena Health | ❌ | ✅ | ✅ | ✅ | | Cerner PowerChart | ❌ | ✅ | ✅ | ✅ | | Health Gorilla | ❌ | ❌ | ✅ | ✅ | | OAuth2 / SMART on FHIR | ❌ | ✅ | ✅ | ✅ | | LOINC / SNOMED Mapper | ❌ | ❌ | ✅ | ✅ | | AI Analytics Plugin | ❌ | ❌ | ✅ | ✅ | | GraphQL API Layer | ❌ | ❌ | ✅ | ✅ | | CLI Tools | ❌ | ❌ | ✅ | ✅ | | Advanced Security (JWT/HMAC) | ❌ | ✅ | ✅ | ✅ | | Priority Support | ❌ | ✅ | ✅ | ✅ | | SLA | ❌ | ❌ | ❌ | ✅ | | Dedicated Success Engineer | ❌ | ❌ | ❌ | ✅ |
MockAdapter Deep Dive
The MockAdapter is the free entry point — and it's not a toy. It simulates a real EHR with full FHIR R4 data so you can build your entire integration before touching a production system.
import { MockAdapter } from "@ehradapter/ehr-adapter-sdk";
const adapter = new MockAdapter({
vendor: "mock",
baseUrl: "http://localhost:3001",
auth: { type: "apikey", apiKey: "dev-key" },
delay: 150, // simulate real network latency (ms)
errorRate: 5, // simulate 5% of requests failing
dataSet: "comprehensive", // "minimal" | "standard" | "comprehensive"
});
await adapter.connect();
// Patient operations
const patient = await adapter.getPatient("patient-001");
const results = await adapter.searchPatients({ name: "Smith", gender: "female" });
// Clinical data
const vitals = await adapter.getVitals("patient-001", {
dateRange: { start: "2024-01-01", end: "2024-12-31" },
_count: 10,
});
const labs = await adapter.getLabs("patient-001");
const meds = await adapter.getMedications("patient-001");
const allergies = await adapter.getAllergies?.("patient-001");
// Scheduling
const upcoming = await adapter.getAppointments("patient-001", {
status: ["booked", "pending"],
});
// Custom queries
const summary = await adapter.executeCustomQuery({
type: "patient-summary",
parameters: { patientId: "patient-001" },
});
// System
const caps = await adapter.getCapabilities();
const health = await adapter.healthCheck();
await adapter.disconnect();Simulate failure scenarios
// Test your error handling before going to production
const flakyAdapter = new MockAdapter({
vendor: "mock",
baseUrl: "http://localhost:3001",
auth: { type: "apikey", apiKey: "dev-key" },
errorRate: 30, // 30% failure rate — stress test your retry logic
delay: 2000, // 2s latency — test your timeout handling
});
// Update config without re-instantiating
flakyAdapter.updateMockConfig({ errorRate: 0, delay: 50 });Architecture Overview
The SDK uses an adapter pattern: your application code talks to the EHRAdapter interface, and the adapter handles all vendor-specific logic. Switching vendors is a one-line config change.
Your Application
│
▼
EHRAdapter (interface)
│
├── MockAdapter (free, MIT)
├── EpicAdapter (commercial)
├── AthenaAdapter (commercial)
├── CernerAdapter (commercial)
└── HealthGorillaAdapter (commercial)Every adapter returns the same FHIR R4 types. Every error is the same EHRAdapterError hierarchy. Your integration code stays the same — you swap the adapter config when you're ready for production.
Multi-Tenant Support
Multi-tenant isolation is a commercial feature and is not available in this MIT package. This SDK builds single-tenant adapters only.
If you set tenant on an adapter config, or call getTenantAdapter(), the
call fails immediately:
import { EHRAdapterFactory } from "@securecloudnetworks/ehr-adapter-sdk";
EHRAdapterFactory.create("mock", {
vendor: "mock",
baseUrl: "http://localhost:3001",
auth: { type: "apikey", apiKey: "dev-key" },
tenant: { tenantId: "hospital-a", isolationLevel: "strict" },
});
// throws EHRAdapterError
// code: "COMMERCIAL_LICENSE_REQUIRED"
// message: "Multi-tenant support requires a commercial license
// — see https://ehradapter.com/pricing"This is deliberate. Returning a plain, non-isolated adapter would look like tenant isolation was in effect when it was not — in a healthcare context that is a PHI leak waiting to happen. The SDK fails loudly instead.
For per-tenant isolation, config, and audit logging across many customers,
use the commercial package @securecloudnetworks/ehr-adapter —
see pricing.
Environment Configuration
cp .env.example .env| Variable | Description | Default |
|---|---|---|
| MOCK_API_KEY | API key for MockAdapter | test-api-key |
| MOCK_BASE_URL | Base URL | http://localhost:3001 |
| MOCK_DELAY | Simulated latency (ms) | 100 |
| MOCK_ERROR_RATE | % of requests that fail | 0 |
| MOCK_DATA_SET | Dataset size | standard |
| NODE_ENV | Environment | development |
| LOG_LEVEL | Log verbosity | info |
| TENANT_ID | Demo tenant ID | demo-tenant |
const adapter = new MockAdapter({
vendor: "mock",
baseUrl: process.env.MOCK_BASE_URL || "http://localhost:3001",
auth: {
type: "apikey",
apiKey: process.env.MOCK_API_KEY || "dev-key",
},
delay: parseInt(process.env.MOCK_DELAY || "100"),
errorRate: parseFloat(process.env.MOCK_ERROR_RATE || "0"),
dataSet: (process.env.MOCK_DATA_SET as "minimal" | "standard" | "comprehensive") || "standard",
});Development
git clone https://github.com/ehradapter/ehr-adapter-sdk.git
cd ehr-adapter-sdk
npm install
npm test # run 986 tests
npm run test:coverage # coverage report
npm run build # compile to lib/
npx tsx examples/mock/basic-usage.ts # run an exampleExamples
See /examples/mock/ for runnable code:
basic-usage.ts— getting started, all core operationspatient-search.ts— search filters, paginationenvironment-usage.ts— env-based configuration
API Reference
Full API docs: docs.ehradapter.com
Integration guides: /docs
- Quick Start — zero to working FHIR query in 5 minutes
- Epic Integration Guide — MockAdapter → Epic production
- Multi-Vendor Guide — write once, run on any EHR
Commercial License
The MIT version is the complete SDK minus vendor adapters and multi-tenant isolation. When you’re ready to connect to real EHRs, or to serve multiple tenants, purchase a commercial license and switch packages:
# Free MIT version (this repo)
npm install @securecloudnetworks/ehr-adapter-sdk
# Commercial version (after license purchase)
npm install @securecloudnetworks/ehr-adapterThe commercial SDK (@securecloudnetworks/ehr-adapter) is a drop-in replacement — same API, same types, same method signatures. You get Epic, Athena, Cerner, Health Gorilla, OAuth2/SMART on FHIR, multi-tenant isolation, premium plugins, and priority support.
Support
| Channel | Details | |---|---| | GitHub Issues | github.com/ehradapter/ehr-adapter-sdk/issues | | Commercial Support | [email protected] | | Documentation | docs.ehradapter.com | | Pricing | ehradapter.com/pricing |
License & Contributing
This project is MIT licensed — free for any use including commercial products, as long as you're using the MockAdapter and core SDK. Production integrations with real EHR vendors require a commercial license.
Contributions welcome — see CONTRIBUTING.md.
Built by EHR Adapter · Maintained by Aether Origins Solutions LLC
