Build
Gateway and relay
Most instrument networks are closed: nothing outside may connect in, and IT will not add a rule for a bench PC. OpenMHP works there without one. The bench PC dials out to a gateway on the company network and asks it for work; your agent talks to the gateway. Nothing is opened, and the bench PC never needs an AI agent on it.
The shape of it
Three kinds of machine, and every connection between them points at the one in the middle.
- The bench PC runs
mhp nodeexactly as on a lab node, serving its instruments locally. Once joined, it also keeps a connection open to the gateway and takes requests from it. It needspip install openmhpand one command, nothing else. - The gateway is one Python process,
mhp gateway serve, on any always-on desktop or small VM on the company network. It listens on one address and one port, over HTTPS. Bench PCs register with it; agents reach every registered instrument through it at the same URL shapes a device has on a LAN, so no client code changes. - Agent machines point
mhp-mcpat the gateway's directory and use the samemhp_find,mhp_readandmhp_invokeas always. Working from home changes nothing: the moment the VPN is up you are on the company network, and the gateway is where it always was.
Nobody has to run this in a cloud. The gateway belongs on the company network, where people in the office and people on the VPN already are. IT has one line to confirm: lab PCs and agent machines can reach the gateway's address and port.
What happens on one call
The relay is ordinary HTTPS from both sides, with the bench PC asking for work instead of waiting for it. That is the whole trick, and it means the gateway never has to connect into the lab.
- The bench PC keeps a long-poll open on the gateway,
GET /relay/next, and renews it every 25 seconds. That poll is also how the gateway knows the PC is alive. - Your agent sends the usual request to the usual kind of URL,
POST /<node>/<device>/rpc, with its agent token. An unknown token is refused before anything is queued. - The gateway queues the request with the agent's name as the client, so leases on the bench PC are per agent, and carries a person's approval because it authenticated who asked.
- The gateway answers the open poll with the request. It is handed over once.
- The driver runs it on the bench PC. Limits, interlocks, approval levels and the e-stop are enforced there, beside the hardware, as always.
- The bench PC posts the reply; the gateway matches it to the waiting request and returns it. Notifications travel the same road, batched upward within half a second and streamed to the agent as server-sent events.
Once, or not at all
If the bench PC is offline, which the gateway decides when no poll has arrived for 45 seconds, the agent gets a 503 at once naming the PC and when it was last seen. If the PC is online but does not answer within the timeout, 120 seconds unless the agent asks for longer with X-MHP-Timeout, the agent gets a 504. In both cases the request is dropped and never re-sent on the agent's behalf, because starting a protocol twice is not the same as starting it once. The agent checks the job's status before repeating anything, which is what the specification asks of it on any transport.
Pairing and trust
Three commands set it up, and each one hands out a different secret to a different machine.
On the gateway machine, once
Any always-on desktop or small VM on the company network. pip install openmhp, then:
mhp gateway init # asks for the address others will use and a port; makes a certificate
mhp gateway serve --install-service # runs now and after every reboot
The gateway listens on that one address only, never on every interface. If IT gives you a certificate, pass --cert and --key to init; otherwise it makes one, and every machine that joins pins it. TLS 1.2 is the oldest it will speak.
For each lab PC
On the gateway, mhp gateway pair prints a one-time code and the exact line to run. On the lab PC, where the device packages live:
pip install openmhp
mhp node C:\lab\devices --join https://gw.office ab12-cd34
It shows the gateway's certificate fingerprint so you can compare it with what pair printed, joins, and serves. From then on plain mhp node C:\lab\devices reconnects by itself, and --install-service keeps it running. If the gateway is down the node retries quietly and the instruments keep working for anyone on the lab network. If a config.json is missing or a port is taken, it says so in words before it serves anything.
For each agent machine
On the gateway, mhp gateway add-agent kushal-laptop prints a token for OPENMHP_DEVICE_TOKEN, the certificate to trust if it is self-made, and one line:
mhp-mcp --directory https://gw.office/directory/
Your agent now finds every instrument of every joined lab PC through that one URL.
Day to day
mhp gateway status # which lab PCs are connected, what they serve, each agent's URL
mhp gateway check # OK or FIX for the gateway, each lab PC and each instrument, with the fix spelled out
mhp gateway remove-node bench-2 # its token stops working; pair again to bring it back
mhp gateway remove-agent old-laptop
Both the gateway and the node install as a user service: systemd on Linux, a LaunchAgent on macOS, a Startup-folder entry on Windows. mhp gateway check is the thing to run when something seems off; it tells you which of the three machines to look at.
What the relay guarantees
- Every connection is outbound from the lab PC, over HTTPS. It passes corporate web proxies. The only thing IT has to confirm is that lab PCs and agent machines can reach the gateway's address and port.
- A request is delivered once or not at all. Offline means an immediate error; no answer means a timeout. Nothing is ever re-sent on the agent's behalf.
- Identity is the gateway's. Agents hold agent tokens; the lab PC's own token never leaves it. The lab PC sees the agent's name as the session, so one agent cannot take another's lease.
- The gateway is the approval boundary. It forwards a person's confirmation from authenticated agents, so give agent tokens only to harnesses that really ask a person.
- Emergency stop never depends on the relay. The hardware stop, the vendor software and the device-side watchdog are all on the bench, exactly as on a LAN.
- Pairing is explicit. Codes last fifteen minutes and work once. A lab PC that is reinstalled pairs again and gets its own name back; the old token stops working.
What it is not
It is not a VPN into the lab, and it does not make the lab network reachable: only the instruments a bench PC chose to serve are visible, and only through the gateway's device URLs. It is not a message queue: nothing is stored for later delivery, by design. And it is not required. On an open lab network, lab nodes find each other over mDNS and the gateway never enters the picture.
The full bench-side guide, including which files hold what, is docs/relay.md in the repository, and the alternatives that were weighed are in docs/firewalled-labs.md. The wire-level rules are in the specification.