DICOM imaging

Send, receive, and route DICOM imaging

MessageFoundry treats imaging as a first-class lane: receive stored objects (C-STORE SCP) and send them to a PACS (C-STORE SCU), verify with C-ECHO, and push over modern DICOMweb STOW-RS — with the Structured-Report-to-HL7 v2 mapping written as versioned, testable Python, not a proprietary GUI mapper, and the same reliability and PHI guarantees as every other connection.

Scope by design — headers and Structured Reports only: no pixel data, no numpy.

What's supported

A complete DICOM transport lane

Inbound and outbound DIMSE, plus the modern HTTP lane — each riding the same staged pipeline, retries, and audit as the rest of the engine.

C-STORE SCP — receive

A pynetdicom Application Entity accepts stored objects inbound. It returns C-STORE Success only after the object is durably committed (the DIMSE analog of commit-before-ACK) — nothing is accepted-and-dropped.

C-STORE SCU — send

Forward an object to a downstream PACS over a C-STORE association — full Mirth-sender parity. The blocking association runs off the event loop, so a slow peer never stalls the engine.

C-ECHO — verify

Connectivity verification both ways: the SCP accepts Verification, and an outbound destination's Test Connection issues a C-ECHO before you trust the link.

DICOMweb STOW-RS — send over HTTP

The modern HTTP imaging lane — store/send to {base}/studies as multipart/related. It reuses the hardened REST plumbing (TLS-verifying, no-redirect, egress-gated). Neither Mirth nor Corepoint ships this out of the box.

SR / header → HL7 v2

Map a Structured Report or header to HL7 v2 (ORU/OBX, PID/OBR) in a code-first Handler — versioned and unit-testable, a replacement for the GUI mapper Corepoint sells behind a license.

DICOM-over-TLS

TLS on the wire for both server and client, with opt-in mTLS. A non-loopback cleartext listener is refused at startup unless explicitly overridden.

Deliberately scoped

What it does not do — on purpose

A tight scope is a feature: it keeps the imaging lane small, auditable, and free of a heavy pixel-processing attack surface. The boundary mirrors what a routing engine actually needs (and what Mirth itself draws).

Need full PACS/VNA behavior — query/retrieve, worklists, pixel rendering? That's an archive's job, not an interface engine's. MessageFoundry routes and transforms imaging metadata; it doesn't become your image store.

Reliability & PHI

Imaging on the same durable, PHI-aware rails

Commit before success

The SCP commits the raw object durably before returning Success; a crash before commit just means the sender re-sends. At-least-once, with idempotent re-store on SOPInstanceUID.

Smart retry classification

Out-of-resources or a transport failure is transient (retried with backoff); a hard refusal — rejected context, unencodable dataset, not-authorized — is permanent and dead-letters, so a bad object never head-blocks the lane.

PHI-safe by construction

A DICOM object is PHI: stored encrypted, never logged at INFO or above, and egress-allowlisted. Log and error lines carry only routing-safe identifiers (SOP/AE/peer) — never the dataset or pixel data.

Fail-closed egress. A DIMSE destination is gated by the [egress].allowed_tcp allowlist and a DICOMweb destination by [egress].allowed_http — both enforced at load, reload, and startup, so the engine can't send imaging anywhere you didn't approve.

How it compares

DICOM vs. Mirth & Corepoint

Full parity with Mirth's DICOM transport scope, a code-first replacement for Corepoint's GUI-mapped transform, and a modern DICOMweb send lane neither incumbent ships.

CapabilityMirthCorepoint "DICOM Gear"MessageFoundry
C-STORE SCP (receive)YesYesYes
C-STORE SCU (send)YesYesYes
C-ECHOYesYesYes
SR / header → HL7 v2 transformTransport onlyYes — GUI mapperYes — code-first Handler
DICOMweb STOW-RS sendNoNoYes
MWL / Query-Retrieve / pixel dataNoPartialNo — out of scope

Honest validation note. The connectors are verified against the DICOM protocol with real pynetdicom loopback tests (and the DICOMweb framing with mocked HTTP) — not yet against a specific vendor PACS. A real-feed validation against your partner's SOP classes, transfer syntaxes, and AE titles is the step before cutover.

Route imaging like any other interface

Wire a DICOM source or destination the same way you wire MLLP or REST — in code you own, tested before it ships.