Skip to content

Open source

obix-mcp — letting an AI agent read a Niagara station, safely

obix-mcp is an MCP server that gives an AI agent 10 read-only ways into a Niagara station over oBIX — the lobby, points, folders, histories, open alarms and live values through server-side watches — and one write tool that is absent from the agent’s tool list unless the bridge was started with writes enabled and a named subtree to write to. Standard-library Python, no dependencies, MIT.

  • oBIX
  • Model Context Protocol
  • Niagara 4
  • Read-only by default
  • 162 tests
  • MIT

What it is for

An operator can ask a control system a question by opening Workbench and knowing where to look. An agent cannot. The gap is not intelligence — it is that a station exposes no interface an agent can discover. oBIX is there, but what a station actually serves differs from what the specification describes, in ways that matter on the first request.

This bridge closes that gap in one direction and refuses to close it in the other by accident. Reading is the whole point and is on by default. Writing moves plant, so it is off, and turning it on takes two deliberate arguments rather than one.

The write gates, and why there are four

“Read-only by default” is worth nothing as a promise and everything as a mechanism. Here it is four separate ones, each of which has to be defeated:

  1. The flag. --allow-write is off unless passed.
  2. No allow-everything value. --allow-write without at least one --write-allow <href prefix> is an argument error, not a permissive default. There is no wildcard to type by mistake.
  3. The tool is not advertised. With writes off, obix_write is not in the list the agent is handed. An agent never sees a capability it cannot use, so it never plans around one.
  4. Dispatch refuses anyway. An agent that names the tool from memory gets an error explaining how writes are enabled, rather than a write.

Past all four, the href still has to match a prefix the bridge was started with. That allowlist — not the station’s own export list — is what scopes the tool, and the tool’s own description says so, because the common assumption is the other way round.

Why the evidence file is the point

Every protocol decision in it was read out of one Niagara 4.15 install — its jars and its shipped documentation — rather than recalled from the oBIX specification. EVIDENCE.md is 819 lines citing the class and the method behind each decision, and saying plainly where the install answers nothing. Four of those findings change what any client has to do:

  • The export branch is mounted as continuousControl, not export — that string is the literal return of BExportLobbyAgent.getLobbyName(). A client that walks to /obix/export because the documentation calls it the export agent finds nothing.
  • HTTP Basic is not enabled on a station by default. HTTPBasicScheme has to be added to the AuthenticationService and assigned to the user, so a 401 is usually a missing scheme rather than a wrong password.
  • A 403 means two unrelated things — an unlicensed oBIX server, or a permission refusal on a single object — and only the response body separates them.
  • A relative href means “under this document”, which is why a client can pass its whole suite against the lobby and then fail on the first nested operation. The lobby is the one document where both readings agree.

None of that is in the specification, and all of it is checkable rather than asserted: each citation names the class to decompile.

How far it has actually been tested

It has never been pointed at a real station. There is no licensed Niagara station here to run it against, so all 162 tests run against a fixture station written from the evidence above — including the fixture serving hrefs the way a station does rather than the way a specification reader would expect, which is the bug that made that behaviour worth writing down in the first place. A real station will differ, most likely in which optional branches are licensed and in what its alarm and history services are configured to expose.

The findings, without the code

If you want what came out of this rather than the bridge itself, it is written up as two notes: what a Niagara oBIX server actually exposes covers the surface, and letting an agent write to a control system covers the part that needs gates. The other three things we publish are single-file read-only tools for BACnet, MQTT and LoRaWAN.

Next step

Want an agent to be able to ask your control system something?

The bridge is the easy half. The hard half is deciding what an agent may see and what it may move, and writing that down before anything is connected. Send what the station is and what you want asked of it.