Getting started

Design principles

The high-level thought process behind OpenMHP, and how each piece follows from it. If you're deciding whether a contribution fits, this is the reasoning to check it against.

Where it came from

Getting several devices in a lab or on a factory floor to work together has always been hard, and putting an AI agent in charge of them is harder still. Each instrument has its own programming interface. There has been no standard way to integrate them, and once they are wired up there is no common way for them to share data with an agent, or to let the agent operate them safely. The knowledge that makes a device safe to use — how heavy an arm is, when a lid is too hot to open, what a reading "usually" looks like — sits in paper manuals, on someone's laptop, or in the head of the person who runs it.

Anthropic solved the equivalent problem for software when it open-sourced the Model Context Protocol. MCP gave any AI application one standard way to reach digital tools, and the ecosystem followed. Agent Skills, also open-sourced, showed how to package procedural knowledge so an agent loads only what a task needs. OpenMHP carries the same idea across to hardware: a shared, open protocol so that any AI agent can connect to lab instruments and machines the way MCP connected it to digital tools, and run experiments agentically — from routine drug-discovery assays to laser calibration on a quantum computer.

The agent is not the enforcement point

Everything that keeps a run safe — limits, interlocks, approval, lease ownership, whether an outcome is even certain — is checked in the driver, on the device side of the wire, on every call including a dry run. An agent can ask for anything; only the driver decides what actually happens. This is why the six safety gates run in a fixed order on every write and invoke rather than being something a client library merely suggests, and why methods (below) are validated against the device's own gate before they're ever saved. Changing a limit is a code review against a descriptor, not something reachable at run time by an agent that argues well.

The host is trusted, the model is not

approved: true means a person confirmed this exact request. It is stripped from whatever the model sends and set only by the host, after MCP elicitation asked a real person and got a real answer. Without an elicitation channel, confirm-gated operations are simply unavailable — the bridge has no trusted way to reach anyone, so it refuses rather than trusting the model's word. This one rule is what makes an approval level mean something instead of being a convention the model could talk itself past.

An instrument should teach an agent the way a colleague would

A device package is written in the owner's own words, carrying the tacit knowledge that used to live in a manual or in someone's head. It loads the way an Agent Skill does: a roughly 40-token card in search results, the full operating summary once an agent picks it, and detailed specs, references and scripts only for the one item about to be used. An agent's context is a resource the protocol protects on purpose — the same lesson Anthropic's own work on tool search and long tool lists taught about software tools, applied here to a lab that might have two thousand devices instead of five servers. Worked examples exist on every action and every bridge tool for the same reason a schema alone never taught anyone a convention.

Fail closed, always

An uncertain outcome is worse than a stopped one, so a failure latches the device in fault rather than guessing it's probably fine. A watchdog protects against a controlling process going silent — not only against malice, but against the far more common case of a crashed script or a dropped connection mid-protocol. Emergency stop always wins, regardless of lease, approval level or interlock state, and it is built to never wait behind an ordinary blocking call to the instrument. Physical actions are not idempotent — sending a command twice is not the same as sending it once — so retries are explicitly the caller's responsibility, never automatic.

Show the plan before doing the thing

Plan mode exists so an agent can rehearse a whole procedure with every gate evaluated and nothing physically moving, then hand a person something concrete to say yes to, instead of narrating an intention in prose and hoping it matches what will actually happen. Virtual time and a step budget keep a rehearsal honest and finite even when the real procedure would run for hours or loop indefinitely. A plan device deliberately narrows its own raw RPC access to read-only calls, so the one general-purpose escape hatch in the client SDK can never quietly become a way to actuate hardware from inside what is supposed to be a dry run.

Physical work does not fit inside one request/response turn

Jobs, leases, background runs and pushed events all exist because chemistry and mechanics run on their own clock, not an agent's. A thirty-cycle PCR program takes over an hour; an agent should not have to hold a connection open and reason continuously for that whole time. Results should be pushed to whoever is watching the moment they exist, and a run's record should survive the bridge restarting, not evaporate with the process that started it. Data belongs in files next to the run it came from, not streamed wholesale through an agent's limited context.

Methods are data, owned by the project, not baked into the instrument

The same gas chromatograph runs a different method for every compound and every project it serves; hard-coding one method into a driver would have been wrong from day one, and asking an agent to invent parameters from nothing is worse. So a method is a versioned, hash-identified record the device itself keeps and validates, filed by project and compound, and the protocol's first move for a method-driven action is to ask which one exists — one match, use it; several, ask a person, or in an unattended loop take the current project's own; none, ask for the parameters and save what worked. Provenance follows every run, so a result can always be traced back to the exact parameters that produced it.

Bridge existing ecosystems; don't compete with them

SiLA 2, PyLabRobot, MADSci, OPC UA and ROS 2 represent years of vendor and lab investment, and plenty of instruments already run well under one of them. OpenMHP's job is to be the layer an agent sees — translating what already works underneath into the same signals, settings, actions and jobs every other device exposes — not to replace any of it. An adapter is a few lines of binding code, not a rewrite.

The protocol is the product, not any one implementation

SPEC.md is written and versioned as the contract; the Python reference implementation is one way to satisfy it, not the definition of correctness. JSON-RPC 2.0 is an ordinary, well-understood wire format on purpose, and conformance is defined behaviorally — pass an equivalent test suite — rather than "matches this code." A second, independent implementation, in any language, on any platform, should be possible and is welcome.

What this means for a contribution

Where to go next