Skip to main content

What HUP is

HUP is FERAL’s equivalent — for heterogeneous hardware — of what the USB HID class spec was for input devices: a stable, versioned, vendor-neutral protocol that lets any vendor plug hardware into any FERAL brain without proprietary glue. Current version: HUP v1.4.0 (stable, Apache-2.0 licensed) Full normative spec: feral-nodes/HUP_SPEC.md

How a daemon connects

  1. Daemon opens a WebSocket to wss://<brain>:<port>/v1/node.
  2. Sends a node_register frame with its node_id, capabilities, sensors, actuators, firmware version.
  3. Brain replies with node_ack — session token, expected heartbeat interval, granted capabilities, denied capabilities.
  4. From that point the daemon can send device_event frames (sensor readings, button presses, camera frames) and respond to hup_action_request frames the Brain sends to trigger actuators (buzz, LED, motor, etc.).

Message types (abbreviated)

Every frame is a JSON object with a type key. Schemas are Pydantic (Python SDK) and Zod (TypeScript SDK) — both enforce the same contract.

Writing a daemon

Two SDKs are published and maintained by FERAL:

Python SDK

pip install feral-node-sdk. Async FeralNode class with auto-reconnect, mDNS discovery, and 6-digit pairing.

TypeScript SDK

npm install @feral-ai/node-sdk. Same surface as the Python SDK for Node.js 20+.
Minimal Python example:

Cookiecutter template

Ship a new daemon in under an hour:
You get a runnable skeleton with manifest.json, mock hardware, two placeholder @on_action handlers, and one placeholder event stream. Replace the mocks with your real integration and feral publish --daemon . when ready.

Publishing to the registry

Once your daemon is stable:
The bundle lands in registry.feral.sh under kind=daemon. Any FERAL user can install it with:

Pairing + security

  • First-time pairing uses a 6-digit code the daemon prints to its own log. The user types that code into Settings → Devices → Pair. The Brain returns an API key the daemon saves locally.
  • Steady-state: daemon sends Authorization: Bearer <key> in the WebSocket upgrade.
  • Per-capability gating: the user approves each capability (camera, audio, actuator) in Settings. The Brain only sends hup_action_request frames for capabilities the user has granted.

Compliance

  • Licensed Apache-2.0 — any vendor may implement, fork, or extend.
  • No certification program — vendors self-declare conformance by passing the schemas in feral-node-sdk / @feral-ai/node-sdk.
  • Bug reports + protocol additions go through github.com/FERAL-AI/FERAL-AI/issues.

Full spec

For the complete normative specification — all frame schemas, error codes, example wire traces, pairing flow details, and reserved fields — read the canonical document: feral-nodes/HUP_SPEC.md.

Brain-side self-description (feral-core)

The wire protocol above covers daemon ↔ brain transport. On the brain, HUP is also a generic hardware hub for any device that self-describes:
  1. Wire format — devices return an actions[] envelope documented as HUP_ACTION_SCHEMA in feral-core/hardware/protocol.py. Converters device_capability_from_action() and device_manifest_from_capabilities() map it to DeviceManifest / DeviceCapability (including optional action_type and verify honesty contracts).
  2. Transport adaptersGenericSelfDescribingAdapter passthrough-executes any self-describing companion library; BridgedPeripheralAdapter routes actions to phone-bridged BLE peripherals via mesh.invoke; mesh nodes use WebSocketNodeAdapter.
  3. Registrationstate.register_generic_hardware_skill_for() runs on every ingress (brain-local discovery, mesh on_node_connected with node-supplied device_manifest, peripheral_bridge_register). It registers GenericHardwareSkill, which auto-generates LLM tools (hwdev_<device>__<capability>), enforces safety tiers and rate_limit_per_minute, and runs the closed-loop honesty loop when verify is declared.
  4. Discovery — brain-local USB devices are listed in DEVICE_DISCOVERY_SPECS (hardware/discovery.py); override CuteBot path with FERAL_CUTEBOT_PATH.
  5. Fleet APIGET /api/hardware/fleet returns manifests, derived safety tiers, last verification state, mesh nodes, and announced devices for companion-app rendering.
  6. Kill switchFERAL_GENERIC_HARDWARE_SKILLS (default "1") enables the generic path; "0" falls back to hand-written skill manifests only.
See also: Hardware Mesh Protocol and HARDWARE_ECOSYSTEM.md.