Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.bricks.tools/llms.txt

Use this file to discover all available pages before exploring further.

Foundation launchers don’t need a hardcoded server URL. Each Buttress server announces itself on the LAN, and bound launchers pick the strongest matching server for each generator type.

How it works

Every Buttress server runs a UDP transport on port 8089:
  • ANNOUNCE — broadcast every 5 seconds with the server’s serverInfo (capabilities, generators, auth status).
  • QUERY — a launcher can broadcast a query and the server unicasts a RESPONSE back. Response delays are randomized to avoid storms when many servers reply at once.
The transport binds a receive socket on 0.0.0.0:8089 for incoming queries, and one send socket per local broadcast interface so each subnet broadcast leaves on the right NIC.

Announcement payload

serverInfo includes a generators[] array with per-backend hardware capabilities computed once at startup:
{
  "id": "buttress-mac-studio",
  "name": "Studio LLM",
  "version": "2.25.0-beta.9",
  "authentication": {
    "required": true,
    "type": "workspace-jwt",
    "kid": "<key id>",
    "bound": true
  },
  "generators": [
    { "type": "ggml-llm", "score": 57, "hasGpu": true, "usableBytes": 21474836480 },
    { "type": "ggml-stt", "score": 57, "hasGpu": true, "usableBytes": 21474836480 }
  ]
}
Foundation launchers filter announcements by generator type (LLM vs STT vs MLX) and prefer the highest-scoring server that runs the requested backend.

Capability score

The score is a 0-100 number combining:
ComponentMax pointsSource
GPU presence40hasGpu
Backend variant20CUDA = 20, Metal = 15, Vulkan = 10, CPU = 5
GPU memory20Scaled against a 12 GB reference
CPU memory10Scaled against a 32 GB reference
Server availability10ok health flag
A laptop with no GPU scores around 15-25; a workstation with an RTX 4090 lands near 80-90.

Trust model

Bound servers and unbound servers both announce, but launchers treat them differently:
  • Unbound servers (authentication.required = false) appear as untrusted endpoints. They are still usable from manual / public clients, but bound launchers ignore them.
  • Bound servers (authentication.required = true) are trusted only when their serverId is in the workspace’s bound-server list and the announcement is signed by the matching per-server announce key the workspace registered at bind time.

Signed announcements

Each Buttress server has its own Ed25519 announce keypair, generated by bricks buttress bind. The public half is registered with the BRICKS cloud and surfaced to launchers via myWorkspaceButtress.buttressServers[].serverPublicKey; the private half stays in ~/.bricks-cli/buttress/state.json on the server host. Every UDP ANNOUNCE and RESPONSE from a bound server carries a signature over { t, d, ts }. Launchers verify the signature against the registered key with a 30-second replay window — packets without a valid signature never enter the endpoint pool. This closes the spoof vector where a LAN peer could re-announce a bound serverId and try to receive a workspace bearer token. The wire protocol version bumped to 2.0 for signed traffic. Launchers and servers running protocol 1.0 silently drop 2.0 packets and vice versa, so old/new combinations co-exist by going dark rather than swapping unsigned trust. To upgrade an existing bound server, re-run bricks buttress bind (which mints a new announce keypair) and restart bricks-buttress.

Manual override

When auto-discovery is impractical (devices on a different subnet, or a cloud-hosted Buttress server), each LLM/STT brick in BRICKS Controller’s Config Editor lets you switch from Auto to Manual and type the WebSocket URL directly. See Use Buttress from Foundation.

HTTP fallback

A launcher can also query a known IP directly over HTTP:
curl http://<server-host>:2080/buttress/info
The endpoint returns the same serverInfo payload as the UDP ANNOUNCE. Foundation launchers use this path internally when UDP broadcast is blocked (some enterprise Wi-Fi networks).

Troubleshooting

SymptomLikely causeFix
Devices never find the serverUDP broadcast blocked by switch or APSwitch to a wired network, allow udp/8089 broadcast, or use a manual URL
iOS device finds the server only over Cellular, not Wi-FiiOS IP_BOUND_IF quirk on the broadcast socketAlready handled — the launcher rebinds active queries to the Wi-Fi IP automatically
Server announces but devices ignore itThe server is unbound, or bound to a different workspaceRun bricks buttress status and re-bind if needed
serverInfo.generators[] is emptyNo generators in the TOML config or all failed to loadCheck the server log for download or hardware probe errors

Next steps

Workspace binding

How a server’s kid and bound-server list are issued.

Use from Foundation

Per-brick connection settings: Auto vs Manual, strategy, fallback.