@benkovy/doh-host
v0.1.17
Published
Host-side connector that bridges OpenClaw and DOH backend
Readme
@benkovy/doh-host
Host-side connector runtime for DOH.
Role in the system
This process runs next to an OpenClaw host and creates an outbound, persistent WebSocket connection to the DOH backend.
It is responsible for:
- host authentication handshake (
host.hello->backend.challenge->host.proof->backend.ready) - receiving downlink relay commands (
relay.send,relay.history.request) - publishing uplink events (
relay.event) - publishing history responses (
relay.history.response) - reconnect behavior when network drops
Why this exists separately from the plugin
Keeping the connector as a standalone package/process allows:
- cleaner deployment and observability
- independent versioning and rollout
- option to reuse connector logic in non-plugin host integrations
The OpenClaw plugin package (@benkovy/doh) can wrap or invoke this connector behavior.
Environment variables
DOH_BACKEND_WS_URL(example:wss://api.doh.example/ws/host)DOH_TENANT_IDDOH_HOST_IDDOH_KEY_IDDOH_KEY_SECRETDOH_RECONNECT_INITIAL_MS(optional)DOH_RECONNECT_MAX_MS(optional)DOH_RECONNECT_FACTOR(optional)DOH_RECONNECT_JITTER(optional)DOH_RECONNECT_MAX_ATTEMPTS(optional,0= unlimited)OPENCLAW_GATEWAY_HTTP_URL(optional, defaulthttp://127.0.0.1:18789)OPENCLAW_GATEWAY_TOKEN(optional bearer token for Gateway HTTP auth)OPENCLAW_AGENT_ID(optional, defaultmain)OPENCLAW_BIN(optional, defaultopenclaw)
Init workflow
CLI help:
doh-host --helpdoh-host supports self-serve bootstrap provisioning:
doh-host init --email [email protected]Or using token directly:
doh-host init --token <token-from-email>Machine-readable mode:
doh-host init --token <token-from-email> --no-start --json
doh-host status --jsonAfter init completes, credentials are written to:
~/.doh-host/config.env
init then starts runtime immediately.
To run with existing env vars/config only:
doh-host runTo inspect runtime/config state:
doh-host statusTo probe live backend auth handshake and gateway health:
doh-host status --probeTo clear local host config state and restart onboarding:
doh-host reset --yesMachine-readable reset output:
doh-host reset --yes --jsonPairing approval commands
When backend pairing enforcement is enabled, first-time user->host pairing must be approved from host side:
doh-host pairing pending
doh-host pairing approve --request-id <requestId>You can also approve/deny by short pairing code:
doh-host pairing approve --code <6-digit-code>
doh-host pairing deny --request-id <requestId>No command defaults to run mode.
LLM/Agent setup
Recommended agent-driven onboarding sequence:
- Run
doh-host init --email <user-email> - Prompt the user to paste the bootstrap token from their email
- Run
doh-host init --token <token> - Verify backend health reports at least one host connection
The runtime config file is written to ~/.doh-host/config.env.
OpenClaw bridge behavior
The connector now bridges relay envelopes through a persistent in-process OpenClaw Gateway WebSocket client:
relay.send-> Gateway RPC methodagent(expectFinal=true)relay.history.request-> local DOH SQLite history storerelay.conversations.request-> local DOH SQLite conversation index
History/conversation reads now avoid POST /tools/invoke and OpenClaw transcript parsing in the request hot path.
DOH history is persisted in a local SQLite store at:
~/.doh-host/history.sqlite
The store is written directly during relay.send processing (pending -> sent/failed + assistant reply), so mobile history remains stable even if OpenClaw session maintenance prunes transcript artifacts.
On success/failure, the connector publishes corresponding relay.event entries for observability.
Development
pnpm --filter @benkovy/doh-host devSecurity notes
- API key secrets are host-machine secrets, never client-facing
- handshake uses nonce/challenge HMAC and timestamp checks in current scaffold
- always use TLS (
wss://) in non-local environments
Runtime diagnostics
Connector logs are emitted as JSON lines and distinguish:
- transport events (
connector.open,connector.closed,connector.error) - auth events (
auth.challenge.received,auth.ready,auth.error) - reconnect behavior (
connector.reconnect_scheduled,connector.reconnect_exhausted)
Release smoke checklist
Before and after publishing @benkovy/doh-host, run this quick checklist:
doh-host status --probereports backend and gateway probes asok.- Backend health (
/health) reportshostConnections > 0whiledoh-host runis active. - Send a message from client and confirm assistant reply arrives (
relay.send.accepted). - Restart mobile app and verify history reloads without duplicated rows.
Next implementation steps
- Add reconnect resume with server-issued session token
- Add message idempotency tracking and ack/nack handling
- Add optional health endpoint wrapper for supervisor integrations
- Add dedicated Gateway transport health probing for startup diagnostics
