Run Your Own Relay (Beta)

Beta. By default your nodes and hubs meet on nfltr.xyz. You can instead run the relay on a VM or machine of your own and join your machines to it, so the path between them stays on your network. It is the same nfltr binary: nfltr relay serve. You bring the TLS certificate; the relay creates its API key. This tutorial goes from an empty Linux VM to a goal run by agents on your nodes. Everything else on this site describes nfltr.xyz.


nfltr.xyz or your own relay

The relay carries messages between hubs, nodes and agents. It runs no model: the hub is Claude, on the machine where you start it, and agents run on your nodes. Nodes and hubs connect out to the relay, so only the relay needs an open port.

nfltr.xyzYour own relay (beta)
Who runs itWe do: updates, certificates, uptime.You do: a VM, its firewall, its certificate, upgrades and backups.
Where traffic goesThrough nfltr.xyz.Through your relay. Your machines need to reach it; nothing else does.
Accounts and keysYour account, with a key per machine if you want.One account and one API key per relay, shared by your machines.
DashboardYes, with Google sign-in.No. Everything below works from the CLI.
Share links, SSH and TCP tunnels, private LANYes.Not in the beta (see below).
AvailabilityOur service.One process on one machine: no failover. Nodes reconnect by themselves after a restart.
SoftwareThe same closed-source nfltr binary.

Use your own relay when the requirement is that orchestration traffic between your machines does not leave your network, and the features in the next table are the ones you need. If you need share links, SSH or the dashboard, use nfltr.xyz.

What works on your own relay

Checked on 2026-10-03 with four Linux containers on one Docker network, each standing in for a machine: a relay with a self-signed certificate (pinned by the others), a node, a hub machine, and a second relay with a certificate from a private CA (no pin). Every command below ran with no relay flags, only the saved set-relay step.

UseResultWhat was checked
nfltr node join and nfltr orch "<goal>"WorksThe hub spawned an agent on the node; the agent completed with its result.
The hub in your own Claude Code (claude mcp add nfltr -- nfltr mcp --toolset hub)WorksThe server Claude Code starts lists the node, spawns an agent there and returns its completion. (A script played Claude Code.)
nfltr orch nodes list, orch doctor, orch task list, nfltr statusWorksEach answers from your relay.
nfltr a2a send / listen, nfltr notify send / listenWorksThe message and the notification arrived on the other machine.
nfltr p2p send / recv / callWorks; across NATs with your STUN and TURNOn one network: a direct connection. Across NATs (a separate lab with cone and symmetric NATs, section 9): direct when both sides name your STUN server, through your TURN server between symmetric NATs, otherwise files go through your relay. Every path is end-to-end encrypted: your relay and TURN server carry only ciphertext.
A certificate from your CAWorksset-relay without a pin; messages across it.
nfltr http, nfltr share, tail, watchNot supportedThe relay refuses share links: shares need http.share_domain.
nfltr tcp, nfltr shell, SSH behind NATNot supportedThe relay refuses: tcp tunneling is not enabled on this server.
nfltr wg (private LAN)Not supportedRefused: the relay does not run end-to-end WireGuard.

1. Prepare a Linux VM

Any small Linux VM or machine that your other machines can reach, amd64 or arm64. Install the CLI as on any machine (Getting Started, step 2), copy it where every user can run it, and give the relay its own user and data directory:

$ curl -fsSL https://nfltr.xyz/install.sh | sh
$ sudo install -m 755 ~/.local/bin/nfltr /usr/local/bin/nfltr
$ sudo useradd --system --create-home --home-dir /var/lib/nfltr-relay nfltr-relay
$ sudo chmod 700 /var/lib/nfltr-relay

The relay listens on two TCP ports: 8443 (gRPC: nodes, hubs, agents) and 8444 (HTTPS: task API, artifacts). Open them to your machines only, for example with ufw:

$ sudo ufw allow from 10.0.0.0/8 to any port 8443,8444 proto tcp

Nothing else needs to be reachable: the admin API, health and metrics listen on 127.0.0.1 (on ports the relay picks and writes to <data-dir>/ports.json). --grpc-port and --http-port change the two public ports; --listen binds one address instead of all.

2. Choose the TLS certificate

The relay does not listen on the network without TLS. Pick one:

3. Start the relay

Start it once in the foreground as the relay user to create the key and see the banner. With your certificate:

$ sudo -u nfltr-relay nfltr relay serve --data-dir /var/lib/nfltr-relay \
    --tls-cert /etc/nfltr-relay/fullchain.pem --tls-key /etc/nfltr-relay/privkey.pem

Or self-signed:

$ sudo -u nfltr-relay nfltr relay serve --data-dir /var/lib/nfltr-relay --tls-self-signed --tls-name relay.lan,192.168.1.10
nfltr relay (beta): gRPC 0.0.0.0:8443, HTTPS 0.0.0.0:8444, data /var/lib/nfltr-relay
API key: /var/lib/nfltr-relay/admin-api-key (created now; copy it to your machines, it is not printed)
TLS certificate SHA-256: 3f1c…9a07
On each machine: nfltr config set-relay relay.lan:8443 --proxy-url https://relay.lan:8444 --cert-sha256 3f1c…9a07 - < admin-api-key

Secure defaults, with no flags to turn them off: every client needs the API key; without TLS the relay refuses any address but loopback (--listen 127.0.0.1, for a TLS proxy of your own in front); a data directory other users can read is refused. Stop it with Ctrl+C and run it as a service:

# /etc/systemd/system/nfltr-relay.service
[Unit]
Description=nfltr relay (beta)
After=network-online.target

[Service]
User=nfltr-relay
ExecStart=/usr/local/bin/nfltr relay serve --data-dir /var/lib/nfltr-relay --tls-cert /etc/nfltr-relay/fullchain.pem --tls-key /etc/nfltr-relay/privkey.pem
Restart=on-failure

[Install]
WantedBy=multi-user.target
$ sudo systemctl enable --now nfltr-relay
$ journalctl -u nfltr-relay | grep 'TLS certificate SHA-256'

For the self-signed form, use the --tls-self-signed --tls-name … flags in ExecStart instead of the certificate files. Ports below 1024 need extra capabilities; keep the defaults.

4. The API key file

The first start wrote the account key to /var/lib/nfltr-relay/admin-api-key (mode 0600) and only its SHA-256 to api-keys. It is never printed, logged or put on a command line. Copy the file to each machine that joins (scp, your secrets manager) and keep it out of shell history and chat. Every machine uses this one key: the beta has one account per relay.

5. Point each machine at the relay

On every node and on the machine where you run the hub, one step saves the relay, the pin (self-signed only) and the key, which - reads from stdin:

$ nfltr config set-relay relay.lan:8443 --proxy-url https://relay.lan:8444 \
    --cert-sha256 3f1c…9a07 - < admin-api-key
Relay relay.lan:8443 saved (/home/you/.config/nfltr/nfltr.json)
$ rm admin-api-key
$ nfltr status

Leave out --cert-sha256 for a certificate your machines trust. From now on every nfltr command on that machine uses your relay, unless NFLTR_SERVER or NFLTR_PROXY_URL in the environment names another one. NFLTR_RELAY_CERT_SHA256 overrides the saved pin. nfltr config set-relay --reset goes back to nfltr.xyz (saved keys stay).

6. Join nodes

On each machine that should run agents, with Claude Code installed and its credentials in the environment, exactly as on nfltr.xyz (Join machines as nodes):

$ export CLAUDE_CODE_OAUTH_TOKEN=…   # from `claude setup-token`, or ANTHROPIC_API_KEY
$ nfltr node join --max-agents 2 --allow-all-tools

Then, from any machine pointed at the relay:

$ nfltr orch nodes list
$ nfltr orch doctor

orch doctor names where the relay came from, e.g. configured: relay.lan:8443 (from saved config /home/you/.config/nfltr/nfltr.json).

7. Run a goal

$ nfltr orch "fix the flaky parser test and push a branch"

The hub runs on this machine and spawns agents on your nodes through your relay. Watching, steering and stopping work as described in Orchestrate a task. To see what your relay holds about the agents:

$ nfltr orch task list --include-completed

8. From your own Claude Code

The same two commands as on nfltr.xyz (Use nfltr from Claude Code). The server Claude Code starts reads the saved relay, pin and key; nothing goes in the MCP config:

$ cd ~/src/my-project
$ claude mcp add nfltr -- nfltr mcp --toolset hub
$ nfltr orch hub install-hook --prefer-agents
$ claude

9. Messages and files between your machines

These work across your relay as in Send files and messages. On the receiving machine:

$ nfltr a2a listen --name work-laptop
$ nfltr notify listen --name work-laptop-notes
$ nfltr p2p recv --name work-laptop-files --output ./inbox

From another machine:

$ nfltr a2a send work-laptop "deploy finished"
$ nfltr notify send work-laptop-notes "Build finished" --title CI
$ nfltr p2p send report.txt work-laptop-files

On one network, p2p connects directly. Between networks behind NAT, each side needs its public address from a STUN server, and with your own relay p2p asks none unless you name one. Run your own (for example coturn) and pass it on both sides:

$ nfltr p2p recv --name work-laptop-files --output ./inbox --stun stun.example.com:3478
$ nfltr p2p send report.txt work-laptop-files --stun stun.example.com:3478

Or set STUN_SERVER on each machine. Without a STUN server, or when no direct path exists, a file still arrives, through your relay. Machines behind symmetric NATs (common on mobile and corporate networks) have no direct path: a TURN server carries their files and calls instead of your relay, and a call between them needs one. Give it one of two ways:

Checked on 2026-10-03 in a lab with your relay (relay serve --tls-self-signed), coturn as the STUN and TURN server, and two LANs behind NAT routers, a 100 MB file and a call each:

MachinesSetupFileCall
One networknonedirect—
Behind two cone NATsno STUNthrough your relay—
Behind two cone NATs--stundirectdirect, video and audio both ways
Behind two symmetric NATs--stun, no TURNthrough your relay—
Behind two symmetric NATs--turn on both sidesthrough TURNthrough TURN, video and audio both ways
Behind two symmetric NATsTURN on the relaythrough TURNthrough TURN, video and audio both ways

A call with no path between the two machines keeps its text chat, and both pages say video failed.

What your relay stores

The hub sends the relay a status summary of its agents: state, machine, timing and token counts. Prompts, progress and results stay on the hub's machine (--dashboard-digest off on nfltr mcp or nfltr orch sends none). On your relay there is no dashboard; nfltr orch task list reads that summary. It is kept in memory and is gone after a relay restart. Tasks, artifacts and keys are on disk under the data directory.

What leaves your network

With your own relay, nfltr contacts nothing but your relay on its own: not nfltr.xyz, and no other service of ours or anyone else's. Checked on 2026-10-03 with the same containers as the table above, on a Docker network with no route out. Their only DNS server and gateway was a logger that recorded every name looked up and every connection attempt, while every row of that table ran:

What still goes out, and only because you set it up:

Restart, upgrade, back up

Not supported in the beta

Troubleshooting

The CLI printsCause and fix
relaytrust: certificate 623f…c7c9 is not the pinned relay certificate and does not verify: x509: certificate signed by unknown authorityThe saved pin (or NFLTR_RELAY_CERT_SHA256) is not the relay's certificate, e.g. after tls/ was recreated. Run set-relay again with the fingerprint from the relay's log.
tls: failed to verify certificate: x509: certificate signed by unknown authorityA self-signed relay and no pin on this machine: add --cert-sha256 to set-relay. With your own CA, install the CA in the machine's trust store.
--cert-sha256: certificate fingerprint "…": want the 64 hex digits of a SHA-256The fingerprint was cut or mistyped. Copy the whole line from the relay's log.
no API key for relay relay.lan:8443 or an account API key is requiredNo key saved on this machine: run set-relay with - < admin-api-key.
list nodes: HTTP 403: invalid API keyThe key is not this relay's, e.g. after a key rotation or an NFLTR_API_KEY left in the environment. Unset it, or run set-relay again with the current key file.
dial tcp 192.168.1.10:8443: connect: connection refusedThe relay is not running or the firewall blocks the port: check systemctl status nfltr-relay and the ufw rule.
refusing to listen on 0.0.0.0 without TLS: give --tls-cert and --tls-key, or --tls-self-signed (or --listen 127.0.0.1 behind your own TLS proxy)Started without a certificate. Add one of the TLS forms from step 2.
data dir /var/lib/nfltr-relay is open to other users (mode 755): chmod 700 /var/lib/nfltr-relayRun the chmod it names.

Related: Join machines as nodes · Use nfltr from Claude Code · Troubleshooting.