Wire
The command line.
harborloop is the command line for Harbor: fourteen commands that wire your agents up, keep them current, and tell you the truth about whether any of it is working. The first one needs no account.
Start here, with no account
harbor context needs no account, no token and no network. It reads the files your agents already load on every turn, prices them, and says who put each one there. Run it before you decide whether any of the rest of this is worth your time.
npx harborloop context always-on budget on this machine at least ~542 tok / turn
skills index (6) ~219 0 managed by harbor · 6 unowned · 0 from other tools
skill files not indexed (2) — no description — nothing can select them, and nothing here can price them
agent definitions (2) ~115
agent files (4) ~208
MCP tools (0) — tool descriptions live on the server — connect to price them
injected context — varies per session — no on-disk record to read
managed by harbor: 0 of 6 · unowned: 6 · other tools: 0
2 more files in a skills root carry no description — write one, or they are shelf-wareThree of those lines carry a dash rather than a number, and the dash is the point. A skill with no description cannot be selected by anything, so nothing here can price it. Tool descriptions live on the server, so a machine with no connection cannot count them. Injected context varies per session and leaves no on-disk record. A zero in those places would be a claim we did not measure, and it would be the flattering one.
--verbose lists every skill with its own cost and owner. --json prints the same measurement for a script.
Install
Node 18 or newer. The install is two packages: a small launcher and the compiled binary for your platform, picked by npm from the optional dependencies. There is nothing else to install and no desktop app required.
npx harborloop initinit does four things: signs you in through your browser, installs the hooks for every agent it finds on the machine, binds this repository to a project, and schedules the background daemon. Each is skippable, and each is separately available as its own command below.
| Agent | MCP config | Hooks |
|---|---|---|
| Claude Code | ~/.claude.json | ~/.claude/settings.json |
| Codex | ~/.codex/config.toml | ~/.codex/hooks.json |
| Cursor | ~/.cursor/mcp.json | ~/.cursor/hooks.json |
Every command
| Command | What it does | Flags |
|---|---|---|
harbor init | Sign in, install the hooks, bind this repo, schedule the daemon. Configures every agent it finds. | --codex / --no-codex, --cursor / --no-cursor, --no-daemon |
harbor update | Bring this machine to the latest release, hooks included. | --check reports without installing anything |
harbor doctor | Is it actually working? | --offline, --json |
harbor status | This repo, from local files only. | none |
harbor context | What this machine pays for on every turn, and who put it there. | --verbose lists every skill, --json |
harbor bind [project] | Tie this repo to a project. | none |
harbor workspaces | Which workspaces you can reach, and the one this machine uses. | none |
harbor sync | Put this repo's team skills, memories and documents on disk. No desktop app needed. | --shapes describes what this machine runs, if you opted in |
harbor daemon | Keep every bound repo and your own environment current, on a timer. | --install to schedule it, --once for one pass, --status |
harbor unbind | Take those files back off this machine. Local only: the repo stays bound, and files you edited stay put. | none |
harbor off | Pause this repo. | --capture keeps recall, --global |
harbor on | Resume. | --global |
harbor login | Re-authenticate. | --no-browser to paste a code, --workspace <id> to switch workspace |
harbor logout | Forget this machine's credential. | none |
harbor help prints this list. --version prints the release.
harbor doctor
The one command worth running when something feels wrong. doctor checks the whole chain, from the endpoint to whether a prompt in this repo actually received anything, and it is built to be able to say no.
Endpoint ✓ https://app.gethrbr.com/v1
MCP target ⚠ no harbor MCP server registered — tool calls reach no graph
↳ harbor init
Signed in ✗ no credential on this machine
↳ harbor init
Token ✗ no MCP bearer in ~/.claude.json or ~/.codex/config.toml or ~/.cursor/mcp.json
↳ harbor init
Hooks ✗ not installed — nothing runs on a prompt
↳ harbor init
Codex ⚠ installed on this machine, but not configured — its sessions get nothing
↳ harbor init
Cursor ⚠ installed on this machine, but not configured — its sessions get nothing
↳ harbor init
This repo ✗ https://github.com/acme/acme-api is not in the local allowlist
↳ harbor bind
Skills · none in .claude/skills/ — no skill is connected to this repo
Skills (Codex) · none in .codex/skills/ — no skill is connected to this repo
Skills (Cursor) · none in .cursor/skills/ — no skill is connected to this repo
Your skills · none in ~/.claude/skills/ — no skill is connected to you
Your skills (Codex) · none in ~/.codex/skills/ — no skill is connected to you
Your skills (Cursor) · none in ~/.cursor/skills/ — no skill is connected to you
Background sync ⚠ Never run on this machine.
↳ Run `harbor daemon --install` to keep context current, or `harbor daemon --once` for a single pass.
Sent to harbor ✓ file digests · ~467 tok floor · 8 skill names (0 ours · 0 other tools · 8 unowned), home only. Never file contents.
Recording ✓ on
Receipt ✓ on (not in Cursor - that host discards it)
Guardrails ✓ observing, refusing nothing (0 from this workspace, none local)
Version · not checked (--offline)
Recall · not checked (--offline)
Fit · not checked (--offline)
Attribution · not checked (--offline)
Contributed · not checked (--offline)
Recall delivery ✓ no prompts recorded yetThat is a machine with nothing set up, which is the run worth printing: every failing line carries the command that fixes it, and no line claims a state it did not check.
Three things doctor refuses to do
- Report a partial install as healthy. Hooks registered for four of six events is a warning naming the two that are missing and what each of them would have done, not a green tick.
- Report a deliberate pause as a fault. A repo you turned off with
harbor offreads as paused, on purpose. An error there would train you to ignore the output. - Print a number it did not measure. Under
--offlinethe five measured lines saynot checked. A dash is not a zero, and the two must never render the same.
What the measured lines mean
The lines below are the reason doctor is more than a config linter. Every one of them needs the network, which is why the run above either marks them not checked or omits them. Each is reported over a window, and each says whether it is scoped to this project or to the whole workspace, because a reader who assumes the wrong one is reading a smaller number than they think.
| Line | What it answers |
|---|---|
| Recall | How many sessions there were, and how many of them received anything. |
| Fit | The average bundle size, and how many served rules went uncited. Warns below half. |
| Attribution | Whether every session here is being counted at all. An unkeyed recall is invisible to the loop, so this line is about the instrument rather than the result. |
| Contributed | What this repo has captured: how many learnings, how many approved, how many still pending review. |
| Corpus | What the brain added and retired, and the commonest reason a rule left. Always workspace-wide. |
| Version | Whether this machine is behind the current release. |
Fit is the one worth staring at, and served versus cited is the page that explains what to do about it. A rule that is served every day and never cited is a rule to retire, not a rule to reword.
Receipt, and Guardrails
Two lines in the run above are about things you can see rather than things you can measure. Receipt is the short note Harbor prints into your own session when it serves something: a count, then up to five numbered rule titles. Those numbers are what an agent cites back, which is why the receipt is on by default and why turning it off is described as off, on purpose rather than as a fault. Cursor cannot show it: its session-start hook is the only recall event that host has, and that runner discards the message the receipt travels in.
Guardrails reports what this machine would refuse. observing, refusing nothing is the resting state: the rules are watching and no command is being blocked. The two counts beside it separate the two reasons a rule might not fire, which are that this machine has never synced and that the workspace has promoted nothing. What a rule is, what a refusal hands back and the switch that has to be on for any of it to happen are on guardrails.
Sent to harbor
The line reading Sent to harbor is an inventory of what leaves the machine: file digests, a token floor, and skill names. Never file contents. It is printed on every run rather than buried in a policy page, because a tool that reads your repository should say what it takes every single time you ask it anything.
--json gives the same checks as structured output, for a CI step that should fail when the loop is broken.
harbor status
status is the small, local, no-network answer to “is this repo wired up?” It reads files on disk and nothing else, so it is instant and it works on a plane.
Workspace ✗ not signed in
↳ harbor init
Repo ✗ https://github.com/acme/acme-api — not bound
↳ harbor bind
Hooks ✗ not installed
↳ harbor init
Codex ⚠ installed here, but not configured
↳ harbor init
Cursor ⚠ installed here, but not configured
↳ harbor init
Recording ✓ onPausing a repo
Plenty of sessions are throwaway, and none of that belongs in your team’s graph. harbor off stops both halves: no context in, nothing recorded.
This repo (https://github.com/acme/acme-api): paused. No context in, nothing recorded.
--capture pauses only the recording, so you keep recall while you experiment.
This repo (https://github.com/acme/acme-api): recall on, recording off.
This repo (https://github.com/acme/acme-api): recall on, recording on.
--global applies the pause to every repo on the machine. The pause is read from a local file before any network call, so it takes effect immediately and holds with no connection.
Workspaces
harbor workspaces lists the workspaces this account can reach and marks the one this machine is using. Switching needs no browser:
harbor login --workspace <id>--no-browser prints a code to paste instead of opening one, which is the path for a remote shell or a container.
The daemon
harbor init schedules a background pass that keeps every bound repo and your own environment current, so a rule approved this morning is on your disk this afternoon without you asking. Pass --no-daemon to init if you would rather run it yourself.
✗ Never run on this machine. ↳ Run `harbor daemon --install` to keep context current, or `harbor daemon --once` for a single pass. Not scheduled. `harbor daemon --install` sets it up.
--install schedules it, --once runs a single pass now.
Syncing files, and CI
harbor sync puts this repository’s team skills, memories and documents on disk. No desktop app is involved. In CI, where there is no browser to sign in with, two environment variables stand in for the stored credential:
export HARBOR_TOKEN=...
export HARBOR_WORKSPACE_ID=...
npx harborloop syncharbor unbind is the reverse, and it is local only: it takes the synced files off this machine, the repository stays bound for everyone else, and any file you edited stays where it is.
Staying current
harbor update brings the machine to the latest release and re-points the installed hooks at it. That second half matters more than it sounds: hooks are recorded by path, so a binary that moved leaves scripts that are listed, enabled, and doing nothing.
harborloop 0.4.3 is the latest release. The installed hooks do not point at this binary. `harbor update` re-wires them.
--check reports and installs nothing, which is the form for a scheduled job or a shell prompt.