Use nfltr from Claude Code
Orchestrate agents on the machines joined to your hosted nfltr.xyz account from your own interactive Claude Code session: your session becomes the hub, with the same spawn, message, stop and wait tools that nfltr orch uses.
Prerequisites are the same as in Getting Started: a saved API key (or NFLTR_API_KEY) on this machine, and at least one machine joined as a node.
First: say that code work goes to agents
Your session keeps its own edit and shell tools, and the hub only tells it what the fleet has. Whether a change is made in the session or in an agent on one of your machines is your choice, so state it. Without it, a session usually works locally; claude -p cannot ask for approval, so its own edits are refused and it stops with "the edit tools were denied" instead of using an agent. Two ways to say it:
- Once per project: record your preference, and every session started in the project is told it, as yours:
This adds a SessionStart hook to$ nfltr orch hub install-hook --prefer-agents.claude/settings.local.json(this machine only) whose text Claude Code adds to each session: "Preference of the user of this project (they set it with nfltr orch hub install-hook --prefer-agents; --prefer-agents=false removes it): run code work, meaning edits, builds, tests and pushes, in agents on their machines through the nfltr hub tools (list_nodes, then spawn_agent), not with this session's own edit and shell tools." Remove it withnfltr orch hub install-hook --prefer-agents=false. - Per goal: one sentence in the request is enough: "have an agent on the build server do this".
The two commands
$ nfltr config add-api-key # once per machine
$ nfltr node join --max-agents 2 --allow-all-tools # on every machine that runs agents,
# with CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY set
Then, in your project:
$ cd ~/src/my-project
$ claude mcp add nfltr -- nfltr mcp --toolset hub
$ nfltr orch hub install-hook --prefer-agents # completions wake the session; code work goes to agents
$ claude
Ask for work in plain words ("fix these three issues in parallel on the laptop and the build server, one branch each"). The session reads its hub tools from the server's instructions, spawns agents on your nodes, and reports their results. Tool inputs and results are in the Hub tools reference.
Non-interactive, the same setup works with claude -p; allow the hub tools, since nobody is there to approve them:
$ claude -p "fix the flaky parser test and push a branch" --allowedTools mcp__nfltr
What the server resolves by itself
- Relay and key: from
NFLTR_SERVER/NFLTR_API_KEYin the environment, else the saved account (nfltr.xyz by default, or a relay of your own: Run your own relay (beta)). The key is never in argv or in the MCP config. If the relay rejects the key or does not answer, the server still connects but offers onlyserver_status, which returns the reason and the fix (API key rejected by relay (HTTP 403) … save a valid key with `nfltr config add-api-key`), so your session can tell you why nothing runs. - Hub id: one per project directory. Reopening the project reattaches its hub, and the session receives every completion it missed while closed; two projects never share one. The server tells a reattached session what the hub already holds (its agents, how many are unfinished, completions not yet received), so the session can pick them up with
list_agentsandwait_for_agentsinstead of starting the same work again. - A second session in the same project fails closed on the hub lock (naming the holder's pid). Give it its own id:
claude mcp add nfltr-review -- nfltr mcp --toolset hub --hub-id review. - Nothing else is defaulted. Add
--hub-agent-model <model>,--hub-max-tokens Nor--hub-max-usd X(needs a token cap) to thenfltr mcpcommand if you want them.
Permissions
Claude Code asks before each hub tool call. Allow them all with /permissions (add mcp__nfltr) or start with claude --allowedTools mcp__nfltr. /permissions writes "permissions": {"allow": ["mcp__nfltr"]} to your settings, and you can add that line yourself. In auto mode Claude Code asks a server-side classifier about each tool call it has no rule for; when that classifier gives no verdict (the status line shows "Classifier unavailable"), the hub's calls wait for you and nothing is spawned. With mcp__nfltr allowed, the calls run without asking it (seen with Claude Code 2.1.284). These permissions are for your session's calls to the hub; what agents may do on a machine is set by that node's flags: --allow-all-tools (commands; codex's full-access sandbox), --load-project-settings (the repository's .claude settings) and --agent-relay-access (the account key, which an agent needs to run a hub of its own). Without them, agents get none of these; see What agents can reach.
This session is yours: its nfltr mcp holds your key. The agents it spawns do not.
nfltr orch "<goal>" starts a session with only the hub tools and no key in its environment, so its work always runs in agents; add --hub-tools Read,Grep there if you want that session to read files itself.
Receiving completions
- Without the hook: the session calls
wait_for_agents, which blocks until a completion lands and returns it (exactly once, across restarts). - With the hook:
nfltr orch hub install-hookadds a Stop hook, a SessionEnd hook (which lists monitors still running when the session ends) and a UserPromptSubmit hook (a message you send while the hub waits inwait_for_agentsends that wait, so the hub reads it at once; without the hook it waits until an agent finishes or the wait times out) and a TeammateIdle hook (see With Claude Code agent teams) to.claude/settings.local.json(this machine only;--printshows them instead). After a turn that leaves agents running, it waits in the background and wakes the session withnfltr orch: agent completion(s) arrivedwhen one completes. If you named a--hub-idon the server, pass the same one toinstall-hook. - Claude Code's background task: when the session itself calls
wait_for_agentswith a long wait, Claude Code moves the call to the background after two minutes ("MCP tool "nfltr/wait_for_agents" is still running after 120s. It was moved to the background as task …") and starts the next turn with a task notification when it returns. No hook is needed for that case. The hook covers the other one: a turn that spawned and ended without waiting. A completion's content reaches the session once either way.
$ nfltr orch hub install-hook --print
Steer and stop
Say it in the session: "tell the agent on the VM to skip the archived rows", "stop the parser agent", "ask the finished agent to add a test". The session calls send_message or stop_agent. From another terminal you can watch the same agents read-only; see Many agents across machines.
$ nfltr orch task list --active
With Claude Code agent teams (experimental)
Claude Code's agent teams are an experimental Claude Code feature: a lead session starts teammates on this machine that share a task list and message each other. Teams form only in an interactive session, never with claude -p. With the hub server added, the same lead has teammates on this machine and agents on your nodes. Which work goes to a teammate, to an agent or to the lead itself is up to the session and to what you ask for; the hub tools describe the machines, not when to use them.
$ cd ~/src/my-project
$ claude mcp add nfltr -- nfltr mcp --toolset hub
$ nfltr orch hub install-hook
$ CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 claude
- Teammates and a waiting lead: Claude Code holds a teammate's messages while the lead is inside a tool call.
install-hookadds a TeammateIdle hook, so a teammate going idle (its idle notification carries its final answer) ends await_for_agentsin progress at once instead of up to two minutes later. Claude Code shows the teammate's messages when the lead's turn ends. A message a teammate sends without going idle waits until then. - Agents never become team leads: nfltr removes the agent-teams switch from the environment it gives agents on your nodes, and those agents run non-interactively, where Claude Code forms no team.
- When the session ends: teammates run inside the lead's process and end with it; Claude Code does not bring them back on
/resume. Agents on your nodes keep running, and the session receives their results when it is opened again in the same project.
Where your runs are
Your runs stay with your hub, end to end encrypted; the dashboard shows none of them. Ask the hub in the session (list_agents, wait_for_agents), or on this machine list every hub and its agents, running or stopped, and read one agent's turns:
$ nfltr orch hub runs
$ nfltr orch hub show --hub-id HUB_ID AGENT_ID
Add --a2a-e2ee-key-file FILE (the same file as your nodes' --e2ee-key-file) so the relay cannot sit in the middle of the end-to-end key exchange. See What the relay sees.
No account: one machine
Without an account, this runs a local hub on this machine only: it starts a loopback relay and a local node, and serves the same tools. The local node needs CLAUDE_CODE_OAUTH_TOKEN (from claude setup-token) or ANTHROPIC_API_KEY in the environment Claude Code starts it from, and --allow-all-tools if its agents should run commands.
$ claude mcp add nfltr -- nfltr orch hub --max-agents 2
Stop the local node with nfltr orch nodes stop. Save a key later to use nodes on other machines.
See it run
Two of the homepage demos are plain Claude Code sessions with exactly this setup: a backlog fixed by three agents across two machines, and an alert investigated and fixed on a remote VM.