Verbs

agentproto rendezvous

agentproto rendezvous serve [--port <n>] [--host <ip>] [--path <p>]
                            [--park-timeout-ms <n>] [--idle-timeout-ms <n>]
                            [--max-message-bytes <n>]
                            [--rate-limit-max <n>] [--rate-limit-window-ms <n>]
                            [--debug]

Run your own rendezvous broker — the untrusted ciphertext splicer that pair routes through. The broker matches two WebSocket sockets sharing a one-time token and pipes their bytes verbatim; it never parses payloads and, because pairing traffic is end-to-end encrypted, it cannot read or forge anything. It learns only the token, the peers' IPs, message sizes, and timing. That token is a route: an opaque meeting-point name derived from the pairing secret that authenticates nothing. Proof of authorisation is a separate auth token sealed inside the encrypted hello, so a broker that logs every route still can't pair or reconnect as a client (see concepts/pairing.md).

Self-hosting is defence in depth (the crypto already protects you against a malicious broker) plus an escape hatch: no third party — not even the hosted default broker pair offer uses out of the box — need sit between your client and daemon. Set pairing.rendezvous to your own URL, or pairing.rendezvous: "" to require an explicit --rendezvous and never fall back to the hosted default.

This is a thin re-export of the standalone agentproto-rendezvous binary, so you don't need that bin on your PATH.

Serve

agentproto rendezvous serve --port 8788 --host 0.0.0.0
agentproto-rendezvous listening on ws://0.0.0.0:8788/v1
  clients dial:  ws://<this-host>:8788/v1?side=client&t=<token>
  daemons dial:  ws://<this-host>:8788/v1?side=daemon&t=<token>
  the broker only ever sees ciphertext — token, IPs, sizes, timing.

Point a daemon at it with pairing.rendezvous in config, or per-offer with agentproto pair offer --rendezvous ws://your-host:8788/v1. For anything beyond localhost, terminate TLS in front of it (wss://) with your usual reverse proxy.

Options

FlagDefaultMeaning
--port <n>, -p8788Port to bind.
--host <ip>, -H0.0.0.0Bind address.
--park-timeout-ms <n>120000How long a lone socket waits for its peer before it's recycled.
--idle-timeout-ms <n>900000Idle teardown after a splice (15 min).
--max-message-bytes <n>1048576Max WS message size (1 MiB).
--path <p>/v1Upgrade path the broker listens on.
--rate-limit-max <n>120Max upgrade attempts per IP per rate-limit window.
--rate-limit-window-ms <n>60000Rate-limit window length.
--debugoffPrint the effective config at startup.

Every flag also has a RENDEZVOUS_* environment-variable twin (RENDEZVOUS_PORT, RENDEZVOUS_HOST, RENDEZVOUS_PATH, RENDEZVOUS_PARK_TIMEOUT_MS, RENDEZVOUS_IDLE_TIMEOUT_MS, RENDEZVOUS_MAX_MESSAGE_BYTES, RENDEZVOUS_RATE_LIMIT_MAX, RENDEZVOUS_RATE_LIMIT_WINDOW_MS, RENDEZVOUS_DEBUG); CLI args take precedence over env vars.

The broker also rate-limits token attempts per IP, enforces single-use tokens (a token that has already spliced is dead), and compares tokens in constant time.

SIGINT / SIGTERM shut it down gracefully.

See also