hl7FHIRGen
Generate, validate, and explain FHIR resources against any StructureDefinition profile — for any FHIR IG, with no vendor lock-in. Includes an NPHIES pack for pre-submission claim checking and rejection-code lookups.
pip install hl7fhirgen
hl7fhirgen generate my-profile.json
That's it — no server, no terminology service, no license required. Point it at any StructureDefinition: a national IG like NPHIES, US Core, a custom hospital profile, or one you're authoring yourself.
Why
Working with FHIR profiles is one of the most painful parts of implementing
FHIR in practice: reading a raw StructureDefinition differential to figure
out what's actually required, generating a conformant test resource by hand,
or checking a resource against a profile all normally mean either wading
through JSON yourself or reaching for a heavyweight Java validator.
hl7fhirgen is a small, free, scriptable tool that closes that gap for the
everyday cases: generate a conformant example, validate a resource against a
profile, and get a plain-English summary of what a profile actually requires.
Demo
$ hl7fhirgen generate examples/patient-example-profile.json --full
{
"resourceType": "Patient",
"identifier": [
{
"use": "official",
"system": "http://example.org/mrn",
"value": "ID-49247090"
}
],
"name": [
{ "use": "official", "family": "Haynes", "given": ["Kelly"] }
],
"gender": "unknown",
"birthDate": "1971-12-03",
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/patient-birthPlace",
"valueAddress": { "use": "home", "line": ["458 Charles Meadow Apt. 615"], "city": "West Sarahburgh", "postalCode": "14285", "country": "MA" }
}
]
}
$ hl7fhirgen validate patient.json --profile examples/patient-example-profile.json
Valid against ExamplePatient.
$ hl7fhirgen explain examples/patient-example-profile.json
# ExamplePatient (Patient)
...
## Required elements
- `gender` [1..1] (code) — Administrative gender
- `identifier` [1..1] (Identifier) — Medical record number
- `identifier.system` [1..1] (uri)
- `identifier.value` [1..1] (string)
- `name` [1..*] (HumanName) — Patient's name
- `name.family` [1..1] (string)
- `name.given` [1..*] (string)
...
Features
- Generate — feed it a
StructureDefinitionJSON file (from Simplifier, an IG build, or your own IDE) and get back a synthetic resource that satisfies every required and must-support element, honoring fixed/pattern values and standard value-set bindings.--fullalso fills in optional elements. - Validate — check a resource against a profile: cardinality, fixed/pattern values, required-strength bindings (for the value sets it knows), and basic primitive-type sanity. See Scope — this is a documented subset of full FHIR conformance checking, not a replacement for the official validator.
- Explain — turn any
StructureDefinitioninto a plain-English markdown summary: required elements, must-support elements, extensions, value-set bindings, and fixed/pattern constraints. Useful the moment you open an unfamiliar IG. - NPHIES pack — pre-submission claim checking for Saudi Arabia's national
FHIR claims/eligibility exchange:
nphies check-claimvalidates a Claim/ClaimResponse-shaped resource against your own profile and explains any recognized rejection pattern;nphies explain-rejectionlooks one up directly. See NPHIES pack below for what this is (and isn't) built from. - Choice types handled generically —
value[x]-style elements (value[x],diagnosis[x],onset[x], ...) resolve to their concrete JSON key (valueString,diagnosisCodeableConcept, ...) automatically, in both generation and validation. - MCP server — exposes
generate_fhir_resource,validate_fhir_resource,explain_profile, and the NPHIES pack's tools to any MCP-capable client (Claude Desktop, Claude Code, etc.) — see MCP server below. - GitHub Action — run generate/validate/explain in CI — see GitHub Action below.
- Web playground — try generate/validate/explain/NPHIES check-claim in the browser, no install required — see Web playground below.
CLI
hl7fhirgen generate my-profile.json --full --out patient.json
hl7fhirgen validate patient.json --profile my-profile.json
hl7fhirgen explain my-profile.json --out summary.md
hl7fhirgen nphies check-claim claim-response.json --profile my-profile.json
hl7fhirgen nphies explain-rejection duplicate-claim
hl7fhirgen nphies list-rejections
NPHIES pack
NPHIES is Saudi Arabia's national FHIR-based claims and eligibility exchange — every hospital, payer, and vendor in the Kingdom is on it, rejection codes are notoriously hard to act on, and there's little open tooling for it. The NPHIES pack adds two things on top of the generic engine:
hl7fhirgen nphies check-claim my-claim-response.json --profile my-nphies-profile.json
hl7fhirgen nphies explain-rejection duplicate-claim
check-claimruns the same generic validator against whatever profile you supply (bring your own copy of a real NPHIES profile from the NPHIES developer portal) and cross-references anyerror[].code.coding[].codefound on the resource against a bundled rejection-pattern knowledge base.explain-rejection/list-rejectionslook a pattern up directly.
Important: the rejection-code knowledge base
(hl7fhirgen.packs.nphies.rejection_codes) ships with a handful of
illustrative example entries seeding its structure — it is a
community-maintained lookup table, not an official mirror of NPHIES's actual
terminology. hl7fhirgen has no live feed of NPHIES's CodeSystem. Every result
carries a disclaimer; verify against the current NPHIES IG and your payer
contract before acting on a real claim decision. Nothing in this pack was
built from non-public NPHIES material — see CONTRIBUTING.md to contribute a
real rejection pattern you've encountered.
MCP server
pip install "hl7fhirgen[mcp]"
Exposes 6 tools over the Model Context Protocol:
generate_fhir_resource, validate_fhir_resource, explain_profile,
nphies_check_claim, nphies_explain_rejection, nphies_list_rejection_codes.
Runs locally over stdio — an MCP client launches hl7fhirgen-mcp as a
subprocess, no network or Docker involved. Tools take profile/resource JSON as
strings, not file paths, so they work regardless of the client's filesystem
access.
For Claude Code: this repo ships a .mcp.json, so opening it in Claude Code
makes the server available automatically. For other clients, point them at the
hl7fhirgen-mcp command (installed by the mcp extra above).
Claude Code plugin
/plugin marketplace add mwaseem75/hl7fhirgen
/plugin install hl7fhirgen@hl7fhirgen-marketplace
Bundles the MCP server above with a skill (SKILL.md) that teaches Claude when
to reach for hl7fhirgen and flags real gotchas discovered while building it
(array-vs-scalar JSON shape, choice-type resolution, per-instance cardinality,
the NPHIES pack's disclaimer).
GitHub Action
- uses: mwaseem75/hl7fhirgen/action@master
with:
command: validate
profile-path: profiles/my-profile.json
resource-path: test-data/patient.json
Wraps the CLI's generate/validate/explain commands for CI — e.g. gate a
PR on every test resource still validating against your profile. See
action/action.yml for all inputs. Not yet published to PyPI, so the action
currently installs hl7fhirgen from this repo directly; switch to a pinned
release tag once one exists.
Web playground
Run locally:
docker compose up --build
Open http://localhost:8000 — generate, validate, explain, and run the NPHIES pack's
check-claim entirely in the browser, with the same bundled examples the CLI/tests use.
Deploy your own copy to Render: connect this repo on Render
via New + → Blueprint — it picks up render.yaml and deploys webapp/Dockerfile
automatically (free tier).
Scope
Full FHIR conformance validation — terminology services, slicing
discriminators, cross-element invariants (.constraint), full base-resource
merging of differentials — is a large, multi-year effort the official
HL7 FHIR Validator
already does well. hl7fhirgen doesn't try to replace it. What it does today:
- Reads
snapshot.element(the normal case for any profile from an IG, Simplifier, or an authoring tool); falls back todifferential.elementwith a caveat if no snapshot is present — inherited base elements not listed in the differential won't be generated or checked. - Honors
min/maxcardinality,fixed[x]/pattern[x], andrequired/extensible-strength bindings for the small set of well-known value sets it ships with (administrative-gender, name-use, identifier-use, contact-point system/use). Other bindings are recognized but not checked against an actual terminology server. - Detects array-vs-scalar JSON shape correctly for the common FHIR elements
that are always arrays in the base spec (
identifier,name,telecom,address,given,extension,coding, etc.) even when a profile narrows them to0..1— FHIR's JSON shape follows the base resource, not the profile's narrowed cardinality. Elements outside that list rely on the profile's own max and can be wrong if narrowed from a repeating base field we don't recognize. - Extension value-type detection works when a profile inlines
value[x]for the slice (as the bundled example does) or you otherwise know the type; since v1 doesn't fetch external extensionStructureDefinitions over the network, an extension slice with no inlinevalue[x]gets a genericvalueStringplaceholder. - Slicing support beyond extensions is best-effort: a repeating element with multiple named slices generates using the first slice's constraints only (this also applies to validation's cardinality/type checks for that group).
- Choice-type elements (
value[x],diagnosis[x], etc.) are resolved to their concrete JSON key automatically, both generating and validating. - Cardinality and other per-element checks are evaluated per parent instance,
not flattened across the whole resource — a repeating
Claim.itemwith a0..1 Claim.item.quantityis checked per item, not pooled.
None of this is hidden — hl7fhirgen validate reports exactly what it
checked, and unsupported constructs are meant to fail loudly rather than
silently pass.
Project layout
src/hl7fhirgen/ core package (structure_definition, generator, validator, explainer, fhir_datatypes, cli, mcp_server)
src/hl7fhirgen/packs/ vertical packs built on the generic engine (nphies: check_claim, rejection_codes)
webapp/ FastAPI web playground + static frontend
examples/ hand-authored demo profiles used in the README and tests (including examples/nphies/)
action/ GitHub Action wrapping the CLI
tests/ pytest suite
Development
pip install -e ".[dev,mcp,webapp]"
pytest
See CONTRIBUTING.md for the project layout, testing conventions, and how to report a
profile that generates or validates incorrectly. CHANGELOG.md tracks released versions.
Every public function and class has a docstring — help(hl7fhirgen.generator) (or your
editor's hover/go-to-definition) works from a plain pip install.
Roadmap
- Optional
--strictmode that shells out to the official validator jar for authoritative validation when installed. - Publish to PyPI (the GitHub Action currently installs from this repo directly as a stand-in).
- Grow the NPHIES rejection-code knowledge base with real, community-reported
patterns (see
CONTRIBUTING.md).
License
MIT — see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hl7fhirgen-0.1.0.tar.gz.
File metadata
- Download URL: hl7fhirgen-0.1.0.tar.gz
- Upload date:
- Size: 34.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2af9afa11527dca7ca2c8a96d23a12e9262a2081ccbf1f4a363983456f43d46f
|
|
| MD5 |
67e37b74d35771704da129a3b5c3b87a
|
|
| BLAKE2b-256 |
79c4d5ca25dc235500c23f406bc634b3f1644ab997cb6574ca6e73f0e6a6488d
|
File details
Details for the file hl7fhirgen-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hl7fhirgen-0.1.0-py3-none-any.whl
- Upload date:
- Size: 28.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5566a3ce8967633c47cd20c2138048b02171907274199f8981a408c2bf1186e
|
|
| MD5 |
ec63e5a43e136070f6a359bec3e5cbed
|
|
| BLAKE2b-256 |
e04991237c7f3ff6e6fec66448dcd847259167d77cd50f5751d539079c404fd4
|