Skip to content

toddegray/integrator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

integrator

An AI teammate for the HL7/FHIR integration engineer. Paste a broken message, get a root cause. Paste a batch of samples from a new trading partner, get an interface spec and a draft transformer. Paste a legacy v2 interface, get a FHIR migration plan.

MIT licensed. TypeScript on Bun. Runs fully local by default β€” no PHI leaves your machine.

integrator web UI


⚠️ integrator is not itself a HIPAA-covered product. It's a tool for integration engineers, shipped AS-IS under the MIT license with no warranty (see LICENSE). Every output is a draft for a human to review, never auto-applied to a production interface. Compliance with HIPAA, GDPR, and your employer's security posture is your responsibility.


Install

git clone https://github.com/toddegray/integrator
cd integrator
bun install
bun run src/cli.ts init      # interactive; writes ~/.integrator/config.json
bun run src/cli.ts seed      # load 10 publicly-cited spec gotchas into memory

Requires Bun 1.1+. That's it β€” no Docker, no database server, no cloud account. The whole thing is one SQLite file at ~/.integrator/data/integrator.db.

To compile a standalone executable: bun run build β†’ ./bin/integrator.

Thirty seconds in

# Diagnose a malformed ADT
bun run src/cli.ts diagnose --file examples/fixtures/adt-a01-missing-msh12.hl7 --vendor epic

# Translate v2 β†’ FHIR
bun run src/cli.ts translate --file examples/fixtures/oru-r01.hl7 --format bundle

# Validate strictly
bun run src/cli.ts validate --file examples/fixtures/observation-missing-code.json

# Explain a segment
bun run src/cli.ts explain PID-3

# Web UI β€” paste, click, done
bun run src/cli.ts web         # http://127.0.0.1:4321

All eleven skills ship with the repo. Every fixture under examples/fixtures/ is real, runnable, and included in the test suite.

What it does

integrator is one executable that wraps eleven deterministic skills:

Skill What it does
diagnose Root-cause analysis on a malformed / rejected HL7 v2 message. Applies vendor-quirk memory.
translate HL7 v2 ↔ FHIR R4/R5 (both directions). Z-segments preserved as FHIR extensions.
validate Strict v2 parse + structure + FHIR cardinality/reference/primitive checks.
explain-segment Plain-English explanation of any segment / field / code with spec citations.
synthesize PHI-safe synthetic HL7 v2 test data, reproducible by seed.
diff-specs Compare two interface specs; flag breaking changes.
map-interfaces Field-by-field mapping between sender and receiver.
onboard-interface Infer a spec from a batch of samples. Detects message mix, version drift, Z-segments.
generate-transformer Draft code for Mirth, Iguana, Cloverleaf, Rhapsody, Corepoint, generic JS, or generic Python.
migrate-to-fhir End-to-end migration plan: resource mapping, Z-segment strategy, phased rollout.
batch-report Run diagnose+validate across a directory; consolidated report.

And one natural-language entrypoint:

ask Give it a question in English. Claude picks the right skill(s) and composes. Requires cloud inference opt-in.

How it works

Four layers. Each one is small and replaceable.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Surfaces (src/cli.ts, src/mcp/, src/web/, src/agents/)      β”‚
β”‚   CLI Β· stdio MCP server Β· paste-and-go web UI Β· ask agent   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Skills (src/skills/*)                                       β”‚
β”‚   Pure functions. Return Brief<T> = { data, citations, md }. β”‚
β”‚   No hidden I/O. Tested in isolation.                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Core (src/core/hl7.ts, fhir.ts, vendors.ts, config.ts)      β”‚
β”‚   HL7 v2 parser Β· FHIR validator Β· vendor/version metadata.  β”‚
β”‚   Zero dependencies on anything higher up.                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Memory (src/db/*)                                           β”‚
β”‚   SQLite (bun:sqlite) with a Statement cache.                β”‚
β”‚   Nine tables: entities, briefs, vendor_quirks, …            β”‚
β”‚   Everything stays on your machine.                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Skills are pure. Every skill takes structured input and returns a Brief<T>:

interface Brief<T> {
  skill: string;
  schema_version: number;
  entity: EntityId;             // kind + id + display
  generated_at: string;         // ISO-8601
  data: T;                      // deterministic structured payload
  citations: Citation[];        // every claim links to HL7.org / FHIR spec
  markdown: string;             // rendered report
}

The data and citations fields are reproducible β€” same input, same output, byte-for-byte. The markdown can be LLM-enhanced via Ollama; the structured payload never is.

Memory is the moat. Every time you run a skill, what integrator learned goes into SQLite: vendor quirks, Z-segments seen in the wild, trading-partner notes, local-code mappings. The second diagnosis of an Epic ADT quirk is better than the first. After a month of real traffic, integrator knows your environment better than a new hire could in six months.

Local-first by default. The CLI, MCP server, and web UI don't require network access. Ollama provides optional local LLM narrative. Anthropic or OpenAI cloud inference is off by default; you opt in via integrator init --enable-cloud, and when on, PHI redaction (src/inference/redact.ts) runs before any outbound call.

Examples

diagnose a malformed ADT

$ bun run src/cli.ts diagnose --file examples/fixtures/adt-a01-missing-msh12.hl7 --vendor epic
# diagnose β€” ADT^A01

**Message type:** ADT^A01
**Version:** (empty)
**Sending app:** DEMO_SENDER
**Receiving app:** DEMO_RECEIVER
**Vendor:** epic (3 quirks matched)

## Root causes (1)

### 1. MSH-12 (Version ID) is empty; many receivers assume 2.3 and reject higher-version payloads
_Confidence: medium Β· Code: MSH.12_MISSING_

**Suggested fix**
Populate MSH-12 with the HL7 version, e.g. `2.5.1`.

Run it again after you record a vendor-specific quirk, and the second diagnosis surfaces that too.

translate HL7 v2 β†’ FHIR

$ bun run src/cli.ts translate --file examples/fixtures/oru-r01.hl7 --format bundle
{
  "resourceType": "Bundle",
  "type": "collection",
  "entry": [
    { "resource": { "resourceType": "Patient", "name": [{"family":"LOVELACE","given":["ADA"]}], … } },
    { "resource": { "resourceType": "DiagnosticReport", "code": { … LOINC 24323-8 … }, "result": [...] } },
    { "resource": { "resourceType": "Observation", "code": { … Sodium LOINC … }, "valueQuantity": {"value": 140, "unit": "mmol/L"} } }
    // …
  ]
}

Both directions work. --direction fhir-to-v2 takes a FHIR Bundle and infers the trigger (ADT^A01 / ORU^R01 / ORM^O01).

validate a FHIR resource

$ bun run src/cli.ts validate --file examples/fixtures/observation-missing-code.json
# validate β€” Observation/obs-no-code

**Verdict:** invalid
**Findings:**
- [error] FHIR.MISSING_REQUIRED_FIELD β€” Observation.code is required but missing

Exit code 1 if invalid, so you can wire it into CI.

onboard a new trading partner

$ bun run src/cli.ts onboard --dir ./partner-samples --partner memorial-regional --vendor epic

Reads every .hl7 file in the directory, infers the interface spec (message-type mix, version mix, Z-segments, field population rates), and records what it saw into memory. Run integrator batch --dir ./partner-samples afterwards for a consolidated diagnose+validate report.

generate a transformer

$ bun run src/cli.ts generate-transformer \
    --engine mirth \
    --sender examples/fixtures/adt-a01.hl7 \
    --receiver examples/fixtures/adt-a04-register.hl7 \
    --label memorial-adt \
    --output code
// integrator-generated mirth transformer β€” review before deploying.
// Interface: memorial-adt
// Do not commit as-is; treat this as a starting point.
  tmp['MSH']['MSH.3'] = msg['MSH']['MSH.3'];
  tmp['MSH']['MSH.9'] = msg['MSH']['MSH.9'];
  tmp['PID']['PID.3'] = msg['PID']['PID.3'];
  tmp['PID']['PID.5'] = msg['PID']['PID.5'];
  // …

Also supports iguana, cloverleaf, rhapsody, corepoint, generic-js, generic-py.

remember what you learned

# You just figured out an Epic quirk. Save it so every future diagnose sees it.
bun run src/cli.ts quirks record --vendor epic --segment PID --field 3 --component 5 \
    --behavior "uses PID-3.5 for MRN even though spec says PID-3.4" \
    --citation "https://hl7-definition.caristix.com/v2/HL7v251/Fields/PID.3"

# Tag a trading partner with notes
bun run src/cli.ts partners add --id memorial-regional \
    --vendor epic --notes "primary contact: Rhonda K. Β· prefers EDI cutover Fridays"

# See what you've accumulated
bun run src/cli.ts quirks              # vendor quirks
bun run src/cli.ts partners            # trading partners
bun run src/cli.ts quirks z-segments   # custom Z-segments seen in the wild
bun run src/cli.ts recall              # every brief ever generated

Surfaces

Surface Command Use
CLI integrator <skill> Terminal-first, pipeable, scriptable
Web UI integrator web Paste-and-go at http://127.0.0.1:4321
Batch integrator batch --dir <path> Run diagnose+validate across an inbox
MCP integrator mcp stdio server for Claude Code, Claude Desktop, Cursor
ask integrator ask "why …?" Natural language (needs cloud inference on)

Use from Claude Code / Cursor / Claude Desktop

Add this to your MCP client config:

{
  "integrator": {
    "command": "bun",
    "args": ["run", "/absolute/path/to/integrator/src/mcp/server.ts"]
  }
}

Every skill is exposed as a tool. Claude picks the right one and composes them for you.

The memory model

A single SQLite file at ~/.integrator/data/integrator.db with nine tables:

  • entities Β· messages, resources, bundles, interfaces, trading partners, vendors, Z-segments, code systems
  • briefs Β· the latest output of every skill per entity
  • vendor_quirks Β· observed behaviors per vendor / message-type / field; grows with use
  • version_diffs Β· HL7 v2 version-over-version changes
  • trading_partners Β· your specific partners + their quirks
  • z_segments Β· every custom Z* segment encountered
  • code_mappings Β· local codes ↔ LOINC / SNOMED / RxNorm / ICD-10
  • annotations Β· free-form notes on any entity
  • user_context Β· your stack (engine, EMR, default versions)

Back up with:

sqlite3 ~/.integrator/data/integrator.db "VACUUM INTO '~/.integrator/backups/integrator-$(date +%F).db'"

See docs/OPERATING.md for the full operating manual.

Why this exists

The existing FHIR MCP servers are data-access layers for building new apps β€” they don't help the integration engineer who's already running v2 traffic between legacy systems. integrator focuses on that work: diagnosis, translation, validation, transformer scaffolding, migration planning β€” all driven by a memory layer that learns the quirks of your specific environment as you use it.

Design rules

  1. Local-first. No PHI leaves the machine unless the user explicitly opts into cloud inference.
  2. Public specs only. HL7.org, FHIR R4/R5, IHE, US Core, CARIN, Da Vinci, SMART Health IT, Synthea. No proprietary vendor documentation ingested.
  3. Every claim cites a spec. Narrative output links to HL7.org, the FHIR spec, or an IHE profile. Hallucinated segment definitions are unshippable.
  4. Reproducible. Same input, same structured output, byte-identical.
  5. User-settable config. Every knob goes through integrator init. Env vars are the escape hatch, not the front door.
  6. Vendor-agnostic code paths. No hard-coded Epic / Cerner / MEDITECH branches. Vendor quirks live as data in the memory layer, observed from user traffic.
  7. Outputs are drafts. The tool never auto-applies a transformer to a production interface.
  8. No clinical reasoning. integrator handles data about messages, not patient-level clinical logic.

Project layout

src/
  cli.ts          entry point; dispatches to cli/*
  cli/            one file per command
  skills/         one file per skill (pure functions)
  core/           HL7 parser, FHIR validator, config, types
  db/             bun:sqlite engine + schema + typed repos
  inference/      Ollama client + PHI redaction
  mcp/            stdio MCP server
  web/            Bun HTTP server + single-page UI
  agents/         ask orchestrator (Anthropic SDK + prompt caching)
  seeds/          curated starter vendor quirks
examples/
  fixtures/       runnable HL7 + FHIR samples
  *.md            committed example briefs
test/             64 passing tests (bun test)
docs/             ARCHITECTURE, OPERATING, DEMO

Status

v1.0.0. 11 skills, 5 surfaces, 64 tests passing. See CHANGELOG.md for what's in and what's known-thin. CI at .github/workflows/ci.yml runs tsc, bun test, and bun run build on every push.

Real feedback from integration engineers is what will make the memory layer compound. Issues and PRs welcome.

License

MIT.

About

AI HL7/FHIR integration engineer. Local-first. Paste a broken message, get a root cause. MIT.

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors