Skip to main content

MMIO — how you connect

A program connects to the Zeq machine by mapping a register page, not by reading a .env. The local zeqd agent owns a 4 KiB region (~/.zeq/mmio) holding the machine's identity (ZID), the live 1.287 Hz clock (ZEQOND, PULSE_PHASE), its CREDIT, and a revocable credential handle — never the raw key. The SDK reads the region and resolves the handle → a short-lived bearer per request. No secret in your code, no .env.

Four ways to reach it — SDK · HTTP endpoint · MCP · CLI — all below.

SDK — @zeq/sdk

import { ZeqReactorClient, ZeqMachine } from "@zeq/sdk";

// read the machine's live registers (no API call)
const m = await ZeqMachine.map();
// { ok, version, status, zid, origin, handle, zeqond, pulsePhase, pulseHz, credit, heartbeat }

// connect — MMIO-first (no key in code, no .env), env fallback is deprecated
const reactor = await ZeqReactorClient.connect();
await reactor.create({ solver: "kalman", initialInput: { steps: 60 } });

ZeqMachine (Node only — the browser uses your session):

MethodReturnsWhat
map()snapshotread the region (identity + live registers)
available()booleanis a valid region present (no throw)
resolveKey(handle){ ok, key, ttl, origin, zid }resolve a handle → bearer over the socket
keyProvider()() => Promise<string>a rotation-safe per-request bearer resolver
ring(cmd) · ping() · refreshKey()doorbellthe MMIO write path (ping → live Zeqond; refreshKey rotates the handle)

ZeqReactorClient connect paths: connect() (MMIO-first → explicit key → ZEQ_API_KEY with a deprecation warning → throw) · fromMMIO() (force MMIO) · new ZeqReactorClient({ apiKey }) (explicit).

HTTP endpoint — MMIO mirrored to the network

For a device that can't run the agent, the same registers are on HTTP:

curl https://www.zeq.dev/api/zeq/mmio
# → { protocol:"ZeqMMIO", version:1, regionSize:4096, layout:[…17 registers…],
# status_bits, doorbell, resolve, registers:{ zeqond, pulse_phase, pulse_hz, R_t }, connect:{…} }

curl -H "Authorization: Bearer $ZEQ_AK" https://www.zeq.dev/api/zeq/mmio/registers
# → { ok:true, zid:"ZEQ7…", keyValid:true, registers:{ zeqond, pulse_phase, pulse_hz, R_t } }

GET /api/zeq/mmio is public (layout + machine-global clock). GET /api/zeq/mmio/registers needs your zeq_ak_ key and returns your machine's ZID. Per-machine identity/credit/handle otherwise stay local with the agent.

MCP — the zeq_mmio tool

Any MCP client (an agent) gets the same:

zeq_mmio # action=manifest (default): layout + live global registers
zeq_mmio action=registers # your machine's ZID (uses your zeq_ak_ key)

CLI — zeq mmio

zeq mmio # the region manifest — the full layout table + live registers
zeq mmio registers # your machine's ZID + clock (needs your key)
zeq mmio connect # the runbook: install → provision → run → connect()

The agent — zeqd (run a full local machine)

Stdlib Python (zero deps), or a single static Rust binary (zeqd/rust):

cd zeqd && ./install.sh # → ~/.local/bin/zeqd
printf '%s' "$ZEQ_AK" | zeqd provision --zid ZEQ… --origin https://www.zeq.dev # seals the key at rest
zeqd run # owns ~/.zeq/mmio (RAM-backed), ticks 1.287 Hz, mlock'd, serves handle→bearer
zeqd status # the region (no secret)

It seals the zeq_ak_ key with AES-256-GCM under a machine-bound KEK, keeps the region on tmpfs (never persists to disk), mlocks it, and zeroizes on exit. Validated on a real host: mlock=True, AES seal, RAM region, doorbell.

The region (the interop contract)

4096 bytes, little-endian. The full offset/type table is on the hardware page and in zeq-mmio.h; the GET /api/zeq/mmio layout array is its machine-readable form. Key registers: MAGIC(0x000) · ZID(0x010) · ORIGIN(0x030) · KEY_HANDLE(0x070) · ZEQOND(0x0A0) · PULSE_PHASE(0x0A8) · PULSE_HZ(0x0B0) · CREDIT(0x0B8) · HEARTBEAT(0x0C0) · doorbell CMD/DOORBELL/RESP(0x100…). ZEQOND = floor(unix/0.777000777), PULSE_PHASE = (unix mod 0.777000777)/0.777000777.

See also