
Initial Release
Diagnose your InterSystems IRIS instance, see the evidence, and fix it safely — from a browser or an AI agent.
▶ Watch the 4-minute demo video

Operators don’t want forty admin screens. They want to know what is wrong with
the instance, how sure the tool is, and how to fix it without breaking anything.
IRIS Mission Control is a modern portal built on the
/api/admin SysAdmin APIs.
At its center is IRIS Doctor.
git clone https://github.com/Fruitkwan/IRIS_Mission_Control.git irisops
cd irisops
docker compose up -d --build # wait until `docker ps` shows irisops (healthy)
Open http://localhost:52773/irisops/ and sign in as _SYSTEM / SYS.
Open IRIS Doctor from the sidebar, or go to
http://localhost:52773/irisops/#/doctor. Click Diagnose IRIS.
Find “Freeze-on-error is disabled”. It is disabled in the default
container. Click View evidence, then Preview change. You will see
FreezeOnError: false → true with the scope, the operational impact and the
rollback.
Click Confirm and enable journal freeze-on-error. IRIS confirms the
change with a fresh read, and the drawer shows it was recorded in the IRIS
audit log.
Click Run diagnostics and compare. The finding is gone, the score goes
up, and Change history shows who changed what.
Open Time Machine (sidebar → Observability) to see the before/after
snapshots.
Ask the MCP server for the same assessment:
curl -s -X POST http://localhost:3333/mcp -H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"iris_get_health","arguments":{}}}'
Optional: re-open the finding and click Undo change. The previous value
is restored, and an IrisOps/Remediation/Rollback record is written.
![]() |
![]() |
| Evidence-backed findings, highest severity first | Review the exact change before applying it |
| Task | Classic Management Portal | IRIS Mission Control |
|---|---|---|
| Find what needs attention | Check each subsystem’s page and the dashboard indicators | One diagnosis across 19 data sources, with findings ranked by severity and evidence for each |
| Understand a problem | Read raw settings | Each finding explains the operational impact and links to the page that fixes it |
| Change a risky setting | Edit a form and save | Field-level preview, check for concurrent changes, verification, then undo (for five findings) |
| Know who fixed what | Depends on which system audit events are enabled | Every fix writes IrisOps/Remediation/Apply or /Rollback with the before and after values |
| AI and automation | — | MCP server with 16 read-only tools sharing the Doctor’s rules |
IRIS Mission Control is built only on /api/admin. Anything that API does not
expose still needs the classic portal.
DPI-I-966 — Option to show older message.log in IRIS SMP
(status: Community Opportunity).
The classic portal only shows the current messages.log. After a log switch,
for example one forced by mirror trouble, you have to log in to the server to
read messages.old_*. IRIS Mission Control’s Messages Log page (sidebar →
System) handles this from the portal:
messages.log and every rotated messages.old_* fileThe “serious system alert” finding in IRIS Doctor links straight to it. It is
read-only, served by IrisOps.MessagesLog on the broker, and requires
%Admin_Operate or %Admin_Manage. It only accepts those log file names, so it
cannot read any other file.
| Component | Version |
|---|---|
| InterSystems IRIS | IRIS for UNIX 2026.2 (Build 221U), Community Edition, image intersystemsdc/iris-community:2026.2-zpm |
| Node.js (build and MCP) | 22 in CI and Docker; 24 locally |
| Browser | Chromium (Playwright demo recording) |
Other editions, including IRIS for Health with real FHIR endpoints, have not been
tested yet.
flowchart LR subgraph Browser UI["React SPA
IRIS Doctor · Ops Center · admin pages"] end subgraph IRIS["InterSystems IRIS 2026.2"] SPA["/irisops
IrisOps.Router (static shell)"] API["/api/admin
SysAdmin REST APIs (JWT)"] BRK["/irisops-broker (HttpOnly session)
IrisOps.Broker.Router"] AUD[("IRIS audit log + IrisOps.Snapshot
fixes, snapshots, history")] end subgraph MCP["MCP server (Node)"] TOOLS["16 read-only tools"] end Engine["Shared health engine
collectors → rules → findings + scores"] Agent["AI agent / IDE"]
UI --> SPA UI -- telemetry, fixes --> API UI -- audit, history, snapshots --> BRK --> AUD UI -.uses.-> Engine TOOLS -.uses.-> Engine Agent -- Streamable HTTP --> TOOLS -- Basic auth --> API
frontend/src/health/: the engine. collect.ts gathers telemetry and isrules.ts holds the 28 rules and theremediation.ts holds the fixes.src/cls/IrisOps/: IRIS classes.
Router serves the SPA.Broker.Router is the authenticated broker (HttpOnly session cookie).Remediation writes and reads the audit records; Audit is the shared writer.Snapshot stores Time Machine and Config Drift snapshots.Setup runs at install: creates the audit events and configures the broker session.CloudBroker runs server-side cloud checks.mcp-server/: the standalone MCP service.frontend/src/api/generated/: a typed client generated from the OpenAPI spec./doctor): one-click diagnosis with evidence-backed/operations): a rule-based score for each subsystem| Finding | Fix |
|---|---|
| Login auditing disabled | Enables only %System/%Login/Login. Blocked while the master audit switch is off. |
| Unauthenticated custom web app | Clears only the Unauthenticated flag. The portal’s own /irisops shell is protected. |
| Journal freeze-on-error disabled | Sets FreezeOnError; every other journal setting is sent back unchanged. |
| Suspended task | Resumes only that task, after showing its class, namespace and next run. |
| Certificate expiring or expired | Guided steps, then a check of the new expiry date. Certificates are never generated or uploaded. |
iris_get_health, iris_list_databases and iris_get_audit_events.
/mcp page./fhir* web apps, then probes/metadata and reports the version, resources and latency.Ctrl+K) across pages and live entities, and adocker compose up -d --build
_SYSTEM / SYS)http://localhost:3333/status, /tools and /audit.The
-zpmbase image’s post-start hook can fail once on first boot (an
upstreamdbapiregression). The compose file’srestart: unless-stopped
recovers from it automatically.
Upgrading an existing stack: the
irisops-datavolume holds the IRIS
databases, so--buildalone keeps the previously installed classes. Run
docker compose down -vfirst to start from the new image. This deletes
local data such as snapshots.
Requires IRIS 2026.2+. From the community package registry:
zpm "install iris-mission-control"
Or from a clone of this repository (the prebuilt web/ bundle is committed):
zpm "load /path/to/irisops"
This registers two web applications:
/irisops serves the portal shell through IrisOps.Router. The shell loads/api/admin./irisops-broker requires IRIS authentication and the %Admin_SecureThe install step IrisOps.Setup creates the IrisOps/* audit events and
configures the broker’s session cookie.
{ "mcpServers": { "irisops": { "url": "http://localhost:3333/mcp" } } }
Then ask: “Check my IRIS instance and identify anything requiring
attention.” The MCP server reads IRIS_URL, IRIS_USER and IRIS_PASSWORD
from its environment (see .env.example).
docker run -d --name iris-dev -p 1972:1972 -p 52773:52773 intersystemsdc/iris-community:2026.2-zpm
cd frontend && npm ci && npm run dev # http://localhost:5173, proxies /api to :52773
cd mcp-server && npm ci && IRIS_URL=http://localhost:52773/api/admin npm start
| Command | Purpose |
|---|---|
npm test |
Rule, scoring, collector and remediation tests (frontend); secret-redaction tests (mcp-server) |
npm run build |
Type-check and production build into web/ |
npm run lint |
oxlint; any warning fails the build |
npm run generate |
Regenerate the typed API client from the OpenAPI spec |
npm run record:demo |
Record the captioned IRIS Doctor demo video (see demo/README.md) |
Tests (frontend/tests/):
CI (.github/workflows/ci.yml):
/api/admin, and MCP’s connection to IRISIrisOps.Router and embedded inindex.html.frame-ancestors 'none', nosniff and a same-origin^IrisOps("security","connect-src")./api/admin issues JWTs, which the SPA keeps inlocalStorage with transparent refresh.
X-Requested-With header, which%Admin_Secure.IrisOps/Snapshot/* auditMIT