HomeFleet
by Hugodzl
README.md
# HomeFleet

**Your coding agent, but your other PCs do the heavy lifting.**
HomeFleet turns the computers in your home into a fleet your AI coding agent can use. Install a small daemon on each machine, pair them once, and any MCP-capable agent (Claude Code, LM Studio, goose, Cline, ...) gains tools to see every machine in the house and delegate work to them — the delegated work runs entirely on **local models**, entirely on **your LAN**; the agent in front can be cloud or local, but the jobs never leave the house.
> **Status: v0.4.0 — pre-alpha.** The product spine is complete — identity,
> mTLS transport, LAN discovery, executors, job dispatch, the MCP front door,
> workspace (git bundle) sync, the single-process daemon assembly, and the
> `homefleet` operator CLI. v0.2 added **code-writing delegation**: a worker's
> local model edits code in a throwaway worktree and the change comes back as a
> reviewable `homefleet/<id>` branch in your own repo, landed by a non-forced
> fetch that never touches your branches or working tree. v0.3 made it a
> **packaged install** — one `npm i -g` of a GitHub Release tarball, no clone or
> build — and gave each node an enforced **per-node model catalog** (HFP 0.3.0).
> v0.4 added a **read-only web dashboard** — `homefleet dashboard` opens this
> node, paired nodes, and jobs in both directions in a browser, served on the
> existing loopback control port, polling every 3 s with no mutating request.
> All of it has run on real hardware, laptop ↔ tower against a local
> Qwen3.6-35B-A3B: recon returned an accurate architecture summary in ~105 s
> ([rig devlog](devlog/2026-07-09-m8-rig-bringup.md)), a scoped write task
> wrote a new test file that landed and passed in ~169 s
> ([write-delegation rig devlog](devlog/2026-07-15-v02-rig-smoke.md)), both
> rig machines installed v0.3 from its public release URL and passed delegation
> in both directions, and the dashboard showed a live delegated job reach
> `succeeded` against the tower ([dashboard devlog](devlog/2026-09-24-read-only-dashboard.md)).
> Windows-first; not on the npm registry yet. The
> [Quickstart](#quickstart) runs today on a single machine; pairing two real
> machines is the [two-machine demo](#two-machine-demo).
Design history is in the open: the [protocol RFC](docs/rfc/hfp-v0.md),
[ADRs](docs/adr/), the [design doc](docs/specs/2026-07-06-homefleet-design.md),
and day-by-day [devlogs](devlog/).
## Why
Local agents are getting genuinely useful, but a single machine is always the bottleneck — and most of us have more than one computer sitting around. Existing multi-machine tools either pool GPUs to serve one bigger model (exo, GPUStack, llama.cpp RPC) or replace your whole workflow with a new platform (dashboards, kanbans, custom protocols). Nothing lets the agent you *already use* simply reach over and put your other machines to work.
HomeFleet is that missing thin layer:
- **MCP-native** — appears as `list_nodes` / `delegate_task` tools inside your existing agent session; results stream back into its context
- **LAN auto-discovery** — daemons find each other via mDNS; pair with a short code, Syncthing-style (device ID = certificate fingerprint, mutual TLS, no CA, no accounts)
- **Local models by default** — worker machines drive tasks with whatever OpenAI-compatible server they have (Ollama, LM Studio, llama.cpp server)
- **Capability-aware** — nodes advertise a validated model catalog; delegate to a specific model or be cleanly denied
## How it works
```
┌─────────── Machine A (you) ───────────┐ ┌────────── Machine B (worker) ─────────┐
│ │ │ │
│ Your agent (Claude Code, goose, ...) │ │ homefleetd │
│ │ MCP (localhost) │ │ ├─ executor: minimal agent loop ──► │
│ ▼ │ mTLS │ │ local model (OpenAI-compat API) │
│ homefleetd ◄──── discovery/pairing ──┼──────┼─► ├─ executor: command runner │
│ ├─ list_nodes │ LAN │ └─ workspace cache (git bundles) │
│ └─ delegate_task ────────────────────┼──────┼─► │
└────────────────────────────────────────┘ └────────────────────────────────────────┘
```
One daemon per machine. On your machine it faces your agent as an MCP server; on workers it executes delegated jobs — read-only repo recon driven by a local model, allowlisted commands (test suites, builds), or code-**writing** tasks that come back as reviewable `homefleet/<id>` branches (v0.2). Code travels as git bundles; nothing needs a shared remote.
## v0.1 scope
- Delegate **recon** tasks ("explore this repo, summarize the auth flow") to a worker's local model
- Delegate **command** runs ("run the test suite") to any paired machine
- Live node list with capability info, job status/streaming, cancellation
- Windows-first reference setup; code is cross-platform TypeScript
Explicit non-goals for v0.1: code-**writing** delegation (added in v0.2, below), GUI, cloud relay. See the [design doc](docs/specs/2026-07-06-homefleet-design.md) and [roadmap](#roadmap).
## v0.2: code-writing delegation
Workers can now *write* code, not just read it. Configure `executors.write` on a worker (a [catalog](docs/reference/configuration.md#catalog) `defaultModel` plus an optional command allowlist) and `delegate_task` accepts `type: "write"` tasks. From there the flow is three steps: the worker's local model makes the requested change in an isolated, throwaway worktree of the synced repo; the daemon commits the result as `HomeFleet Worker`; and the next `job_result` call lands the change in *your* clone as a branch named `homefleet/<jobId12>` — your own branches and working tree are never touched. Review it with the exact command `job_result` returns (`git diff <base>...homefleet/<id>`), then merge or delete the branch. An optional allowlisted `verifyCommand` runs after the commit and reports its outcome without ever failing the job. Config shape, the git-in-allowlist caveat, and the artifact-lifecycle rules are in the [configuration reference](docs/reference/configuration.md#executorswrite).
## Install
You need **Node ≥ 20** and git. Install the [latest release](https://github.com/Hugodzl/HomeFleet/releases/latest) (currently v0.4.0) globally:
```bash
npm i -g https://github.com/Hugodzl/HomeFleet/releases/download/v<version>/homefleet-<version>.tgz
```
(the exact URL is on the [Releases page](https://github.com/Hugodzl/HomeFleet/releases)).
That puts `homefleetd`, `homefleet` and `homefleet-mcp-stdio` on your PATH.
To update, install the newer tarball the same way. Then scaffold the machine
with `homefleet setup` (below).
Working on HomeFleet itself? See [Development](#development) for running from
source.
## Quickstart
Single machine, dev setup. This is enough to run the daemon and point an MCP
client at it — pairing a second real machine is the
[two-machine demo](#two-machine-demo) below.
See [Install](#install) above; recon jobs additionally need an
OpenAI-compatible model server on the worker (Ollama, LM Studio, llama.cpp
`llama-server`, ...).
Next, scaffold this machine — prints this node's identity and the commands
*you* run yourself in an elevated PowerShell (the daemon never elevates
itself):
```bash
homefleet setup
```
Run the printed `New-NetFirewallRule` commands (TCP for HFP — the daemon's
LAN protocol — plus discovery UDP, scoped to the Private network profile)
in an elevated PowerShell, and check the printed network-profile warning —
the rules only take effect on a Private-profile adapter. They only matter
once you pair a second machine; for this single-machine quickstart they're
safe to defer.
Then `config.json` goes in the daemon's data directory (by default
`%LOCALAPPDATA%\homefleet` on Windows; override with `HOMEFLEET_DATA_DIR`).
For this single-machine quickstart you can skip it and start the daemon
bare — with no config file it runs no executors and syncs no repos;
everything is opt-in. Write one when the machine takes a role. The two
examples below are the two roles — worker and delegator — and one machine
can carry both in the same file. A worker offering a local model plus a
command allowlist, for one repo:
```json
{
"catalog": {
"models": [
{
"id": "qwen3.5-9b",
"contextWindow": 32768,
"endpoint": { "baseUrl": "http://127.0.0.1:8080/v1" }
}
]
},
"executors": {
"agent": { "defaultModel": "qwen3.5-9b" },
"command": { "allowlist": { "pnpm": {} } }
},
"workspace": { "allowedRepoIds": ["homefleet"] }
}
```
(The pre-A2 shape — `executors.agent.endpoint: { baseUrl, model,
contextWindow }` directly, no `catalog` section — still loads unchanged; the
daemon upgrades it automatically at startup.)
A delegator mapping a local repoId to its checkout, so `delegate_task` can
sync it to a worker:
```json
{
"repos": [{ "repoId": "homefleet", "path": "D:\\Git\\HomeFleet" }]
}
```
Every key, type, and default is in the
[configuration reference](docs/reference/configuration.md) — cross-check
before writing a real config; parsing is strict (an unknown key throws rather
than being silently ignored).
Now start the daemon (foreground; stop with Ctrl-C):
```bash
homefleetd
```
It prints its device ID, bound ports, and data directory to stderr once it's
up. Finally, point an MCP-capable agent at it — for Claude Code:
```bash
claude mcp add --transport http homefleet http://127.0.0.1:56372/mcp
```
See [`packages/daemon/README.md`](packages/daemon/README.md#pointing-claude-code-at-the-daemon)
for the exact `.mcp.json` form and the stdio-shim alternative.
## Two-machine demo
This is the v0.1 acceptance path: two physical machines, each running
`homefleetd`, paired, delegating a real job to a real local model. This
exact path ran for real on the reference rig on 2026-07-09 — timings, token
rates, and the Windows MAX_PATH lesson it surfaced are in the
[rig devlog](devlog/2026-07-09-m8-rig-bringup.md). Follow
[Install](#install) above **on both machines** first, then:
1. On **each** machine, run `homefleet setup` and run the printed firewall
commands in an elevated PowerShell. Then write `config.json`: give the
worker machine an `agent` and/or `command` executor and a non-empty
`workspace.allowedRepoIds`; give the delegating machine a `repos` mapping
naming the same repoId (see the Quickstart's examples and the
[configuration reference](docs/reference/configuration.md)). Only then
start `homefleetd` — config is read once at startup, not reloaded.
2. **Pair them.** On machine B (the worker), open a pairing window:
```bash
homefleet pair begin
```
This prints a short code. On machine A (the delegator), connect to B using
B's LAN address, B's HFP port (`56370` by default), and that code:
```bash
homefleet pair connect <B-host> <B-hfp-port> <code> [--expect <B-device-id>]
```
3. **Verify.** On either machine:
```bash
homefleet nodes # the peer, with live capabilities
homefleet status # this node's own live status
homefleet dashboard # opens the read-only web dashboard (this node, paired nodes, recent jobs) served by the local daemon on 127.0.0.1
```
4. **Point a Claude Code session's MCP at machine A's local daemon** (see the
Quickstart's `claude mcp add` command — always the *local* daemon; MCP
never crosses the LAN).
5. **Delegate.** In that session, `delegate_task` a recon prompt naming
machine A's configured `repoId` and machine B's device ID (from
`list_nodes`/`homefleet nodes`) — the repo is bundled and synced to B
automatically before the job runs on B's local model. Poll with
`job_status`/`job_result`; `cancel_job` to abort mid-run.
Recon needs the worker machine to serve a local OpenAI-compatible endpoint
(llama.cpp `llama-server`, Ollama, LM Studio, ...); command jobs need no
model. The design doc's
[reference rig](docs/specs/2026-07-06-homefleet-design.md#reference-rig)
describes the two-machine setup this project develops against (a Vulkan
`llama-server` box and a CUDA Ollama box) if you want a concrete starting
point.
## Repository layout
| Path | What |
|---|---|
| `packages/protocol` | HomeFleet Protocol (HFP) — zod schemas + types; spec in `docs/rfc/` |
| `packages/daemon` | `homefleetd` — MCP front, node service, discovery, dispatch |
| `packages/executors` | Command executor + minimal agent loop |
| `docs/rfc/` | Versioned RFC-style protocol spec |
| `docs/adr/` | Architecture Decision Records |
| `docs/specs/` | Design documents |
| `docs/reference/` | Operator reference (e.g. [`configuration.md`](docs/reference/configuration.md)) |
| `devlog/` | Findings, benchmarks, lessons learned along the way |
## Development
Running from source instead of a release:
```bash
git clone https://github.com/Hugodzl/HomeFleet.git
cd HomeFleet
pnpm install # pnpm 11 — `corepack enable` is the easiest way
pnpm build # tsup — required before running any packages/daemon bin
node packages/daemon/dist/bin/homefleet.js --help
```
The bins are plain, bare-`node`-runnable ESM files; substitute
`node packages/daemon/dist/bin/<bin>.js` for the bare commands used above.
```bash
pnpm test # vitest (includes a real build + npm pack of the release tarball)
pnpm typecheck # tsc across packages and scripts/
pnpm lint # biome
pnpm pack:release # build release/homefleet-<version>.tgz locally
```
Everything is testable on a single machine — integration tests run multiple daemons as local processes with faked capability profiles. Cutting a release: [docs/reference/releasing.md](docs/reference/releasing.md).
## Roadmap
v0.1 (recon + command delegation) → v0.2 code-writing delegation (branches back — done) → per-node model catalog ([A2](docs/specs/2026-07-21-model-catalog-design.md) — done, v0.3) → packaging ([S1](docs/specs/2026-07-12-s1-packaging-design.md) — done, v0.3) → painless install → dashboard ([read-only](docs/specs/2026-09-24-read-only-dashboard-design.md) — done, v0.4; mutations next as S2 + A1) → remote model install. The post-v0.2 ordering was approved 2026-07-12 — see the [backlog structuring doc](docs/specs/2026-07-12-backlog-structuring.md); A2 landed ahead of that sequencing.
Longer horizon, not yet sequenced against the above: macOS/Linux polish, multi-node fan-out, model-pool orchestration on the same fabric.
Unordered ideas and known follow-ups live in the [backlog](docs/backlog.md).
## License
[Apache-2.0](LICENSE) — © 2026 Hugo Deziel
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues