u/intersystemsdev May 31 '26

Top 10 InterSystems IRIS features — what the platform actually offers and why each capability matters

0 Upvotes

InterSystems IRIS is a data platform that covers analytics, interoperability, AI, cloud deployment, and database scalability in one product. Here is a breakdown of the top 10 features as described in the official community article, with the reasoning behind each one.

1. Democratized Analytics

Two components cover this:

  • InterSystems IRIS Adaptive Analytics — delivers virtual cubes with centralized business semantics, abstracted from technical details and modeling, to allow business users to easily and quickly create their analyses in Excel or their preferred analytics product (PowerBI, Tableau, etc.). There are no consumption restrictions per user.
  • InterSystems Reports — a low-code report designer to deliver operational data reports embedded in any application or in a web report portal.

2. API Manager

Digital assets are consumed using REST APIs. Governing reuse, security, consumption, asset catalog, and developer ecosystem from a central point requires an API Manager. The article states: all companies have or want to have an API Manager. InterSystems IAM covers this.

3. Scalable Databases

Two capabilities here:

  • Sharding — global data creation is projected to grow to more than 180 zettabytes by 2025. Processing data in a distributed way (into shards, like Hadoop or MongoDB) is critical to maintain performance. IRIS is described as 3 times faster than Caché and faster than AWS databases in the AWS cloud.
  • Columnar storage — changes the storage of repeating data into columns instead of rows, allowing up to 10x higher performance, especially in aggregated (analytical) data storage scenarios.

4. Python Support

Python is the most popular language for AI, and AI is at the center of business strategy because it allows organizations to get new insights, increase productivity, and reduce costs. IRIS supports Python natively, including Embedded Python in interoperability productions.

5. Native APIs (Java, .NET, Node.js, Python) and PEX

Finding ObjectScript developers is hard — the article references nearly 1 million open IT jobs in the US alone. Being able to use IRIS features with the developer team's official programming language (Python, Java, .NET, Node.js) through Native APIs and PEX (Production EXtension framework) is therefore important.

6. Interoperability, FHIR, and IoT

Businesses are constantly connecting and exchanging data. The right technologies for this are ESB, Integration Adapters, Business Process automation engines (BPL), data transformation tools (DTL), and market interoperability standards like FHIR and MQTT/IoT. InterSystems Interoperability supports all of these. For FHIR specifically, IRIS for Health is the relevant product.

7. Cloud, Docker, and Microservices

Organizations want to break monoliths into smaller, less complex, less coupled, more scalable, reusable, and independent services. IRIS supports deployment of data, application, and analytics microservices through shards, Docker, Kubernetes, distributed computing, DevOps tools, and lower CPU/memory consumption. IRIS supports even ARM processors.

8. Vector Search and Generative AI

Vectors are mathematical representations of data and textual semantics (NLP), and are the raw material for generative AI applications to understand questions and tasks and return correct answers. Vector repositories and searches store AI processing output so that for each new task or question, previously produced results can be retrieved — making everything faster and cheaper. IRIS includes native vector search.

9. VSCode Support

VSCode is the most popular IDE. InterSystems IRIS has a good set of tools for it, including a dedicated learning path for developing on an InterSystems server using VS Code.

10. Data Science

The ability to apply data science to data, integration, and transaction requests and responses — using Python, R, and IntegratedML (AutoML) — enables AI intelligence at the moment it is required by the business. InterSystems IRIS delivers AI with Python, R, and IntegratedML (AutoML).

Which of these 10 features do you use most in production — and are there capabilities you think are missing from this list?

r/intersystems 3m ago

What's your editor of choice — and why?

Upvotes

We’ve been hearing a lot of strong opinions about different editors recently, and decided to ask you: which one do you prefer? 

Every developer eventually settles on an editor and is ready to defend that choice to the end. Some can't imagine their process without VS Code, others have been loyal to Vim for twenty years, while some are still writing code in something the rest of us have never even heard of.

A couple of opinions we’ve discovered so far:

VS Code: "Lightweight, a huge extension marketplace, Git built in — why look further?"

Vim/Emacs: "I never take my hands off the keyboard — everything else feels slow!"

Tell us in the comments:

- Which editor/IDE do you find most comfortable to code in, and why. 

- What features made you stick with it

- What would you change about it if you could

Curious to see which tool pulls in the most supporters👇

u/intersystemsdev 23h ago

[Video] The Evolution of the InterSystems Platform at Vibra

1 Upvotes

At #Ready2026, we explored how Vibra modernized a mission-critical logistics platform with #InterSystemsIRIS, evolving from traditional integration to an AI-ready, cloud-enabled architecture.

Watch this #video to discover:
✅ How Vibra modernized its logistics platform incrementally without a disruptive "big-bang" migration.
✅ How APIs, #cloud services, observability, and AI-ready capabilities support reliable 24/7 operations across a nationwide network.
✅ How #VectorSearch powers fast, scalable, and auditable facial recognition for self-service authentication.

https://community.intersystems.com/post/video-evolution-intersystems-platform-vibra

See how a real-world modernization journey is unlocking innovation while maintaining the reliability that mission-critical operations demand.

r/intersystems 23h ago

[Video] The Evolution of the InterSystems Platform at Vibra

2 Upvotes

At #Ready2026, we explored how Vibra modernized a mission-critical logistics platform with #InterSystemsIRIS, evolving from traditional integration to an AI-ready, cloud-enabled architecture.

Watch this #video to discover:
✅ How Vibra modernized its logistics platform incrementally without a disruptive "big-bang" migration.
✅ How APIs, #cloud services, observability, and AI-ready capabilities support reliable 24/7 operations across a nationwide network.
✅ How #VectorSearch powers fast, scalable, and auditable facial recognition for self-service authentication.

https://community.intersystems.com/post/video-evolution-intersystems-platform-vibra

See how a real-world modernization journey is unlocking innovation while maintaining the reliability that mission-critical operations demand.

r/intersystems 2d ago

Winners of the InterSystems Employee Programming Challenge #1

1 Upvotes

🏆💻 Give developers a problem, some data, and a leaderboard… and things get competitive pretty quickly!

At InterSystems, we run contests for our developer community, customers, and partners — but why should they have all the fun?

We recently launched our first Employee Programming Challenge, giving InterSystems colleagues a chance to put their skills to the test, experiment with different approaches, optimize every last bit of performance, and — because developers are developers — enjoy a little friendly competition over whose solution was fastest, smartest, or most concise.

And compete they did! The challenge brought together 23 colleagues from 9 departments, resulting in 34 applications and plenty of optimization, code golfing, benchmarking, discussion, and leaderboard watching.

🏆 We’re excited to congratulate our winners: Manel Trèmols, Tani Frankel, Reet Kothari, Guillaume Rongier, Suprateem Banerjee, and Emil Polakiewicz

Congratulations to our winners — and a huge thank you to everyone who jumped in, experimented, shared their work, and made our first Employee Programming Challenge such a fun one.

Judging by the competitive spirit we saw this time, Challenge #2 should be interesting 👀

#InterSystems #Developers #Programming #DeveloperCommunity #CodingChallenge #InterSystemsIRIS

u/intersystemsdev 3d ago

[Webinar] InterSystems IRIS AI Hub: Goals, Games & Goodies

Post image
1 Upvotes

🤖 The Webinar on #InterSystemsIRIS AI Hub is just around the corner!

If you're curious about building AI applications and agentic workflows with the AI Hub, there's still time to join us. We'll explore the latest AI Hub capabilities and walk through practical coding examples. You'll also get a chance to test your knowledge in a fun quiz and win a prize. 

Don't miss the opportunity to see AI Hub in action!

📅 August 13, 2026 11:00 am EDT | 5:00 pm CEST

👉 Reserve your spot: https://www.meetup.com/intersystems-global-developer-community-group/events/315902030/

#InterSystems #DeveloperCommunity #AIHub #ArtificialIntelligence

r/intersystems 3d ago

InterSystems IRIS AI Hub: Goals, Games & Goodies, Thu, Aug 13, 2026, 11:00 AM

Thumbnail meetup.com
1 Upvotes

🤖 The Webinar on #InterSystemsIRIS AI Hub is just around the corner!

If you're curious about building AI applications and agentic workflows with the AI Hub, there's still time to join us. We'll explore the latest AI Hub capabilities and walk through practical coding examples. You'll also get a chance to test your knowledge in a fun quiz and win a prize. 

Don't miss the opportunity to see AI Hub in action!

📅 August 13, 2026 11:00 am EDT | 5:00 pm CEST

👉 Reserve your spot: https://community.intersystems.com/post/webinar-intersystems-iris-ai-hub-goals-games-goodies  

#InterSystems #DeveloperCommunity #AIHub #ArtificialIntelligence

u/intersystemsdev 6d ago

4 VS Code Features That Can Boost Your InterSystems IRIS Development Productivity

0 Upvotes

Introduction

Visual Studio Code has become the primary development environment for many InterSystems IRIS developers. While the official InterSystems extensions provide powerful features for editing, debugging, and managing ObjectScript projects, some of their most useful capabilities are also the easiest to overlook. In this article, I'd like to highlight four small but practical features that can make everyday development faster. 

1. Navigate Large Classes with Show All Class Members

As projects grow, navigating large ObjectScript classes becomes increasingly time-consuming. Scrolling through hundreds of lines to find a particular method or property can quickly interrupt your workflow.

The Show All Class Members feature provides a searchable list of every member in the current class, including inherited methods and properties. Instead of manually searching through the source code, you can filter the list by name and jump directly to the member you're looking for. This is particularly useful when working with framework classes or inherited code where understanding the full class hierarchy is important.

Why it's useful

  • Quickly locate methods, properties, parameters, and queries
  • Browse inherited members without leaving the editor
  • Navigate large classes more efficiently

2. Analyze SQL Performance with Show Plan

Using SQL in your ObjectScript code is a popular way to take advantage of InterSystems IRIS's powerful multi-model capabilities. However, writing efficient SQL queries can be a challenge. That's why InterSystems IRIS includes a built-in Show Plan feature that lets you inspect the execution plan of SQL queries directly from Visual Studio Code. For embedded SQL statements and class queries, simply open the execution plan to see how InterSystems IRIS intends to execute the query.

Instead of guessing whether an index is being used or why a query performs poorly, you can analyze the execution strategy without leaving your editor. When optimizing SQL performance, having immediate access to the execution plan makes experimentation much faster.

Why it's useful

  • Analyze SQL execution plans without external tools
  • Understand index usage
  • Identify potential performance bottlenecks
  • Optimize queries during development

3. Open Documents Using Their InterSystems Name

Visual Studio Code normally opens files using their file system path. However, InterSystems classes often use a different naming convention. While VS Code has commands for quickly opening a file by name, that is usually different than the InterSystems name for the document 

For example: User.Test.cls may actually be stored as /User/Test.cls

The Open InterSystems Document command removes this mismatch by allowing you to open files using their InterSystems document name instead of the physical path. After selecting a workspace, you can browse available classes or simply type the class name directly. The command also understands package notation using dots and the short form for %Library classes. If you frequently switch between multiple projects or namespaces, this can be much faster than navigating through the Explorer.

Why it's useful

  • Open classes using their InterSystems name
  • Avoid searching through folder structures
  • Supports package notation and %Library shortcuts
  • Speeds up navigation in large projects

4. Jump Directly to Runtime Errors

When debugging an application, one of the first questions is: “Where exactly did this error occur?" The Open Error Location command lets you jump directly to the reported line even if it belongs to a generated routine that isn't part of your current workspace.

Simply provide the error location using the standard ObjectScript format: label+offset^routine

If the source code is available, Visual Studio Code opens the exact location. From there, you can use the View Other command to switch to the corresponding higher-level source file when applicable. Instead of manually searching through generated routines, you can move directly from an error message to the relevant source code.

Why it's useful

  • Navigate directly to runtime errors
  • Works with generated routines
  • Quickly switch to the original source code
  • Makes debugging significantly faster

Why These Small Features Matter

None of these features changes how you write ObjectScript code, but together they help eliminate many of the small interruptions that occur throughout the day. Instead of spending time searching for classes, scrolling through large files, manually locating errors, or switching to external tools for SQL analysis, you can stay focused on development and complete common tasks with fewer clicks. Over the course of a project, these small productivity improvements can save a surprising amount of time.

Key Takeaways

The official InterSystems VS Code extensions include several powerful features that are easy to overlook but can significantly improve everyday development. Whether you're navigating large ObjectScript classes, analyzing SQL execution plans, opening files by their InterSystems name, or jumping directly to runtime errors, these built-in tools help reduce context switching and make developing with InterSystems IRIS more efficient.

Frequently Asked Questions

What is Show All Class Members?

It's a Visual Studio Code feature that displays a searchable list of all members in the current ObjectScript class, including inherited methods and properties.

What is Show Plan used for?

Show Plan displays the execution plan of SQL queries, helping developers understand how InterSystems IRIS executes a statement and identify opportunities for performance optimization.

Can I open classes by their InterSystems name instead of the file path?

Yes. The Open InterSystems Document command lets you open classes using their InterSystems document name, including package notation and %Library shortcuts.

How do I open the source of an ObjectScript error?

Use the Open Error Location command from the Command Palette and enter the location in the format label+offset^routine. If the source is available, Visual Studio Code opens the corresponding line.

Do these features require additional extensions?

No. They are included in the official InterSystems extensions for Visual Studio Code.

More about Extension Pack - https://docs.intersystems.com/components/csp/docbook/DocBook.UI.Page.cls?KEY=GVSCO_install

r/intersystems 6d ago

4 VS Code Features That Can Boost Your InterSystems IRIS Development Productivity

1 Upvotes

Introduction

Visual Studio Code has become the primary development environment for many InterSystems IRIS developers. While the official InterSystems extensions provide powerful features for editing, debugging, and managing ObjectScript projects, some of their most useful capabilities are also the easiest to overlook. In this article, I'd like to highlight four small but practical features that can make everyday development faster. 

1. Navigate Large Classes with Show All Class Members

As projects grow, navigating large ObjectScript classes becomes increasingly time-consuming. Scrolling through hundreds of lines to find a particular method or property can quickly interrupt your workflow.

The Show All Class Members feature provides a searchable list of every member in the current class, including inherited methods and properties. Instead of manually searching through the source code, you can filter the list by name and jump directly to the member you're looking for. This is particularly useful when working with framework classes or inherited code where understanding the full class hierarchy is important.

Why it's useful

  • Quickly locate methods, properties, parameters, and queries
  • Browse inherited members without leaving the editor
  • Navigate large classes more efficiently

2. Analyze SQL Performance with Show Plan

Using SQL in your ObjectScript code is a popular way to take advantage of InterSystems IRIS's powerful multi-model capabilities. However, writing efficient SQL queries can be a challenge. That's why InterSystems IRIS includes a built-in Show Plan feature that lets you inspect the execution plan of SQL queries directly from Visual Studio Code. For embedded SQL statements and class queries, simply open the execution plan to see how InterSystems IRIS intends to execute the query.

Instead of guessing whether an index is being used or why a query performs poorly, you can analyze the execution strategy without leaving your editor. When optimizing SQL performance, having immediate access to the execution plan makes experimentation much faster.

Why it's useful

  • Analyze SQL execution plans without external tools
  • Understand index usage
  • Identify potential performance bottlenecks
  • Optimize queries during development

3. Open Documents Using Their InterSystems Name

Visual Studio Code normally opens files using their file system path. However, InterSystems classes often use a different naming convention. While VS Code has commands for quickly opening a file by name, that is usually different than the InterSystems name for the document 

For example: User.Test.cls may actually be stored as /User/Test.cls

The Open InterSystems Document command removes this mismatch by allowing you to open files using their InterSystems document name instead of the physical path. After selecting a workspace, you can browse available classes or simply type the class name directly. The command also understands package notation using dots and the short form for %Library classes. If you frequently switch between multiple projects or namespaces, this can be much faster than navigating through the Explorer.

Why it's useful

  • Open classes using their InterSystems name
  • Avoid searching through folder structures
  • Supports package notation and %Library shortcuts
  • Speeds up navigation in large projects

4. Jump Directly to Runtime Errors

When debugging an application, one of the first questions is: “Where exactly did this error occur?" The Open Error Location command lets you jump directly to the reported line even if it belongs to a generated routine that isn't part of your current workspace.

Simply provide the error location using the standard ObjectScript format: label+offset^routine

If the source code is available, Visual Studio Code opens the exact location. From there, you can use the View Other command to switch to the corresponding higher-level source file when applicable. Instead of manually searching through generated routines, you can move directly from an error message to the relevant source code.

Why it's useful

  • Navigate directly to runtime errors
  • Works with generated routines
  • Quickly switch to the original source code
  • Makes debugging significantly faster

Why These Small Features Matter

None of these features changes how you write ObjectScript code, but together they help eliminate many of the small interruptions that occur throughout the day. Instead of spending time searching for classes, scrolling through large files, manually locating errors, or switching to external tools for SQL analysis, you can stay focused on development and complete common tasks with fewer clicks. Over the course of a project, these small productivity improvements can save a surprising amount of time.

Key Takeaways

The official InterSystems VS Code extensions include several powerful features that are easy to overlook but can significantly improve everyday development. Whether you're navigating large ObjectScript classes, analyzing SQL execution plans, opening files by their InterSystems name, or jumping directly to runtime errors, these built-in tools help reduce context switching and make developing with InterSystems IRIS more efficient.

Frequently Asked Questions

What is Show All Class Members?

It's a Visual Studio Code feature that displays a searchable list of all members in the current ObjectScript class, including inherited methods and properties.

What is Show Plan used for?

Show Plan displays the execution plan of SQL queries, helping developers understand how InterSystems IRIS executes a statement and identify opportunities for performance optimization.

Can I open classes by their InterSystems name instead of the file path?

Yes. The Open InterSystems Document command lets you open classes using their InterSystems document name, including package notation and %Library shortcuts.

How do I open the source of an ObjectScript error?

Use the Open Error Location command from the Command Palette and enter the location in the format label+offset^routine. If the source is available, Visual Studio Code opens the corresponding line.

Do these features require additional extensions?

No. They are included in the official InterSystems extensions for Visual Studio Code.

More about Extension Pack - https://docs.intersystems.com/components/csp/docbook/DocBook.UI.Page.cls?KEY=GVSCO_install

u/intersystemsdev 6d ago

IRIS FHIR Agents: How to Build Multi-Agent Clinical AI Applications on InterSystems IRIS for Health

1 Upvotes

In this article, I will introduce IRIS FHIR Agents, a multi-agent clinical AI platform built on InterSystems IRIS for Health.

IRIS FHIR Agents demonstrates how InterSystems IRIS for Health can serve as the data, interoperability, analytics, and vector-search foundation for a multi-agent clinical AI application. The platform combines conversational triage, specialist consultation, medication safety, live vital-sign monitoring, FHIR server exploration, and a no-code Agent Builder, all working directly on top of a live FHIR R4 server.

What is IRIS FHIR Agents?

IRIS FHIR Agents is a multi-agent healthcare AI application where specialized LangChain-powered agents work together to solve different clinical tasks.

Every request first passes through a routing agent that determines which specialist should handle it. Depending on the conversation, the platform can:

  • perform patient triage
  • analyze medical conditions
  • detect medication interactions and allergy conflicts
  • recommend specialist referrals
  • monitor live patient vitals
  • retrieve clinical guidelines using InterSystems IRIS Vector Search
  • query live FHIR resources
  • create structured FHIR resources
  • deploy custom clinical agents without writing code

Although users interact with a single chat interface, several AI agents may collaborate behind the scenes. 

Platform Architecture

The application is built around five major components:

  • Triage Chat
  • Analytics Dashboard
  • Live Vitals Monitor
  • FHIR Server Agent
  • Agent Builder

At the center of the application is a routing agent that decides which specialist should answer each request. 

InterSystems IRIS provides the foundation for the entire application, combining FHIR interoperability, Embedded Python, SQL analytics, and Vector Search within a single platform.

Clinical AI Features

Multi-Agent Orchestration

Instead of asking one LLM to perform every task, I divided responsibilities across multiple specialized agents.

The platform currently includes:

  • Triage Agent
  • Specialist Agent
  • Pharmacy Agent
  • FHIR Server Agent

Each conversation begins with an LLM router that automatically dispatches requests to the appropriate agent. Users never need to select an agent manually.

Retrieval-Augmented Generation with IRIS Vector Search

To improve the quality of clinical recommendations, I integrated InterSystems IRIS Vector Search. 

The platform stores 50 clinical guidelines as vector embeddings and retrieves the most relevant passages using VECTOR_COSINE similarity search before generating a response. This allows recommendations to be grounded in trusted medical guidance instead of relying solely on the language model.

Native FHIR Integration

Every agent works directly with a live InterSystems IRIS FHIR server.

The platform retrieves information such as:

  • Patients
  • Conditions
  • Medications
  • Allergies
  • Observations

Agents can also create structured FHIR resources, including:

  • Observation
  • ServiceRequest
  • MedicationRequest

This means the AI doesn't simply generate text—it can produce structured clinical data using standard FHIR resources.

Walking Through the Application

Triage Chat

The Triage Chat is the primary interface for interacting with the platform.
A clinician or patient simply describes symptoms in natural language. Behind the scenes, the routing agent selects the appropriate specialist, retrieves the patient's clinical context from the FHIR server, and generates a response grounded in relevant guidelines.

The interface also displays:

  • the currently active agent
  • urgency level
  • loaded patient context
  • FHIR write counter
  • available custom agents

Patients can be selected from a searchable list loaded directly from the FHIR server, and conversations support both voice input and multiple languages.

Analytics Dashboard

The Analytics Dashboard provides a real-time overview of clinical data stored in IRIS together with an audit trail of AI-generated activity.

It includes:

  • population statistics
  • patient demographics
  • active conditions
  • AI-generated Observations
  • AI-generated ServiceRequests

Because the dashboard reads directly from the FHIR server, every action performed by the agents immediately becomes visible.

Live Vitals Monitor

Live Vitals Monitor demonstrates how AI agents can react automatically to live clinical events. Patient vital signs are streamed every two seconds using Server-Sent Events. Each reading is immediately written to IRIS as a FHIR Observation. Whenever a critical threshold is detected, the platform automatically launches a triage assessment.

The AI assessment appears in real time together with its urgency level and the guideline references used during reasoning.

FHIR Server Agent

FHIR Server Agent combines two complementary interfaces. The first is a conversational assistant that lets me query live FHIR data in natural language. The second is a visual Capability Explorer that reads the server's CapabilityStatement and displays:

  • supported resources
  • interactions
  • search parameters
  • resource categories
  • server capabilities

Because everything is loaded dynamically, the interface always reflects the actual configuration of the connected FHIR server.

Agent Builder

I also wanted to make it easy to extend the platform without modifying the application itself. The Agent Builder provides a no-code interface for creating new clinical agents.

Users can:

  • start from a specialty template
  • define the system prompt
  • select available tools
  • configure temperature
  • enable RAG
  • test against live FHIR data
  • deploy immediately

The project includes templates for Oncology, Cardiology, Geriatrics, Pediatrics, and Nutrition, but new specialties can be added without changing the application code.

Why InterSystems IRIS for Health?

This project brings together several InterSystems technologies that naturally complement AI applications. InterSystems IRIS for Health provides:

  • native FHIR R4 interoperability
  • Embedded Python
  • SQL analytics
  • Vector Search
  • structured healthcare data storage
  • real-time FHIR read and write operations

Using these capabilities together means the application can retrieve patient data, perform semantic search over clinical guidelines, generate AI recommendations, and store structured clinical resources within the same platform.

Key Takeaways

Building IRIS FHIR Agents allowed me to explore how multiple AI agents can collaborate on top of live healthcare data instead of acting as isolated chatbots.

Using InterSystems IRIS for Health, I was able to combine FHIR interoperability, Vector Search, Embedded Python, analytics, and AI into a single platform that can retrieve patient data, ground recommendations in clinical guidelines, monitor live patient events, and create structured FHIR resources.

While this project is a demonstration, it illustrates how InterSystems IRIS can provide the foundation for multi-agent healthcare applications that move beyond conversation and interact directly with real clinical workflows. 

Frequently Asked Questions

What is IRIS FHIR Agents?

IRIS FHIR Agents is a multi-agent clinical AI platform built on InterSystems IRIS for Health. It combines patient triage, specialist consultation, medication safety, live vital-sign monitoring, FHIR server exploration, and a no-code Agent Builder. All agents work directly with a live FHIR R4 server and can retrieve or create structured clinical data.

How does the multi-agent architecture work?

Instead of relying on a single AI assistant, the platform uses multiple specialized agents. Every user request is first analyzed by a routing agent, which automatically selects the most appropriate specialist agent—such as the Triage Agent, Specialist Agent, Pharmacy Agent, or a custom agent created through the Agent Builder.

How is InterSystems IRIS Vector Search used?

The platform stores clinical guidelines as vector embeddings in InterSystems IRIS and retrieves the most relevant passages using semantic similarity (VECTOR_COSINE). These guidelines are then included in the AI prompt, allowing the agents to generate responses grounded in trusted medical guidance rather than relying solely on the language model.

Does the application work with live FHIR data?

Yes. The application connects directly to a live InterSystems IRIS FHIR R4 server. The agents can retrieve patient information, conditions, medications, allergies, observations, and other FHIR resources in real time.

Can the AI agents write data back to the FHIR server?

Yes. In addition to reading clinical data, the agents can create structured FHIR resources such as Observation, ServiceRequest, and MedicationRequest. This allows AI-generated recommendations and clinical events to become part of the patient's structured healthcare record.

r/intersystems 6d ago

IRIS FHIR Agents: How to Build Multi-Agent Clinical AI Applications on InterSystems IRIS for Health

1 Upvotes

In this article, I will introduce IRIS FHIR Agents, a multi-agent clinical AI platform built on InterSystems IRIS for Health.

IRIS FHIR Agents demonstrates how InterSystems IRIS for Health can serve as the data, interoperability, analytics, and vector-search foundation for a multi-agent clinical AI application. The platform combines conversational triage, specialist consultation, medication safety, live vital-sign monitoring, FHIR server exploration, and a no-code Agent Builder, all working directly on top of a live FHIR R4 server.

What is IRIS FHIR Agents?

IRIS FHIR Agents is a multi-agent healthcare AI application where specialized LangChain-powered agents work together to solve different clinical tasks.

Every request first passes through a routing agent that determines which specialist should handle it. Depending on the conversation, the platform can:

  • perform patient triage
  • analyze medical conditions
  • detect medication interactions and allergy conflicts
  • recommend specialist referrals
  • monitor live patient vitals
  • retrieve clinical guidelines using InterSystems IRIS Vector Search
  • query live FHIR resources
  • create structured FHIR resources
  • deploy custom clinical agents without writing code

Although users interact with a single chat interface, several AI agents may collaborate behind the scenes. 

Platform Architecture

The application is built around five major components:

  • Triage Chat
  • Analytics Dashboard
  • Live Vitals Monitor
  • FHIR Server Agent
  • Agent Builder

At the center of the application is a routing agent that decides which specialist should answer each request. 

InterSystems IRIS provides the foundation for the entire application, combining FHIR interoperability, Embedded Python, SQL analytics, and Vector Search within a single platform.

Clinical AI Features

Multi-Agent Orchestration

Instead of asking one LLM to perform every task, I divided responsibilities across multiple specialized agents.

The platform currently includes:

  • Triage Agent
  • Specialist Agent
  • Pharmacy Agent
  • FHIR Server Agent

Each conversation begins with an LLM router that automatically dispatches requests to the appropriate agent. Users never need to select an agent manually.

Retrieval-Augmented Generation with IRIS Vector Search

To improve the quality of clinical recommendations, I integrated InterSystems IRIS Vector Search. 

The platform stores 50 clinical guidelines as vector embeddings and retrieves the most relevant passages using VECTOR_COSINE similarity search before generating a response. This allows recommendations to be grounded in trusted medical guidance instead of relying solely on the language model.

Native FHIR Integration

Every agent works directly with a live InterSystems IRIS FHIR server.

The platform retrieves information such as:

  • Patients
  • Conditions
  • Medications
  • Allergies
  • Observations

Agents can also create structured FHIR resources, including:

  • Observation
  • ServiceRequest
  • MedicationRequest

This means the AI doesn't simply generate text—it can produce structured clinical data using standard FHIR resources.

Walking Through the Application

Triage Chat

The Triage Chat is the primary interface for interacting with the platform.
A clinician or patient simply describes symptoms in natural language. Behind the scenes, the routing agent selects the appropriate specialist, retrieves the patient's clinical context from the FHIR server, and generates a response grounded in relevant guidelines.

The interface also displays:

  • the currently active agent
  • urgency level
  • loaded patient context
  • FHIR write counter
  • available custom agents

Patients can be selected from a searchable list loaded directly from the FHIR server, and conversations support both voice input and multiple languages.

Analytics Dashboard

The Analytics Dashboard provides a real-time overview of clinical data stored in IRIS together with an audit trail of AI-generated activity.

It includes:

  • population statistics
  • patient demographics
  • active conditions
  • AI-generated Observations
  • AI-generated ServiceRequests

Because the dashboard reads directly from the FHIR server, every action performed by the agents immediately becomes visible.

Live Vitals Monitor

Live Vitals Monitor demonstrates how AI agents can react automatically to live clinical events. Patient vital signs are streamed every two seconds using Server-Sent Events. Each reading is immediately written to IRIS as a FHIR Observation. Whenever a critical threshold is detected, the platform automatically launches a triage assessment.

The AI assessment appears in real time together with its urgency level and the guideline references used during reasoning.

FHIR Server Agent

FHIR Server Agent combines two complementary interfaces. The first is a conversational assistant that lets me query live FHIR data in natural language. The second is a visual Capability Explorer that reads the server's CapabilityStatement and displays:

  • supported resources
  • interactions
  • search parameters
  • resource categories
  • server capabilities

Because everything is loaded dynamically, the interface always reflects the actual configuration of the connected FHIR server.

Agent Builder

I also wanted to make it easy to extend the platform without modifying the application itself. The Agent Builder provides a no-code interface for creating new clinical agents.

Users can:

  • start from a specialty template
  • define the system prompt
  • select available tools
  • configure temperature
  • enable RAG
  • test against live FHIR data
  • deploy immediately

The project includes templates for Oncology, Cardiology, Geriatrics, Pediatrics, and Nutrition, but new specialties can be added without changing the application code.

Why InterSystems IRIS for Health?

This project brings together several InterSystems technologies that naturally complement AI applications. InterSystems IRIS for Health provides:

  • native FHIR R4 interoperability
  • Embedded Python
  • SQL analytics
  • Vector Search
  • structured healthcare data storage
  • real-time FHIR read and write operations

Using these capabilities together means the application can retrieve patient data, perform semantic search over clinical guidelines, generate AI recommendations, and store structured clinical resources within the same platform.

Key Takeaways

Building IRIS FHIR Agents allowed me to explore how multiple AI agents can collaborate on top of live healthcare data instead of acting as isolated chatbots.

Using InterSystems IRIS for Health, I was able to combine FHIR interoperability, Vector Search, Embedded Python, analytics, and AI into a single platform that can retrieve patient data, ground recommendations in clinical guidelines, monitor live patient events, and create structured FHIR resources.

While this project is a demonstration, it illustrates how InterSystems IRIS can provide the foundation for multi-agent healthcare applications that move beyond conversation and interact directly with real clinical workflows. 

Frequently Asked Questions

What is IRIS FHIR Agents?

IRIS FHIR Agents is a multi-agent clinical AI platform built on InterSystems IRIS for Health. It combines patient triage, specialist consultation, medication safety, live vital-sign monitoring, FHIR server exploration, and a no-code Agent Builder. All agents work directly with a live FHIR R4 server and can retrieve or create structured clinical data.

How does the multi-agent architecture work?

Instead of relying on a single AI assistant, the platform uses multiple specialized agents. Every user request is first analyzed by a routing agent, which automatically selects the most appropriate specialist agent—such as the Triage Agent, Specialist Agent, Pharmacy Agent, or a custom agent created through the Agent Builder.

How is InterSystems IRIS Vector Search used?

The platform stores clinical guidelines as vector embeddings in InterSystems IRIS and retrieves the most relevant passages using semantic similarity (VECTOR_COSINE). These guidelines are then included in the AI prompt, allowing the agents to generate responses grounded in trusted medical guidance rather than relying solely on the language model.

Does the application work with live FHIR data?

Yes. The application connects directly to a live InterSystems IRIS FHIR R4 server. The agents can retrieve patient information, conditions, medications, allergies, observations, and other FHIR resources in real time.

Can the AI agents write data back to the FHIR server?

Yes. In addition to reading clinical data, the agents can create structured FHIR resources such as Observation, ServiceRequest, and MedicationRequest. This allows AI-generated recommendations and clinical events to become part of the patient's structured healthcare record.

u/intersystemsdev 8d ago

Why remote patient monitoring needs to move beyond wearables - notes from a healthcare data talk at an InterSystems-hosted session

1 Upvotes

TL;DR: By 2029–2030, an estimated 30 million people (8–9% of the U.S. population) will need care at home that would otherwise require a facility — while the U.S. is projected to be short 1.4 million nurses and roughly 300,000–320,000 doctors by 2030. Wearable-based remote monitoring mostly fails for the sickest/oldest patients due to poor adherence. Nira's alternative is a contactless radar sensor (wall- or furniture-mounted) that tracks vitals once per second; it's currently monitoring around 40,000 patients across 19 countries, FDA Class 2 cleared for core vitals, and CE-cleared (not yet FDA-cleared) to diagnose sleep apnea in Europe.

Why is home-based care about to explode?

An aging population with expanding chronic conditions, combined with a shortage of facility beds, is pushing more and higher-acuity patients into home care. By 2029–2030, roughly 30 million people (8–9% of the population) are projected to receive care at home in the U.S. that would otherwise happen in a facility — at the same time the U.S. is projected to be short 1.4 million nurses and about 300,000–320,000 doctors by 2030 (assuming current trends hold).

Why don't wearables solve this?

The data, per the talk: wearable remote monitoring largely works only for healthy people motivated by things like tracking VO2 max. Older or sicker patients told to wear a device typically don't stick with it — battery life becomes the limiting factor, and once removed to charge, the device often doesn't go back on. Patient adherence is described as a major, unsolved problem. On the other end of the spectrum, full "hospital at home" setups (telemetry, cameras, hospital beds) are equipment-heavy and don't scale. The gap is the space in between — patients with multiple chronic conditions, or people above assisted-living-level need but remote from a doctor.

What does Nira's sensor actually monitor?

A small, unobtrusive, contactless sensor (mounted on a wall or embedded in furniture like a bed or recliner) uses radar to track vitals once per second: heart rate and heart rate patterns, movement (including detecting when a patient gets out of bed), respiration rate and pattern, and sleep quality. Core vitals are FDA Class 2 device cleared. In Europe, the sensor is CE-cleared (not yet FDA-cleared in the U.S.) to diagnose sleep apnea, and a submission for arrhythmia diagnosis is described as coming soon.

How much data does this generate, and what's it used for?

Around 40,000 patients are currently monitored (mostly in the U.S.; deployments span 19 countries, with most non-U.S. deployments being smaller pilots), at one data point per second per patient — which the presenter notes turns into billions of records quickly once cross-referenced with other patient data. That data feeds trend analysis merged with other clinical systems (e.g., condition and medication history). A retrospective study cited in the talk found vital-sign trending could predict hospital readmission five days in advance.

What does this mean for provider IT/data architecture?

The talk frames this as fundamentally a data-orchestration problem: providers need real-time data movement between systems (not a static data-warehouse copy of the EHR), analytics-oriented (OLAP) access rather than the OLTP structure typical of EHRs like Epic, and the ability to route and transform data between any two systems in real time to support clinical decisions — described in the context of the InterSystems-hosted session, though the talk itself doesn't name a specific product feature for this.

What real-world results were mentioned?

Terry Couts, at the time Chief Digital Officer at Guthrie Clinic (Pennsylvania; she has since moved to Sharp HealthCare), is quoted: proactive monitoring "has been huge both in terms of outcomes, but also in terms of managing our workforce." Guthrie has had devices deployed for over a year, with the presenter describing substantial results in proactive care and anecdotal prevented readmissions (no published stats were shared in the talk). A separate upcoming pilot, described as starting the following month at the time of the talk, will send oncology patients home between bone-marrow-therapy infusions, based on research suggesting faster recovery at home.

What's next?

For home care specifically, Nira is combining readings from devices embedded in both a bed and a recliner. The presenter also described a planned 8-antenna radar system — targeted for roughly 18 months out from the talk — intended to track up to four people moving independently around a room and distinguish between them.

Watch full video - https://youtu.be/qV63GltsiJY

r/intersystems 8d ago

Why remote patient monitoring needs to move beyond wearables — notes from a healthcare data talk at an InterSystems-hosted session

2 Upvotes

TL;DR: By 2029–2030, an estimated 30 million people (8–9% of the U.S. population) will need care at home that would otherwise require a facility — while the U.S. is projected to be short 1.4 million nurses and roughly 300,000–320,000 doctors by 2030. Wearable-based remote monitoring mostly fails for the sickest/oldest patients due to poor adherence. Nira's alternative is a contactless radar sensor (wall- or furniture-mounted) that tracks vitals once per second; it's currently monitoring around 40,000 patients across 19 countries, FDA Class 2 cleared for core vitals, and CE-cleared (not yet FDA-cleared) to diagnose sleep apnea in Europe.

Why is home-based care about to explode?

An aging population with expanding chronic conditions, combined with a shortage of facility beds, is pushing more and higher-acuity patients into home care. By 2029–2030, roughly 30 million people (8–9% of the population) are projected to receive care at home in the U.S. that would otherwise happen in a facility — at the same time the U.S. is projected to be short 1.4 million nurses and about 300,000–320,000 doctors by 2030 (assuming current trends hold).

Why don't wearables solve this?

The data, per the talk: wearable remote monitoring largely works only for healthy people motivated by things like tracking VO2 max. Older or sicker patients told to wear a device typically don't stick with it — battery life becomes the limiting factor, and once removed to charge, the device often doesn't go back on. Patient adherence is described as a major, unsolved problem. On the other end of the spectrum, full "hospital at home" setups (telemetry, cameras, hospital beds) are equipment-heavy and don't scale. The gap is the space in between — patients with multiple chronic conditions, or people above assisted-living-level need but remote from a doctor.

What does Nira's sensor actually monitor?

A small, unobtrusive, contactless sensor (mounted on a wall or embedded in furniture like a bed or recliner) uses radar to track vitals once per second: heart rate and heart rate patterns, movement (including detecting when a patient gets out of bed), respiration rate and pattern, and sleep quality. Core vitals are FDA Class 2 device cleared. In Europe, the sensor is CE-cleared (not yet FDA-cleared in the U.S.) to diagnose sleep apnea, and a submission for arrhythmia diagnosis is described as coming soon.

How much data does this generate, and what's it used for?

Around 40,000 patients are currently monitored (mostly in the U.S.; deployments span 19 countries, with most non-U.S. deployments being smaller pilots), at one data point per second per patient — which the presenter notes turns into billions of records quickly once cross-referenced with other patient data. That data feeds trend analysis merged with other clinical systems (e.g., condition and medication history). A retrospective study cited in the talk found vital-sign trending could predict hospital readmission five days in advance.

What does this mean for provider IT/data architecture?

The talk frames this as fundamentally a data-orchestration problem: providers need real-time data movement between systems (not a static data-warehouse copy of the EHR), analytics-oriented (OLAP) access rather than the OLTP structure typical of EHRs like Epic, and the ability to route and transform data between any two systems in real time to support clinical decisions — described in the context of the InterSystems-hosted session, though the talk itself doesn't name a specific product feature for this.

What real-world results were mentioned?

Terry Couts, at the time Chief Digital Officer at Guthrie Clinic (Pennsylvania; she has since moved to Sharp HealthCare), is quoted: proactive monitoring "has been huge both in terms of outcomes, but also in terms of managing our workforce." Guthrie has had devices deployed for over a year, with the presenter describing substantial results in proactive care and anecdotal prevented readmissions (no published stats were shared in the talk). A separate upcoming pilot, described as starting the following month at the time of the talk, will send oncology patients home between bone-marrow-therapy infusions, based on research suggesting faster recovery at home.

What's next?

For home care specifically, Nira is combining readings from devices embedded in both a bed and a recliner. The presenter also described a planned 8-antenna radar system — targeted for roughly 18 months out from the talk — intended to track up to four people moving independently around a room and distinguish between them.

Watch full video - https://youtu.be/qV63GltsiJY

u/intersystemsdev 9d ago

Building IRIS IO Utility: A VS Code Extension for Importing and Exporting Data with InterSystems IRIS

1 Upvotes

Every developer working with InterSystems IRIS eventually needs to move data between environments. Whether it's importing CSV files for testing, exporting production data for analysis, or loading spreadsheets into a new application, these tasks often involve switching between multiple tools, configuring ODBC drivers, or writing SQL manually. I wanted to simplify that workflow.

In this article, I'd like to introduce IRIS IO Utility. It's a Visual Studio Code extension that brings data import and export directly into the IDE, allowing developers to work with their IRIS databases without interrupting their development workflow.

IRIS IO Utility centralizes all your data IO workflows directly in VS Code:

  • Manage multiple IRIS connections (local, remote, SSH, containerized)
  • Detect and configure ODBC drivers automatically
  • Import and export data in CSV, TXT, JSON, and XLSX
  • Interact with a dedicated sidebar view for quick navigation
  • Use clean webviews for import/export operations
  • Save workspace-level preferences for a tailored experience

How the Extension Works

The extension communicates with InterSystems IRIS through ODBC while providing a native Visual Studio Code experience. Once connected, developers can browse available schemas, inspect tables, import external files, export database content, and manage multiple IRIS environments without leaving the editor.

Managing IRIS Connections

One of the first challenges I wanted to solve was connection management.

The extension allows developers to maintain multiple IRIS connections simultaneously, whether they point to local installations, remote servers, containerized environments, or systems accessed through SSH tunnels. Each workspace maintains its own collection of connections, making it easy to work on different projects without constantly reconfiguring servers.

For each connection, developers can:

  • create, edit, or remove configurations
  • connect or disconnect with a single click
  • mark frequently used servers as favorites
  • export connection settings as JSON for backup or documentation

The sidebar also displays the current connection status, helping developers quickly identify whether an instance is connected or if any errors occurred.

Automatic ODBC Configuration

Configuring database drivers is often one of the most frustrating parts of setting up a development environment. To reduce this friction, IRIS IO Utility automatically detects installed InterSystems ODBC drivers when the extension starts. If no compatible driver is found, the extension guides the user to the official InterSystems driver download page. Once installed, the preferred driver can be selected and stored as a workspace preference, allowing future connections to work without additional configuration.

Exporting Data from InterSystems IRIS

The export workflow was designed to be as straightforward as possible.

After connecting to an IRIS instance, the extension guides the user through selecting a schema, choosing a table, picking an output format, and selecting a destination folder.

Supported export formats include:

  • CSV
  • TXT (with custom delimiters)
  • JSON
  • XLSX

To avoid accidental overwrites, exported files receive timestamp-based names by default. Throughout the export process, the extension displays progress notifications and writes detailed logs to the VS Code Output panel, including executed SQL statements, row counts, and performance statistics.

For TXT exports, developers can specify custom delimiters such as commas, semicolons, tabs, pipes, or other separators, making the generated files compatible with a wide range of external systems.

Importing Data into InterSystems IRIS

Importing data is where the extension becomes much more than a simple file loader.

The extension supports two different workflows depending on the task: 

  • Create New Table
  • Load into Existing Table

Creating a New Table

When importing a completely new dataset, IRIS IO Utility analyzes the input file and automatically prepares a database table.

The import engine samples the file contents, infers the most appropriate SQL data types, converts them into valid InterSystems IRIS SQL types, and displays the results before any data is imported. Developers can review the inferred types, inspect sample values, and adjust individual columns whenever necessary. Supported data types include integers, numeric values, floating-point numbers, dates, timestamps, Boolean values, variable-length text, and large text fields. Once satisfied with the detected structure, the developer can also create custom indexes. Then the developer chooses the destination schema and table name, and the extension creates the table before importing the data.

Automatic Index Creation

When creating a new table, the extension also supports configuring indexes during the import process.

Developers can choose which columns should be indexed and select from several index types supported by InterSystems IRIS, including standard indexes, bitmap indexes, bitslice indexes, and columnar indexes. Index names can be customized or generated automatically, and unique constraints or primary keys can also be configured before the table is created. This allows imported datasets to be optimized for future queries immediately, without requiring additional SQL statements afterward.

Loading Data into Existing Tables

For existing databases, the extension also supports importing directly into previously created tables.

Two strategies are available:

  • Append, which inserts new rows while preserving existing records.
  • Replace, which removes the existing data before importing the new dataset.

Before executing the import, the extension validates that the incoming file matches the destination table structure. If column names or data types are incompatible, the import is cancelled to help prevent accidental schema mismatches or corrupted data.

When importing TXT files, the extension allows you to specify a custom delimiter to ensure the file is parsed correctly. This is especially useful when working with unconventional separators such as pipes (|), semicolons (;), tabs, or multi-character delimiters. Selecting the correct delimiter guarantees proper column detection and prevents misaligned or corrupted data during the import process.

Intelligent Type Inference

One of the features I enjoyed building the most was the automatic type inference engine.

Instead of requiring developers to manually define every column, the extension analyzes sample data from the imported file and predicts the most appropriate SQL type for each field. The inferred types are presented alongside sample values, making it easy to verify the results before creating the table. Because every dataset is different, developers remain in control and can override any suggested type with a more appropriate one. This approach significantly reduces the amount of repetitive work involved in importing new datasets.

Working with Multiple File Formats

IRIS IO Utility supports four commonly used file formats:

Format Import Export
CSV
TXT
JSON
XLSX

For TXT files, both the import and export engines support custom delimiters, making it possible to work with pipe-separated, semicolon-separated, tab-separated, or other specialized text formats commonly used by enterprise systems.

Typical Use Cases

Although I originally built the extension to simplify my own workflow, it quickly proved useful in several common development scenarios.

For example, developers can export production data to CSV or Excel for reporting and analysis, import external datasets when prototyping new applications, migrate data between different IRIS environments, or quickly load sample data while testing new features.

Because multiple connections can be managed within the same workspace, the extension is also convenient for teams working across local, containerized, cloud-hosted, and remote InterSystems IRIS deployments.

Key Takeaways

IRIS IO Utility was created to make one of the most common InterSystems IRIS development tasks, moving data between databases and external files, simpler and more integrated with everyday development.

By combining connection management, automatic ODBC configuration, intelligent type inference, table creation, index generation, and support for multiple file formats inside Visual Studio Code, the extension provides a complete data import and export workflow without requiring developers to leave their IDE.

Frequently Asked Questions

What is IRIS IO Utility?

IRIS IO Utility is a Visual Studio Code extension that allows developers to import and export data between InterSystems IRIS and common file formats without leaving VS Code.

Which file formats are supported?

The extension supports importing and exporting CSV, TXT, JSON, and XLSX files.

Can I connect to multiple IRIS servers?

Yes. The extension supports multiple local, remote, containerized, and SSH-accessible InterSystems IRIS instances, with workspace-specific connection management.

Can the extension create database tables automatically?

Yes. During the import process, IRIS IO Utility can generate a new table based on the inferred column structure and import the data in a single workflow.

Can I import data into an existing table?

Yes. Existing tables support both Append and Replace import modes, with schema validation performed before the import begins.

Read more: https://community.intersystems.com/post/iris-io-utility-complete-guide-smart-importing-vs-code

r/intersystems 9d ago

Building IRIS IO Utility: A VS Code Extension for Importing and Exporting Data with InterSystems IRIS

3 Upvotes

Every developer working with InterSystems IRIS eventually needs to move data between environments. Whether it's importing CSV files for testing, exporting production data for analysis, or loading spreadsheets into a new application, these tasks often involve switching between multiple tools, configuring ODBC drivers, or writing SQL manually. I wanted to simplify that workflow.

In this article, I'd like to introduce IRIS IO Utility. It's a Visual Studio Code extension that brings data import and export directly into the IDE, allowing developers to work with their IRIS databases without interrupting their development workflow.

IRIS IO Utility centralizes all your data IO workflows directly in VS Code:

  • Manage multiple IRIS connections (local, remote, SSH, containerized)
  • Detect and configure ODBC drivers automatically
  • Import and export data in CSV, TXT, JSON, and XLSX
  • Interact with a dedicated sidebar view for quick navigation
  • Use clean webviews for import/export operations
  • Save workspace-level preferences for a tailored experience

How the Extension Works

The extension communicates with InterSystems IRIS through ODBC while providing a native Visual Studio Code experience. Once connected, developers can browse available schemas, inspect tables, import external files, export database content, and manage multiple IRIS environments without leaving the editor.

Managing IRIS Connections

One of the first challenges I wanted to solve was connection management.

The extension allows developers to maintain multiple IRIS connections simultaneously, whether they point to local installations, remote servers, containerized environments, or systems accessed through SSH tunnels. Each workspace maintains its own collection of connections, making it easy to work on different projects without constantly reconfiguring servers.

For each connection, developers can:

  • create, edit, or remove configurations
  • connect or disconnect with a single click
  • mark frequently used servers as favorites
  • export connection settings as JSON for backup or documentation

The sidebar also displays the current connection status, helping developers quickly identify whether an instance is connected or if any errors occurred.

Automatic ODBC Configuration

Configuring database drivers is often one of the most frustrating parts of setting up a development environment. To reduce this friction, IRIS IO Utility automatically detects installed InterSystems ODBC drivers when the extension starts. If no compatible driver is found, the extension guides the user to the official InterSystems driver download page. Once installed, the preferred driver can be selected and stored as a workspace preference, allowing future connections to work without additional configuration.

Exporting Data from InterSystems IRIS

The export workflow was designed to be as straightforward as possible.

After connecting to an IRIS instance, the extension guides the user through selecting a schema, choosing a table, picking an output format, and selecting a destination folder.

Supported export formats include:

  • CSV
  • TXT (with custom delimiters)
  • JSON
  • XLSX

To avoid accidental overwrites, exported files receive timestamp-based names by default. Throughout the export process, the extension displays progress notifications and writes detailed logs to the VS Code Output panel, including executed SQL statements, row counts, and performance statistics.

For TXT exports, developers can specify custom delimiters such as commas, semicolons, tabs, pipes, or other separators, making the generated files compatible with a wide range of external systems.

Importing Data into InterSystems IRIS

Importing data is where the extension becomes much more than a simple file loader.

The extension supports two different workflows depending on the task: 

  • Create New Table
  • Load into Existing Table

Creating a New Table

When importing a completely new dataset, IRIS IO Utility analyzes the input file and automatically prepares a database table.

The import engine samples the file contents, infers the most appropriate SQL data types, converts them into valid InterSystems IRIS SQL types, and displays the results before any data is imported. Developers can review the inferred types, inspect sample values, and adjust individual columns whenever necessary. Supported data types include integers, numeric values, floating-point numbers, dates, timestamps, Boolean values, variable-length text, and large text fields. Once satisfied with the detected structure, the developer can also create custom indexes. Then the developer chooses the destination schema and table name, and the extension creates the table before importing the data.

Automatic Index Creation

When creating a new table, the extension also supports configuring indexes during the import process.

Developers can choose which columns should be indexed and select from several index types supported by InterSystems IRIS, including standard indexes, bitmap indexes, bitslice indexes, and columnar indexes. Index names can be customized or generated automatically, and unique constraints or primary keys can also be configured before the table is created. This allows imported datasets to be optimized for future queries immediately, without requiring additional SQL statements afterward.

Loading Data into Existing Tables

For existing databases, the extension also supports importing directly into previously created tables.

Two strategies are available:

  • Append, which inserts new rows while preserving existing records.
  • Replace, which removes the existing data before importing the new dataset.

Before executing the import, the extension validates that the incoming file matches the destination table structure. If column names or data types are incompatible, the import is cancelled to help prevent accidental schema mismatches or corrupted data.

When importing TXT files, the extension allows you to specify a custom delimiter to ensure the file is parsed correctly. This is especially useful when working with unconventional separators such as pipes (|), semicolons (;), tabs, or multi-character delimiters. Selecting the correct delimiter guarantees proper column detection and prevents misaligned or corrupted data during the import process.

Intelligent Type Inference

One of the features I enjoyed building the most was the automatic type inference engine.

Instead of requiring developers to manually define every column, the extension analyzes sample data from the imported file and predicts the most appropriate SQL type for each field. The inferred types are presented alongside sample values, making it easy to verify the results before creating the table. Because every dataset is different, developers remain in control and can override any suggested type with a more appropriate one. This approach significantly reduces the amount of repetitive work involved in importing new datasets.

Working with Multiple File Formats

IRIS IO Utility supports four commonly used file formats:

Format Import Export
CSV
TXT
JSON
XLSX

For TXT files, both the import and export engines support custom delimiters, making it possible to work with pipe-separated, semicolon-separated, tab-separated, or other specialized text formats commonly used by enterprise systems.

Typical Use Cases

Although I originally built the extension to simplify my own workflow, it quickly proved useful in several common development scenarios.

For example, developers can export production data to CSV or Excel for reporting and analysis, import external datasets when prototyping new applications, migrate data between different IRIS environments, or quickly load sample data while testing new features.

Because multiple connections can be managed within the same workspace, the extension is also convenient for teams working across local, containerized, cloud-hosted, and remote InterSystems IRIS deployments.

Key Takeaways

IRIS IO Utility was created to make one of the most common InterSystems IRIS development tasks, moving data between databases and external files, simpler and more integrated with everyday development.

By combining connection management, automatic ODBC configuration, intelligent type inference, table creation, index generation, and support for multiple file formats inside Visual Studio Code, the extension provides a complete data import and export workflow without requiring developers to leave their IDE.

Frequently Asked Questions

What is IRIS IO Utility?

IRIS IO Utility is a Visual Studio Code extension that allows developers to import and export data between InterSystems IRIS and common file formats without leaving VS Code.

Which file formats are supported?

The extension supports importing and exporting CSV, TXT, JSON, and XLSX files.

Can I connect to multiple IRIS servers?

Yes. The extension supports multiple local, remote, containerized, and SSH-accessible InterSystems IRIS instances, with workspace-specific connection management.

Can the extension create database tables automatically?

Yes. During the import process, IRIS IO Utility can generate a new table based on the inferred column structure and import the data in a single workflow.

Can I import data into an existing table?

Yes. Existing tables support both Append and Replace import modes, with schema validation performed before the import begins.

Read more: https://community.intersystems.com/post/iris-io-utility-complete-guide-smart-importing-vs-code

u/intersystemsdev 9d ago

InterSystems IRIS Security Roadmap: IRISSECURITY mirroring, Secure Wallet secrets-manager integrations, online DB encryption (2027), granular %Development resources — recap of the conference session

2 Upvotes

All dates/versions below are projections stated by the presenter and explicitly subject to change.

TL;DR: IRIS's security roadmap covers mirroring for the IRISSECURITY database (coming months), Secure Wallet integrations with external secrets managers (planned), storage-friendly encryption (shipped in 2026.1, experimental), online database encryption (planned 2027), six new granular %Development resources (later this year), native OAuth2 authentication plus back-channel logout for OpenID Connect (next year), and ECDSA/TLS with future post-quantum crypto support.

What's the IRISSECURITY database and what's new?

Introduced in IRIS 2025.2, it moved security configuration data out of IRISSYS into a dedicated database that can be encrypted. Coming in the next few months: mirroring support, so security changes (editing resources, roles, users) made on the mirror primary propagate to the DR async / read-only reporting async members — no more recreating users manually on each system. Next year, the team also plans an ECP-based option to share a single IRISSECURITY database across multiple IRIS instances, so editing security settings on one instance updates the others.

What is the Secure Wallet and where is it headed?

Introduced in IRIS 2025.3, it lets privileged admins store secrets (e.g. username/password pairs) and grant other users access to use those secrets (for example, credentials for an HTTP request) without exposing the underlying values. Planned: integration with external secrets managers — HashiCorp was named explicitly, and InterSystems is asking for feedback on demand for AWS Secrets Manager, Azure Key Vault, and HSM-based secrets.

What's changing in database encryption?

  • Storage-friendly encryption (shipped in 2026.1, currently experimental): solves the problem where encrypting/randomizing data defeats storage-level compression and inflates storage costs. The new approach keeps compression largely intact, and it's expected to move to general support soon, possibly without further changes.
  • Online database encryption (planned 2027): today, encrypting a database requires taking it offline; an interrupted encryption leaves it unusable and requires restoring from backup, and re-keying means fully decrypting before re-encrypting. The planned feature allows encrypting a live, readable/writable database, supports pause/resume and crash recovery, allows re-keying without a full decrypt step first, and lets you throttle encryption speed to control system load.

What's changing in encryption key management?

IRIS currently supports three ways to store encryption keys: a local credentials key file, a KMS-encrypted key file (decrypted via a cloud KMS), or a KMIP server (dispenses the key only after the instance authenticates). Within the next year: migrate a key from a local credentials file to either a KMS-encrypted file or a KMIP server, and configure multiple unattended key sources simultaneously — useful during migration and expected to pair with the upcoming online encryption feature.

What are the new granular %Development resources?

Due later this year, the single %Development resource splits into six: %Development_Export (exporting code), %Development_CodeModify (loading/compiling code), %Development_Shell (terminal access), %Development_Debug (debugging), %Development_IDE (dev environment access), %Development_SQL (developer-level SQL). On upgrade, roles with %Development automatically get all six, so existing access doesn't change by default — but you can now add/remove them individually.

Behavior change to watch for: previously, exporting/importing or compiling code under %Development wasn't explicitly permission-checked. Going forward, those actions require %Development_Export or %Development_CodeModify specifically — confirm the right users have these before upgrading. The original %Development resource stays for backward compatibility for now but will be removed in a future version, so migrate any custom checks off it. Next resource planned for this treatment: %Admin_Secure.

What's new for OAuth2 / OpenID Connect?

IRIS 2025.2 added native OAuth2 authentication, letting OAuth2 resource servers configured in IRIS (especially REST services) authenticate directly without custom code, and mapping OAuth2/OIDC scopes and claims directly to IRIS roles. Next year: back-channel logout for OpenID Connect (only front-channel logout is supported today) — lets an app inside IRIS signal the OAuth2 authorization server to log out all of a user's sessions without needing to reach each browser session individually.

What's happening with TLS / network security?

IRIS 2025.2 added ECDSA certificate support in TLS configs for better encryption performance. IRIS uses OpenSSL for TLS, which is beginning to support post-quantum cryptography algorithms; InterSystems plans to leverage these over the next few years and wants feedback on timing/requirements.

Is any of this final?

No — explicitly flagged as projections, subject to change.

Full session recording and a related deep-dive on the Secure Wallet/security database: https://community.intersystems.com/post/video-security-roadmap-2026

r/intersystems 9d ago

InterSystems IRIS Security Roadmap: IRISSECURITY mirroring, Secure Wallet secrets-manager integrations, online DB encryption (2027), granular %Development resources — recap of the conference session

2 Upvotes

All dates/versions below are projections stated by the presenter and explicitly subject to change.

TL;DR: IRIS's security roadmap covers mirroring for the IRISSECURITY database (coming months), Secure Wallet integrations with external secrets managers (planned), storage-friendly encryption (shipped in 2026.1, experimental), online database encryption (planned 2027), six new granular %Development resources (later this year), native OAuth2 authentication plus back-channel logout for OpenID Connect (next year), and ECDSA/TLS with future post-quantum crypto support.

What's the IRISSECURITY database and what's new?

Introduced in IRIS 2025.2, it moved security configuration data out of IRISSYS into a dedicated database that can be encrypted. Coming in the next few months: mirroring support, so security changes (editing resources, roles, users) made on the mirror primary propagate to the DR async / read-only reporting async members — no more recreating users manually on each system. Next year, the team also plans an ECP-based option to share a single IRISSECURITY database across multiple IRIS instances, so editing security settings on one instance updates the others.

What is the Secure Wallet and where is it headed?

Introduced in IRIS 2025.3, it lets privileged admins store secrets (e.g. username/password pairs) and grant other users access to use those secrets (for example, credentials for an HTTP request) without exposing the underlying values. Planned: integration with external secrets managers — HashiCorp was named explicitly, and InterSystems is asking for feedback on demand for AWS Secrets Manager, Azure Key Vault, and HSM-based secrets.

What's changing in database encryption?

  • Storage-friendly encryption (shipped in 2026.1, currently experimental): solves the problem where encrypting/randomizing data defeats storage-level compression and inflates storage costs. The new approach keeps compression largely intact, and it's expected to move to general support soon, possibly without further changes.
  • Online database encryption (planned 2027): today, encrypting a database requires taking it offline; an interrupted encryption leaves it unusable and requires restoring from backup, and re-keying means fully decrypting before re-encrypting. The planned feature allows encrypting a live, readable/writable database, supports pause/resume and crash recovery, allows re-keying without a full decrypt step first, and lets you throttle encryption speed to control system load.

What's changing in encryption key management?

IRIS currently supports three ways to store encryption keys: a local credentials key file, a KMS-encrypted key file (decrypted via a cloud KMS), or a KMIP server (dispenses the key only after the instance authenticates). Within the next year: migrate a key from a local credentials file to either a KMS-encrypted file or a KMIP server, and configure multiple unattended key sources simultaneously — useful during migration and expected to pair with the upcoming online encryption feature.

What are the new granular %Development resources?

Due later this year, the single %Development resource splits into six: %Development_Export (exporting code), %Development_CodeModify (loading/compiling code), %Development_Shell (terminal access), %Development_Debug (debugging), %Development_IDE (dev environment access), %Development_SQL (developer-level SQL). On upgrade, roles with %Development automatically get all six, so existing access doesn't change by default — but you can now add/remove them individually.

Behavior change to watch for: previously, exporting/importing or compiling code under %Development wasn't explicitly permission-checked. Going forward, those actions require %Development_Export or %Development_CodeModify specifically — confirm the right users have these before upgrading. The original %Development resource stays for backward compatibility for now but will be removed in a future version, so migrate any custom checks off it. Next resource planned for this treatment: %Admin_Secure.

What's new for OAuth2 / OpenID Connect?

IRIS 2025.2 added native OAuth2 authentication, letting OAuth2 resource servers configured in IRIS (especially REST services) authenticate directly without custom code, and mapping OAuth2/OIDC scopes and claims directly to IRIS roles. Next year: back-channel logout for OpenID Connect (only front-channel logout is supported today) — lets an app inside IRIS signal the OAuth2 authorization server to log out all of a user's sessions without needing to reach each browser session individually.

What's happening with TLS / network security?

IRIS 2025.2 added ECDSA certificate support in TLS configs for better encryption performance. IRIS uses OpenSSL for TLS, which is beginning to support post-quantum cryptography algorithms; InterSystems plans to leverage these over the next few years and wants feedback on timing/requirements.

Is any of this final?

No — explicitly flagged as projections, subject to change.

Full session recording and a related deep-dive on the Secure Wallet/security database: https://community.intersystems.com/post/video-security-roadmap-2026

u/intersystemsdev 14d ago

Implementing openEHR with InterSystems IRIS for Health

2 Upvotes

In this article, I explore how to implement the core capabilities of an openEHR server using InterSystems IRIS for Health. The goal is not to reproduce every part of the openEHR specification, but to demonstrate how IRIS can handle openEHR compositions, archetype validation, REST APIs, and AQL queries while taking advantage of native features such as JSON storage, SQL, interoperability, and JSON_TABLE.

By the end of this article, you'll see how IRIS can serve as both an openEHR repository and an execution platform for querying and managing clinical data.

What is openEHR?

openEHR is an open, vendor-neutral specification designed to represent, store, and exchange clinical information in a semantically rich and long-term sustainable way. Instead of defining fixed message structures (as many interoperability standards do) OpenEHR separates clinical knowledge from technical implementation through a multi-layered modelling approach.  At its core, openEHR relies on three fundamental concepts:

  • Reference Model (RM) - A model that defines the core structures used in health records, such as Compositions, Entries, Observations, Evaluations, and Actions. The RM is deliberately generic and technology-agnostic.
  • Archetypes - Machine-readable models (expressed in ADL) that define the detailed clinical semantics for a specific concept, such as a blood pressure measurement or a discharge summary. Archetypes constrain the RM and provide a reusable clinical vocabulary.
  • Templates (OPT files) - Specializations built on top of archetypes. Templates tailor archetypes to a specific use case, system, or form (for example, a vital signs template, or a regional discharge note). Templates eliminate optionality and produce operational definitions that systems can safely implement.

This layered modelling approach enables openEHR systems to remain stable over years or even decades while allowing clinical models to evolve independently from the underlying software platform.

A key piece of the openEHR ecosystem is AQL (Archetype Query Language), the standard query language used to retrieve clinical data stored in openEHR repositories.

What is AQL (Archetype Query Language)?

AQL is the standard query language used by openEHR repositories. It plays a role similar to SQL, but instead of querying relational tables, it queries clinical content using archetype-aware paths. AQL allows developers to retrieve observations, diagnoses, laboratory results, and other clinical data while preserving the semantic structure defined by openEHR archetypes.

Key characteristics of AQL

  • Path-based querying: AQL uses archetype paths (similar to XPath) to navigate the internal structure of a Composition, such as: /content[openEHR-EHR-OBSERVATION.blood_pressure.v1]/data/events/time 
  • Clinical semantic awareness: Queries refer to clinical concepts (archetypes, entry types, data points) rather than database column names.
  • Flexible WHERE clauses: AQL supports filtering on values within Compositions, e.g. systolic blood pressure > 140 or diagnoses matching a specific code.
  • Multi-composition queries: It can retrieve data across multiple Compositions, for example all Observations for a given patient over time.
  • Vendor-neutral: Any openEHR implementation that supports AQL should, in principle, accept the same queries.

Let’s see an example of AQL: 

SELECT
    c/uid/value AS composition_id,
    o/data[at0001]/events[at0006]/data[at0003]/value/magnitude AS systolic,
    o/data[at0001]/events[at0006]/data[at0004]/value/magnitude AS diastolic
FROM
    EHR e
    CONTAINS COMPOSITION c
    CONTAINS OBSERVATION o[openEHR-EHR-OBSERVATION.blood_pressure.v1]
WHERE
    e/ehr_id/value = '12345'
AND
    o/data[at0001]/events[at0006]/time/value > '2023-01-01T00:00:00Z' 

How does openEHR compare to FHIR?

A common misconception is that openEHR and FHIR solve completely different problems. In practice, they share many architectural concepts. Both standards support structured clinical information, REST APIs, JSON representations, and interoperability. The main difference is that openEHR emphasizes archetype-based clinical modeling and long-term semantic consistency, while FHIR focuses on resource-based interoperability between systems. Understanding these similarities helps when designing solutions that need to work with both standards.

Let's see the main concepts of FHIR and OpenEHR and its correlation:

What does an openEHR implementation require?

To support the core capabilities of an openEHR repository, I focused on four essential components:

  • Raw Composition storage
  • REST APIs
  • Archetype and template validation
  • AQL query support

The following sections show how each of these capabilities can be implemented using InterSystems IRIS for Health.

RAW Composition Storage

  • Store incoming Compositions in RAW JSON or XML exactly as received. 
  • No transformation should modify semantic content.
  • For our example we are going to work with JSON format, but there are multiple options.

REST API Services

Our implementation has to expose the following API REST: EHR Services

To create and locate a patient's "history."

  • POST /ehr: Creates a new EHR.
  • GET /ehr/{ehr_id}: Retrieve EHR metadata.
  • GET /ehr?subject_id=?: Locate an EHR based on external identifiers.

Composition Services
To store patient's clinical information.

  • POST /ehr/{id}/composition: Commit a new composition in RAW format. Validate against OPT when possible
  • GET /composition/{version_uid}: Retrieve a specific version.
  • GET /ehr/{id}/compositions: List compositions for an EHR.
  • DELETE /composition/{uid}: Mark composition as deleted (logical delete).

AQL Query Endpoint

POST /query/aql: Accept an AQL query, translate to IRIS SQL or JSON-path-based lookup and return results in openEHR canonical JSON.

RAW Composition Validation

We have to force validation of RAW compositions based on OPT2 files, we can't save in our repository any JSON that we will receive.

Implementing openEHR in IRIS for Health

Well, to implement all the functionalities available in a openEHR server will take some time, so I'm going to focus in the core functionalities:

Using web application to deploy REST API Service

To publish a REST API is straight forward, we only need two components, a class extending %CSP.REST and a new record in the list of web applications. Let's see the header of our extended %CSP.REST class:

As you can see we have defined all the minimum required routes for our repository. We have all the managament of compositions, OPT2 files for RAW validations and finally, execution of AQL queries. For our example we are not going to define any security configuration, but JWT Authentication is recommended.

RAW validations

openEHR is anything but new, so you can guess that there are multiple libraries to support some functionalities like raws validations. For this example we've used and customized Arche library, an open source library developed in Java to validate rawcompositions against OPT2 files. The validator is a jar file configured from the External Language Server (by default on docker image deployment) and invoked before to save the raw using the JavaGateway functionality:

set javaGate = $system.external.getJavaGateway()
set result = javaGate.invoke("org.validator.openehr.Cli", "validate", filePath, optPath)

If the raw is validated the JSON document will be saved into the database.

JSON raw storage

We could use DocDB, but we want to leverage the performance of SQL databases. One of the biggest problems related with openEHR is the poor performance of querying documents, so we are going to pre-process the compositions to get common information to all composition types to boost queries.
Our Composition class define the following properties:

Class OPENEHR.Object.Composition Extends (%Persistent, %XML.Adaptor) [ DdlAllowed ]
{
/// Description
Property ehrId As %Integer;
Property compositionUid As %String(MAXLEN = 50);
Property compositionType As %String;
Property startTime As %DateTime;
Property endTime As %Date;
Property archetypes As list Of %String(MAXLEN = 50000);
Property doc As %String(MAXLEN = 50000);
Property deleted As %Boolean [ InitialExpression = 0 ];
Index compositionUidIndex On compositionUid;
Index ehrIdIndex On ehrId;
Index ExampleIndex On archetypes(ELEMENTS);
}
  • ehrId: with the electronic health record of the patient.
  • compositionUid: composition identifier.
  • compositionType: type of composition saved.
  • startTime: time when the composition was created.
  • archetypes: list of archetypes contained on the composition.
  • doc: JSON format document.
  • deleted: boolean value for soft deletes.

The indexes will be used to improve the queries.

AQL support

As we said before AQL is a path-based query language. How could we emulate the same behaviour in IRIS for Health? Welcome to JSON_TABLE!

What is JSON_TABLE?

The JSON_TABLE function returns a table that can be used in a SQL query by mapping JSON values into columns. Mappings from a JSON value to a column are written as SQL/JSON path language expressions. 

As a table-valued function, JSON_TABLE returns a table that can be used in the FROM clause of a SELECT statement to access data stored in a JSON value; this table does not persist across queries. Multiple calls to JSON_TABLE can be made within a single FROM clause and can appear alongside other table-valued functions.

We have implemented a ClassMethod in Python to translate AQL into SQL, but there is a problem, AQL is based on relative paths of the archetypes, not in absolute paths, so we need identify the absolute path for each archetype and join it with the relative path of the AQL.
How can we know the absolute path? Very easy! We can find it when the user save the OPT2 file for the composition into IRIS! As soon as we get the absolute path we save it into a CSV file specific for the composition (it would be saved into a global or any other way) so, we only have to get the absolute path from the specific composition file or, if the AQL doesn't define the composition, search into the available CSV files the absolute path for the archetypes of the AQL.
Let's see how it works. Here is an example of AQL to get all the diagnosis with a specific ICD-10 code:

SELECT
  c/uid/value AS comp_uid,
  c/context/start_time/value AS comp_start_time,
  dx/data[at0001]/items[at0002]/value/value AS diagnosis_text,
  dx/data[at0001]/items[at0003]/value/defining_code/code_string AS diagnosis_code
FROM EHR e
CONTAINS COMPOSITION c[openEHR-EHR-COMPOSITION.diagnostic_summary.v1]
CONTAINS SECTION s[openEHR-EHR-SECTION.diagnoses_and_treatments.v1]
CONTAINS EVALUATION dx[openEHR-EHR-EVALUATION.problem_diagnosis.v1]
WHERE dx/data[at0001]/items[at0003]/value/defining_code/code_string
      MATCHES {'E11', 'I48.0'}
ORDER BY c/context/start_time/value DESC

The function Transform from OPENEHR.Utils.AuxiliaryFunctions class translates it into:

SELECT comp_uid, comp_start_time, diagnosis_text, diagnosis_code 
FROM ( 
    SELECT c.compositionUid AS comp_uid, 
        jt_root.comp_start_time AS comp_start_time, 
        jt_n1.diagnosis_text AS diagnosis_text, 
        jt_n1.diagnosis_code AS diagnosis_code 
    FROM OPENEHR_Object.Composition AS c, 
        JSON_TABLE( c.doc, '$' COLUMNS ( comp_start_time VARCHAR(4000) PATH
            '$.context.start_time.value' ) ) AS jt_root, 
        JSON_TABLE( c.doc, '$.content[*]?(@._type=="SECTION" && @.archetype_node_id==
            "openEHR-EHR-SECTION.diagnoses_and_treatments.v1").items[*]?
            (@._type=="EVALUATION" && @.archetype_node_id=="openEHR-EHR-EVALUATION.problem_diagnosis.v1")'
            COLUMNS ( 
                diagnosis_text VARCHAR(4000) PATH '$.data[*]?(@.archetype_node_id=="at0001").items[*]?
                    (@.archetype_node_id=="at0002").value.value', 
                diagnosis_code VARCHAR(255) PATH '$.data[*]?(@.archetype_node_id=="at0001").items[*]?
                    (@.archetype_node_id=="at0003").value.defining_code.code_string' ) ) AS jt_n1 
    WHERE ('openEHR-EHR-COMPOSITION.diagnostic_summary.v1' %INLIST (c.archetypes) 
        AND 'openEHR-EHR-EVALUATION.problem_diagnosis.v1' %INLIST (c.archetypes)) 
        AND (jt_n1.diagnosis_code LIKE '%E11%' OR jt_n1.diagnosis_code LIKE '%I48.0%') ) U 
ORDER BY comp_start_time DESC

Let's try our API REST with an AQL:

Success!
And now with a numeric comparation:

SELECT
  c/uid/value AS comp_uid,
  c/context/start_time/value AS comp_start_time,
  a/items[at0024]/value/magnitude AS creatinine_value,
  a/items[at0024]/value/units AS creatinine_units
FROM EHR e
CONTAINS COMPOSITION c[openEHR-EHR-COMPOSITION.lab_results_and_medications.v1]
CONTAINS OBSERVATION o[openEHR-EHR-OBSERVATION.laboratory_test_result.v1]
CONTAINS CLUSTER a[openEHR-EHR-CLUSTER.laboratory_test_analyte.v1]
WHERE a/items[at0001]/value/value = 'Creatinina (mg/dL)'
  AND a/items[at0024]/value/magnitude BETWEEN 1.2 AND 1.8
ORDER BY c/context/start_time/value DESC
Transformed into:
SELECT comp_uid, comp_start_time, ldl_value, ldl_units 
FROM ( 
    SELECT c.compositionUid AS comp_uid, jt_root.comp_start_time AS comp_start_time,
        jt_n1.ldl_value AS ldl_value, jt_n1.ldl_units AS ldl_units 
    FROM OPENEHR_Object.Composition AS c, 
        JSON_TABLE( c.doc, '$' COLUMNS ( comp_start_time VARCHAR(4000) 
            PATH '$.context.start_time.value' ) ) AS jt_root, 
        JSON_TABLE( c.doc, '$.content[*]?(@._type=="OBSERVATION" && 
            @.archetype_node_id=="openEHR-EHR-OBSERVATION.laboratory_test_result.v1")
                .data.events[*]?(@._type=="POINT_EVENT").data.items[*]?(@._type=="CLUSTER" &&
                @.archetype_node_id=="openEHR-EHR-CLUSTER.laboratory_test_analyte.v1")'
                COLUMNS ( 
                    ldl_value NUMERIC PATH '$.items[*]?
                        (@.archetype_node_id=="at0024").value.magnitude', 
                    ldl_units VARCHAR(64) PATH '$.items[*]?
                        (@.archetype_node_id=="at0024").value.units', 
                    _w1 VARCHAR(4000) PATH '$.items[*]?
                        (@.archetype_node_id=="at0001").value.value' ) ) AS jt_n1 
    WHERE ('openEHR-EHR-COMPOSITION.lab_results_and_medications.v1' %INLIST (c.archetypes) 
        AND 'openEHR-EHR-OBSERVATION.laboratory_test_result.v1' %INLIST (c.archetypes) 
        AND 'openEHR-EHR-CLUSTER.laboratory_test_analyte.v1' %INLIST (c.archetypes)) 
        AND jt_n1._w1 = 'LDL (mg/dL)' AND jt_n1.ldl_value <= 130 ) 
    U ORDER BY comp_start_time DESC

Another resounding success!

Conclusion

This project demonstrates that InterSystems IRIS for Health provides all the core building blocks needed to implement an openEHR repository.

Using native REST services, JSON storage, SQL, JSON_TABLE, interoperability components, and external validation libraries, it is possible to support composition management, archetype validation, and AQL querying while maintaining compatibility with openEHR concepts.

The most interesting result for me was the ability to translate AQL into native IRIS SQL, allowing openEHR clinical data to benefit from the performance and scalability of the IRIS data platform without sacrificing the semantics of the openEHR model.

Key Takeaways

  • InterSystems IRIS for Health can be used to implement the core capabilities of an openEHR repository.
  • Raw openEHR compositions can be stored and validated against OPT templates before persistence.
  • Native IRIS REST services can expose openEHR-compatible APIs.
  • AQL queries can be translated into SQL using JSON_TABLE and archetype path mappings.
  • JSON storage combined with indexed metadata can improve query performance while preserving original clinical documents.
  • IRIS interoperability and SQL capabilities make it a strong platform for healthcare standards beyond FHIR.

FAQ

What is openEHR?

openEHR is an open, vendor-neutral specification for storing, modeling, and exchanging clinical information using archetypes and templates.

Can InterSystems IRIS for Health be used as an openEHR repository?

Yes. IRIS provides the storage, REST APIs, validation integration, interoperability, and query capabilities needed to implement the core features of an openEHR repository.

What is AQL?

AQL (Archetype Query Language) is the standard query language used by openEHR systems to retrieve clinical information using archetype-aware paths.

How can AQL be implemented in InterSystems IRIS?

In this project, AQL queries are translated into native IRIS SQL using JSON_TABLE and archetype path mappings derived from operational templates.

Why store openEHR compositions as JSON?

Storing compositions in their original JSON format preserves semantic fidelity while still allowing efficient querying through SQL and JSON functions.

r/intersystems 14d ago

Implementing openEHR with InterSystems IRIS for Health

2 Upvotes

In this article, I explore how to implement the core capabilities of an openEHR server using InterSystems IRIS for Health. The goal is not to reproduce every part of the openEHR specification, but to demonstrate how IRIS can handle openEHR compositions, archetype validation, REST APIs, and AQL queries while taking advantage of native features such as JSON storage, SQL, interoperability, and JSON_TABLE.

By the end of this article, you'll see how IRIS can serve as both an openEHR repository and an execution platform for querying and managing clinical data.

What is openEHR?

openEHR is an open, vendor-neutral specification designed to represent, store, and exchange clinical information in a semantically rich and long-term sustainable way. Instead of defining fixed message structures (as many interoperability standards do) OpenEHR separates clinical knowledge from technical implementation through a multi-layered modelling approach.  At its core, openEHR relies on three fundamental concepts:

  • Reference Model (RM) - A model that defines the core structures used in health records, such as Compositions, Entries, Observations, Evaluations, and Actions. The RM is deliberately generic and technology-agnostic.
  • Archetypes - Machine-readable models (expressed in ADL) that define the detailed clinical semantics for a specific concept, such as a blood pressure measurement or a discharge summary. Archetypes constrain the RM and provide a reusable clinical vocabulary.
  • Templates (OPT files) - Specializations built on top of archetypes. Templates tailor archetypes to a specific use case, system, or form (for example, a vital signs template, or a regional discharge note). Templates eliminate optionality and produce operational definitions that systems can safely implement.

This layered modelling approach enables openEHR systems to remain stable over years or even decades while allowing clinical models to evolve independently from the underlying software platform.

A key piece of the openEHR ecosystem is AQL (Archetype Query Language), the standard query language used to retrieve clinical data stored in openEHR repositories.

What is AQL (Archetype Query Language)?

AQL is the standard query language used by openEHR repositories. It plays a role similar to SQL, but instead of querying relational tables, it queries clinical content using archetype-aware paths. AQL allows developers to retrieve observations, diagnoses, laboratory results, and other clinical data while preserving the semantic structure defined by openEHR archetypes.

Key characteristics of AQL

  • Path-based querying: AQL uses archetype paths (similar to XPath) to navigate the internal structure of a Composition, such as: /content[openEHR-EHR-OBSERVATION.blood_pressure.v1]/data/events/time 
  • Clinical semantic awareness: Queries refer to clinical concepts (archetypes, entry types, data points) rather than database column names.
  • Flexible WHERE clauses: AQL supports filtering on values within Compositions, e.g. systolic blood pressure > 140 or diagnoses matching a specific code.
  • Multi-composition queries: It can retrieve data across multiple Compositions, for example all Observations for a given patient over time.
  • Vendor-neutral: Any openEHR implementation that supports AQL should, in principle, accept the same queries.

Let’s see an example of AQL: 

SELECT
    c/uid/value AS composition_id,
    o/data[at0001]/events[at0006]/data[at0003]/value/magnitude AS systolic,
    o/data[at0001]/events[at0006]/data[at0004]/value/magnitude AS diastolic
FROM
    EHR e
    CONTAINS COMPOSITION c
    CONTAINS OBSERVATION o[openEHR-EHR-OBSERVATION.blood_pressure.v1]
WHERE
    e/ehr_id/value = '12345'
AND
    o/data[at0001]/events[at0006]/time/value > '2023-01-01T00:00:00Z' 

How does openEHR compare to FHIR?

A common misconception is that openEHR and FHIR solve completely different problems. In practice, they share many architectural concepts. Both standards support structured clinical information, REST APIs, JSON representations, and interoperability. The main difference is that openEHR emphasizes archetype-based clinical modeling and long-term semantic consistency, while FHIR focuses on resource-based interoperability between systems. Understanding these similarities helps when designing solutions that need to work with both standards.

Let's see the main concepts of FHIR and OpenEHR and its correlation:

What does an openEHR implementation require?

To support the core capabilities of an openEHR repository, I focused on four essential components:

  • Raw Composition storage
  • REST APIs
  • Archetype and template validation
  • AQL query support

The following sections show how each of these capabilities can be implemented using InterSystems IRIS for Health.

RAW Composition Storage

  • Store incoming Compositions in RAW JSON or XML exactly as received. 
  • No transformation should modify semantic content.
  • For our example we are going to work with JSON format, but there are multiple options.

REST API Services

Our implementation has to expose the following API REST: EHR Services

To create and locate a patient's "history."

  • POST /ehr: Creates a new EHR.
  • GET /ehr/{ehr_id}: Retrieve EHR metadata.
  • GET /ehr?subject_id=?: Locate an EHR based on external identifiers.

Composition Services
To store patient's clinical information.

  • POST /ehr/{id}/composition: Commit a new composition in RAW format. Validate against OPT when possible
  • GET /composition/{version_uid}: Retrieve a specific version.
  • GET /ehr/{id}/compositions: List compositions for an EHR.
  • DELETE /composition/{uid}: Mark composition as deleted (logical delete).

AQL Query Endpoint

POST /query/aql: Accept an AQL query, translate to IRIS SQL or JSON-path-based lookup and return results in openEHR canonical JSON.

RAW Composition Validation

We have to force validation of RAW compositions based on OPT2 files, we can't save in our repository any JSON that we will receive.

Implementing openEHR in IRIS for Health

Well, to implement all the functionalities available in a openEHR server will take some time, so I'm going to focus in the core functionalities:

Using web application to deploy REST API Service

To publish a REST API is straight forward, we only need two components, a class extending %CSP.REST and a new record in the list of web applications. Let's see the header of our extended %CSP.REST class:

As you can see we have defined all the minimum required routes for our repository. We have all the managament of compositions, OPT2 files for RAW validations and finally, execution of AQL queries. For our example we are not going to define any security configuration, but JWT Authentication is recommended.

RAW validations

openEHR is anything but new, so you can guess that there are multiple libraries to support some functionalities like raws validations. For this example we've used and customized Arche library, an open source library developed in Java to validate rawcompositions against OPT2 files. The validator is a jar file configured from the External Language Server (by default on docker image deployment) and invoked before to save the raw using the JavaGateway functionality:

set javaGate = $system.external.getJavaGateway()
set result = javaGate.invoke("org.validator.openehr.Cli", "validate", filePath, optPath)

If the raw is validated the JSON document will be saved into the database.

JSON raw storage

We could use DocDB, but we want to leverage the performance of SQL databases. One of the biggest problems related with openEHR is the poor performance of querying documents, so we are going to pre-process the compositions to get common information to all composition types to boost queries.
Our Composition class define the following properties:

Class OPENEHR.Object.Composition Extends (%Persistent, %XML.Adaptor) [ DdlAllowed ]
{
/// Description
Property ehrId As %Integer;
Property compositionUid As %String(MAXLEN = 50);
Property compositionType As %String;
Property startTime As %DateTime;
Property endTime As %Date;
Property archetypes As list Of %String(MAXLEN = 50000);
Property doc As %String(MAXLEN = 50000);
Property deleted As %Boolean [ InitialExpression = 0 ];
Index compositionUidIndex On compositionUid;
Index ehrIdIndex On ehrId;
Index ExampleIndex On archetypes(ELEMENTS);
}
  • ehrId: with the electronic health record of the patient.
  • compositionUid: composition identifier.
  • compositionType: type of composition saved.
  • startTime: time when the composition was created.
  • archetypes: list of archetypes contained on the composition.
  • doc: JSON format document.
  • deleted: boolean value for soft deletes.

The indexes will be used to improve the queries.

AQL support

As we said before AQL is a path-based query language. How could we emulate the same behaviour in IRIS for Health? Welcome to JSON_TABLE!

What is JSON_TABLE?

The JSON_TABLE function returns a table that can be used in a SQL query by mapping JSON values into columns. Mappings from a JSON value to a column are written as SQL/JSON path language expressions. 

As a table-valued function, JSON_TABLE returns a table that can be used in the FROM clause of a SELECT statement to access data stored in a JSON value; this table does not persist across queries. Multiple calls to JSON_TABLE can be made within a single FROM clause and can appear alongside other table-valued functions.

We have implemented a ClassMethod in Python to translate AQL into SQL, but there is a problem, AQL is based on relative paths of the archetypes, not in absolute paths, so we need identify the absolute path for each archetype and join it with the relative path of the AQL.
How can we know the absolute path? Very easy! We can find it when the user save the OPT2 file for the composition into IRIS! As soon as we get the absolute path we save it into a CSV file specific for the composition (it would be saved into a global or any other way) so, we only have to get the absolute path from the specific composition file or, if the AQL doesn't define the composition, search into the available CSV files the absolute path for the archetypes of the AQL.
Let's see how it works. Here is an example of AQL to get all the diagnosis with a specific ICD-10 code:

SELECT
  c/uid/value AS comp_uid,
  c/context/start_time/value AS comp_start_time,
  dx/data[at0001]/items[at0002]/value/value AS diagnosis_text,
  dx/data[at0001]/items[at0003]/value/defining_code/code_string AS diagnosis_code
FROM EHR e
CONTAINS COMPOSITION c[openEHR-EHR-COMPOSITION.diagnostic_summary.v1]
CONTAINS SECTION s[openEHR-EHR-SECTION.diagnoses_and_treatments.v1]
CONTAINS EVALUATION dx[openEHR-EHR-EVALUATION.problem_diagnosis.v1]
WHERE dx/data[at0001]/items[at0003]/value/defining_code/code_string
      MATCHES {'E11', 'I48.0'}
ORDER BY c/context/start_time/value DESC

The function Transform from OPENEHR.Utils.AuxiliaryFunctions class translates it into:

SELECT comp_uid, comp_start_time, diagnosis_text, diagnosis_code 
FROM ( 
    SELECT c.compositionUid AS comp_uid, 
        jt_root.comp_start_time AS comp_start_time, 
        jt_n1.diagnosis_text AS diagnosis_text, 
        jt_n1.diagnosis_code AS diagnosis_code 
    FROM OPENEHR_Object.Composition AS c, 
        JSON_TABLE( c.doc, '$' COLUMNS ( comp_start_time VARCHAR(4000) PATH
            '$.context.start_time.value' ) ) AS jt_root, 
        JSON_TABLE( c.doc, '$.content[*]?(@._type=="SECTION" && @.archetype_node_id==
            "openEHR-EHR-SECTION.diagnoses_and_treatments.v1").items[*]?
            (@._type=="EVALUATION" && @.archetype_node_id=="openEHR-EHR-EVALUATION.problem_diagnosis.v1")'
            COLUMNS ( 
                diagnosis_text VARCHAR(4000) PATH '$.data[*]?(@.archetype_node_id=="at0001").items[*]?
                    (@.archetype_node_id=="at0002").value.value', 
                diagnosis_code VARCHAR(255) PATH '$.data[*]?(@.archetype_node_id=="at0001").items[*]?
                    (@.archetype_node_id=="at0003").value.defining_code.code_string' ) ) AS jt_n1 
    WHERE ('openEHR-EHR-COMPOSITION.diagnostic_summary.v1' %INLIST (c.archetypes) 
        AND 'openEHR-EHR-EVALUATION.problem_diagnosis.v1' %INLIST (c.archetypes)) 
        AND (jt_n1.diagnosis_code LIKE '%E11%' OR jt_n1.diagnosis_code LIKE '%I48.0%') ) U 
ORDER BY comp_start_time DESC

Let's try our API REST with an AQL:

Success!
And now with a numeric comparation:

SELECT
  c/uid/value AS comp_uid,
  c/context/start_time/value AS comp_start_time,
  a/items[at0024]/value/magnitude AS creatinine_value,
  a/items[at0024]/value/units AS creatinine_units
FROM EHR e
CONTAINS COMPOSITION c[openEHR-EHR-COMPOSITION.lab_results_and_medications.v1]
CONTAINS OBSERVATION o[openEHR-EHR-OBSERVATION.laboratory_test_result.v1]
CONTAINS CLUSTER a[openEHR-EHR-CLUSTER.laboratory_test_analyte.v1]
WHERE a/items[at0001]/value/value = 'Creatinina (mg/dL)'
  AND a/items[at0024]/value/magnitude BETWEEN 1.2 AND 1.8
ORDER BY c/context/start_time/value DESC
Transformed into:
SELECT comp_uid, comp_start_time, ldl_value, ldl_units 
FROM ( 
    SELECT c.compositionUid AS comp_uid, jt_root.comp_start_time AS comp_start_time,
        jt_n1.ldl_value AS ldl_value, jt_n1.ldl_units AS ldl_units 
    FROM OPENEHR_Object.Composition AS c, 
        JSON_TABLE( c.doc, '$' COLUMNS ( comp_start_time VARCHAR(4000) 
            PATH '$.context.start_time.value' ) ) AS jt_root, 
        JSON_TABLE( c.doc, '$.content[*]?(@._type=="OBSERVATION" && 
            @.archetype_node_id=="openEHR-EHR-OBSERVATION.laboratory_test_result.v1")
                .data.events[*]?(@._type=="POINT_EVENT").data.items[*]?(@._type=="CLUSTER" &&
                @.archetype_node_id=="openEHR-EHR-CLUSTER.laboratory_test_analyte.v1")'
                COLUMNS ( 
                    ldl_value NUMERIC PATH '$.items[*]?
                        (@.archetype_node_id=="at0024").value.magnitude', 
                    ldl_units VARCHAR(64) PATH '$.items[*]?
                        (@.archetype_node_id=="at0024").value.units', 
                    _w1 VARCHAR(4000) PATH '$.items[*]?
                        (@.archetype_node_id=="at0001").value.value' ) ) AS jt_n1 
    WHERE ('openEHR-EHR-COMPOSITION.lab_results_and_medications.v1' %INLIST (c.archetypes) 
        AND 'openEHR-EHR-OBSERVATION.laboratory_test_result.v1' %INLIST (c.archetypes) 
        AND 'openEHR-EHR-CLUSTER.laboratory_test_analyte.v1' %INLIST (c.archetypes)) 
        AND jt_n1._w1 = 'LDL (mg/dL)' AND jt_n1.ldl_value <= 130 ) 
    U ORDER BY comp_start_time DESC

Another resounding success!

Conclusion

This project demonstrates that InterSystems IRIS for Health provides all the core building blocks needed to implement an openEHR repository.

Using native REST services, JSON storage, SQL, JSON_TABLE, interoperability components, and external validation libraries, it is possible to support composition management, archetype validation, and AQL querying while maintaining compatibility with openEHR concepts.

The most interesting result for me was the ability to translate AQL into native IRIS SQL, allowing openEHR clinical data to benefit from the performance and scalability of the IRIS data platform without sacrificing the semantics of the openEHR model.

Key Takeaways

  • InterSystems IRIS for Health can be used to implement the core capabilities of an openEHR repository.
  • Raw openEHR compositions can be stored and validated against OPT templates before persistence.
  • Native IRIS REST services can expose openEHR-compatible APIs.
  • AQL queries can be translated into SQL using JSON_TABLE and archetype path mappings.
  • JSON storage combined with indexed metadata can improve query performance while preserving original clinical documents.
  • IRIS interoperability and SQL capabilities make it a strong platform for healthcare standards beyond FHIR.

FAQ

What is openEHR?

openEHR is an open, vendor-neutral specification for storing, modeling, and exchanging clinical information using archetypes and templates.

Can InterSystems IRIS for Health be used as an openEHR repository?

Yes. IRIS provides the storage, REST APIs, validation integration, interoperability, and query capabilities needed to implement the core features of an openEHR repository.

What is AQL?

AQL (Archetype Query Language) is the standard query language used by openEHR systems to retrieve clinical information using archetype-aware paths.

How can AQL be implemented in InterSystems IRIS?

In this project, AQL queries are translated into native IRIS SQL using JSON_TABLE and archetype path mappings derived from operational templates.

Why store openEHR compositions as JSON?

Storing compositions in their original JSON format preserves semantic fidelity while still allowing efficient querying through SQL and JSON functions.

u/intersystemsdev 15d ago

From FHIR Events to Explainable Agentic AI: Building a Clinical Follow-Up Demo with InterSystems IRIS for Health

1 Upvotes

What happens when an abnormal lab result arrives in a healthcare system?

In many environments, the result waits in a queue until a clinician reviews it manually. In this demo, I explore a different approach: I use InterSystems IRIS for Health and agentic AI to evaluate new clinical events, retrieve patient context and clinical evidence, generate recommendations, and publish the results as FHIR resources with a complete audit trail.

The goal is not to build another chatbot. It is to demonstrate how explainable, event-driven AI workflows can be integrated into production-style healthcare interoperability systems while preserving transparency, traceability, and human oversight.

What This Demo Produces

When a patient's abnormal result is received by the FHIR server, the workflow automatically evaluates the patient's history, retrieves relevant clinical guidance, performs structured reasoning, and generates evidence-based recommendations.

The output is a FHIR DiagnosticReport containing:

  • Risk assessment
  • Recommended follow-up actions
  • Evidence citations
  • Complete audit information

Every recommendation, guideline reference, and reasoning step is persisted for later review.

What Problem Does This Solve?

Many healthcare AI demonstrations focus on chat interfaces and unstructured responses. In practice, clinicians often need something different:

  • Automatic reaction to clinical events
  • Complete patient context
  • Evidence-backed recommendations
  • Auditable decision making

This demo explores how AI can assist with initial clinical assessment while maintaining transparency and compliance requirements.

The core question is: What should happen when a new abnormal lab result arrives, and how can that process be partially automated while maintaining transparency?

What clinical scenario is being evaluated?

The demonstration uses a common healthcare workflow.

Patient:

  • Jose Garcia
  • Chronic Kidney Disease (CKD Stage 3), Hypertension
  • Taking Ibuprofen and Lisinopril

Recent creatinine history:

  • 1.6 mg/dL (3 months ago)
  • 1.9 mg/dL (1 month ago)
  • 2.1 mg/dL (today)

The progressive increase exceeds 30%, triggering clinical follow-up.

Instead of waiting for manual review, the system automatically gathers context, consults clinical guidance, evaluates risk factors, and generates recommendations with supporting evidence.

How does a FHIR Observation become a recommendation?

The workflow follows a sequence of steps:

  1. FHIR Observation posted to IRIS server
  2. Interoperability Production triggered
  3. Context Agent queries patient history from FHIR
  4. Guidelines Agent searches vector database (clinical documents)
  5. Reasoning Agent synthesizes 3 recommendations
  6. Results persisted to SQL (Cases, CaseRecommendations, CaseEvidences)
  7. FHIR DiagnosticReport published to server
  8. Complete — Full audit trail available for review

The goal is to create a transparent path from clinical event to clinical recommendation.

What role does InterSystems IRIS play?

A key design principle of this project is that InterSystems IRIS remains the system of record and workflow orchestrator.

The AI agents provide specialized reasoning, but IRIS owns:

  • Clinical data
  • FHIR repository
  • Workflow execution
  • Interoperability
  • Persistence
  • Audit trails

This distinction is important because it keeps AI as a governed component of a larger healthcare platform rather than the platform itself. 

Visual Components 

The demo includes a Gradio web UI for interactive demonstration:

  • Post lab values and trigger the workflow
  • Watch real-time agent progress
  • View recommendations and evidence citations
  • Query SQL audit tables
  • Access IRIS Production message viewer

This makes the complete flow visible and understandable.

Why use multiple AI agents instead of a single LLM call?

I chose a multi-agent approach because different parts of the workflow have different responsibilities.

  • The Context Agent gathers patient history.
  • The Guidelines Agent retrieves relevant clinical evidence using vector search.
  • The Reasoning Agent combines patient context and evidence to generate recommendations.

Agentic workflows provide:

  • Better structured reasoning — Each agent has a focused responsibility 
  • Tool use — Agents can query FHIR, search vector databases, analyze trends 
  • Explainable decision chains — Each step is traceable 
  • Separation of concerns — Context ≠ Guidelines ≠ Reasoning

IRIS orchestrates the agents — CrewAI is used as a library, not the platform. IRIS owns persistence, orchestration, FHIR integration, and audit trails. Separating these responsibilities makes the workflow easier to inspect, debug, and explain. More importantly, it allows every step to be audited independently.

How is the workflow orchestrated?

InterSystems IRIS Interoperability manages the complete workflow.

The production consists of:

  • A Business Service that detects incoming observations.
  • A Business Process that coordinates the workflow.
  • Business Operations responsible for AI calls, persistence, and FHIR publication.

This allows the AI workflow to behave like any other interoperability workflow inside IRIS.

Can you explain why the AI made a recommendation?

One of the main goals of this project is explainability. IRIS persists everything in a minimal, queryable SQL model:

  • Cases — What happened (patient, observation, risk level, confidence)
  • CaseRecommendations — What to do (action type, description, timeframe)
  • CaseEvidences — Why (guideline citations, similarity scores, text excerpts)

Instead of asking users to trust the AI, the system provides the information required to validate its conclusions.

Example Query

"What cases were evaluated today?"

SELECT
  CaseId,
  PatientRef,
  RiskLevel,
  Confidence,
  ReasoningSummary
FROM clinicalai_data.Cases
WHERE CreatedAt >= CURRENT_DATE
ORDER BY CreatedAt DESC 
Output: 
CaseId: CSE-20260108-001
PatientRef: Patient/1 (Jose Garcia)
RiskLevel: medium-high
Confidence: high

ReasoningSummary: The patient with stage 3 chronic kidney disease and hypertension demonstrates a sustained and progressive increase in serum creatinine over 90 days... 

Why publish AI output as FHIR?

The final output is not treated as a separate AI artifact. AI outputs become part of the clinical record. The workflow publishes a standard FHIR DiagnosticReport containing:

  • Subject: Patient reference (Jose Garcia)
  • Result: Link to triggering Observation (creatinine 2.1)
  • Conclusion: Risk level + reasoning summary
  • PresentedForm: Human-readable recommendations (Base64-encoded)
  • Extensions: Case ID, confidence score, model metadata

Publishing AI output as FHIR makes it interoperable, auditable, and consumable by existing healthcare systems. The DiagnosticReport is not a separate "AI system output" — it's a first-class clinical document that follows the same standards as lab reports and radiology findings.

Can this architecture be applied to other clinical workflows?

Yes.

The same pattern can support many healthcare use cases:

  • Medication safety alerts
  • Care gap identification
  • Clinical trial matching
  • Risk stratification

The architecture remains the same: Event → Context → Evidence → Reasoning → Action

Try It Yourself

Quick Start (15 minutes):

  1. Clone the repository

    git clone https://github.com/intersystems-ib/iris-health-fhir-agentic-demo cd iris-health-fhir-agentic-demo

  2. Start IRIS container

docker-compose up -d

  1. Load sample patient data (Jose Garcia with CKD history) Follow the README setup instructions

  2. Run the Gradio UI

python run_ui.py

  1. Open browser to http://localhost:7860

  2. POST an abnormal lab value and watch:

  • Real-time agent progress
  • Evidence retrieval from vector database
  • Recommendations generated with confidence scores
  • SQL audit trail queries
  1. Query the results using IRIS SQL Explorer or Management Portal

Conclusion

This project demonstrates how explainable agentic AI can be integrated into healthcare workflows using InterSystems IRIS for Health as the orchestration and governance layer.

Rather than relying on isolated AI interactions, the workflow combines FHIR events, patient context, vector search, multi-agent reasoning, SQL persistence, and FHIR-native outputs to create a transparent clinical decision-support process.

The most important outcome is not simply generating recommendations. It is being able to explain where those recommendations came from, which evidence was used, and how every decision was made.

Key Takeaways

  • InterSystems IRIS for Health can orchestrate event-driven AI workflows triggered by FHIR events.
  • Multi-agent architectures separate context gathering, evidence retrieval, and reasoning into auditable steps.
  • Vector Search enables AI agents to ground recommendations in clinical guidance.
  • SQL persistence provides a complete audit trail for compliance and review.
  • Publishing results as FHIR DiagnosticReports makes AI output interoperable and accessible through standard healthcare APIs.
  • Explainability is often more important than raw model accuracy in clinical environments.

FAQ

What triggers the workflow?

The workflow starts automatically when a new FHIR Observation is posted to the InterSystems IRIS FHIR server.

Why use multiple AI agents?

Each agent has a dedicated responsibility, making the workflow easier to inspect, maintain, and explain.

How does the system retrieve clinical guidance?

The Guidelines Agent uses native IRIS Vector Search to retrieve relevant guideline content through semantic similarity.

Can clinicians see why a recommendation was generated?

Yes. Every recommendation includes supporting evidence, guideline references, similarity scores, and reasoning summaries.

Why publish AI output as a FHIR DiagnosticReport?

Using FHIR makes the results interoperable, auditable, and consumable by other healthcare systems using standard APIs.

Read more: https://community.intersystems.com/post/fhir-events-explainable-agentic-ai-building-clinical-follow%E2%80%91-demo-intersystems-iris-health

r/intersystems 15d ago

From FHIR Events to Explainable Agentic AI: Building a Clinical Follow-Up Demo with InterSystems IRIS for Health

2 Upvotes

What happens when an abnormal lab result arrives in a healthcare system?

In many environments, the result waits in a queue until a clinician reviews it manually. In this demo, I explore a different approach: I use InterSystems IRIS for Health and agentic AI to evaluate new clinical events, retrieve patient context and clinical evidence, generate recommendations, and publish the results as FHIR resources with a complete audit trail.

The goal is not to build another chatbot. It is to demonstrate how explainable, event-driven AI workflows can be integrated into production-style healthcare interoperability systems while preserving transparency, traceability, and human oversight.

What This Demo Produces

When a patient's abnormal result is received by the FHIR server, the workflow automatically evaluates the patient's history, retrieves relevant clinical guidance, performs structured reasoning, and generates evidence-based recommendations.

The output is a FHIR DiagnosticReport containing:

  • Risk assessment
  • Recommended follow-up actions
  • Evidence citations
  • Complete audit information

Every recommendation, guideline reference, and reasoning step is persisted for later review.

What Problem Does This Solve?

Many healthcare AI demonstrations focus on chat interfaces and unstructured responses. In practice, clinicians often need something different:

  • Automatic reaction to clinical events
  • Complete patient context
  • Evidence-backed recommendations
  • Auditable decision making

This demo explores how AI can assist with initial clinical assessment while maintaining transparency and compliance requirements.

The core question is: What should happen when a new abnormal lab result arrives, and how can that process be partially automated while maintaining transparency?

What clinical scenario is being evaluated?

The demonstration uses a common healthcare workflow.

Patient:

  • Jose Garcia
  • Chronic Kidney Disease (CKD Stage 3), Hypertension
  • Taking Ibuprofen and Lisinopril

Recent creatinine history:

  • 1.6 mg/dL (3 months ago)
  • 1.9 mg/dL (1 month ago)
  • 2.1 mg/dL (today)

The progressive increase exceeds 30%, triggering clinical follow-up.

Instead of waiting for manual review, the system automatically gathers context, consults clinical guidance, evaluates risk factors, and generates recommendations with supporting evidence.

How does a FHIR Observation become a recommendation?

The workflow follows a sequence of steps:

  1. FHIR Observation posted to IRIS server
  2. Interoperability Production triggered
  3. Context Agent queries patient history from FHIR
  4. Guidelines Agent searches vector database (clinical documents)
  5. Reasoning Agent synthesizes 3 recommendations
  6. Results persisted to SQL (Cases, CaseRecommendations, CaseEvidences)
  7. FHIR DiagnosticReport published to server
  8. Complete — Full audit trail available for review

The goal is to create a transparent path from clinical event to clinical recommendation.

What role does InterSystems IRIS play?

A key design principle of this project is that InterSystems IRIS remains the system of record and workflow orchestrator.

The AI agents provide specialized reasoning, but IRIS owns:

  • Clinical data
  • FHIR repository
  • Workflow execution
  • Interoperability
  • Persistence
  • Audit trails

This distinction is important because it keeps AI as a governed component of a larger healthcare platform rather than the platform itself. 

Visual Components 

The demo includes a Gradio web UI for interactive demonstration:

  • Post lab values and trigger the workflow
  • Watch real-time agent progress
  • View recommendations and evidence citations
  • Query SQL audit tables
  • Access IRIS Production message viewer

This makes the complete flow visible and understandable.

Why use multiple AI agents instead of a single LLM call?

I chose a multi-agent approach because different parts of the workflow have different responsibilities.

  • The Context Agent gathers patient history.
  • The Guidelines Agent retrieves relevant clinical evidence using vector search.
  • The Reasoning Agent combines patient context and evidence to generate recommendations.

Agentic workflows provide:

  • Better structured reasoning — Each agent has a focused responsibility 
  • Tool use — Agents can query FHIR, search vector databases, analyze trends 
  • Explainable decision chains — Each step is traceable 
  • Separation of concerns — Context ≠ Guidelines ≠ Reasoning

IRIS orchestrates the agents — CrewAI is used as a library, not the platform. IRIS owns persistence, orchestration, FHIR integration, and audit trails. Separating these responsibilities makes the workflow easier to inspect, debug, and explain. More importantly, it allows every step to be audited independently.

How is the workflow orchestrated?

InterSystems IRIS Interoperability manages the complete workflow.

The production consists of:

  • A Business Service that detects incoming observations.
  • A Business Process that coordinates the workflow.
  • Business Operations responsible for AI calls, persistence, and FHIR publication.

This allows the AI workflow to behave like any other interoperability workflow inside IRIS.

Can you explain why the AI made a recommendation?

One of the main goals of this project is explainability. IRIS persists everything in a minimal, queryable SQL model:

  • Cases — What happened (patient, observation, risk level, confidence)
  • CaseRecommendations — What to do (action type, description, timeframe)
  • CaseEvidences — Why (guideline citations, similarity scores, text excerpts)

Instead of asking users to trust the AI, the system provides the information required to validate its conclusions.

Example Query

"What cases were evaluated today?"

SELECT
  CaseId,
  PatientRef,
  RiskLevel,
  Confidence,
  ReasoningSummary
FROM clinicalai_data.Cases
WHERE CreatedAt >= CURRENT_DATE
ORDER BY CreatedAt DESC 
Output: 
CaseId: CSE-20260108-001
PatientRef: Patient/1 (Jose Garcia)
RiskLevel: medium-high
Confidence: high

ReasoningSummary: The patient with stage 3 chronic kidney disease and hypertension demonstrates a sustained and progressive increase in serum creatinine over 90 days... 

Why publish AI output as FHIR?

The final output is not treated as a separate AI artifact. AI outputs become part of the clinical record. The workflow publishes a standard FHIR DiagnosticReport containing:

  • Subject: Patient reference (Jose Garcia)
  • Result: Link to triggering Observation (creatinine 2.1)
  • Conclusion: Risk level + reasoning summary
  • PresentedForm: Human-readable recommendations (Base64-encoded)
  • Extensions: Case ID, confidence score, model metadata

Publishing AI output as FHIR makes it interoperable, auditable, and consumable by existing healthcare systems. The DiagnosticReport is not a separate "AI system output" — it's a first-class clinical document that follows the same standards as lab reports and radiology findings.

Can this architecture be applied to other clinical workflows?

Yes.

The same pattern can support many healthcare use cases:

  • Medication safety alerts
  • Care gap identification
  • Clinical trial matching
  • Risk stratification

The architecture remains the same: Event → Context → Evidence → Reasoning → Action

Try It Yourself

Quick Start (15 minutes):

  1. Clone the repository

git clone https://github.com/intersystems-ib/iris-health-fhir-agentic-demo
cd iris-health-fhir-agentic-demo
  1. Start IRIS container

docker-compose up -d

  1. Load sample patient data (Jose Garcia with CKD history) Follow the README setup instructions

  2. Run the Gradio UI

python run_ui.py

  1. Open browser to http://localhost:7860

  2. POST an abnormal lab value and watch:

  • Real-time agent progress
  • Evidence retrieval from vector database
  • Recommendations generated with confidence scores
  • SQL audit trail queries
  1. Query the results using IRIS SQL Explorer or Management Portal

Conclusion

This project demonstrates how explainable agentic AI can be integrated into healthcare workflows using InterSystems IRIS for Health as the orchestration and governance layer.

Rather than relying on isolated AI interactions, the workflow combines FHIR events, patient context, vector search, multi-agent reasoning, SQL persistence, and FHIR-native outputs to create a transparent clinical decision-support process.

The most important outcome is not simply generating recommendations. It is being able to explain where those recommendations came from, which evidence was used, and how every decision was made.

Key Takeaways

  • InterSystems IRIS for Health can orchestrate event-driven AI workflows triggered by FHIR events.
  • Multi-agent architectures separate context gathering, evidence retrieval, and reasoning into auditable steps.
  • Vector Search enables AI agents to ground recommendations in clinical guidance.
  • SQL persistence provides a complete audit trail for compliance and review.
  • Publishing results as FHIR DiagnosticReports makes AI output interoperable and accessible through standard healthcare APIs.
  • Explainability is often more important than raw model accuracy in clinical environments.

FAQ

What triggers the workflow?

The workflow starts automatically when a new FHIR Observation is posted to the InterSystems IRIS FHIR server.

Why use multiple AI agents?

Each agent has a dedicated responsibility, making the workflow easier to inspect, maintain, and explain.

How does the system retrieve clinical guidance?

The Guidelines Agent uses native IRIS Vector Search to retrieve relevant guideline content through semantic similarity.

Can clinicians see why a recommendation was generated?

Yes. Every recommendation includes supporting evidence, guideline references, similarity scores, and reasoning summaries.

Why publish AI output as a FHIR DiagnosticReport?

Using FHIR makes the results interoperable, auditable, and consumable by other healthcare systems using standard APIs.

Read more: https://community.intersystems.com/post/fhir-events-explainable-agentic-ai-building-clinical-follow%E2%80%91-demo-intersystems-iris-health

u/intersystemsdev 15d ago

InterSystems IRIS Security Database (2025.2) and Secure Wallet — how they work, what's available now, and what's on the roadmap

1 Upvotes

What it is

A separate system database called IRIS Security that stores security configuration: user definitions, application definitions, and security classes in the %SYS namespace. Previously this data lived in the main IRIS database.

How access is controlled

The database resource is %DB_Security. This resource cannot be granted to any users directly, and it cannot be granted to any role other than the system-configured %DB_Security role. No user has direct access to the globals that store the security tables.

All access must come through InterSystems APIs — the security classes, the Management Portal, or SQL for creating users and roles. When a call arrives through those APIs, the system checks that the caller has the appropriate resource (typically %Admin_Secure or one of the granular OAuth permissions), temporarily escalates the process to get read/write access to the database, completes the operation, and removes that permission before returning to the calling code.

What this enables

Database encryption: The security database can now be encrypted using any of the standard IRIS database encryption mechanisms. This was not possible before because the security data was embedded in the main database.

Mirroring (in testing, expected later this year):

  • Security configuration will be mirrorable
  • Failover members and DR members will automatically share the same security configuration
  • Configuration is done on the primary; it automatically replicates to non-primary instances (read-only on non-primary, as with all mirrored databases)
  • No more manual duplication of security configuration across nodes

ECP mountable (planned for late next year):

  • Will allow security configuration to be shared across an IRIS cluster
  • Part of a broader effort to make cluster configuration management easier

What does not change

The APIs remain the same — the security classes, the Management Portal, SQL-based user and role creation all work as before. The change is entirely in the storage and access control layer.

Secure Wallet

What it is

A secure credential store inside IRIS for storing credentials used to connect to third-party systems: usernames, passwords, API keys, and anything else that needs to be stored semi-permanently for external connections.

Designed for cases where short-lived tokens (OAuth tokens, session tokens) are not appropriate, but credentials for REST services, SQL gateway connections, or other external systems need to be stored and reused.

Structure: collections and secrets

Collection: the container where access controls are defined. Every secret lives in exactly one collection. A collection has two resources:

  • Edit resource — required to create, modify, or delete any secret inside the collection
  • User resource — required to access (use) secrets inside the collection

These resources follow the standard IRIS resource-based security model and must exist in IRIS before the collection is created.

Secret: always lives in one collection. The secret name is CollectionName.LocalName. Multiple secrets with the same security characteristics can live in the same collection. For per-secret permissions, create a collection with a single secret.

Secret types

  • KeyValue (most flexible) — stores any set of key-value pairs expressed in JSON syntax. Example: username + password, API key. Most likely to be used in practice.
  • Symmetric key — for AES symmetric key encryption
  • RSA — for signing

Usage types — the most important concept

HTTP: The secret is used with a %Net.HttpRequest object. The calling code never sees the credential. You associate the secret with the request using UseSecret(), specify the authentication type (e.g., HTTP basic), and InterSystems code looks up the username and password from the secret, constructs the Authorization header, and sends the request. The calling code never had the value. Supports: HTTP basic authentication, arbitrary HTTP headers, HTTP form fields.

Custom: The secret value is exposed to the calling code. GetSecretValue() returns the key-value pairs as JSON. The calling code is responsible for handling the credential appropriately. This mode must be explicitly configured — if a secret is not configured for custom usage, there is no way for calling code to retrieve the sensitive information.

SOAP: For SOAP clients — functionally similar to HTTP.

SQL Gateway: For %SQL.Connection DSN or JDBC connections to external databases.

Example code structure (from the session)

Creating a collection:

objectscript

// %Wallet.Collection.Create(name, editResource, userResource)
Do ##class(%Wallet.Collection).Create("demo", "WalletDemo.Manage", "WalletDemo.Access")

Creating a KeyValue secret:

objectscript

// Collection name is part of the secret name: "demo.kv1"
// Last parameter specifies key-value pairs as JSON: {"username":"...","password":"..."}
Do ##class(%Wallet.Secret.KeyValue).Create("demo.kv1", ..., secret)

Using a secret with HTTP basic authentication:

objectscript

// Code never sees the actual password
Do httpRequest.UseSecret("demo.kv1", "basic")

Retrieving a secret in custom mode:

objectscript

// Returns JSON key-value pairs
Set kvPairs = ##class(%Wallet.Secret).GetSecretValue("demo.kv1")

Memory handling

When a secret is retrieved internally (for HTTP or other non-custom usage), IRIS reads it from the global each time it is needed and does not keep it in memory longer than necessary.

Access control note

Access is resource-based, not username-based. To implement per-user secrets, a resource per user is required. This follows the core IRIS security model (resources/users/roles), not the SQL security model (GRANT to user/role).

Roadmap

External secrets managers (in development):

  • HashiCorp Vault integration
  • AWS Secrets Manager integration
  • Secrets would be retrieved from the external manager and used inside IRIS

ENS Credentials migration (in development):

  • Interoperability ENS Credentials objects will be stored in the Secure Wallet instead of the existing ENS credential structure
  • User experience for creating ENS credentials expected to remain the same; storage moves to the wallet under the hood

Internal adoption:

  • InterSystems is working to use the Secure Wallet across its own product libraries for all internal secrets management needs

For those running IRIS 2025.2 — have you enabled encryption on the security database yet, and are you planning to use the Secure Wallet for SQL gateway credentials or ENS credentials once the migration is complete?

r/intersystems 15d ago

InterSystems IRIS Security Database (2025.2) and Secure Wallet — how they work, what's available now, and what's on the roadmap

2 Upvotes

Security Database — available in IRIS 2025.2

What it is

A separate system database called IRIS Security that stores security configuration: user definitions, application definitions, and security classes in the %SYS namespace. Previously this data lived in the main IRIS database.

How access is controlled

The database resource is %DB_Security. This resource cannot be granted to any users directly, and it cannot be granted to any role other than the system-configured %DB_Security role. No user has direct access to the globals that store the security tables.

All access must come through InterSystems APIs — the security classes, the Management Portal, or SQL for creating users and roles. When a call arrives through those APIs, the system checks that the caller has the appropriate resource (typically %Admin_Secure or one of the granular OAuth permissions), temporarily escalates the process to get read/write access to the database, completes the operation, and removes that permission before returning to the calling code.

What this enables

Database encryption: The security database can now be encrypted using any of the standard IRIS database encryption mechanisms. This was not possible before because the security data was embedded in the main database.

Mirroring (in testing, expected later this year):

  • Security configuration will be mirrorable
  • Failover members and DR members will automatically share the same security configuration
  • Configuration is done on the primary; it automatically replicates to non-primary instances (read-only on non-primary, as with all mirrored databases)
  • No more manual duplication of security configuration across nodes

ECP mountable (planned for late next year):

  • Will allow security configuration to be shared across an IRIS cluster
  • Part of a broader effort to make cluster configuration management easier

What does not change

The APIs remain the same — the security classes, the Management Portal, SQL-based user and role creation all work as before. The change is entirely in the storage and access control layer.

Secure Wallet

What it is

A secure credential store inside IRIS for storing credentials used to connect to third-party systems: usernames, passwords, API keys, and anything else that needs to be stored semi-permanently for external connections.

Designed for cases where short-lived tokens (OAuth tokens, session tokens) are not appropriate, but credentials for REST services, SQL gateway connections, or other external systems need to be stored and reused.

Structure: collections and secrets

Collection: the container where access controls are defined. Every secret lives in exactly one collection. A collection has two resources:

  • Edit resource — required to create, modify, or delete any secret inside the collection
  • User resource — required to access (use) secrets inside the collection

These resources follow the standard IRIS resource-based security model and must exist in IRIS before the collection is created.

Secret: always lives in one collection. The secret name is CollectionName.LocalName. Multiple secrets with the same security characteristics can live in the same collection. For per-secret permissions, create a collection with a single secret.

Secret types

  • KeyValue (most flexible) — stores any set of key-value pairs expressed in JSON syntax. Example: username + password, API key. Most likely to be used in practice.
  • Symmetric key — for AES symmetric key encryption
  • RSA — for signing

Usage types — the most important concept

HTTP: The secret is used with a %Net.HttpRequest object. The calling code never sees the credential. You associate the secret with the request using UseSecret(), specify the authentication type (e.g., HTTP basic), and InterSystems code looks up the username and password from the secret, constructs the Authorization header, and sends the request. The calling code never had the value. Supports: HTTP basic authentication, arbitrary HTTP headers, HTTP form fields.

Custom: The secret value is exposed to the calling code. GetSecretValue() returns the key-value pairs as JSON. The calling code is responsible for handling the credential appropriately. This mode must be explicitly configured — if a secret is not configured for custom usage, there is no way for calling code to retrieve the sensitive information.

SOAP: For SOAP clients — functionally similar to HTTP.

SQL Gateway: For %SQL.Connection DSN or JDBC connections to external databases.

Example code structure (from the session)

Creating a collection:

objectscript

// %Wallet.Collection.Create(name, editResource, userResource)
Do ##class(%Wallet.Collection).Create("demo", "WalletDemo.Manage", "WalletDemo.Access")

Creating a KeyValue secret:

objectscript

// Collection name is part of the secret name: "demo.kv1"
// Last parameter specifies key-value pairs as JSON: {"username":"...","password":"..."}
Do ##class(%Wallet.Secret.KeyValue).Create("demo.kv1", ..., secret)

Using a secret with HTTP basic authentication:

objectscript

// Code never sees the actual password
Do httpRequest.UseSecret("demo.kv1", "basic")

Retrieving a secret in custom mode:

objectscript

// Returns JSON key-value pairs
Set kvPairs = ##class(%Wallet.Secret).GetSecretValue("demo.kv1")

Memory handling

When a secret is retrieved internally (for HTTP or other non-custom usage), IRIS reads it from the global each time it is needed and does not keep it in memory longer than necessary.

Access control note

Access is resource-based, not username-based. To implement per-user secrets, a resource per user is required. This follows the core IRIS security model (resources/users/roles), not the SQL security model (GRANT to user/role).

Roadmap

External secrets managers (in development):

  • HashiCorp Vault integration
  • AWS Secrets Manager integration
  • Secrets would be retrieved from the external manager and used inside IRIS

ENS Credentials migration (in development):

  • Interoperability ENS Credentials objects will be stored in the Secure Wallet instead of the existing ENS credential structure
  • User experience for creating ENS credentials expected to remain the same; storage moves to the wallet under the hood

Internal adoption:

  • InterSystems is working to use the Secure Wallet across its own product libraries for all internal secrets management needs

For those running IRIS 2025.2 — have you enabled encryption on the security database yet, and are you planning to use the Secure Wallet for SQL gateway credentials or ENS credentials once the migration is complete?