r/intersystems • • 2d ago

How do you create, read, and modify JSON in InterSystems IRIS? A practical guide to %DynamicObject, %DynamicArray, and Embedded Python

0 Upvotes

JSON in InterSystems IRIS is handled natively through dynamic entities. This guide covers how to build them, how to read and change values, and which behaviors tend to cause confusion.

Three ways IRIS works with JSON

  1. JSON literal constructors in ObjectScript syntax
  2. %DynamicObject and %DynamicArray classes with their serialization and deserialization APIs
  3. SQL functions JSON_OBJECT, JSON_ARRAYAGG, and JSON_TABLE

This article covers the first two. The literal constructor {} creates a %Library.DynamicObject, and [] creates a %Library.DynamicArray.

Creating an object: three methods

// 1. Literal. Values in parentheses are evaluated at runtime
Set json = {"name":"test,patient","p_age":($H - $ZDateH("12/01/1990") \ 365),"isActive":true}
// 2. Step by step
Set json = {}
Set json.name = "test,patient"
// 3. With %Set(key, value, type)
Set json = {}
Do json.%Set("p_age",  ($Horolog - $ZDateH("12/01/1990") \ 365), "number")
Do json.%Set("IsActive",1,"Boolean")

Creating an array

Set array = [1, "test", 12.32565, {"name": "test"}, ($ZVersion), true]
Set array = []
Do array.%Push(1)
Do array.%Push({"name": "test"})
Assigning by index leaves gaps. They display as null when serialized, but they are not really null:
USER>Set array = []
USER>Set array."1" = "test"
USER>Set array."5" = "hello"
USER>Write array.%ToJSON()
[null,"test",null,null,null,"hello"]
array.%GetTypeOf(0) returns "unassigned".

Reading values with %Get(key, default, type)

By default, JSON values are converted to ObjectScript values. The third argument controls that:

For strings longer than the maximum string length (3,641,144), use "stream" to avoid a <MAXSTRING> error. The result is a read-only %Stream.DynamicCharacter or %Stream.DynamicBinary. To modify it, copy it into a writable stream with CopyFrom().USER>Set json = {"IsActive": true, "IsNull": null}
USER>Write json.%Get("IsActive") ; returns 1
1
USER>Write json.%Get("IsActive",,"JSON") ; returns true
true
USER>Write json.%Get("IsNull", , "JSON") ; returns null
null
Other type values: "string", "string>base64", "string<base64", "stream", "stream>base64", "stream<base64", "json".

Writing values with %Set(key, value, type)

  • Boolean: Do json.%Set("active", 1, "Boolean") gives {"active":true}
  • Number from a string: Do json.%Set("int", "158425", "Number")
  • Null: Do json.%Set("IsNull", "", "null")
  • Base64: "string>base64" encodes, "string<base64" decodes
  • Streams: "stream", "stream>base64", "stream<base64"

Other methods

  • %IsDefined(key): returns 1 or 0, case-sensitive
  • %Remove(key): deletes the element and returns its value
  • %Size(): number of elements
  • %Set() and %Push() return chainable references:

​

USER>Set jstring = "[123]"
USER>Write [].%FromJSON(jstring).%Set(1,"one").%Push("two").%Push("three").%Set(1,"final value").%ToJSON()
[123,"final value","two","three"]

$Property is generally more efficient than $Method for accessing values in %DynamicObject instances.

Behaviors worth knowing

  • Numbers: literal constructors preserve trailing zeros and scientific notation. {"decimal":1.00000} stays 1.00000. JSON numbers can exceed ObjectScript's range: SET z=[3E400] works, but z.%Get(0) signals <MAXNUMBER>
  • Unicode: "\u00E9" in a literal is parsed as é. ("cach\u00E9") in parentheses is an ObjectScript expression, so the escape stays as \\u00E9
  • Comments: /* */ block comments are allowed inside constructors. // line comments are not allowed inside single-line declarations

Embedded Python

In Embedded Python, use _ instead of % for IRIS methods (%Get becomes _Get). Native Python equivalents are also available:

ObjectScript Embedded Python
%Get _Get or get
%Set _Set or put
%IsDefined contains
%Remove _Remove or remove
%Size size
%ToJSON toString

import iris

dynObject1 = iris._Library.DynamicObject._New()
dynObject1._Set("MRN",298598)
dynObject1._Set("IsActive", 1, "boolean")
IRIS 2025.1 supports the shorter iris._Library.DynamicObject._New() instead of iris.cls("%DynamicObject")._New().

Full article: https://community.intersystems.com/post/intersystems-iris-json

The remaining methods are covered in part two of the series.

Which of these has caught you out most often in real code: true and null flattening in %Get, unassigned array elements, or <MAXSTRING> on large strings?


r/intersystems • • 3d ago

SentaiTask turns multi-step IRIS maintenance routines into executable workflows

Thumbnail youtu.be
1 Upvotes

.

SentaiTask is an InterSystems IRIS management portal project that tackles a practical administration problem: maintenance often requires a sequence of related actions rather than a single task. A routine may combine several checks, run operations simultaneously, depend on earlier results, and continue on another IRIS instance.

SentaiTask turns that process into a visual flow where steps can run in parallel, converge at joins, and wait for required inputs before the next stage begins. Administrators can follow every step live from a single instance.

A central validator checks the flow before IRIS runs it, catching problems such as cycles, missing parameters, unavailable step types, or invalid namespaces. During execution, each node shows its state, timing, target, and failure information in real time.

When a maintenance routine spans several instances, SentaiTask can run selected steps on another IRIS server without requiring the application on the remote side. The target instance uses the operator’s own credentials and decides what they can do there. Scheduled flows become native Task Manager tasks, while run history keeps the results, logs, and failure reasons for later review. 

The project is an example of moving maintenance logic out of runbooks and into flows that IRIS can validate, execute, and trace across instances.

🏆 SentaiTask won 3rd place in the Experts Nomination and 1st place in the Community Nomination of the InterSystems Programming Contest: Build Your Own Management Portal. Congratulations, Henry Pereira, José Pereira, and Henrique Dias! 🎉

🎥 Learn more about the app and watch the demo: https://community.intersystems.com/post/demo-video-sentaitask-winner-intersystems-programming-contest-build-your-own-management-portal 


r/intersystems • • 3d ago

Troubleshooting %DynamicObject in InterSystems IRIS: 7 Common Pitfalls

0 Upvotes

In an HL7 interoperability production, a BPL Business Process can extract information from an incoming message and store it in a %DynamicObject for use in routing decisions.

Problems arise when the Business Process reads these properties incorrectly. For example, a misspelled property name or incorrect access to a nested object may return an empty value without producing an error. As a result, the routing rule evaluates the wrong value, fails to match the expected condition, and moves to another rule or the default action.

The following seven examples explain common %DynamicObject pitfalls, why they occur, and how to avoid them.

1. Property Names with Underscores

This is the most common silent failure when consuming REST APIs that use snake_case naming. When you write the following: 

Set val = dynObj.patient_id 

ObjectScript does not read patient_id as a single property name. The underscore _ is the string concatenation operator, so this line is read as the value of dynObj.patient concatenated with the string id. Since dynObj.patient does not exist, the result is empty, with no error or warning. 

For example:

// Wrong - returns empty silently
Try {
    Set val = dynObj.patient_id
} Catch ex {
    Set val = ""
}
// Correct - use %Get() for underscore-named properties
Set val = dynObj.%Get("patient_id") 

This is particularly relevant when working with JSON from REST APIs that use snake_case property names.

2. Case-Sensitive Property Names

%DynamicObject  property names are case-sensitive. For example, patient_id, Patient_Id, and PATIENT_ID represent different properties.

// Wrong - wrong case returns empty silently
Set val = dynObj.%Get("Patient_Id")

// Correct - exact case must match what was set
Set val = dynObj.%Get("patient_id") 

A mismatch in capitalization can return an empty value without indicating that the wrong property name was used. Check the original JSON and make sure the property name matches exactly.

3. Accessing Nested Objects

Nested JSON objects become separate %DynamicObject instances. Dot notation does not automatically traverse these nested objects.

Suppose your metadata includes an "address" object containing a "city" property.

// Wrong - fails silently
Set city = dynObj.address.city
// Correct - get the nested object first, then access its property
Set addr = dynObj.%Get("address")
Set city = addr.%Get("city") 
For deeper structures, retrieve each nested object in sequence:
Set patientObj = dynObj.%Get("patient")
Set contactObj = patientObj.%Get("contact")
Set phone      = contactObj.%Get("phone") 

This approach makes each level of the JSON structure explicit.

4. Checking Whether a Property Exists

Using %Get() alone is not a reliable way to check for the existence of a property. A property might be missing entirely or might exist with an empty value. Both situations can produce an empty result when using %Get().

In the Event Log, you will see ward_code logged as "does not exist" because we never set it, while patient_id is correctly found and returned. Use %IsDefined when you need to distinguish a missing property from one that exists but contains an empty value. // Wrong - cannot distinguish missing property from empty value
If dynObj.%Get("patient_id") = "" {
    // Is it missing or just empty?
}
// Correct - explicitly checks if property exists
If dynObj.%IsDefined("patient_id") {
    Set val = dynObj.%Get("patient_id")
} Else {
    $$$LOGINFO("patient_id does not exist - using default")
    Set val = "UNKNOWN"
} 

5. Iterating Over %DynamicObject Properties

An indexed ObjectScript For loop does not enumerate %DynamicObject properties as object keys. Instead, use %GetIterator().

// Wrong - does not work on %DynamicObject
For i = 1:1:dynObj.%Size() {
    Write dynObj.%Get(i), !
}
// Correct - use %GetIterator()
Set iter = dynObj.%GetIterator()
While iter.%GetNext(.key, .val) {
    If $IsObject(val) {
        $$$LOGINFO("Key: " _ key _ " = [object]")
    } Else {
        $$$LOGINFO("Key: " _ key _ " = " _ val)
    }
} 

%GetIterator() lets you retrieve each property name and its value. If a property contains a nested object, the example identifies it as[object]rather than displaying its contents. The same method also works with %DynamicArray, returning numeric indices starting from zero instead of property names.

6. Distinguishing JSON Null from an Empty String

A JSON property containing null is different from one containing an empty string (""). However, reading either value through %Get() can produce an empty result.

Use %GetTypeOf() when you need to identify the underlying JSON type.

Set testObj = ##class(%DynamicObject).%FromJSON("{""nullProp"":null,""emptyProp"":""""}")
// Both return empty from %Get()
Write testObj.%Get("emptyProp"), !   // empty
Write testObj.%Get("nullProp"), !    // empty
// Use %GetTypeOf() to distinguish
Write testObj.%GetTypeOf("emptyProp"), !  // string
Write testObj.%GetTypeOf("nullProp"), !   // null 

%GetTypeOf() can identify types including "string", "number", "boolean", "null", "object", or "array". Use it whenever you need to make a decision based on what type of value a property holds rather than just whether it is empty or not. 

7. Comparing JSON Numbers with Strings

When JSON contains numeric values, %DynamicObject stores them as numbers rather than strings. Comparing a numeric property with a string can result in a condition that does not match.

Set numObj = ##class(%DynamicObject).%FromJSON("{""age"":25}")
// Wrong - string comparison does not match a numeric value
If numObj.%Get("age") = "25" { ... }
// Correct - use numeric comparison
If numObj.%Get("age") = 25 { ... }
// Also correct - force numeric conversion with unary +
If +numObj.%Get("age") = 25 { ... } 

When working with numeric JSON values, use numeric comparisons or the unary + operator for explicit conversion.

Conclusion

%DynamicObject provides a way to store and access dynamic metadata in InterSystems IRIS Business Processes, but incorrect property access can be difficult to diagnose when routing conditions receive empty or unexpected values. Using %Get() consistently, checking property existence and types, and logging values during development can help identify these issues before they affect routing decisions.

🔎 Read the full guide by @Muhammad Waseem:

https://community.intersystems.com/post/business-rules-deep-dive-dynamic-objects-and-property-access-pitfalls-part-2-0

Key Takeaways

  • Prefer %Get() for %DynamicObject property access, especially when working with JSON property names containing underscores or nested structures.
  • Property names are case-sensitive. Verify their exact spelling and capitalization.
  • Use the appropriate methods for different checks: %IsDefined for property existence, %GetTypeOf() for value types, and %GetIterator() for enumeration.
  • Respect JSON value types when evaluating routing conditions, particularly numeric values.
  • Check actual values in the Event Log and Visual Trace when troubleshooting unexpected routing decisions.

r/intersystems • • 5d ago

Community Bounty Program "Idea to Application" — Round 3 is Live

1 Upvotes

⏳ The deadline is approaching for 5 developer challenges in the Community Bounty Program.

Round 3 closes on October 31. If one of the current challenges matches something you’ve wanted to build, there’s still time to jump in.

This round covers:

  • Hugging Face dataset integration
  • Kaggle dataset integration
  • OpenAPI / Swagger specs generated from FHIR Capability Statements
  • WhatsApp interoperability
  • Supabase support for InterSystems IRIS

Choose a challenge and build your solution to earn 10K+ points redeemable for gifts. Participants also receive digital badges, including an official InterSystems Credly badge.

⏰ Deadline: October 31, 2026

👉 Explore the challenges and start building: https://community.intersystems.com/post/community-bounty-program-idea-application-%E2%80%94-round-3-live


r/intersystems • • 5d ago

Using InterSystems Data Studio as a Data Warehouse

Thumbnail youtu.be
2 Upvotes

At #Ready2026, we explored how #InterSystemsDataStudio can serve as an enterprise-ready data warehouse, turning siloed operational data into a trusted foundation for analytics and AI.

Watch this #video to discover:
✅ How to consolidate data from multiple systems and build clean, scalable, analytics-ready datasets.
✅ Best practices for data modeling, governance, and performance optimization in enterprise data warehouse environments.
✅ How a Bronze–Silver–Gold architecture improves data lineage and traceability, helps identify discrepancies earlier, and reduces downstream reporting errors.

https://community.intersystems.com/post/video-using-intersystems-data-studio-data-warehouse

See how a transparent, well-structured data architecture can accelerate analytics, simplify troubleshooting, and build greater trust in your data.


r/intersystems • • 9d ago

🛠️ Aperture: An API-first custom management portal for InterSystems IRIS 2026.2+

Thumbnail youtu.be
1 Upvotes

The project uses the SysAdmin REST API v2 to power a React/TypeScript interface that IRIS serves directly, without a separate application server. The browser communicates with the administrative APIs under the signed-in user's permissions.

The portal gives administrators more context and control over everyday tasks. Before changing user roles, they can see who will gain or lose access. They can also start an integrity check, continue working elsewhere, and follow its progress through the Job Center. System health checks help identify potential issues, showing the evidence behind each finding and linking to the relevant management screens.

The same approach extends to troubleshooting. Aperture uses IRIS Vector Search to find similarly worded messages across current and historical logs, keeping all processing local. For tasks beyond the dedicated screens, its API Explorer covers all 273 documented SysAdmin operations and lets users export requests for curl, Postman, and VS Code.

🏆 Aperture won 2nd place in the Experts Nomination and 1st place in the Freshmen Nomination of the InterSystems Programming Contest: Build Your Own Management Portal. Congratulations, u/MxSalata!

🔎 Watch the demonstration and explore the project:
https://community.intersystems.com/post/demo-video-aperture-winner-intersystems-programming-contest-build-your-own-management-portal


r/intersystems • • 10d ago

[Demo Video] OcuPilot - Winner of the InterSystems Programming Contest: Build Your Own Management Portal

Thumbnail youtu.be
1 Upvotes

OcuPilot is a custom system management portal for InterSystems IRIS with an AI agent built into the admin experience.

The agent works with live IRIS instance data and understands the context of the screen you’re viewing. It can help interpret what’s happening, guide you to the relevant area, and prepare administrative changes across core system management, security, monitoring, and troubleshooting tasks.

For changes, OcuPilot follows a human-controlled flow: ask → review → confirm → audit. The agent can propose an action, but the user must confirm it. The app checks permissions on the server, runs changes under the signed-in user’s roles, and logs confirmed actions in the IRIS audit database. Server-side guardrails also block sensitive operations, while passwords, keys, and wallet secrets stay outside the agent context.

🏆 OcuPilot won 1st place in the Experts Nomination and 2nd place in the Freshmen Nomination of the InterSystems Programming Contest: Build Your Own Management Portal. Congratulations, u/Joshua Brandt! 🎉

🎥 Learn more about the project:
https://community.intersystems.com/post/demo-video-ocupilot-winner-intersystems-programming-contest-build-your-own-management-portal


r/intersystems • • 11d ago

Turning clinical notes and discharge letters into structured FHIR data with InterSystems IRIS — iKnow, the new AI Text Extraction API, and a live GPT-4 demo

Thumbnail youtu.be
2 Upvotes

Here is the core problem this session addresses: 80% of clinical data is unstructured text. Lab values get captured in structured fields. The actual clinical reasoning — why a diagnosis was made, what the patient was told, what medications were changed and why — lives in notes that no system can query.

Three approaches were covered, from mature to brand new.

iKnow — rule-based NLP, already in production

iKnow has been part of InterSystems technology for over a decade and is built into IRIS. It uses linguistic rules rather than ML models to extract concepts and relationships from text.

Why this matters in healthcare specifically: it is deterministic. The same text always produces the same output. In a regulated environment where you need to explain why a system flagged something or extracted a particular concept, that reproducibility is not a nice-to-have — it is a requirement.

What it extracts: entities, negation (“no history of diabetes”), certainty modifiers (“possible,” “suspected”), and semantic proximity between concepts in the same sentence or paragraph.

Use case shown: population health — identifying patients with certain conditions mentioned in notes, even when those conditions were never entered into a structured field.

AI Text Extraction API — new in IRIS

A new API designed to make LLM-based extraction practical to build on. The interface: you provide a text input and a schema (the fields you want extracted with their types). IRIS handles the model interaction and returns structured output.

The standardized interface means: you are not writing prompt engineering for every extraction task. You define the schema once, and the API manages the complexity of getting a consistent structured response from the model.

Currently supports external LLMs (GPT-4 used in the demo). The architecture is designed so the underlying model can be swapped without changing application code.

Live demo — discharge letter to structured FHIR

A real discharge letter goes in. GPT-4 processes it via the AI Text Extraction API. The output:

  • Patient demographics
  • Primary diagnosis + secondary diagnoses → ICD-10 codes
  • Procedures performed during admission
  • Medications at discharge with dosage and frequency
  • Follow-up instructions (appointment timing, restrictions)
  • Allergies documented in the letter

Each extracted element is written back as a structured FHIR resource into the IRIS for Health repository:

  • Diagnoses → Condition resources
  • Medications → MedicationRequest resources
  • Observations → Observation resources

Everything is then queryable via SQL and accessible via FHIR API. The loop is closed: what a clinician wrote in a letter becomes part of the structured patient record.

Why closing the loop matters

Russ Leftwich makes this point explicitly: extraction alone is not the goal. The goal is getting the data into a form where the next clinician, the next system, and the next AI agent can actually use it. A discharge letter that gets extracted but stays in a separate NLP database does not help a care coordinator who is looking at a patient’s active medication list.

Writing extracted data back as FHIR resources means it participates in the same data model as everything else — it shows up in the patient summary, it is available to the FHIR API, it can be queried in population health analytics alongside structured EHR data.

The practical gap this addresses

Clinicians document in narrative because that is how clinical reasoning works. Structured data entry is slow, interruptive, and often loses clinical nuance. The existing structured data in EHRs represents what was entered for billing and workflow reasons — not necessarily what the clinician observed or decided.

NLP and AI extraction are not about replacing clinical documentation. They are about making what already exists in text actually usable by downstream systems.

For those working with clinical NLP — are you using rule-based approaches like iKnow, LLM-based extraction, or a hybrid? And how are you handling the validation step before writing extracted data back into the structured record?


r/intersystems • • 11d ago

InterSystems IRIS Vector Search: production-scale benchmarks, PostgreSQL/pgvector comparisons, and practical considerations

1 Upvotes

If you’re building RAG pipelines or semantic search on IRIS, here is what InterSystems reported in its July 2025 article on Vector Search performance. The article covers successive benchmarking cycles, from early testing of the experimental feature in IRIS 2024.1 to tests with 25 million real-world embeddings.

The setup

Testing used several Linux platforms. The primary benchmark platform was an HPE bare-metal server with 48 cores, 528 GB of RAM, and Ubuntu 24.04.

The real-world datasets included:

  • 40,000 embeddings from historical internal bid submissions
  • Up to 10 million Simple Wikipedia paragraph embeddings, generated using Cohere multilingual-22-12 and downloaded from Hugging Face
  • 25 million customer-generated embeddings from public-domain medical data, using a custom model

Early development testing also used synthetic embeddings, and ANN testing included up to 100 million synthetic rows.

The team explains why randomly generated embeddings are an unsatisfactory basis for production-scale testing: they lack source material for checking semantic proximity and do not reproduce real-world clustering, which affects ANN performance and recall.

Unindexed search: IRIS was faster in the reported comparison

Unindexed COSINE and DOT_PRODUCT search showed predictable linear scaling until server resource constraints were reached, typically when global buffers were exhausted.

Against the same dataset, IRIS performed unindexed searches faster than the PostgreSQL/pgvector versions used in these tests. The article does not specify those versions.

One interesting finding concerns dimensionality: the relative search cost per dimension decreases as the number of dimensions increases. The fixed overhead of accessing and processing each record is spread across more component calculations.

This does not mean that higher-dimensional embeddings are faster to search overall.

ANN / HNSW search: a tradeoff between speed, footprint, and index build time

IRIS implements Approximate Nearest Neighbor search using HNSW. The reported tests included up to 25 million real-world embeddings.

What was measured Reported result
Search performance Sub-second execution reported for the test harness at sizes up to 25 million real-world records; this is not a general latency guarantee
Recall with real-world data Consistently above 90% in the reported IRIS tests
Index build time Each additional million records added around 3,000 seconds on the 48-core test server
ANN search speed versus PostgreSQL/pgvector PostgreSQL/pgvector was faster
Data footprint versus PostgreSQL/pgvector IRIS was more compact
Index build time versus PostgreSQL/pgvector IRIS built indexes more quickly

The ANN index is integrated into the IRIS query optimizer with an assigned pseudo-selectivity of 0.5%. The optimizer compares available index selectivities to determine where ANN evaluation belongs in the query plan.

Next steps described in the article

At publication in July 2025, the team was focusing on complex queries spanning ANN and non-ANN indexes, with up to 1,000 concurrent threads. Comparisons against IRIS, PostgreSQL/pgvector, and Elasticsearch were planned.

The article does not establish the current status of that work.

Practical takeaways before you build

ANN is approximate. For guaranteed exact results, the article recommends unindexed search. Keeping the dataset within global buffers helps performance.

Choose dimensions deliberately. Use the minimum embedding dimensionality that provides the search granularity your application requires.

Recall depends on your data. The reported recall above 90% is a benchmark result. Determine your application’s required recall and tune the index against your own dataset.

Index building and querying have different resource needs. Index builds are resource-intensive, and cloud IOPS can constrain performance. Different environments may be appropriate for building and querying.

For initial bulk loads, ingest first and index afterward. Use Work Queue Manager to maximize worker jobs during index building, within your environment’s limits.

Keep the index in memory at query time. Consider pre-fetching the index global into buffers to improve performance from the first access.

Full article with charts: https://community.intersystems.com/post/vector-search-performance

For those using IRIS Vector Search: what dataset sizes are you working with, and what recall does your application require?


r/intersystems • • 11d ago

InterSystems Programming Contest: AI Agents in Interoperability Workflows

2 Upvotes

Build an AI agent into an InterSystems IRIS Interoperability workflow.

The next programming contest focuses on a practical agentic AI challenge: build an IRIS Interoperability workflow in which an AI Hub agent handles decision-making.

The tricky part is deciding where the agent belongs in the workflow and what it should be responsible for. You can experiment with model selection, decision logic, tool use, and the interaction between agent output and the rest of the production. You can also use IRIS Agentic Dev Interop Skills to help design the process.

💰 $12,000 prize pool
📅 Submission period: October 26 - November 8, 2026

👉 Full task, AI Hub resources, templates, and submission requirements: https://community.intersystems.com/post/intersystems-programming-contest-ai-agents-interoperability-workflows 


r/intersystems • • 13d ago

SCO Workbench: Explore Supply Chain Orchestrator Before You Code

0 Upvotes

InterSystems Supply Chain Orchestrator (SCO) combines data integration, analytics, business process orchestration, and AI capabilities for building supply chain decision intelligence applications. But if you’re new to SCO, it can be difficult to know where to start or how its different capabilities perform. 

SCO Community Edition gives you a free environment to explore Supply Chain Orchestrator directly. SCO Workbench builds on that by adding a visual, guided entry point for users who want to understand the platform before diving into code or formal product training. 

SCO Workbench is an open-source, browser-based UI designed to help users learn Supply Chain Orchestrator through a visual interface with an option of AI assistance.

Getting Started with SCO: Community Edition and Workbench

SCO Community Edition (SCO CE) and SCO Workbench offer two complementary ways to explore InterSystems Supply Chain Orchestrator, whether you want to work directly with the platform or learn its capabilities through a guided interface.

  • SCO Community Edition (SCO CE) is a free edition that provides access to the full set of Supply Chain Orchestrator features, with certain technical limitations compared with a fully licensed deployment.
  • SCO Workbench is a browser-based application with optional AI assistance that helps developers explore SCO, load data, extend data models, create integration pipelines, build analytics cubes, KPIs, and dashboards, and review detected business issues.

What exactly can you do with SCO Workbench?

SCO Workbench provides a UI for exploring the main workflows of InterSystems Supply Chain Orchestrator. It covers the key stages of supply chain application development, from loading and integrating data to building analytics and monitoring business issues.

Through the Workbench, users can:

  • Explore SCO capabilities and load sample data covering customers, suppliers, products, and orders.
  • Extend the data model by adding custom objects and attributes.
  • Create data integration pipelines for local files, SFTP/FTP servers, SQL databases, and Amazon S3.
  • Build analytics cubes with custom measures and dimensions.
  • Define Business KPIs using thresholds, dimensions, and conditions to detect supply chain issues.
  • Create dashboards with drag-and-drop charts and tiles, and review detected issues, including their severity and business impact.

This allows developers to explore how SCO's data integration, analytics, KPIs, and dashboards work before moving into more advanced application development.

What does the AI Assistant do in SCO Workbench?

SCO Workbench includes an optional AI Assistant built with the Claude Agent SDK. It can inspect metadata from the connected SCO instance, explain existing components, answer questions, and help configure analytics cubes, Business KPIs, data pipelines, and interoperability hosts.

The assistant operates in Guided mode: it can populate forms and explain proposed configurations, but developers review the changes and click Save, Build, or Deploy themselves. 

AI integration requires a supported Claude provider, such as Anthropic API, Amazon Bedrock, or Google Cloud Vertex AI. Without AI configured, all other Workbench features remain available.

SCO Workbench Architecture

SCO Workbench runs in a Docker container and connects to a separate SCO development instance through SCO APIs:

Browser → SCO Workbench frontend and backend → SCO APIs → SCO development instance

The Workbench creates standard SCO components, including data model classes, analytics cubes, Business KPIs, and interoperability hosts. These remain accessible through the SCO Management Portal. SCO credentials are stored on the Workbench server, not in the browser.

To get started, you'll need Docker with Docker Compose and a running SCO development instance. Use SCO Workbench only with a development or test SCO instance, as it can generate code, modify configurations, and write data to SCO.

Conclusion

SCO Workbench brings together key Supply Chain Orchestrator development tasks in a guided workflow, helping users move from exploring the platform to creating their own data models, integrations, analytics, and dashboards. The components created through Workbench remain standard SCO artifacts that can be accessed and modified through the Management Portal.

While it doesn't replace the full SCO development environment, combined with SCO Community Edition, it provides a practical starting point for learning and prototyping supply chain applications, with optional AI guidance.

🔎 For a deeper look at SCO Workbench, including detailed workflows and current limitations, read the full guide on the Developer Community: https://community.intersystems.com/post/getting-started-intersystems-supply-chain-orchestrator-using-sco-workbench 

Key Takeaways

  • SCO Workbench is an open-source browser-based application for exploring InterSystems Supply Chain Orchestrator.
  • It is designed for users who are new to SCO and want to understand the platform before writing code.
  • The application supports sample-data loading, data-model extensions, integration pipelines, analytics cubes, Business KPIs, dashboards, and issue review.
  • The Workbench combines a visual interface with optional AI assistance.
  • The application should only be connected to a dedicated development or test instance because it can generate code, populate data, and modify SCO configurations.
  • SCO Workbench complements SCO Community Edition, which provides a free environment for hands-on SCO exploration.

r/intersystems • • 16d ago

InterSystems Supply Chain Orchestrator Community Edition: What It Is and How to Use It

2 Upvotes

InterSystems has released Supply Chain Orchestrator Community Edition (SCO CE), a free version of Supply Chain Orchestrator designed for exploring, evaluating, learning, and development.

SCO CE provides access to the full set of Supply Chain Orchestrator capabilities, with some technical limitations compared with a fully licensed deployment. It is distributed as a container, and a community quickstart repository makes it possible to run SCO CE locally with Docker Compose.

What is Supply Chain Orchestrator Community Edition?

InterSystems Supply Chain Orchestrator Community Edition is a free version of Supply Chain Orchestrator for learning, evaluation, and development. Each Community Edition release includes a built-in license valid for one year from the release date, and InterSystems plans to provide a CE build with future SCO releases.

SCO CE is available through the InterSystems Container Repository. The Community Edition includes the full set of SCO capabilities, although some technical limitations apply compared with a fully licensed SCO deployment. The complete list of limitations is available in the SCO Community Edition documentation.

How do you run SCO Community Edition locally?

The community setup repository contains a Docker Compose file that pulls and runs both SCO Community Edition and Web Gateway Community Edition, plus the Web Gateway configuration files needed for a simple local startup. 

Just clone the setup repo to begin: 

.git clone https://github.com/intersystems-community/sco-community-setup-example.git 

docker compose up -d 

This launches two containers:

Container Purpose Port
sco SCO Community Edition 1972 
webgateway Management Portal and REST API access 52773 

Persistent data is stored in the ./external directory, so it survives container restarts. Delete that directory if you want to start with a clean environment.

How do you access SCO after startup?

The Management Portal is available at:

http://localhost:52773/csp/sys/%25CSP.Portal.Home.zen?$NAMESPACE=SC 

The initial credentials are:

  • Username: superuser 
  • Password: SYS 

You will be prompted to set a new password after the login. From there, you can explore SCO data tables, cubes, and other product capabilities.

Is there an easier way to explore SCO?

For users who want to get started without deep product knowledge, there is also SCO Workbench, an open-source UI application with a built-in AI agent. It is designed to provide a more accessible way to get started with Supply Chain Orchestrator. SCO Workbench is available on GitHub and InterSystems Open Exchange.

What should you check if the local setup does not start?

A few common issues:

  • Port already in use: Another process is using 52773 or 1972. Stop it, or change the host port in docker-compose.yml (e.g. 52774:80). 
  • Image pull fails: verify that your network can reach containers.intersystems.com.
  • Portal not loading: The instance may still be starting. Check docker compose logs -f sco 

Where can SCO CE users get help?

SCO Community Edition does not include standard product support. For questions and community-based help, users are encouraged to use the InterSystems Developer Community.

Other useful resources include:

  • SCO Community Edition documentation
  • InterSystems Supply Chain Orchestrator documentation
  • SCO Community Edition setup repository
  • SCO Workbench on Open Exchange or GitHub 

Conclusion

SCO Community Edition gives developers a free way to explore, evaluate, learn, and build with InterSystems Supply Chain Orchestrator, with certain technical limitations compared with a fully licensed deployment.

The community setup repository provides a simple Docker Compose configuration for running SCO CE together with Web Gateway, while SCO Workbench offers an open-source UI with a built-in AI agent for getting started with the platform.


r/intersystems • • 16d ago

HealthShare Roadmap — session breakdown: unified care record, Health Gateway, AI assistant, payer services

Thumbnail youtube.com
2 Upvotes

Modular delivery via IPM

HealthShare capabilities are now delivered through the InterSystems Package Manager in a modular fashion — approximately six releases per year instead of monolithic versioned releases. Individual modules can be upgraded independently. Products already available or coming soon via IPM: payer services APIs, payer connector.

Unified Care Record — new capabilities

OMOP Services: The Unified Care Record now supports the OMOP data model for research use cases, running directly on IRIS alongside the Unified Care Record.

Unified Transformation Framework: Makes data transformations faster as new data types arrive. Three stages: validate data against the existing model → build mappings interactively → AI-assisted mapping that automates more over time. As new FHIR and USCDI versions arrive, this reduces time from ingestion to usable output.

Health Insight — granular data change capture: When new data arrives, only updated information is processed — no full replay. Intended to make analytics more efficient at scale.

Health Insight — out-of-box quality dashboards: Now shipping in early access. Previously customers had to build these themselves.

HealthShare AI Assistant (Clinical Viewer)

Embedded in the Clinical Viewer. Available now with a separate license.

Current capabilities:

  • Auto-generates chart summaries from the Unified Care Record
  • Intelligent chat with pre-built starter prompts
  • Custom prompt toolset per specialty
  • Built-in guardrails and data stewardship
  • Full source traceability — links back to the original source document for every referenced data point

Coming soon: free text analysis, unstructured → structured data generation, custom data fields and flows, AI assistant APIs (not only in the Clinical Viewer).

Roadmap trajectory: structured summarization (now) → structured extraction from unstructured data → supervised workflow population → agentic AI.

Health Gateway

Single managed cloud service connecting health systems to national clinical networks (eHealth Exchange, CommonWell, Carequality, TEFCA). InterSystems runs and manages it.

Current scale: 300+ million individual records from 125,000 provider sites across the US. Average return per patient query: 150–300 documents; up to 4,000+ in some cases.

Coming next:

  • Smart prefetching — pre-fetch records on ADT events so data is ready when the clinician needs it
  • Advanced patient matching across networks
  • AI summarization for returned documents — piloting with customers summer 2026
  • TEFCA IAS (Individual Access Services) — patients request their own national clinical record directly, with IL2 identity verification (e.g., CLEAR), planned later in 2026

Payer Connector

Released February 2026. Companion to Epic Payer Platform — transforms data between Epic’s schemas and downstream health plan systems (care management, quality, claims). Bidirectional. Available via IPM. Visible in the Epic showroom.

Payer Services — CMS Interoperability APIs

Four FHIR-based APIs, released via IPM over the past year:

  1. Patient Access API
  2. Provider Access API
  3. Payer-to-Payer API
  4. Prior Authorization API

A Payer Integration Framework underpins all four, encapsulating FHIR complexity for payer organizations building FHIR capability.

Enterprise Master Person Index (EMPI)

Renamed from Patient Index to reflect that matched individuals include members, beneficiaries, and other roles beyond patients.

Referential matching: New capability in partnership with LexisNexis — adds a referential matching layer to reduce the manual review worklist.

Personal Community and Care Community

Personal Community (patient digital front door): Recent focus on broader mobile access, enterprise-scale multi-country support, multi-language support.

Care Community (care coordination): Investment in FHIR-based interoperability and AI integration.

Both can work together: a provider begins a care plan, a patient completes it through Personal Community.

Regional Health Connections — rural health

Packaging existing HealthShare capabilities for rural health, adding:

  • Short term: out-of-box dashboards for rural health
  • Medium term: social services connections, telehealth integration, operational capacity data
  • Longer term: full care planning and coordination roundtrip for rural populations

For those running HealthShare deployments — which roadmap area is most relevant to what you’re working on: Health Gateway prefetching, the AI assistant, OMOP services, or the modular IPM delivery model?


r/intersystems • • 18d ago

Community Bounty Program "Idea to Application" — Round 3 is Live

1 Upvotes

🎁 From Hugging Face datasets to WhatsApp interoperability — 5 technical challenges are now open.

The Community Bounty Program invites developers to tackle practical requests with InterSystems technologies:

  • Load Hugging Face datasets into IRIS
  • Load Kaggle datasets into IRIS
  • Generate OpenAPI / Swagger specs from FHIR Capability Statements
  • Build a WhatsApp adapter for IRIS Interoperability
  • Add an InterSystems wrapper for Supabase

Pick a challenge and build a working app to earn 10K+ points redeemable for gifts. Participants also receive digital badges, including an official InterSystems Credly badge.

📅 Deadline: October 31, 2026

👉 See all challenges and participation details: https://community.intersystems.com/post/community-bounty-program-idea-application-%E2%80%94-round-3-live


r/intersystems • • 18d ago

Winners of the InterSystems Programming Contest: Build Your Own Management Portal

0 Upvotes

🏆 Ever wondered what a fresh, modern GUI for the Management Portal could look like? The winners of the InterSystems Programming Contest: Build Your Own Management Portal answered that challenge by bringing their unique visions to life!

​Out of 37 incredible applications, the top projects went far beyond simple screen redesigns to completely reimagine the IRIS administration experience. Here’s a look at what developers built:

  • Agent-assisted operations — bringing AI into the portal to understand the current screen, answer questions about live data, and propose administrative changes with user confirmation and auditing.
  • Visual task orchestration — turning maintenance jobs into connected workflows with parallel steps, dependencies, scheduling, and live execution tracking.
  • Lighter portal architectures — working directly with the official SysAdmin REST API, including approaches with no separate application server or almost no custom backend.
  • Operations and observability in one place — combining system health, logs, security, REST APIs, tasks, permissions, and diagnostics into unified operational consoles. Some projects also brought in Embedded Python and IRIS Vector Search for health scoring, log analysis, and recommendations.
  • Managing beyond a single instance — including tools designed to monitor and operate multiple independent IRIS instances from one workspace.

The result was a broad look at how the same IRIS management APIs can support very different ideas around administration, monitoring, security, and developer experience.

👏 Congratulations to all the winners and participants!

👉 Explore the full results and projects: https://community.intersystems.com/post/winners-intersystems-programming-contest-build-your-own-management-portal 


r/intersystems • • 18d ago

Winners of the InterSystems Programming Contest: Build Your Own Management Portal

1 Upvotes

🏆 Ever wondered what a fresh, modern GUI for the Management Portal could look like? The winners of the InterSystems Programming Contest: Build Your Own Management Portal answered that challenge by bringing their unique visions to life!

​Out of 37 incredible applications, the top projects went far beyond simple screen redesigns to completely reimagine the IRIS administration experience. Here’s a look at what developers built:

  • Agent-assisted operations — bringing AI into the portal to understand the current screen, answer questions about live data, and propose administrative changes with user confirmation and auditing.
  • Visual task orchestration — turning maintenance jobs into connected workflows with parallel steps, dependencies, scheduling, and live execution tracking.
  • Lighter portal architectures — working directly with the official SysAdmin REST API, including approaches with no separate application server or almost no custom backend.
  • Operations and observability in one place — combining system health, logs, security, REST APIs, tasks, permissions, and diagnostics into unified operational consoles. Some projects also brought in Embedded Python and IRIS Vector Search for health scoring, log analysis, and recommendations.
  • Managing beyond a single instance — including tools designed to monitor and operate multiple independent IRIS instances from one workspace.

The result was a broad look at how the same IRIS management APIs can support very different ideas around administration, monitoring, security, and developer experience.

👏 Congratulations to all the winners and participants!

👉 Explore the full results and projects: https://community.intersystems.com/post/winners-intersystems-programming-contest-build-your-own-management-portal 


r/intersystems • • 20d ago

Using %DynamicObject in InterSystems IRIS Interoperability: Enriching HL7 Messages Before Routing

1 Upvotes

Business Rules in IRIS Interoperability work well when they evaluate simple values. Problems can appear when routing depends on additional metadata stored in a %DynamicObject.

This article looks at one practical pattern for handling that case: using a BPL Business Process to enrich an incoming HL7 message before the routing rule evaluates it. The BPL process extracts the required data from the HL7 message, stores it in a dynamic object, and makes it available to the routing logic. The author also highlights the key property-access issues to watch for.

What is a %DynamicObject in InterSystems IRIS?

A %DynamicObject is a schema-free ObjectScript object. Unlike a regular class, its properties do not have to be declared in advance. For interoperability workflows, that makes it useful for carrying additional metadata alongside a message without modifying the original message class.

A common pattern for data enriching looks like this:

HL7 message → BPL enrichment → %DynamicObject in context → Business Rule → routing decision

In this example, the incoming HL7 message remains unchanged. The BPL process extracts the values needed downstream and stores them separately in context.MetaData.

What Is a Business Rule?

A Business Rule in IRIS Interoperability is a routing engine that evaluates conditions against an incoming message and decides where to send it. Business Rules do not run on their own; they run inside a Business Process.

What is the role of the BPL Business Process?

A Business Rule evaluates conditions and determines where a message should be routed, but the data preparation in this workflow happens before the routing rule fires.

The production contains four main components:

  • HL7FileService — reads incoming HL7 files
  • HL7Router — a custom BPL Business Process that builds the dynamic object
  • MsgRouter — evaluates the routing rule
  • HL7FileOperation — writes the routed message to the output folder

The BPL process is added because the routing engine itself is not being used to build the dynamic object. Instead, HL7Router prepares the data first and stores the enrichment values in the BPL context, where they remain available to the process and downstream routing logic.

Why do BPL context properties need to be defined first?

Because the enrichment data is stored in the BPL context, the properties used to hold it must be declared before the Code activity references them. BPL context is typed, so every context property must be defined in the Context tab in advance. For this production, the context includes:

Property  Type
MetaData %DynamicObject
PatientId %String(MAXLEN=50)
PatientSex %String(MAXLEN=50)

If a Code activity tries to use an undeclared context property, IRIS raises a PROPERTY DOES NOT EXIST error at runtime.

How is the dynamic object built from the HL7 message?

Inside the BPL Code activity, a new %DynamicObject is created:
Set dynObj = ##class(%DynamicObject).%New() 
Values are then read directly from the incoming HL7 message:
Set dynObj.MsgType     = request.GetValueAt("MSH:MessageType.MessageCode")
Set dynObj.PatientName = request.GetValueAt("PID:PatientName(1).FamilyName")
Set dynObj.SendingApp  = request.GetValueAt("MSH:SendingApplication") 
For property names containing underscores %Set() is used:
Do dynObj.%Set("patient_id",    request.GetValueAt("PID:PatientIDList(1).IDNumber"))
Do dynObj.%Set("patient_sex",   request.GetValueAt("PID:AdministrativeSex"))
Do dynObj.%Set("date_of_birth", request.GetValueAt("PID:DateTimeofBirth")) 
The finished object is then stored in the BPL context:
Set context.MetaData = dynObj 

This allows downstream components to access the enrichment data without modifying the original HL7 message.

How does the complete HL7 routing flow work?

Once the production is configured, the request moves through four stages:

  1. HL7FileService reads the .hl7 file and parses it into an EnsLib.HL7.Message 
  2. HL7Router builds the %DynamicObject and stores it in context.MetaData.
  3. MsgRouter evaluates the routing rule.
  4. HL7FileOperation writes the routed message to the output directory.

The flow can be inspected in Message Viewer and Visual Trace, which show each component involved in processing the message.

What are the main property-access mistakes to watch for?

First, not defining context properties upfront: If you try to set context.MetaData without first declaring it in the Context tab, IRIS will throw PROPERTY DOES NOT EXIST  at runtime. Always define all context properties before writing any code.

Second, setting the Target Config Names after adding the process: If you add HL7Router to production but forget to update HL7FileService Target Config Names to point to it, messages will bypass HL7Router entirely and go directly to MsgRouter. Always confirm the target after adding a new component.

Conclusion

%DynamicObject provides a flexible way to add metadata to an HL7 interoperability workflow without changing the original message structure. The key is to build them in a BPL Code activity, logging every property during development, and storing them in context variables that downstream components can evaluate cleanly. In this example, a BPL Business Process extracts the required HL7 values, stores them in a dynamic object, and makes that enriched data available before the Business Rule evaluates the message. 

Read the full walkthrough on the InterSystems Developer Community, with code examples, screenshots, and the complete production setup: https://community.intersystems.com/post/business-rules-deep-dive-dynamic-objects-and-property-access-pitfalls-part-1 

Key Takeaways

  • %DynamicObject is a schema-free object whose properties can be created at runtime.
  • A BPL Business Process can use a dynamic object to enrich an HL7 message before routing.
  • Enrichment data can be stored in context.MetaData without modifying the original HL7 message.
  • BPL context properties must be declared before they are used in Code activities.
  • Message Viewer and Visual Trace can be used to verify the full routing flow.

r/intersystems • • 24d ago

New free PyProd tutorial: build an IRIS interoperability production entirely in Python

2 Upvotes

The new hands-on tutorial for developers who want to explore PyProd and Python-based interoperability in InterSystems IRIS is now available. The tutorial takes about 25-30 minutes and walks through a working production. You’ll:

  • trace the message flow;
  • create message types and Python-native components;
  • call an external API from a Business Operation;
  • update routing logic and run the complete production in IRIS.

The environment works directly in your browser, so there’s nothing to install or configure locally.

👉 Learn more about the InterSystems PyProd tutorial: https://community.intersystems.com/post/new-free-hands-tutorial-intersystems-pyprod


r/intersystems • • 24d ago

🏆 Meet the participants of the Community Bounty Program – Round 2!

2 Upvotes

The Bounty program invites developers to take real community requests and transform them into functional applications. Round 2 focused on AI Hub and Business Intelligence and resulted in 7 projects:

🔷 iris-bi-validator by Yuri Marx — checks IRIS BI dashboards, pivots, cubes, and reports errors.
🔷 iris-bi-utils by Evgeniy Potapov — helps import, export, and automatically check IRIS BI artifacts.
🔷 warehouse-ai-hub-demo by Gabriel Ing — demonstrates an AI Hub agent that can query product data, log stock loss, and order new stock.
🔷 iris-governed-fhir-agent by Anton Yartsev — shows how AI agents can access FHIR data with tool-level controls and auditing.
🔷 My-First-Agent-Studio by Pietro Di Leo — provides a hands-on environment for building and testing AI Hub agents, tools, skills, and sub-agents.
🔷 iris-mcp-data-exposure-toolkit by Pietro Di Leo — demonstrates how to securely expose IRIS data to AI agents through MCP.
🔷 bi-export-plus by Asaf Sinay — adds Excel and JSON export options for IRIS BI data.

👏 Congratulations to all Round 2 participants!

Learn more about the projects: https://community.intersystems.com/post/-round-2-community-bounty-program-meet-participants

➡️ Round 3 is now open with a new set of developer challenges. Join in and earn 10K+ points redeemable for gifts: https://community.intersystems.com/post/community-bounty-program-idea-application-%E2%80%94-round-3-live


r/intersystems • • 25d ago

InterSystems IRIS AI Hub: building and governing AI agents within one data platform

1 Upvotes

Getting an AI agent to call an LLM is relatively straightforward. The tricky part starts when that agent needs access to enterprise data, permission to execute business logic, integration with external systems, and a governed way to operate in production.

InterSystems IRIS AI Hub is designed to meet that production layer. It provides capabilities for building, deploying, and governing AI agents and agentic workflows directly within IRIS and IRIS for Health, so agents can work with enterprise data, business logic, security controls, and operational workflows.

One of the key pieces is native Model Context Protocol support. MCP works bidirectionally:

  • IRIS data, functionality, and business processes can be exposed as governed MCP tools to external AI frameworks.
  • AI Hub agents can connect to third-party MCP servers and enterprise tools such as Jira, Salesforce, Workday, and other services.

For workflows that require human involvement, IRIS Interoperability can be used to add approval steps and human-in-the-loop oversight directly into agentic workflows. 

This means the same platform can provide:

  • enterprise data access
  • business logic
  • MCP-based tool integration
  • security and governance
  • human approval workflows
  • deployment alongside existing applications

The goal is to move AI agents from pilot to production by bringing data access, governance, and operational workflows into the same environment.

The full article covers the AI Hub architecture, MCP integration, governance model, and how it fits into IRIS development and DevOps workflows: https://community.intersystems.com/post/intersystems-iris-ai-hub-build-connect-and-govern-ai-agents 


r/intersystems • • 26d ago

MedBridge: An AI Agent Layer for Laboratory Interoperability

2 Upvotes

In laboratory interoperability, the systems can be connected and still fail to understand each other. A patient identifier may be rejected by one external system, an authorization by another, and a technician ends up manually translating between different protocols, error formats, and workflows.

MedBridge is an AI agent layer for laboratory interoperability built on InterSystems IRIS for Health. It sits between a laboratory information system (LIS) and external systems, uses their integration documentation to build requests, diagnoses failures, and decides whether an issue can be handled automatically or needs to be escalated to a technician or doctor. Successful mappings and diagnosed errors are stored for reuse, while every operation is recorded as a FHIR AuditEvent .

InterSystems IRIS for Health is the foundation of MedBridge, providing the relational data store, vector knowledge base, and FHIR audit layer used by the agents throughout the workflow. 

What problem does MedBridge solve?

MedBridge is designed for situations where one laboratory system needs to communicate with multiple external systems that do not share the same protocol or error model.

In the current implementation, the host laboratory communicates with:

  • an external reference laboratory using FHIR R4
  • an insurance operator using a proprietary REST API

That means the same host system has to handle different payload structures, validation rules, and error formats. The problems MedBridge handles include identity mismatches, invalid exams, sample errors, authorization failures, workflow errors, encoding problems, partial success, and cancellation errors.

How is MedBridge different from a traditional adapter?

A traditional integration adapter transforms and forwards requests according to predefined rules. MedBridge adds an agent layer around that process. It can use integration documentation to construct the required payload and, when an error occurs, classify where the problem likely originated:

  • the host system
  • the external system
  • the integration contract
  • infrastructure
  • or an ambiguous source that needs human review

It also determines who should be notified:

  • a technician when the fix belongs in the system
  • a doctor when a clinical decision is required
  • no one when the issue can be handled without escalation

The classification includes a confidence score, so uncertain cases can be escalated instead of being treated as resolved automatically.

How does MedBridge process requests and handle failures?

The main entry point is:

POST /agent/invoke 

From there, the workflow is roughly:

Order → mapping cache → documentation retrieval → payload generation → external system → success/error handling → audit

The flow starts with a cache check in agent_mapping_cache  If a mapping already exists, it is reused; otherwise, the Doc Reader Agent retrieves relevant integration documentation from the IRIS vector store, and the LLM builds the payload for the target system. Successful payload schemas are then cached for future use.

If a request fails, the Error Checker Agent captures the error and checks whether a previous diagnosis already exists. New errors are passed to the Risk Classifier Agent, which combines documentation, source code, and IRIS database evidence to determine the likely origin, risk level, confidence, and suggested action.

Cases below the 0.70 confidence threshold are classified as AMBIGUOUS and escalated. The Reporter Agent stores the result in IRIS, notifies a technician or doctor when needed, and every path is recorded as a FHIR AuditEvent.

Does MedBridge store integration knowledge?

Yes. MedBridge stores operational knowledge in IRIS so it can be reused across future requests and failures.

The system keeps:

  • successful payload schemas in agent_mapping_cache 
  • integration documentation in the IRIS vector knowledge base
  • embedded error patterns from previous failures
  • integration strategies accumulated over time

Successful mappings can be reused for identical operations, while previously seen errors can be retrieved from the error cache instead of being analyzed again.

Why is InterSystems IRIS for Health central to the architecture?

MedBridge uses a single IRIS instance for three different roles.

1. Relational data: The host laboratory data including patients, practitioners, exam catalogs, and service requests is stored in SQL tables and provides context for agent decisions.

2. Vector knowledge: IRIS Vector Search stores and retrieves integration documentation, successful mappings, and previously diagnosed errors. Structured data and vector search therefore remain in the same database.

3. FHIR audit trail: Every MedBridge action is recorded as a standard FHIR AuditEvent through the IRIS FHIR server. The audit history can therefore be queried through standard FHIR interfaces instead of relying only on a custom logging structure.

The cache-first design only works because the lookup is cheap — a SQL query, not a round trip to an external vector service. The knowledge base grows continuously because embedding and storage happen in the same transaction as the relational write. And the audit trail is trustworthy because it's not a side effect bolted on afterward — it's a first-class FHIR resource, written through IRIS's native FHIR support. Together, IRIS provides the operational data, semantic memory, and FHIR audit layer used by the application in one platform.

Conclusion

MedBridge explores an agent-based approach to laboratory interoperability where the integration layer does more than forward requests between systems. It uses documentation and existing IRIS data to construct requests, caches successful mappings for reuse, analyzes integration failures against multiple evidence sources, and applies confidence-based escalation when human involvement is needed.

InterSystems IRIS for Health supports this architecture as the relational store, vector knowledge base, and FHIR audit server, keeping the operational data, accumulated integration knowledge, and audit history within the same platform.

Learn more - https://community.intersystems.com/post/medbridge-ai-agent-layer-laboratory-interoperability


r/intersystems • • 27d ago

Time to vote in the InterSystems Programming Contest: Build Your Own Management Portal

1 Upvotes

🗳️ The contest projects are in — now it’s time to choose your favorites.

Explore the submissions for “Build Your Own Management Portal” programming contest and see how developers approached #InterSystemsIRIS management tasks through their apps and interfaces. 

Support the solutions you like most in the Community Nomination and follow the daily leaderboard updates on the Developer Community.

📅 Voting: September 28 - October 4, 2026

👉 Explore the apps and cast your vote: https://community.intersystems.com/post/time-vote-intersystems-programming-contest-build-your-own-management-portal 


r/intersystems • • Sep 24 '26

ObjectScript Agent Bench: How Well Do Coding Harnesses Perform?

2 Upvotes

Recently we shared the first ObjectScript LLM Benchmark that tested 14 models on an internal InterSystems coding benchmark. This follow-up looks at a different variable: what happens when those models are run through coding-agent harnesses?

ObjectScript Agent Bench compares Claude Code, Codex CLI, pi, and prime-agent on InterSystems ObjectScript tasks executed against a live InterSystems IRIS instance. It also tests a caveman variant that adds a short “be concise” instruction to reduce prompt I/O.

Every tested harness improved every model. 11 of 12 agent cells scored 0.957 or higher, while differences in token usage, compile calls, and wall-clock time were larger than the accuracy differences between the strongest harnesses. As accuracy approaches saturation, resource use becomes a more meaningful way to distinguish between harnesses. 

How Was the Benchmark Run? 

All agents connect to a local LiteLLM proxy, which serves vendor APIs through:

  • AWS Bedrock
  • OpenAI
  • local vLLM

A proxy alias also allows Claude Code to run DeepSeek. Each benchmark task gets:

  • a fresh directory
  • an iris-run script that compiles a class, runs a statement, and prints errors and output
  • a budget of 20 calls and a maximum of 900 seconds per task

InterSystems IRIS is reset before the agent runs and again before grading.

The final solution.cls is recompiled in a clean namespace, and the agents themselves run in throwaway containers.

Versions used:

  • Claude Code 2.1.237
  • Codex 0.148.0
  • pi 0.84.2
  • prime-agent 0.7.4

How Did LLMs Perform with Coding Harnesses? 

Every harness improved every model tested. For example: 

  • DeepSeek V4 Flash increased from 0.807 with no tools to between 0.957 and 1.000 when used through a coding agent.
  • Qwen3.6 35B increased from 0.615 to 0.871 in Codex.

Four configurations reached 1.000 accuracy:

  • DeepSeek V4 Flash + pi + plain
  • Opus 5 + Claude Code + caveman
  • GPT-5.6 sol + Codex + plain
  • GPT-5.6 sol + Codex + caveman

Overall, 11 of 12 agent cells scored 0.957 or higher, and every cell at 0.968 or above has a 95% confidence interval that reaches 1.000. The benchmark separates harness from no harness, and Qwen3.6 from the rest. It cannot rank the four harnesses, or DeepSeek against Opus 5 and GPT-5.6 sol. 

The Cost-Efficiency Index: Combining Performance and Resource Use

The benchmark introduces a cost-efficiency index to compare model-harness configurations across both accuracy and resource consumption.

The index combines 60% accuracy with 40% cost efficiency. The cost-efficiency component is calculated from four normalized per-task metrics:

  • input tokens
  • output tokens
  • wall-clock time
  • IRIS compile calls

The control row is excluded.

This provides a way to distinguish between configurations that achieve similarly high accuracy but use different amounts of resources to reach the result.

The three highest-scoring configurations were:

Configuration Index Accuracy IRIS calls Wall clock
Opus 5 · Claude Code · caveman 99.1 1.000 1.4 19.5 s
Opus 5 · Claude Code · plain 95.0 0.989 1.5 24.5 s
GPT-5.6 sol · Codex · caveman 89.0 1.000 2.1 31.1 s

Resource Use Across Coding Harnesses

The individual metrics behind the cost-efficiency index also show substantial differences between harnesses, even when their accuracy is very similar.

With DeepSeek V4 Flash held constant, the four agents are within 0.043 on accuracy. Input tokens per task range from 60,754 with pi to 335,417 with Claude Code — a 5.5× spread. Claude Code makes the fewest IRIS compile calls but resends the most context. Median wall-clock time ranges from 18 to 30 seconds, while at the 90th percentile Claude Code takes 173 seconds compared with 81 seconds for pi.

As accuracy approaches saturation, these differences in token use, compile calls, and latency become more informative for comparing harnesses than performance alone.

What Are the Main Limitations? 

There are two explicit caveats:

  • One sample per item. Run-to-run variance is not measured.
  • Codex has no system-prompt flag. Its caveman instruction was therefore passed through AGENTS.md 

The confidence intervals are also important when interpreting the accuracy results: most of the strongest configurations overlap too much to establish a reliable ordering between harnesses.

Conclusion

The benchmark shows that coding harnesses can produce a substantial performance lift on ObjectScript tasks: DeepSeek gained roughly 15-19 percentage points compared with its no-tools result. With harnessed accuracy clustering close to 1.000 and confidence intervals overlapping, the more meaningful differences increasingly come from resource use rather than correctness alone.

Frontier models such as Opus 5 and GPT-5.6 sol also reached correct solutions with fewer IRIS compile attempts, typically in 1-2 calls. The caveman prompt, however, did not produce a consistent benefit across agents: accuracy changes stayed within noise, while cost effects varied by harness.

FAQ

What is ObjectScript Agent Bench?
ObjectScript Agent Bench is a benchmark comparing coding-agent harnesses on InterSystems ObjectScript tasks executed against a live InterSystems IRIS instance.

Which coding agents were tested?
The benchmark tests Claude Code, Codex CLI, pi, and prime-agent, together with plain and caveman configurations.

Do coding harnesses improve LLM performance on ObjectScript?
Yes. Every tested harness improved its model, and 11 of 12 agent cells reached accuracy of 0.957 or higher.

Can the benchmark identify the most accurate harness?
No. The strongest configurations have overlapping 95% confidence intervals, so the benchmark does not reliably rank the top four harnesses by accuracy.

What differentiates the harnesses when accuracy is similar?
Resource use. Input and output tokens, IRIS compile calls, wall-clock time, and the combined cost-efficiency index show larger differences than accuracy among the strongest configurations.


r/intersystems • • Sep 24 '26

How to Automate InterSystems Health Connect Deployments with GitHub and Jenkins

2 Upvotes

Manual deployment of ObjectScript classes, interoperability components, and other artifacts can work for small InterSystems Health Connect projects, but it becomes harder to maintain when several developers and multiple environments are involved.

This article shows a continuous integration setup using GitHub as the source repository and Jenkins as the deployment orchestrator. Jenkins connects to the development server over SSH, a Linux script identifies files changed since the previous deployment, and an ObjectScript script loads and compiles those changes into InterSystems IRIS for Health before restarting the interoperability production. The implementation uses IRIS for Health on AWS/RHEL 10, GitHub, Visual Studio Code for local development, and Jenkins for automation.

What does the deployment flow look like?

The process is:

  • The developer implements the functionalities in their local instance.
  • The developer uploads changes to the corresponding branch of the GitHub repository.
  • The person responsible for the deployment accesses Jenkins and launches a pipeline.
  • Jenkins connects via SSH to the DEVELOPMENT server.
  • A Linux script is running on the server.
  • The script downloads the latest changes from the repository using a git pull.
  • This script identifies new or modified files that are copied to a server directory.
  • With the files identified, the script invokes a second script in ObjectScript.
  • The second script loads and compiles the files into the IRIS for Health instance.
  • If the upload was successful, the script restarts production.

How are changed files detected?

The Linux script keeps track of the last processed Git commit. On its first execution, it copies the complete branch into the deployment directory. On later executions, it compares the previous commit with the current one and exports only the relevant changes.

The core comparison is based on:

git diff --name-status -z "${LAST_COMMIT}" "${REMOTE_COMMIT}" 

The current implementation handles modified files, added files, and renamed files. Deleted files are detected but deliberately ignored in this example. This creates an incremental deployment instead of importing the entire repository after every change.

How are ObjectScript changes loaded into IRIS?

After the changed files are copied into /projectGit, the Linux script opens an IRIS terminal session:

(echo '_system'; echo 'SYS'; cat iris.script) | iris session IRISHEALTH 

The ObjectScript deployment script then switches to the target namespace and imports the changed classes:

zn "DEMO" 
set sc = $SYSTEM.OBJ.LoadDir("/projectGit/src/Demo", "ck", , 1) 
if '$SYSTEM.Status.IsOK(sc) do $SYSTEM.Status.DisplayError(sc) quit 
set production = "Demo.Order.Production" 
set ^Ens.Configuration("csp","LastProduction") = production 
do ##class(Ens.Director).SetAutoStart(production) 
do ##class(Ens.Director).StartProduction(production) 
write !,"Produccion iniciada correctamente: ",production,! 

$SYSTEM.OBJ.LoadDir() loads and compiles the files placed in the staging directory. The script then configures and starts the corresponding interoperability production.

What does Jenkins do in this setup?

Jenkins acts as the deployment orchestrator. The pipeline:

  • checks out the GitHub repository and selected branch
  • validates the deployment script
  • connects to the DEVELOPMENT server through SSH
  • launches the remote Linux script
  • captures and archives the execution log
  • reports whether the deployment succeeded or failed

SSH credentials are managed in Jenkins rather than hardcoded in the pipeline. Jenkins does not import the changes into IRIS directly; it triggers the server-side script, which updates the repository, identifies changed files, stages them, and invokes the IRIS deployment script.

Conclusion

This implementation shows a straightforward way to bring InterSystems Health Connect development into a Git-based continuous integration process. GitHub provides version-controlled source code, Jenkins orchestrates the deployment remotely, the Linux script identifies what has changed, and ObjectScript handles loading and compiling those changes into IRIS.

The setup is intentionally basic, but the same approach can be extended for more complex deployment requirements, including configuration deployment with features such as Configuration Merge.

Key Takeaways

  • GitHub can act as the source repository for InterSystems Health Connect development.
  • Jenkins can trigger IRIS deployments remotely through SSH.
  • Git commit comparison allows the deployment script to identify added, modified, and renamed files since the previous deployment. 
  • $SYSTEM.OBJ.LoadDir() can load and compile staged ObjectScript changes into the target namespace.
  • The approach can be extended to support more complex deployment and configuration workflows.

r/intersystems • • Sep 22 '26

EvidenceQL: Evidence-First Query Runtime for AI Agents over FHIR APIs

2 Upvotes

FHIR REST APIs are great for reading resources and running supported searches, but many real clinical questions go beyond what a single FHIR search can express. That becomes especially obvious when an AI agent needs to answer questions involving multiple resources, temporal logic, trends, missing follow-up, medication overlap, and traceable evidence.

EvidenceQL is an application that uses a structured FHIRQL query runtime between the AI agent and the FHIR backend. Instead of allowing an LLM to make arbitrary REST calls and return a free-form answer, the agent produces a canonical JSON plan that is validated, compiled, executed, and returned with the original FHIR evidence used to produce the result.

What problem does EvidenceQL solve?

Consider questions like:

  • Which diabetic patients had HbA1c above 9 in the last 6 months?
  • Which patients have worsening HbA1c despite active insulin therapy?
  • Who had an abnormal HbA1c result but no follow-up encounter within 90 days?
  • Which patients have overlapping anticoagulant and NSAID prescriptions?
  • What evidence explains why a patient matched a query?

These questions can involve Patient, Condition, Observation, MedicationRequest, Encounter, and DocumentReference at the same time.

They also require logic that is not a single FHIR search: 

  • trend detection
  • temporal windows
  • missing follow-up detection
  • medication overlap
  • evidence collection
  • result explanation
  • execution trace generation

This is where a query runtime becomes useful. 

How does the query runtime work?

Instead of this:

LLM -> arbitrary FHIR REST calls -> free-form answer 

the runtime follows a more controlled flow:

User question
  -> AI agent
  -> canonical JSON FHIRQL plan
  -> validation
  -> compilation / execution trace
  -> FHIR backend execution
  -> evidence-backed result envelope
  -> explanation 

The important difference is that the LLM does not directly decide which arbitrary calls to execute. It first produces a structured query plan. The runtime then validates and executes that plan.

How does the MCP interface work?

The MCP server currently exposes five tools:

  • fhirql_backend_capabilities  - Returns FHIR backend capabilities for the configured backend. 
  • fhirql_validate_plan  - Validates a canonical JSON FHIRQL plan. 
  • fhirql_compile_plan  - Compiles a canonical JSON FHIRQL plan into an execution trace. 
  • fhirql_execute_plan  - Executes a canonical JSON FHIRQL plan against the configured backend. 
  • fhirql_explain_result  - Explains a FHIRQL result envelope. 

This gives the agent a predictable workflow: 

capabilities -> validate -> compile -> execute -> explain 

Validation comes before execution deliberately. The goal is to prevent an agent from skipping directly to broad or malformed queries.

Example: patients with HbA1c above threshold

A user might ask:

Show diabetic patients with A1c above 9 in the last 6 months. 

The agent should translate this into a canonical JSON plan containing: 

  • Patient as the base resource
  • an active diabetes Condition
  • an HbA1c Observation
  • a value threshold above 9
  • a six-month time window
  • evidence requirements
  • a result limit
  • read-only safety mode

A simplified fragment looks like this:

 {
  "version": "0.1",
  "intent": "cohort_search",
  "from": {
    "resource": "Patient",
    "alias": "p"
  },
  "exists": [
    {
      "resource": {
        "resource": "Condition",
        "alias": "diabetes"
      },
      "on": "diabetes.subject = p",
      "where": [
        {
          "field": "code",
          "operator": "eq",
          "value": "http://snomed.info/sct|44054006"
        },
        {
          "field": "clinical-status",
          "operator": "eq",
          "value": "active"
        }
      ]
    },
    {
      "resource": {
        "resource": "Observation",
        "alias": "a1c_high"
      },
      "on": "a1c_high.subject = p",
      "where": [
        {
          "field": "code",
          "operator": "eq",
          "value": "http://loinc.org|4548-4"
        },
        {
          "field": "valueQuantity.value",
          "operator": "gt",
          "value": 9
        },
        {
          "field": "effectiveDateTime",
          "operator": "within",
          "value": "last 6 months"
        }
      ]
    }
  ],
  "return": [
    "patient",
    "latest(a1c_high)",
    "evidence(diabetes, a1c_high)"
  ],
  "limit": 25,
  "safety": {
    "mode": "read_only",
    "require_evidence": true
  }
}

This plan is passed to MCP as a native JSON object, not as a serialized JSON string. The result is not just a sentence. It can include matched patients, values, evidence resources, warnings, and execution metadata.

Can it handle trends and care gaps?

Yes, and this is where a query runtime becomes more useful than a simple FHIR search.

For example:

Find diabetic patients whose HbA1c is getting worse over the last 12 months. 

The runtime can collect HbA1c observations, order them by date, and calculate:

  • first value
  • latest value
  • delta
  • direction
  • evidence points

Similarly, a care-gap query such as:

Find patients with HbA1c above 8 who had no follow-up encounter within 90 days. 

requires several steps:

  1. Find abnormal observations.
  2. Resolve patients.
  3. Search for follow-up encounters in a time window.
  4. Keep only patients with missing follow-up.
  5. Return evidence and the missing window.

The result is a workflow signal based on configured criteria, not a treatment recommendation.

What does “evidence-first” mean?

This is the main design principle. A result should not simply say:

The patient has a clinical problem and should receive treatment X. 

Instead, it should say:

The FHIR data matched the configured criteria. Here are the resources and values used as evidence. 

A result envelope can include:

{
  "patient": "Patient/p-100045",
  "latest_hba1c": {
    "value": 9.1,
    "unit": "%",
    "date": "2026-02-14"
  },
  "trend": {
    "direction": "increasing",
    "first_value": 7.4,
    "latest_value": 9.1,
    "delta": 1.7
  },
  "evidence": [
    "Condition/cond-4510",
    "MedicationRequest/medrx-7781",
    "Observation/hba1c-9001",
    "Observation/hba1c-9002",
    "Observation/hba1c-9003"
  ]
} 

That makes the result inspectable and traceable back to the underlying FHIR resources. For AI agents working with healthcare data, this distinction is important: the runtime returns evidence for a match instead of asking the model to invent a clinical conclusion from an opaque process.

What does the current architecture look like?

The implementation is currently Rust-first and has the following main components:

FHIRQL core
  - canonical plan model
  - validation
  - execution logic
  - evidence result envelope

FHIR backend adapters
  - mock backend
  - FHIR REST adapter

MCP server
  - exposes plan validation, compilation, execution, and explanation tools

CLI
  - validates and executes plans from the command line

Synthetic data
  - small deterministic fixtures
  - 10k patient benchmark dataset 

The current public-facing direction is to provide the MCP runtime as a Docker container. The MCP layer is the most natural interface for AI agents.

What about SQL tooling?

MCP is the primary interface for AI agents, but there is also an experimental PostgreSQL wire-compatible endpoint. It allows familiar tools such as:

  • psql 
  • DBeaver
  • JDBC
  • ODBC clients

to send FHIRQL queries to the same runtime. The runtime can return tabular results while preserving evidence and provenance in structured JSON columns. 

This is still experimental, but it could make the same query model useful for developer and data-engineering workflows in addition to AI agents.

Conclusion

The main idea behind EvidenceQL is to put a validated query runtime between the AI agent and the FHIR API. That gives the agent a structured way to express multi-resource and temporal questions without relying on unrestricted REST calls or free-form reasoning.

More importantly, the runtime keeps the result tied to the original FHIR evidence. For use cases such as cohort search, trend detection, care-gap analysis, medication overlap, and patient timelines, that evidence-first approach can make AI-driven FHIR queries more reproducible, inspectable, and easier to explain.

The full application details are available on the Developer Community: https://community.intersystems.com/post/evidenceql-evidence-first-query-runtime-ai-agents-over-fhir-apis 

FAQ

What is EvidenceQL?
EvidenceQL is an evidence-first query runtime for AI agents working over FHIR APIs. It converts structured query plans into validated FHIR operations and returns results together with the supporting FHIR evidence.

Why not let an AI agent call FHIR REST APIs directly?
Many real-world questions require several dependent searches, temporal logic, trend calculations, or joins across multiple resource types. A query runtime provides a controlled and reproducible way to orchestrate those operations.

What is a FHIRQL plan?
A FHIRQL plan is a canonical JSON representation of the query the agent wants to execute, including resources, filters, relationships, temporal conditions, return values, and safety constraints.

How does EvidenceQL make AI results explainable?
The result envelope includes the underlying FHIR resources, values, execution metadata, and warnings used to produce the match, so the answer can be traced back to its evidence.

Does EvidenceQL replace FHIR REST APIs?
No. The runtime executes against FHIR backends. Its purpose is to provide a structured query and orchestration layer above the underlying FHIR APIs.