How nfltr Works
Draft
This page is a draft for review.
nfltr runs Claude Code agents on machines you own and lets one Claude session, the hub, coordinate them. The machines meet on a relay: the hosted one at nfltr.xyz, or your own relay (beta). This page explains the parts, the flow of one goal, what each machine controls, what the relay can and cannot see, which reliability guarantees hold and how they are tested, and the limits today.
The parts
- The hub. A Claude session that owns the goal: your own Claude Code session with the hub tools added (
claude mcp add nfltr -- nfltr mcp --toolset hub). It decides which agents to start, where, with which model, and what to do with their results. - The relay. Carries messages between the hub, nodes and agents; it keeps no view of your runs. It runs no model and makes no decisions. It is nfltr.xyz, or a relay you run with
nfltr relay serve(beta). - Nodes. Machines you join once with
nfltr node join: a laptop, a build server, a GPU box. A node connects out to the relay, so it needs no open port, and starts agents only when the hub asks. - Agents. Claude Code processes a node starts for one piece of work. Each gets its own directory, clones the repository it needs, works, pushes its branch and reports back.
The flow of one goal
- Join. Each machine joins once:
nfltr node join --max-agents 4, with the repositories and tools you allow (Nodes guide). - The hub sees the machines. When you give the hub a goal, it lists your nodes with their facts: free agent slots, CPU cores, load and memory, the repositories each allows, and the description and resources you gave the machine.
nfltr orch nodes listshows you the same list. - The hub spawns agents where the data and tools are. It chooses how many agents, on which machine, with which model and which instructions. A node starts an agent process only then.
- Agents work. An agent clones through its node's local mirror of the repository (refreshed from your git host before it serves, so it never sees stale branches), works in its own directory, and pushes its branch to your git host itself.
- Results come back. Each agent's answer, branch and commit reach the hub as a completion, once.
- The hub decides what is next: continue an agent with a follow-up, start more, stop one, check the work, or finish and answer you.
Provide, don't decide. nfltr provides the machines, their facts, the messages and the results. It never decides for the hub: it does not pick a machine, a model or an effort when the hub leaves one out, it does not retry a failed agent, and it does not merge or land code. Those choices belong to the hub, which is Claude, and through it to you.
What each machine controls
A node offers only what its owner turns on when it joins. The hub cannot widen it.
| Control | How |
|---|---|
| How many agents | --max-agents (required): the most agent processes it runs at once. |
| Tool permissions | Restricted by default: agents only edit files. --allow-all-tools lets them run commands (shell, tests, pushes) without approval. |
| Tool rules | --tool-policy-file: deny rules checked before every tool call (for example, no force push). |
| Approvals signed by the owner | A rule marked "unless approved" is lifted only by a grant you sign on your own device, bound to this node and one prompt, and expiring. The node holds only your public key (--approval-public-key, from nfltr orch hub approval-key). |
| Repositories | --allow-repo patterns (with --allow-all-tools): only these get a mirror and git credentials that answer for them alone. A spawn naming another repository goes elsewhere. |
| Which hubs it serves | --serve-hubs: agents only for the listed hub ids. It narrows which of your hubs use the machine; it is not a security boundary between machines of one account. |
| A clean Claude config | By default agents run without your Claude Code settings, hooks, memory, plugins or MCP servers, and isolated from your other Claude sessions. --inherit-host-claude-config opts in. |
| Git identity | The node passes on the commit identity you configured in git. If you configured none, it sets none; it never invents one. |
| Your account key | Agents never get the node's account key unless you pass --agent-relay-access. |
What the relay can and cannot see
Always visible to the relay: your account, machine names, labels and capabilities, which machine connects to which and when, and the size and timing of traffic. Never sent to it: your git credentials and Claude tokens (they stay on your machines) and your approval signing key. It stores your API keys only as hashes.
| Feature | What the relay sees |
|---|---|
| Hub runs (agents, turns, results) | Nothing: the hub sends the relay no summary or status of its runs and refuses the relay's own requests for them, so the dashboard shows none. They stay on the hub's machine (nfltr orch hub runs, nfltr orch hub show); the relay sees only whether the hub is online. |
| Hub ↔ agent messages (assignments, prompts, results) | Encrypted end to end between the hub, nodes and agents by default. With the same pairing key on every machine (--e2ee-key-file), a relay that swaps keys is refused. |
| Answers from your phone (remote messages) | Encrypted end to end between your paired device and the hub; the relay stores and forwards ciphertext. Approvals also need your passkey. |
nfltr p2p files, chat and calls | Encrypted end to end on every path, including when the data falls back through the relay or a TURN server. The relay sees the two machines, the kind of session, direct-connection addresses, and sizes and timing; not file names, contents, chat or call setup. Both machines print a session fingerprint: if they match, nothing in between swapped the keys. With a pairing key, a swapped session is refused. |
nfltr wg (private LAN) | WireGuard is end to end between the client and the exit; the relay forwards sealed packets. Against a relay that substitutes keys it holds only with a pairing key (--e2ee-key-file). |
nfltr http (tunnels and their share links) | Encrypted end to end by default: TLS ends on your machine. Readable at the relay only in inspectable mode (--mode inspectable), which features that read requests at the relay need, such as routes. |
nfltr tcp (raw TCP tunnels) | Readable at the relay, unless the protocol inside is encrypted (SSH is). |
Reliability guarantees and how they are tested
Each guarantee below is checked automatically. The checks run against real relays, nodes and hub processes; most use a scripted stand-in for Claude Code so they can run often at no model cost.
| Guarantee | How it is tested |
|---|---|
| If the hub process dies or your terminal closes, starting it again with the same hub id delivers every result it missed, exactly once. | Fault injection: soak runs and a Kubernetes chaos lab kill the hub mid-run and reattach it. A production canary checks exactly-once delivery against nfltr.xyz. |
| A turn the hub sent runs once and has at most one accepted result. A send that could not be confirmed is never sent again; the hub asks the machine instead. | Linearizability checks of the task stores under concurrent owners, crashes and lease expiry; an audit of every recorded event history after each soak and chaos run. |
| A relay restart or deploy does not end running agents. Everyone reconnects; agents keep working and deliver their results when the relay is back. | Fault injection: soaks and the chaos lab stop and kill the relay at random points of a turn. |
| Stopping a node gracefully (Ctrl-C or SIGTERM) reports its running agents as lost to the hub right away. A killed node is reported within about half a minute. | Fault injection soaks that stop, kill, freeze and rejoin nodes; every turn must end within a bound. |
| Continuing a finished agent keeps its work: it restarts on the same machine with its directory, uncommitted files included, until the hub archives it. A node restart clears those directories, so only pushed work survives that. | End-to-end tests of continuations on the same and on another process. |
| An agent process that is leaving never takes a new turn and never loses one: the turn is refused before it starts and the hub places it elsewhere. | A test against a real relay of a dispatch racing the exit, and a load test that fails on any lost turn. |
| Every turn ends: completed, failed, cancelled, or reported lost. | Long soaks with random faults; the history audit checks a liveness bound. |
Where it runs
- Hosted (nfltr.xyz). We run the relay. Your machines connect out to it. What leaves your network: the messages above to nfltr.xyz (status only by default, the rest encrypted end to end where the table says so), your agents' git traffic to your git host, and Claude Code's calls to its model provider from the machines that run it.
- Your own relay (beta).
nfltr relay serveon a machine of yours, with your TLS certificate or a pinned self-signed one, andnfltr config set-relayon each machine. Nothing in nfltr calls out on its own: only your relay, your git host, the model provider and any STUN or TURN server you configure are contacted.nfltr updatereaches nfltr's download server only when you run it. Claude Code's own non-essential traffic stops withCLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1on those machines. Share links work on a domain of yours with a wildcard certificate; no dashboard, WireGuard tunnels or failover in the beta (tutorial).
Limits today
- Claude Code only. The hub is a Claude session and agents run Claude Code.
- One relay host. nfltr.xyz runs on a single relay host, without high availability: a deploy or restart interrupts connections for up to a minute or two, and running agents ride through it. Your own relay is also one process.
- Beta pieces. Your own relay is a beta, with one account per API key, share links only on a domain of yours, and no dashboard or private LAN.
Next
- Getting Started: sign up, join a machine, give the hub a goal.
- Join Machines as Nodes: every node flag.
- Use nfltr from Claude Code: the hub inside your own session.
- Run Your Own Relay (Beta): step by step.
- How distributed Claude Code is built with nfltr: the architecture, in a blog post.