harnsy

harnsy MaxSince 0.9.0

Your main machine can sit behind NAT. Nobody opens a port.

Available since harnsy 0.9.0; the hosted relay is in beta.

A laptop, a home computer or a server behind NAT can be the main machine of your cluster. The main machine and each member that joins through the relay connect out to it, and the relay only passes bytes between them. A member behind NAT needs no relay: it joins a reachable main machine directly.

TLS between your machines

Masterkestrelbill-officeno open port
connects out
Relaycopies bytes · sees who, when, how much
connects out
Memberhome-laptopno open port
A machine behind NAT joins the cluster through a relay. Sample data.

Both sides connect out.

The main machine and the member each open a connection to the relay. No port is forwarded, and neither machine needs a public address.

The relay only copies bytes.

It joins the member’s stream to the one the main machine opens for it, and from then on copies bytes in both directions. It does not read, parse or store them.

TLS runs between your machines.

Inside the stream the cluster uses its own TLS, end to end. The member checks the main machine’s certificate against a pin in its join token, so the relay cannot pose as the main machine. A join through a relay without the pin is refused.

What the relay sees, exactly.

Who (a hash of the main machine’s relay id; on our hosted relay also a hash of the license id), when, and how much traffic. It can cut a connection; it cannot read or change what is inside. Its log keeps one line per stream: hashed ids, the client address cut to its network (/24 for IPv4, /48 for IPv6), bytes in and out, how long it lasted and why it ended. No names, no messages, no tokens.

The short version.

On the main machine: make it the master, turn the relay on, restart harnsy and issue a join line. On the other machine: paste the line. Every step, with what you see, is in the guide.

Direct and relay members at once.

One main machine can have members on its own network and members through the relay at the same time.

Hosted by us (beta).

harnsy Max

Our hosted relay is in beta and comes with harnsy Max: the main machine gets a ticket, a daily permit to use it, from the license service. A relay of your own, with its own key, is planned; it is not available yet.

When to use the relay

  • Your main machine is at home

    It is a laptop or Mac behind a home router, with no public address. Your servers and other machines join it through the relay, you open no port, and members keep the same address when the laptop moves to another network.

    The relay sees: which machine (as a hash), when and how much. Not messages, tokens or keys.

    Steps for this case →

  • A colleague joins with their own login

    Their machine joins your main machine through the relay, with its own Claude, Codex or OpenCode login. The login stays on their machine, and they use their own harnsy Max key or borrow a seat from your main machine.

    The main machine sees: agent names, harness, status, folder and messages. Not logins or keys.

    Steps for this case →

  • A server with no public address

    If the server itself is the main machine and others cannot reach it, members join through the relay. Nobody forwards a port or sets up a VPN.

    A server that is only a member needs no relay: it joins a reachable main machine directly.

    Steps for this case →

  • Some members are on your network, some are not

    One main machine serves both: members on your network join directly, the others through the relay.

    Each member’s row in Nodes says its route: “via relay …” or “direct, port 7789”.

    Steps for this case →

Step by step: a cluster through the relay

Pick your case. Each one gives the steps, what you see after them and how to undo them. Where the dashboard has a button, it comes first; the terminal line is the alternative. The relay is for a main machine that other machines cannot reach, for example one at home behind NAT. A member behind NAT needs no relay.

My home machine is the main one

The main machine is a laptop or Mac at home, or any machine with no public address. Your server and other machines join it through the relay.

  1. Make it the main machine.

    On the machine that will be the main one, run this once in a terminal; the dashboard has no button for it. home is a name you choose. Do it first: the relay command below works only on a main machine.

    harnsy debug cluster init home --master
  2. Turn the relay on.

    The machine needs a harnsy Max key (License page). The command uses our hosted relay, which is in beta.

    harnsy debug cluster relay on
  3. Restart harnsy on this machine.

    A running main machine reads the relay setting only at start. Restart harnsy to apply it. Linux: systemctl --user restart harnsy.service. macOS: launchctl kickstart -k gui/$(id -u)/com.github.butschster.harnsy. Windows: schtasks /End /TN harnsy, then schtasks /Run /TN harnsy.

  4. Issue a join line for the other machine.

    In the dashboard open Nodes and choose “Add to the cluster”. Pick “Node”, name the machine (for example server), set its permissions and leave “Master address” empty, so the line carries the relay address. Press “Issue token”. “manage” is access to the main machine’s shell: give it only to a machine you own.

    harnsy debug cluster issue server

    You see “Shown once. Copy it now.” and “Run this on server.”, with the line harnsy debug cluster init server --join harnsy-relay://… --token <token> below them.

  5. Check that the relay is connected.

    Open Nodes on the main machine. The relay panel says “waiting” until a join token exists and the license allows other machines. In a terminal, the command prints the relay and the address members join at.

    harnsy debug cluster relay

    You see “connected since …”, an “address for members” (harnsy-relay://…) and “relay access: renews automatically”.

  6. Join, on the other machine.

    In the dashboard of the other machine open Nodes, choose “Join a master”, paste the line and press “Join”. Or run the line in a terminal. Paste the whole line: a join through the relay without the pin is refused.

    harnsy debug cluster init server --join harnsy-relay://… --token <token>

    You see “Joined … connecting…”. On the main machine the member appears in the Nodes list, and its row says “route: via relay …”.

To undo To take a member out, revoke it (case 5). To stop using the relay, run harnsy debug cluster relay off and restart harnsy; members then need a direct address again.

↑ Cases

A colleague’s machine with their own login

A colleague joins your main machine with their own Claude, Codex or OpenCode login. The login stays on their machine.

  1. Have the main machine ready.

    Set it up as in case 1, or use a main machine whose address your colleague can reach.

  2. Decide whose harnsy Max the colleague uses.

    A machine with its own harnsy Max key takes no seat. A machine without one borrows harnsy Max from the main machine while a seat is free. The number of seats comes from your key.

    You see In License, the panel “Seats for connected machines”: “Taken: 1 of 3.”

  3. Issue a token for the colleague.

    In the dashboard: Nodes → “Add to the cluster”, “Node”, their machine’s name, the permissions, “Issue token”. Give them only what they need: read and send. “manage” is access to your shell.

    harnsy debug cluster issue anna-laptop --scope read,send

    You see The token appears once: “Shown once. Copy it now.”

  4. Send them the line, privately.

    The line holds a secret: the token. It also carries the main machine’s pin, so their machine checks that it is talking to yours.

  5. The colleague joins.

    On their machine: Nodes → “Join a master”, paste the line, “Join”. Or run the line in a terminal.

    harnsy debug cluster init anna-laptop --join https://<main machine address>:7789 --token <token>

    You see “Connected.” If the machine has no key of its own and the main machine has no free seat: “Connected. The master has not lent harnsy Max yet: its license may have no free seat.”

  6. Check.

    On the main machine the colleague’s machine is in the Nodes list. If it borrowed a seat, License shows it as taken. The main machine sees their agent names, harness, status and folder; their login stays on their machine.

To undo Revoke their token (case 5). The seat frees at once; their machine keeps harnsy Max for up to 3 days, until its last grant runs out.

↑ Cases

A server with no public address

What to do depends on the server’s role.

  1. The server is a member: join it directly.

    A member always dials out and opens no port, so a server behind NAT or a firewall joins a reachable main machine directly. Issue a token and join as in case 2.

  2. The server is the main machine: use the relay.

    If the server itself is the main machine and others cannot reach it, set it up as in case 1. Members join it through the relay address, with no open port.

To undo As in case 1 or case 5.

↑ Cases

Direct and relay members on one main machine

Some members are on your network, others are not. One main machine serves both at once.

  1. Set up the relay as in case 1.

    Steps 1 and 2 of case 1; the restart comes next.

  2. Open the cluster port for the direct members.

    Only machines on your network need this: a main machine with only relay members needs no open port. Run the installer again with the cluster address. It rewrites the service and restarts harnsy, which is also the restart the relay setting needs. 0.0.0.0 means every address of this machine; to open the port only on your own network, give the machine’s address there, for example 192.168.1.10:7789. The port serves TLS by itself.

    harnsy install --cluster-addr 0.0.0.0:7789
  3. Issue a token for a relay member.

    Leave “Master address” empty: the line carries the relay address.

    harnsy debug cluster issue far-laptop
  4. Issue a token for a direct member.

    Put the main machine’s address on your network in “Master address”.

    harnsy debug cluster issue office-pc --url https://<main machine address>:7789
  5. Join each machine with its own line.

    As in case 1, step 6, each on its own machine.

    You see Each row in Nodes says its route: “via relay …” or “direct, port 7789”.

To undo Revoke a member (case 5).

↑ Cases

Take a member out

A machine should no longer be in the cluster, or its token may have leaked.

  1. Find its token.

    On the main machine: Nodes → “revoke” next to the member’s token, and you are done. In a terminal, list the tokens first.

    harnsy debug cluster tokens
  2. In a terminal, revoke it by number.

    Take the number from the list.

    harnsy debug cluster revoke <id>

    You see The member’s connection closes at once if you revoke in the dashboard, and within 20 seconds from a terminal. Anything queued for it is dropped. Its seat frees at that moment: License shows one less taken. A member that borrowed harnsy Max keeps it until its last grant runs out, up to 3 days.

To undo To join again, issue a new token on the main machine; on the member choose “Re-join” on the Nodes tab, or run the printed harnsy debug cluster init … --join … --token … --force.

↑ Cases

A key turns it on.

Add a harnsy Max key on the License page to turn it on.

Apply for a key →

What's in harnsy, and what's in harnsy Max? →

Limits, honestly

  • While the main machine is offline, members keep working locally and keep their messages until it is back.
  • The relay is not blind to everything: it knows who, when and how much, and keeps that in its log. It can cut a connection; it cannot read or change what is inside.
  • The hosted relay (beta) needs a harnsy Max key. A relay of your own is planned.

Your first team is one prompt away.

Installing takes one sentence to your agent. To open agents for you, harnsy drives a terminal: tmux on Linux and macOS, its own terminal host on Windows.

Install harnsy following https://harnsy.dev/llms.txt
site-3flead · Claude Codeliveview only
❯ Plan #42 with the team.

Waiting for the breakdown from analyst-7a…

from analyst-7a through harnsy❯ #42 broken down: three acceptance criteria, including a retry after 24 h.

I’ll hand #42 to site-9a.

❯