DEV Community

easysolutions906
easysolutions906

Posted on

Managing Mirth Connect with AI Agents: An MCP Server for Healthcare Integration Engines

Managing Mirth Connect with AI Agents: An MCP Server for Healthcare Integration Engines

Mirth Connect (NextGen Connect) is the most widely deployed open-source healthcare integration engine. It moves HL7 messages between EHRs, labs, pharmacies, imaging systems, and billing platforms. A typical hospital runs dozens or hundreds of Mirth channels, each with its own source connector, transformer scripts, filters, and destinations. Managing them means reading XML exports, writing Rhino-compatible JavaScript, debugging cryptic error messages, and reviewing channel configurations before promoting them across environments.

All of this is tedious, detail-oriented work. It is also exactly the kind of work that AI agents handle well -- if you give them the right tools.

The Mirth Connect MCP server exposes 18 tools that let AI assistants parse, analyze, generate, and debug Mirth channels. This article walks through what the tools do and how to use them in practice.

The 18 tools

Tool Description
mirth_parse_channel Parse a channel XML export into structured JSON
mirth_analyze_channel Lint a channel for hardcoded IPs, SQL injection, missing error handling, Rhino issues
mirth_explain_channel Generate a plain-English description of what a channel does
mirth_generate_transformer Generate a transformer step in Rhino-compatible JavaScript
mirth_generate_filter Generate a filter step (message type, field value, test patient exclusion)
mirth_generate_channel Generate a complete importable channel XML
mirth_map_fields Generate HL7 field mapping code (PID-5-1 to patient_last_name)
mirth_generate_code_template Generate a code template using the IIFE pattern
mirth_debug_error Explain a Mirth error message and suggest fixes
mirth_validate_js Validate JavaScript for Rhino compatibility across Mirth versions
mirth_diff_channels Compare two channel XMLs and show what changed
mirth_migration_guide Generate a migration guide for upgrading channels between Mirth versions
mirth_extract_sql Extract all SQL queries from a channel and flag injection risks
mirth_dependency_map Map dependencies between channels (Channel Writer/Reader, router.routeMessage)
mirth_generate_deploy_script Generate a bash deploy script for CI/CD pipelines
mirth_convert_to_code_template Convert inline transformer JavaScript into a proper code template
mirth_estimate_throughput Estimate message throughput and identify bottlenecks
mirth_generate_test_message Generate a realistic test message based on source connector type

Installation

Add to your Claude Desktop config (claude_desktop_config.json):

{
  "mcpServers": {
    "mirth-connect": {
      "command": "npx",
      "args": ["-y", "@easysolutions906/mirth-mcp"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Restart Claude Desktop. All 18 tools become available immediately.

For Cursor, add the same configuration to .cursor/mcp.json in your project. For Claude Code, run:

claude mcp add mirth-connect npx -y @easysolutions906/mirth-mcp
Enter fullscreen mode Exit fullscreen mode

Scenario: Onboarding a new team member

You just joined a healthcare IT team and need to understand 30 Mirth channels you have never seen before. Someone hands you a channel XML export. Normally you would open it in the Mirth Administrator, expand each connector, read the transformer steps, look up field paths in the HL7 specification, and take notes. This takes 15-30 minutes per channel.

Instead, paste the XML into Claude and ask: "Explain this Mirth channel."

Claude calls mirth_explain_channel and returns something like:

## ADT Feed - Epic to Lab

### Source: TCP Listener
Listens on port 6661

**Source Filter** (1 rules):
- Accept ADT A01/A04/A08 only (enabled)

**Source Transformer** (3 steps):
- Extract patient demographics (enabled)
- Format MRN with facility prefix (enabled)
- Map attending physician NPI (enabled)

### Destinations (2)

**1. Lab System** (TCP Sender)
  - Target: 10.1.5.20:5000
  - Transformer: 2 steps

**2. Patient Index** (Database Writer)
  - Transformer: 1 steps

### Properties
- Initial state: STARTED
- Storage mode: PRODUCTION
- Tags: ADT, Epic, Lab
Enter fullscreen mode Exit fullscreen mode

In 10 seconds you know the channel's purpose, data flow, and architecture. You can follow up with "Analyze this channel for issues" and Claude calls mirth_analyze_channel:

{
  "channelName": "ADT Feed - Epic to Lab",
  "summary": { "total": 4, "errors": 1, "warnings": 2, "info": 1 },
  "findings": [
    {
      "ruleId": "sql-injection",
      "severity": "error",
      "location": "Destination: Patient Index Transformer",
      "detail": "SQL string concatenation detected — use parameterized queries to prevent SQL injection"
    },
    {
      "ruleId": "hardcoded-ip",
      "severity": "warning",
      "location": "Destination: Lab System",
      "detail": "Hardcoded IP \"10.1.5.20\" — use configurationMap or a channel variable instead"
    },
    {
      "ruleId": "missing-error-handling",
      "severity": "warning",
      "location": "Destination: Patient Index Transformer",
      "detail": "I/O operations without try/catch — database operations should be wrapped in error handling"
    },
    {
      "ruleId": "large-inline-script",
      "severity": "info",
      "location": "Source Transformer",
      "detail": "Script is 78 lines — consider extracting to a code template for reusability"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Now you know the channel has a SQL injection vulnerability, hardcoded IPs, and missing error handling. On your first day. Without opening the Mirth Administrator.

Writing Rhino-compatible JavaScript

Mirth runs JavaScript through Mozilla Rhino, not V8 or SpiderMonkey. This means no template literals, no destructuring, no async/await, no optional chaining, no nullish coalescing, and no ES modules. Arrow functions and const work inside IIFEs on Mirth 3.7+ with ES6 mode enabled, but const/let at root level in code templates causes cross-template scope collisions. Every integration engineer has been bitten by at least one of these.

Ask Claude: "Generate a transformer that extracts patient demographics from PID and maps them to channelMap variables."

Claude calls mirth_generate_transformer and returns:

// Transformer: Extract patient demographics from PID
// Generated for Mirth Connect (Rhino ES6)

// Access HL7 message fields via msg object
// Example: var patientName = msg['PID']['PID.5']['PID.5.1'].toString();

try {
  var patientLastName = msg['PID']['PID.5']['PID.5.1'].toString();
  var patientFirstName = msg['PID']['PID.5']['PID.5.2'].toString();
  var mrn = msg['PID']['PID.3']['PID.3.1'].toString();

  channelMap.put('patientLastName', patientLastName);
  channelMap.put('patientFirstName', patientFirstName);
  channelMap.put('mrn', mrn);
} catch (e) {
  logger.error('Transformer error: ' + e.message);
  throw e;
}
Enter fullscreen mode Exit fullscreen mode

The generated code uses var at root level, string concatenation instead of template literals, and wraps everything in try/catch. It follows Rhino rules automatically.

If you already have JavaScript and want to check it, paste it in and ask Claude to validate it. Claude calls mirth_validate_js and returns a version compatibility matrix:

{
  "valid": false,
  "mirthVersion": "es5",
  "rhinoMode": "ES5 (pre-3.7 or legacy config)",
  "errors": 2,
  "violations": [
    {
      "id": "arrow-function",
      "message": "Arrow functions require Mirth 3.7+ with rhino.languageversion=es6.",
      "fix": "Replace (x) => { } with function(x) { }. Or set rhino.languageversion=es6 in mirth.properties."
    },
    {
      "id": "template-literal",
      "message": "Template literals require Mirth 3.7+ with rhino.languageversion=es6.",
      "fix": "Use string concatenation: \"hello \" + name. Safest across all versions."
    }
  ],
  "versionMatrix": {
    "es5": "incompatible",
    "3.7": "compatible",
    "4.0": "compatible",
    "4.5": "compatible"
  }
}
Enter fullscreen mode Exit fullscreen mode

This is especially useful when your team supports multiple Mirth versions across different client environments. The version matrix tells you exactly where the code will work and where it will break.

Environment promotion: diffing channels

Before promoting a channel from DEV to PROD, you need to know what changed. Export both versions and ask Claude: "Compare these two channel XMLs."

Claude calls mirth_diff_channels and returns:

{
  "channel1": "ADT Feed v2.1 (DEV)",
  "channel2": "ADT Feed v2.0 (PROD)",
  "totalChanges": 3,
  "changes": [
    {
      "field": "destination.Lab System.transformer",
      "from": "2 steps",
      "to": "3 steps",
      "type": "modified"
    },
    {
      "field": "destination.Audit Log",
      "type": "added",
      "details": "New Database Writer destination"
    },
    {
      "field": "postprocessingScript",
      "type": "modified"
    }
  ],
  "summary": "1 added, 0 removed, 2 modified"
}
Enter fullscreen mode Exit fullscreen mode

A clear summary of what will change when you promote. No need to manually compare XML files or click through the Mirth Administrator.

Extracting SQL for DBA review

Healthcare organizations require database changes to go through a DBA review process. If your Mirth channels contain SQL in transformer scripts, Database Reader/Writer connectors, or inline JavaScript, extracting it manually is painful.

Ask Claude: "Extract all SQL from this channel and flag any injection risks."

Claude calls mirth_extract_sql and returns every query with its location and a flag for potential injection vulnerabilities:

{
  "channel": "Patient Sync",
  "totalQueries": 5,
  "injectionRisks": 1,
  "queries": [
    {
      "source": "Source connector query",
      "sql": "SELECT patient_id, mrn, last_name, first_name FROM patients WHERE updated_at > ${date}",
      "potentialInjection": false
    },
    {
      "source": "Dest[Patient Index] transformer: Update MPI",
      "sql": "UPDATE patient_index SET last_name = '" ,
      "potentialInjection": true
    }
  ],
  "warning": "1 queries may be vulnerable to SQL injection. Use parameterized queries instead of string concatenation."
}
Enter fullscreen mode Exit fullscreen mode

Hand this to your DBA. They get the SQL without needing to open Mirth or understand channel XML structure.

Mapping channel dependencies

In a large Mirth environment with 50+ channels, channels route messages to each other via Channel Writer destinations and router.routeMessage calls. Understanding the dependency graph is critical before you disable, rename, or redeploy a channel.

Pass all your channel XMLs to Claude and ask: "Map the dependencies between these channels."

Claude calls mirth_dependency_map and returns:

{
  "totalChannels": 12,
  "totalDependencies": 8,
  "dependencies": [
    { "from": "ADT Router", "to": "Lab Feed", "type": "Channel Writer", "connector": "Lab Destination" },
    { "from": "ADT Router", "to": "Radiology Feed", "type": "Channel Writer", "connector": "Rad Destination" },
    { "from": "ADT Router", "to": "Audit Logger", "type": "router.routeMessage", "connector": "script" },
    { "from": "Lab Feed", "to": "Results Notifier", "type": "Channel Writer", "connector": "Notify" }
  ],
  "orphans": ["Test Channel", "Old Migration Channel"]
}
Enter fullscreen mode Exit fullscreen mode

You can see which channels feed into which, and which channels are orphaned with no connections -- candidates for cleanup.

Generating complete channels

Need a new channel quickly? Describe it and Claude generates importable XML.

Ask: "Generate a Mirth channel called 'Lab Results Inbound' with a TCP Listener on port 7001 and two destinations: an HTTP Sender called 'EHR API' and a Database Writer called 'Results Archive'."

Claude calls mirth_generate_channel and returns valid XML that you can import directly into Mirth Connect. The generated channel includes proper connector classes, transformer and filter placeholders, and standard channel properties.

Generating deploy scripts for CI/CD

Mirth channels are usually deployed manually through the Administrator GUI. For teams practicing CI/CD, this is a bottleneck. The mirth_generate_deploy_script tool generates a bash script that uses the Mirth REST API to log in, check if the channel exists, stop it, update or create it, deploy, and start it.

Ask Claude: "Generate a deploy script for this channel targeting https://mirth-prod.internal:8443/api."

The output is a ready-to-use bash script for your Jenkins, GitHub Actions, or GitLab CI pipeline.

Debugging errors

Mirth error messages range from helpful to inscrutable. Rhino errors are especially confusing for developers used to V8. Paste an error into Claude and ask what it means.

Ask: "Debug this Mirth error: ReferenceError: \"formatDate\" is not defined"

Claude calls mirth_debug_error and returns:

{
  "error": "ReferenceError: \"formatDate\" is not defined",
  "cause": "The variable or function \"formatDate\" is not declared in the current scope. In Mirth, code templates execute in a shared global scope — if a code template has not been loaded, its functions will not be available.",
  "fixes": [
    "Verify the code template library containing \"formatDate\" is enabled and linked to this channel.",
    "Check for typos in the function/variable name.",
    "If using ES6 syntax (let/const) at root level, switch to var for global visibility.",
    "Ensure code template libraries are listed in the correct order (dependencies first)."
  ]
}
Enter fullscreen mode Exit fullscreen mode

The tool recognizes common error patterns including ReferenceErrors, TypeErrors, SQL exceptions, network connection failures, and OutOfMemoryErrors. Each match returns a specific cause and actionable fixes.

Refactoring: inline scripts to code templates

Mirth best practice is to keep transformer scripts short and put reusable logic into code templates. In practice, integration engineers write everything inline first and refactor later -- or never. The mirth_convert_to_code_template tool automates the refactoring.

Paste an inline transformer script and ask Claude to convert it to a code template. The tool extracts function definitions, wraps them in the IIFE pattern with var declarations at root level for global visibility, and generates usage examples showing how to call the functions from a transformer step.

Estimating throughput

Before going live with a high-volume channel, you want to know where the bottlenecks are. The mirth_estimate_throughput tool analyzes transformer complexity, counts database queries, detects HTTP calls in transformers (a common anti-pattern), identifies heavy regex usage, and factors in destination type overhead.

The output includes an estimated messages-per-second figure and a ranked list of bottlenecks with specific optimization suggestions -- like moving HTTP calls from transformers to HTTP Sender destinations, or replacing repeated new RegExp with pre-compiled patterns in a deploy script.

Upgrading Mirth versions

Upgrading from Mirth 3.x to 4.x, or from 4.x to 4.5, introduces breaking changes in APIs, plugin interfaces, and Rhino behavior. The mirth_migration_guide tool scans all scripts in a channel for deprecated APIs, Rhino compatibility issues, and patterns that changed between versions.

Pass a channel XML and specify the from/to versions. The tool returns a list of issues with locations, descriptions, and fixes -- a checklist you can work through before upgrading.

Generating test messages

When building or debugging a channel, you need test messages that match the source connector type. The mirth_generate_test_message tool analyzes the channel's source connector and generates an appropriate test message: an HL7 ADT^A01 for TCP/LLP sources, a JSON payload for HTTP sources, or delimited text for file reader sources.

Getting started

  1. Add the MCP server config to Claude Desktop, Cursor, or Claude Code
  2. Restart and verify the 18 tools appear
  3. Export a channel from Mirth Connect (Channels > Export Channel)
  4. Paste the XML into Claude and ask: "Explain this channel" or "Analyze this channel for issues"
  5. Try generating code: "Generate a transformer that extracts PID-5-1 and PID-3-1 to channelMap"

Mirth Connect is powerful but demands deep knowledge of Rhino quirks, HL7 field positions, and XML channel structure. An MCP server gives AI agents that knowledge, so you can focus on the integration logic instead of fighting the tooling.

Top comments (0)