Integration fabric for federated, AI-native operational apps. The on-prem MCP substrate underneath domain-specific decision-support apps.
IONe is a single Rust binary + static UI that federates a heterogeneous portfolio of operational apps into one workspace for an operator. Each connected app stays opinionated about its own data, compute, storage, and frontend; IONe handles federation over MCP, brokered identity, signed push event ingress, a generator↔adversarial LLM loop that gates app actions through human approval with audit trail, and a thin UX shell that renders refs (maps, tables, charts, documents) the apps provide.
Status: pre-alpha. v0.1.0 is a reference implementation of the federation thesis under the older chat-first framing; current architectural direction is captured in md/design/ione-substrate.md. Expect breakage.
Organizations that run operational decision-support workflows across many specialized apps, with a chain-of-command that needs information up and commands down. The reference deployments pair IONe with one or more domain apps: GroundPulse for infrastructure risk, TerraYield for crop-health intelligence, bearingLineDash for financial analytics. The same substrate serves them all — domain-specific data and compute live inside each app; IONe brokers identity, federates over MCP, gates actions through approval, and presents the unified pane of glass.
The canonical reference is md/design/ione-substrate.md (integration-fabric framing, 2026-05-12). The earlier chat-first design md/design/ione-v1.md and product-completion design md/design/ione-complete.md are preserved as historical context for what shipped on main. Short version of the current thesis:
- IONe is integration fabric, not a hosting platform. Apps stay independent; IONe federates over MCP + brokered identity + approval/audit gateway + UX shell.
- Any MCP-speaking app is a peer. The contract apps satisfy lives at md/design/app-integration-playbook.md: MCP server + OAuth 2.1 + signed webhooks + view-hint resource metadata + foreign-tenant
whoami+ role declaration. - Identity is brokered. IONe consumes one identity (OIDC, SAML 2.0 SP, MFA) and holds delegated tokens per app per user. Apps trust IONe-issued OAuth credentials.
- State-changing app actions go through IONe's approval gateway. Apps declare which tools require human-in-the-loop. IONe routes the operator's intent through a generator↔adversarial LLM survivor chain, then through approval, then invokes the app. Audit on every action.
- The UX shell renders refs. Apps own their tile servers, raster stores, report generators, time-series DBs. IONe embeds tile URLs, MIME-typed documents, and view-hinted resources from MCP metadata. No data is hosted in IONe that belongs to an app.
- Chat is one surface, not the engine. The engine is federation + identity broker + approval gateway. Chat, map, table, chart, document are surfaces over that engine.
Prerequisites: Docker, Rust (1.78+), and a local Ollama install (ollama pull llama3.2:latest qwen3:14b phi4-reasoning:14b qwen3:8b nomic-embed-text).
git clone <this-repo> ione && cd ione
cp .env.example .env
docker compose up -d postgres minio
cargo sqlx database create
cargo sqlx migrate run
cargo run --release
# open http://localhost:3000.env.example sets IONE_SEED_DEMO=1, so after copying it to .env a fresh local install lands in the read-only [Demo] IONe Ops workspace automatically. The demo is populated and chat works offline through canned replies; switch to your real workspace when you are ready to connect live systems.
The UI ships with Chat, Connectors, Signals, Survivors, and Approvals tabs. Create a workspace, register an NWS connector with your lat/lon, poll it, watch rule + generator signals land, watch the critic rank them, watch the classifier route them.
./scripts/demo.sh
# brings up two IONe processes on :3000 and :3001,
# wires a peer relationship, and prints the audit trail of
# survivors flowing from Node A to Node B. ┌─ Connector fabric ─────────────────────────────────────┐
│ MCP servers · OpenAPI adapters · hand-wired Rust │
└────────────────┬────────────────────────────────────────┘
│
▼
┌─ Workspace (generic persistent container) ─────────────┐
│ streams → events → (rules + LLM generator) → signals │
│ │ │
│ ▼ │
│ (adversarial critic) → survivors│
│ │ │
│ ▼ │
│ (routing classifier) → decisions │
│ │ │
│ ┌──────────────┬─────────────────┼─────────────┐ │
│ ▼ ▼ ▼ ▼ │
│ feed notification draft peer │
│ (role- (connector send — (approval → (federate │
│ scoped Slack, SMTP, ...) deliver) to another│
│ inbox) IONe) │
└─────────────────────────────────────────────────────────┘
- Rust (axum + tokio) — single binary
- Postgres 16 + pgvector — primary store + embeddings
- S3 / MinIO — blob store (documents, imagery)
- Ollama — local-first LLM (generator
qwen3:14b, criticphi4-reasoning:14b, routerqwen3:8b; all configurable) - MCP — hand-rolled JSON-RPC 2.0 + SSE subset; both as server (
/mcp) with OAuth 2.1 + PKCE + CIMD, and as client (consuming peer nodes). Connect from Claude Desktop (Pro/Max), Claude Code, Cursor, or VS Code via the in-app "Connect to MCP" panel. - OIDC / SAML — per-node local CoC + federated claims layered on top; Keycloak default IdP in docker-compose; PIV/CAC-capable for federal deployments
- Demo Workspace (
IONE_SEED_DEMO=1) — first-run is populated, and chat works offline through the canned layer. - Ollama preflight + chat remediation — health dot in the top bar; remediation card with
pullCommandwhen models are missing or Ollama is unreachable. - Guided connector setup — provider-specific forms,
POST /api/v1/connectors/validatedry-runs, and inline hints before create. - Publish-don't-poll — scheduler emits
pipeline_eventsper stage; SSE stream at/api/v1/workspaces/:id/events/stream; connector cards show a live timeline. - Split activation — separate demo walkthrough and real activation trackers; demo completion shows a CTA to create a real workspace.
- Funnel telemetry —
funnel_eventstable;POST /api/v1/telemetry/eventsplusGET /api/v1/admin/funnelgated onIONE_ADMIN_FUNNEL=1. - MCP OAuth 2.1 — discovery, register, authorize, token, and revoke at
/mcp/oauth/*; bearer middleware on/mcp/*; per-client tiles in the Connect-to-MCP panel. - Peer federation — OAuth-based federation with tool allowlist;
POST /api/v1/peers,GET /api/v1/peers/:id/manifest, andPOST /api/v1/peers/:id/authorize.
All integration tests are #[ignore]-gated and run serially against a live Postgres:
# Cheap unit path:
cargo test --test phase01_chat
# Integration, live DB, Ollama-gated where applicable:
DATABASE_URL=postgres://ione:ione@localhost:5433/ione \
IONE_SKIP_LIVE=1 \
cargo test -- --ignored --test-threads=1Unset IONE_SKIP_LIVE to exercise the live Ollama generator/critic/router paths against the models above.
| Var | Default | Purpose |
|---|---|---|
IONE_BIND |
0.0.0.0:3000 |
Server address |
DATABASE_URL |
postgres://ione:ione@localhost:5433/ione |
Postgres |
OLLAMA_BASE_URL |
http://localhost:11434 |
Ollama HTTP |
OLLAMA_MODEL |
llama3.2:latest |
Chat default |
OLLAMA_GENERATOR_MODEL |
qwen3:14b |
Signal generator |
OLLAMA_CRITIC_MODEL |
phi4-reasoning:14b |
Adversarial critic |
OLLAMA_ROUTER_MODEL |
qwen3:8b |
Routing classifier |
IONE_SEED_DEMO |
0 prod, 1 in .env.example / docker-compose |
Seeds the demo workspace |
IONE_POLL_INTERVAL_SECS |
60 |
Scheduler tick |
IONE_AUTH_MODE |
local |
local or oidc |
IONE_OAUTH_ISSUER |
http://{IONE_BIND} |
Absolute issuer URL used in the OAuth discovery document |
IONE_OAUTH_STATIC_BEARER |
unset | CI/headless escape hatch for /mcp/* |
IONE_TOKEN_KEY |
required | 32-byte base64 or hex key for encrypting peer OAuth tokens |
IONE_ADMIN_FUNNEL |
unset | Gates /api/v1/admin/funnel; returns 404 when unset |
IONE_SKIP_LIVE |
unset | Skip external network / Ollama calls in tests |
IONE_HTTP_UA |
IONe/0.1 … |
User-Agent for outbound fetches |
IONE_STATIC_DIR |
./static |
Static UI assets path |
IONE_SESSION_SECRET |
random | HS-signed session cookie key (set in prod) |
IONE_SMTP_TEST_MODE |
unset | 1 short-circuits SMTP to in-memory capture (tests) |
- v0.2: streaming chat (SSE), workspace-scoped conversation listing, token accounting, per-workspace RBAC enforcement beyond routing scope.
- v0.3: pgvector-backed semantic search on stream_events, policy-editor UI for auto_exec + sharing policies.
- v0.4: rmcp crate swap once its axum integration stabilizes; full MCP resources + prompts.
- v0.5+: hosted tier (only if three unsolicited asks arrive and there's a third hire — see md/strategy/market/ione-pricing.md).
IONe descends directly from Morton Analytics' 2024 DIA NeedipeDIA submission (docs/ione_wp.pdf) — originally conceived as an "input-output network of micro-services" for analyst-driven data engineering + ML + analytics. v0.1 is the AI-native rebuild: same thesis, with chat + gen↔adversarial loop + MCP federation as the three new ingredients.
Apache 2.0. See LICENSE.
Morton Analytics LLC · morton@myma.us