Quick start
Initialize a pump and dispense 500 µL from the media reservoir to a chip. You'll need your Habitat device's API URL and, for the Python examples, the SDK installed — see Access.
1. Set up
curl (or any HTTP client) is all you need — no extra install required.
Add the Open Culture connector once (see MCP), then just ask Claude in plain language — no code, no URLs. The steps below show what to say.
2. Check the server
Expected: a JSON object with device, drivers, and status fields.
from openculture import HabitatClient
with HabitatClient("http://mistyforest.local:8000") as h:
health = h.system.health()
print(health.device_name, health.driver_ready)
HabitatClient is a context manager — it owns its connection pool and closes it on exit. The default per-request timeout is 300 s to accommodate long pump moves.
Ask: "Is MistyForest ready?"
3. List pumps
A MistyForest-class device has two pumps: address 0 (Dispense) and address 1 (Aspirate).
with HabitatClient("http://mistyforest.local:8000") as h:
for pump in h.pumps.list():
print(pump.addr, pump.name, pump.ready)
h.pumps.list() returns a list[PumpStatus] with typed fields — your editor will autocomplete addr, valve_position, syringe_volume_ul, etc.
Ask: "What pumps does MistyForest have, and are they ready?"
4. Initialize pump 0
Pumps must be initialized before use. Initialization homes the plunger and valve.
5. Dispense 500 µL
from openculture import HabitatClient
from openculture.client.habitat.models import ExecuteRoutineRequest
with HabitatClient("http://mistyforest.local:8000") as h:
result = h.routines.execute_routine(
"dispense",
request=ExecuteRoutineRequest(
params={"volume_ul": 500.0, "chip_id": "chip_A", "source_role": "media"}
),
)
print(result)
The dispense routine is the workflow-level call — it draws from a media port,
switches the valve to the chip port, and dispenses in one call. For lower-level
plunger control, POST /pumps/{addr}/dispense (h.pumps.dispense(addr, request))
moves the plunger directly.
Ask: "Dispense 500 µL of media to chip_A on MistyForest." Claude proposes
the operation and waits for your approval before anything moves.
6. Observe the result
Ask: "What's pump 0's plunger position on MistyForest?"
Error handling
Non-2xx responses return a JSON body with a detail field:
Non-2xx responses raise HabitatAPIError, which carries the parsed detail field:
from openculture import HabitatClient, HabitatAPIError
try:
with HabitatClient("http://mistyforest.local:8000") as h:
h.system.set_port_chip(pump_name="bad-name", port_number=99)
except HabitatAPIError as exc:
print("status:", exc.response.status_code)
print("detail:", exc.detail)
HabitatAPIError extends httpx.HTTPStatusError, so existing httpx error-handling
still works.
When something fails, Claude relays it in plain language — e.g. that pump 99 doesn't exist, or which safety interlock blocked an action — and suggests a fix. Actuating tools always wait for your approval first.
Where next
- Explore every endpoint interactively in Try it.
- Read the API overview for conventions, units, and error shapes.
- Drive your Habitat device in natural language with MCP.