Hub Tools Reference
The MCP tools an orchestration hub uses to run agents on your joined machines. nfltr orch and nfltr mcp --toolset hub (in your own Claude Code session) serve the same set on the hosted nfltr.xyz relay.
The hub decides everything: what to spawn, where, with which model, when to continue or stop. nfltr only dispatches, routes messages, persists and reports. spawn_agent makes no model call; the first model call is the agent's own.
Tools
| Tool | Input | Result |
|---|---|---|
spawn_agent | prompt (the whole brief), optional constraints | agent_id, status: pending, fleet, returned immediately |
send_message | agent_id, text | mode: steer (running: delivered into the live session between tool calls) or mode: continue (finished or stopped: a new turn in the same session and workspace, on the same machine) |
stop_agent | agent_id, optional reason | the agent; its cancellation arrives through wait_for_agents |
list_agents | none | per agent: status, worker, machine, prompt summary, turns, progress, last activity; fleet |
wait_for_agents | optional agent_ids, timeout_ms (default 30000, max 600000) | completions[], pending[], timed_out, fleet |
list_nodes | none | joined machines: machine, labels (resources, description, allowed repositories), max_agents, running_agents, free_agents; fleet |
list_worker_peers | none | connected agents with their labels and free slots |
A node starts no agent process until a spawn needs one, so a joined machine shows in list_nodes, not in list_worker_peers.
Completions
Each entry of completions[] carries the agent's final text, its structured result when it gave one, artifacts, branch and sha when it pushed work, state, worker, machine, turn, and usage (tokens and USD as reported). Failures arrive the same way, as a completion with a reason:
| Reason | Meaning |
|---|---|
node_lost | the node running the agent died mid-turn |
tools_not_allowed | the agent needed a command the node does not allow (joined without --allow-all-tools) |
budget_exceeded | the agent's or the hub's budget was reached |
no connected worker satisfies constraints … | nothing eligible connected within the spawn's bound; lists what was connected |
| cancelled | stopped by stop_agent or timeout_ms; artifacts holds a recovery patch of the uncommitted edits |
Spawn constraints
All optional; unknown keys are rejected.
| Key | Meaning |
|---|---|
machine | hard filter: the machine id (from list_nodes) |
labels | hard filter: every label must match exactly (e.g. flavor to pick a harness on a node that has several) |
model, effort | passed to the agent unchanged; omitted stays omitted |
isolation | shared or per_task workspace |
mutates_workspace | true gives the agent a git task workspace whose edits come back as branch, sha or patch. A permission, not an obligation: a turn that edits nothing completes with its answer. It does not limit what the agent's tools do on the machine; the node's tool setting does. |
timeout_ms | hard bound per turn, including waiting for a free slot or for a named machine to join (default 30 s for that wait) |
workspace | {repo, ref}: the agent works in a worktree of that repository at ref. Routed only to nodes whose checkout is that repository or whose --allow-repo matches it; every spelling of one remote matches. |
output_validation | {require_object, allowed_statuses, required_fields, non_empty_fields}: the agent must answer with a structured result that satisfies it (say so in the brief); a nonconforming result fails the turn. Omitted: plain text. |
budget | {max_tokens, max_usd}: cap on this agent's reported usage across its turns; the running turn is stopped (budget_exceeded) and further messages refused. max_usd needs max_tokens. |
Fleet capacity
fleet (in spawn_agent, list_agents, wait_for_agents and list_nodes results) is the capacity at that moment: free_agent_slots = worker_free_slots (free slots on connected agents) + node_free_agents (agent processes the nodes may still start), with connected_workers, node_max_agents, node_running_agents, nodes_unreachable and read errors. It states capacity only; using it is the hub's call.
Placement is mechanism only: among eligible agents, one with a free slot is chosen, idle first; if none is free, a node that matches starts one; if every slot is busy the agent stays pending and dispatches when a slot frees, within its bound. A continuation always runs where its session is.
Budgets
Hub-wide caps: --hub-max-tokens N and --hub-max-usd X on nfltr orch or nfltr mcp --toolset hub cover every agent of the hub; once passed, running turns are stopped and spawns and messages refused. Usage is what agents report; every completion carries it. A stopped or lost turn's tokens are counted up to the stop, but its cost is never estimated (cost_unreported: true), so a USD cap needs a token cap. Nothing is capped by default.
$ nfltr orch --hub-max-tokens 2000000 --hub-max-usd 5 "<goal>"
Delivery guarantees
- Exactly once: a completion is marked delivered before
wait_for_agentsreturns it, so it is never returned twice, across hub restarts. - Agents outlive the hub: a hub that exits and reopens with the same id reattaches every unfinished agent and receives the completions it missed.
- Push, not poll:
wait_for_agentsreturns the moment a completion lands; theorch://hub/inboxresource notifies subscribers as well. - No hidden retries: nfltr never starts a replacement attempt on its own; the hub decides every retry.
- One process per hub id: a second process with the same id fails closed naming the holder; a dead holder's lock is reclaimed.
- Relay restarts: a dropped task stream is resumed, not reported as the agent's outcome.
- Retention: the hub keeps the newest 128 settled agents; older ones are archived to their usage (still counted by budgets). Running, pending or undelivered agents are never archived.
Related: Use nfltr from Claude Code · Many agents across machines · Join machines as nodes.