hotloop
GitHub
HotLoop Gateway

An industrial gateway that tells you what it has not proven.

It polls real equipment over real protocols, keeps what it reads, alarms on it, automates against it, and exposes the whole plant to agents over MCP. One static Go binary, no sidecar, running as a non-root user with every capability dropped.

Not yet published.

Version 4.13.0 is merged, and the code is moving into this org. Nothing here is downloadable yet, and the release notes say exactly which versions have and have not been tagged.

The write gate

Every write goes through one function that cannot be routed around.

From the UI, the API, an automation, or an agent. Policy lives in that one place rather than being re-implemented at each call site, where one of them would eventually be forgotten.

  1. 01

    Writes are enabled.

    safety.allowWrites is off by default, and has been since 4.4.0.

  2. 02

    Agent writes are enabled.

    safety.allowMcpWrites is a narrowing of the master switch, not a way around it.

  3. 03

    The caller has permission.

    values.write for a logged-in user, which a viewer does not have, or the MCP write setting for an agent.

  4. 04

    The tag is marked writable.

    Tags are read-only until somebody decides otherwise, one at a time. A browse import never arms anything.

  5. 05

    The value is within range.

    It is rejected, not clamped, because sending 400 when someone asked for 500 is quietly doing something else.

  6. 06

    The attempt is audited.

    Before the value reaches the wire, including every refusal, with the actor and the source.

An MCP client gets no special path. write_tag hits the same gate an operator does, and it requires a stated reason that is recorded next to the write, because an audit row nobody can interpret six months later is barely better than none.

Built for agents

MCP in both directions.

13 tools and 4 resources, over streamable HTTP and over stdio, so an agent can read the plant and, only through the gate, act on it. There is also an outbound client, so a rule can call a tool on another system.

The Sites screen uses the same mechanism. Point one gateway at the others as outbound MCP servers and it asks each of them the question it would answer itself. A site that does not answer is shown as unreachable, with the reason, and is left out of the roll-up, because counting a plant you cannot reach as zero alarms would be the worst possible default.

Bad is not zero

A failed read is not a value.

Every reading carries good, uncertain, or bad. A driver that cannot read a point still emits a reading, marked bad, because silence looks identical to a value that has not changed.

Alarm evaluation holds its previous state on a bad reading rather than evaluating it. A sensor that fails to zero would otherwise trip every low alarm on the unit and look like a process event, when it is an instrument problem.

What is inside

The rest of the plant, in one binary.

Historian

TimescaleDB, promoted to a hypertable when the extension is there and falling back to native range partitioning when it is not. Per-tag deadband filtering, so a sensor jittering in its last bit does not write a row every scan forever.

Alarms

ISA-18.2, including rtn-unack for an alarm that cleared before anybody saw it. Acknowledgement and return-to-normal are independent axes, so a transient trip at 03:00 is still on the list when the morning shift arrives.

Automations

Nine trigger types, a sandboxed condition, and actions. Conditions are compiled when a rule is saved, so a broken rule is caught in the editor and not at 3am.

The Board

The screen that gets left on a wall. Pinned tags are gauges with their alarm limits marked where they fall, layout stored with the plant so the panel PC and the laptop show the same board.

Paging

Alarm notifications by webhook or email, so a 03:00 alarm can reach a phone. It composes with whatever paging service you already use, and off by default.

OPC UA server

Read-only, so a third-party client can browse and read the Gateway's tags. Secure channels, the same users as the web login, and no write handler at all.

Edge Relay

A second, lighter binary with no database, about 16.9 MB against the Gateway's 33.4 MB, that polls and forwards over Sparkplug B. Fleet management tracks and commands registered relays.

Embedded broker

An optional in-process MQTT broker, so a single-box install can be its own Sparkplug hub. There is no per-topic access control by design, so use a dedicated broker at scale.

Backups

A logical snapshot taken in pure Go over the existing connection, with a restore that refuses to touch a database that already has data.

Licensing

Free for individuals. Business goes through Embernet.

The Gateway is source-available under the HotLoop Community License, which is not an OSI open source license. Individual, home, hobbyist, nonprofit, and educational use is free. Any business or for-profit use goes through Embernet, which provides the support and the warranty.

Read the terms