Open-Source Mirth Connect Alternative (in Python)


By Dariusz Suchojad
Open-source Mirth Connect alternative in Python

For close to two decades, Mirth Connect was the open-source interface engine behind the HL7 interfaces of a large number of hospitals, laboratories, health information exchanges and healthcare software vendors. Its channel model - a source connector, filters, JavaScript transformers and destination connectors - became the common vocabulary of interface work.

That changed in 2025, when the vendor stopped publishing the source code of new releases. Installations built on the open-source releases continue to run, but they no longer receive fixes, and every organization that runs them has to decide where its interfaces go next.

This article describes the change, the options it leaves and how Mirth channels are re-implemented in Zato, an open-source interface engine in Python. The article on the open-source healthcare interface engine covers the engine itself in more detail.

What changed in Mirth Connect

  1. The announcement. On March 19, 2025, NextGen Healthcare announced the move from a dual open-source and commercial license to a single commercial and proprietary license, starting with Mirth Connect 4.6.
  2. Distribution of new releases. Version 4.6 and every later release are available only from NextGen Healthcare and its authorized resellers, and their source code is not published.
  3. The last open-source release. Version 4.5.2, published on September 23, 2024, is the last release with public source code, and it remains available on GitHub.

The change came after two changes of ownership. Quality Systems, the parent company of NextGen Healthcare, acquired Mirth Corporation in 2013 and stated at the time that it would continue to serve as the hub of the Mirth Connect open-source community. Thoma Bravo acquired NextGen Healthcare in November 2023.

The security position of installations on 4.5.2

An installation on 4.5.2 continues to run, and its channels continue to process messages. What it no longer receives is fixes from the vendor.

On September 10, 2026, CISA published advisory ICSMA-26-253-01, describing three high-severity vulnerabilities in Mirth Connect - an SQL injection through the Database Connector API and two XML external entity vulnerabilities, in the XSLT transformer step and in XML batch processing. Every version up to and including 4.7.1 is affected. The vendor fix is version 4.7.2, downloaded from the NextGen customer portal, so an installation on 4.5.2 without a commercial license receives no fix from NextGen.

Interface engines are a known target. CVE-2023-43208, an unauthenticated remote code execution vulnerability in Mirth Connect versions before 4.4.1, was added to the CISA Known Exploited Vulnerabilities catalog in May 2024, on evidence of active exploitation.

The options open to a Mirth team

A team that runs Mirth Connect 4.5.2 or an earlier open-source release has four courses of action:

  1. Remaining on 4.5.2. Nothing changes and nothing is paid, but no fixes arrive from the vendor, so the installation keeps every vulnerability found from now on.
  2. Licensing Mirth Connect 4.6 or later. The upgrade is a version upgrade with the channels unchanged, and the installation receives fixes and support on the commercial terms NextGen Healthcare sets.
  3. Moving to a fork. Two projects continue the 4.5.2 code and run existing channels without changes. Eclipse Open Integration Engine is a community project hosted by the Eclipse Foundation since September 2026. BridgeLink is maintained by Innovar Healthcare, which keeps the engine open source and distributes its web administrator under separate terms that are not open source.
  4. Rebuilding the interfaces on another engine. Every channel is re-implemented and tested again. This course involves the most work, and it is the course for teams that intend to leave the Java and JavaScript channel model itself.

The rest of this article concerns the fourth course - for teams that treat the license change as the occasion to decide in which language and on which platform their interfaces are maintained for the next decade.

Reasons to rebuild rather than fork

  1. Interface logic in a general-purpose language. In a Mirth channel, the logic is JavaScript executed inside a Java engine. In Zato, it is Python, with the Python libraries, test tools and code review practices that any Python team already uses.
  2. Interfaces as code. Zato services are Python modules, and channel and connection definitions are YAML files. Both are kept in Git, reviewed in pull requests and deployed identically to each environment.
  3. FHIR as part of the engine. HL7 v2 messages are converted to FHIR R4 transaction bundles with one call, and C-CDA documents are converted the same way.
  4. One platform beyond clinical messages. The same environment integrates REST APIs, SQL databases, SOAP services, files and queues, so the billing, scheduling and ERP interfaces of a healthcare organization run on the same engine as its HL7 feeds.
  5. Python instead of a Java engine of an earlier generation. Mirth Connect is a Java application administered from a Java desktop client, and its channels are assembled in forms and dialog boxes. Python is the most widely used programming language, first in the TIOBE index for October 2026, and the language of data, machine learning and AI. Zato interfaces are Python code that your developers read and review in one place, and that AI assistants write fluently.
  6. AI agents. Zato exposes services to AI agents over MCP, under access controls the organization defines, and services call language models with only the fields they select.

Mirth Connect concepts in Zato

Each part of a Mirth channel has a counterpart in Zato. A service is a Python class that a channel invokes with each message it accepts, and a connection is a named, configured link to an external system that services and channels use by name.

Mirth ConnectZato
ChannelMLLP channel, configured in the Dashboard or in YAML
TCP Listener source connector in MLLP modeOne MLLP port shared by all channels, and a second port for TLS
Source filterMatch criteria on sending application, facility, message type and trigger event, or a condition in the service
JavaScript transformer stepsA Python service
Destination connectorsDestinations selected in the channel, or outgoing MLLP, FHIR and REST connections invoked from the service
Automatically generated acknowledgmentsAA, AE and AR acknowledgments generated by the channel
Message browserThe audit log, searchable by patient identifier
Reprocessing messagesResubmission, to all destinations or to one selected destination
Channel export in XMLChannel and connection definitions in YAML, kept in Git

A Mirth installation usually assigns each channel its own TCP port. In Zato, all MLLP channels listen on the same port, and the match criteria on the MSH segment of each message select the channel that receives it. Senders that previously connected to different ports connect to the same port in Zato.

Many Mirth channels contain no transformer logic and only deliver a feed to several systems. In Zato, a channel of this kind is configured in the Dashboard without code - the destinations are selected from a list, MLLP destinations receive the message as it arrived and FHIR destinations receive a FHIR bundle converted automatically.

A Mirth transformer in Python

A Mirth transformer step reads fields through positional paths:

// A Mirth Connect transformer step
var mrn = msg['PID']['PID.3']['PID.3.1'].toString();
var familyName = msg['PID']['PID.5']['PID.5.1'].toString();

In Zato, the same fields are read by their names, or by path expressions that keep the positional style of Mirth paths, as described in field access:

# Field names ..
mrn = msg.pid.patient_identifier_list[0].id_number
family_name = msg.pid.patient_name.family_name

# .. or path expressions.
family_name = msg.get('PID.5.1')

A complete re-implemented channel is one service. The service below performs what a typical admission channel in Mirth performs - it rejects a message without a medical record number, forwards the message to the electronic health record and stores the patient data in a FHIR server:

# -*- coding: utf-8 -*-

# Zato
from zato.common.hl7.exception import HL7ApplicationError
from zato.server.service import Service

class AdmissionFeed(Service):
    """ Validates admissions and forwards them to the EHR and the FHIR server.
    """
    name = 'adt.admission-feed'

    def handle(self) -> 'None':

        # The MLLP channel has already parsed the message ..
        msg = self.request.input

        # .. a message without a medical record number is rejected with AE ..
        mrn = msg.pid.patient_identifier_list[0].id_number
        if not mrn:
            raise HL7ApplicationError('PID-3 contains no medical record number')

        # .. the EHR receives the message as it arrived ..
        result = self.mllp['EHR ADT'].send(msg)
        self.logger.info('EHR acknowledgment -> %s', result.ack_code)

        # .. and the FHIR server receives it as a transaction bundle.
        bundle = msg.to_fhir()
        client = self.fhir['Clinical Data Repository']
        response = client.execute('', method='post', data=bundle.to_dict())
        self.logger.info('FHIR server response -> %s', response['type'])

The channel generates the acknowledgment. The sender receives AA when the service completes and AE when the service raises HL7ApplicationError, which tells the sender not to resend the message. Any other exception, for instance a FHIR server that refuses the connection, is answered with AR, and the sender retransmits the message later.

The migration sequence

A migration from Mirth Connect proceeds one channel at a time, with both engines running side by side for as long as it takes:

  1. Inventory the channels. For each Mirth channel, record its sender, its filters, its transformer logic, its destinations and its acknowledgment settings. Channels that only deliver messages become channels without code in Zato.
  2. Define the connections. Create the outgoing MLLP, FHIR and REST connections for the destinations and export them to YAML, so every environment receives the same definitions.
  3. Re-implement one channel. Start with a low-volume feed, write its service and test it with representative messages until its output matches the output of the Mirth channel.
  4. Run both engines on the same feed. Add a destination to the Mirth channel that forwards a copy of every message to the Zato channel, deliver the Zato output to test systems, and compare the results of both engines in their logs.
  5. Move the sender. Point the sending system at the Zato MLLP port, and keep the Mirth channel deployed and idle as the fallback until the new interface is verified in production.
  6. Repeat and decommission. Move the next channel, and stop the Mirth installation when its last channel has been moved.

For retransmissions during the cutover, deduplication recognizes a message that was already processed by its MSH-10 control ID and acknowledges it without invoking the service again. Enterprise support from the team that builds Zato is available for the planning and execution of the migration.

The team after the migration

The HL7 knowledge of a Mirth team carries over completely - segments, fields, trigger events, acknowledgments and the behavior of the sending systems remain the same. What changes is the language of the interface logic. JavaScript transformer steps become Python services, which the developers of the organization's data, analytics and back-end teams already read and maintain, and which new team members are hired to work on from the large population of Python developers.

Frequently asked questions

Is Mirth Connect still open source?

No. Since version 4.6, released in March 2025, Mirth Connect is closed source and distributed under a commercial license by NextGen Healthcare and its authorized resellers.

What is the last open-source version of Mirth Connect?

Version 4.5.2, published on September 23, 2024. Its source code remains on GitHub.

Can I continue to run Mirth Connect 4.5.2?

Yes. Released open-source code remains open source. The installation receives no fixes from the vendor, however, including the fixes for the vulnerabilities published by CISA in September 2026.

Is Zato a fork of Mirth Connect?

No. Zato is a completely unrelated engine, written in Python. Mirth channels are re-implemented in Zato as channels, connections and services.

Can Zato import Mirth channel exports?

No. Each channel is re-implemented. Channels that only deliver messages are configured in the Dashboard without code, and transformer logic is rewritten as Python services.

Do I have to rewrite all channels at once?

No. Zato and Mirth Connect run side by side, and senders are moved one channel at a time.

Do I need Python to replace a Mirth channel?

Not for channels that only receive and deliver messages, which are configured in the Dashboard. Python is used where a Mirth channel contains transformer logic.

Does Zato support FHIR?

Yes. Zato connects to FHIR servers as a client, with OAuth, SMART on FHIR Backend Services and mutual TLS, and converts HL7 v2 messages and C-CDA documents to FHIR.

Is Zato open source?

Yes. The complete source code is on GitHub, and no feature is reserved for a commercial edition.

How do I get started?

Start the HL7 v2 tutorial, which builds a routing channel and a Python service in minutes, or schedule a demo to discuss the migration of your channels.

Planning your move off Mirth Connect? Request your customized demo today.

How organizations like yours succeed with Zato

"Zato Source has been a huge asset in helping us do things the correct way. They are really easy to work with, and always come with fresh ideas to help us design what we need."
- Vilberg Eiríksson, Senior Technical Architect at Isavia (KEF)
"Zato Source is the house of problem solvers. They enabled us to overcome major pain points thanks to their ability to really understand and deliver exactly what we need."
- John Adams, Program Manager of Channel Enablement at Keysight
"When you're dealing with a massive company, often it seems they don't really care about you. That's not the case with Zato Source. They are responsive and always available to help."
- Daryl Dusheiko, Chief Solutions Architect at SATO Vicinity
"I would highly recommend Zato Source because it's been such a good experience working with them. They're fast, very reliable, and very proactive. It's a really good, easy relationship."
- Bob Nitekman, Vice President of IT at RRC
Ready to accelerate your digital transformation journey?
Talk to an expert

Schedule a meaningful demo

Book a demo with an expert who will help you build meaningful systems that match your ambitions

"For me, Zato Source is the only technology partner to help with operational improvements."

- John Adams
Program Manager of Channel Enablement at Keysight