TCP / MLLP Source
Listen for raw TCP or MLLP (Minimal Lower Layer Protocol) connections. MLLP is the standard transport protocol for HL7v2 messages in healthcare.
Overview
The TCP source opens a socket listener that accepts inbound connections and reads data from connected clients. In raw mode, the source reads data until the connection closes or a timeout is reached. In mllp mode, it uses MLLP framing to delimit individual HL7v2 messages within a persistent connection.
MLLP wraps each message with a start block character (0x0B), followed by the message content, an end block character (0x1C), and a carriage return (0x0D). This framing allows multiple messages to flow over a single TCP connection, which is the standard transport mechanism in hospital integration engines.
mode: mllp and configure acknowledgment settings for standard HL7v2 interoperability.
Configuration
Configure the TCP source within the listener block of channel.yaml. Set type to tcp and provide options under the tcp key.
listener:
type: tcp
tcp:
port: 2575
mode: mllp
max_connections: 50
timeout_ms: 30000
tls:
cert_file: /etc/intu/certs/server.crt
key_file: /etc/intu/certs/server.key
ack:
auto: true
success_code: AA
error_code: AE
reject_code: AR
Properties
raw reads until connection close; mllp uses MLLP framing. Defaults to raw.cert_file and key_file paths. Enables encrypted transport for the TCP listener.ACK Properties
| Property | Type | Description |
|---|---|---|
auto |
bool |
When true, automatically generate an HL7 ACK message after processing. Defaults to true in MLLP mode. |
success_code |
string |
ACK code for successful processing. Typically AA (Application Accept). |
error_code |
string |
ACK code when an error occurs during processing. Typically AE (Application Error). |
reject_code |
string |
ACK code when the message is rejected. Typically AR (Application Reject). |
Complete Example
An MLLP listener on port 2575 that receives HL7v2 ADT messages, validates them, transforms the data, and forwards it to a database destination.
id: hl7-mllp-inbound
enabled: true
listener:
type: tcp
tcp:
port: 2575
mode: mllp
max_connections: 100
timeout_ms: 60000
ack:
auto: true
success_code: AA
error_code: AE
reject_code: AR
validator:
runtime: node
entrypoint: validator.ts
transformer:
runtime: node
entrypoint: transformer.ts
destinations:
- patient-db
TypeScript Transformer Example
This transformer parses an HL7v2 message received over MLLP and extracts patient demographic fields from the PID segment.
import { Message, TransformResult } from "@intu/sdk";
interface PatientDemographics {
mrn: string;
familyName: string;
givenName: string;
dateOfBirth: string;
gender: string;
address: {
street: string;
city: string;
state: string;
zip: string;
};
phone: string;
}
export default function transform(msg: Message): TransformResult {
const raw = msg.body as string;
const segments = raw.split("\r").filter(Boolean);
const segmentMap = new Map<string, string[][]>();
for (const seg of segments) {
const fields = seg.split("|");
const name = fields[0];
if (!segmentMap.has(name)) segmentMap.set(name, []);
segmentMap.get(name)!.push(fields);
}
const msh = segmentMap.get("MSH")?.[0];
const pid = segmentMap.get("PID")?.[0];
if (!msh || !pid) {
return { success: false, error: "Missing MSH or PID segment" };
}
const nameParts = (pid[5] || "").split("^");
const addrParts = (pid[11] || "").split("^");
const patient: PatientDemographics = {
mrn: pid[3]?.split("^")[0] || "",
familyName: nameParts[0] || "",
givenName: nameParts[1] || "",
dateOfBirth: formatDate(pid[7]),
gender: pid[8] || "",
address: {
street: addrParts[0] || "",
city: addrParts[2] || "",
state: addrParts[3] || "",
zip: addrParts[4] || "",
},
phone: pid[13]?.split("^")[0] || "",
};
return {
success: true,
body: JSON.stringify(patient),
contentType: "application/json",
};
}
function formatDate(hl7Date: string | undefined): string {
if (!hl7Date || hl7Date.length < 8) return "";
return `${hl7Date.slice(0, 4)}-${hl7Date.slice(4, 6)}-${hl7Date.slice(6, 8)}`;
}