bro-agent
v0.2.4
Published
bro local agent — loopback service for the hosted bro UI: filesystem, Remote Control relay + usage (user's own ~/.claude), the Operator control plane, and a headless `claude /remote-control` launcher (node-pty, the one native dep, used only to give claude
Downloads
1,171
Readme
bro-agent
The bro local agent — the "bring your own compute" piece for the hosted bro UI.
bro's UI is hosted: you use it in your browser at the bro site. Anything that touches
your machine — your files, your Claude sessions and usage (read from your own
~/.claude), launching a new claude session — runs in this small loopback agent on
your machine. The browser bridges the two. This agent serves no web UI; it's a
headless service on 127.0.0.1 only, never exposed to the internet.
Run it
npx bro-agentIt prints a one-time pairing code. Open the bro site, click Connect agent, and enter the code. That's it — the agent is now paired to your browser (the token persists, so you don't re-pair on reload). Press Enter in the agent's console any time for a fresh code.
Requirements: Node ≥ 20. The agent's one native dependency is
node-pty (used solely to give a launched
claude a windowless TTY); npm installs a prebuilt binary for common platforms.
Keep it running (autostart)
The agent only drives your sessions while it's running. To keep it up across reboots:
- Windows — the bro repo ships
scripts/install-services.ps1, which registers the agent (and server + tunnel) as auto-restarting Scheduled Tasks. Seescripts/README.md. - Linux (systemd user service) — create
~/.config/systemd/user/bro-agent.service:
then[Unit] Description=bro local agent [Service] ExecStart=%h/.npm-global/bin/bro-agent Restart=always RestartSec=3 [Install] WantedBy=default.targetsystemctl --user enable --now bro-agent(andloginctl enable-linger $USERso it runs without an active login). AdjustExecStartto yourbro-agentpath (which bro-agent). - macOS (launchd) — a
~/Library/LaunchAgents/dev.bro.agent.plistwith aProgramArgumentsof yourbro-agentpath andRunAtLoad/KeepAliveset totrue, loaded vialaunchctl load.
Safe default: relay-only
If you only use bro to drive/watch existing Claude sessions (not the file editor or launching new sessions), run it relay-only — the least-privilege posture: no filesystem access, no session launching, just the relay.
BRO_AGENT_RELAY_ONLY=1 npx bro-agentThe agent prints its posture on startup. Widen it (BRO_AGENT_READONLY, BRO_AGENT_ROOTS,
full) only as far as the features you actually use require — this bounds the blast radius
if the hosted coordinator is ever compromised.
Configuration (env vars, all optional)
| Var | Default | Purpose |
|---|---|---|
| BRO_HOSTED_ORIGIN | https://bro.usurp.dev | The hosted site this agent trusts (CORS + WS origin). Set this if you self-host the bro UI elsewhere. |
| BRO_AGENT_ORIGINS | — | Extra trusted origins (comma-separated), in addition to the hosted one. |
| BRO_AGENT_PORT | 8765 | Preferred port; probes 8765–8770 if taken. |
| BRO_AGENT_DIR | ~/.bro-agent | Where the persisted token + bound port live (config.json). |
| CLAUDE_BIN | resolved from PATH | Path to the claude executable. |
| BRO_NO_REMOTE_CONTROL | — | If set, launched sessions don't auto-run /remote-control. |
| BRO_AGENT_ROOTS | whole machine | Restrict filesystem + new-session cwd to these roots (comma-separated). |
| BRO_AGENT_NO_LAUNCH | — | 1 = refuse to launch new claude sessions. |
| BRO_AGENT_READONLY | — | 1 = no file writes, no launch (reads + relay only). |
| BRO_AGENT_RELAY_ONLY | — | 1 = drive/watch relay sessions only — no filesystem, no launch. |
These cap what the agent will do regardless of what the hosted coordinator asks — i.e. they bound the blast radius if the coordinator is ever compromised. The agent prints its current posture on startup. Lock it down to the least you need.
What it exposes (all token-gated, loopback only)
- Filesystem:
/dirs,/mkdir,/file(the folder picker + Project editor). - Remote Control relay + usage:
/relay/*,/relay-stream(WS),/usage— reads your own~/.claudeOAuth token; bro never holds your keys. - New session:
/new-session— launchesclaude /remote-controlheadless. - Operator control plane:
/op,/operator-info,/control(WS).
Security: every privileged route requires the pairing token, the agent binds 127.0.0.1
only, and it accepts requests only from the trusted hosted origin. Sessions it launches
run claude --dangerously-skip-permissions — that is bro's purpose, on your own machine.
Revoking access
Each agent is linked to your account with its own account key (TTL-bounded, rotated
on every reconnect). To cut an agent off: open the bro site → Connect agent panel →
Revoke the agent (calls /agent/revoke, which forgets the key and force-closes the
live connection). Re-linking issues a fresh key, so an old/leaked key stops working. The
local config.json token can also be reset by deleting ~/.bro-agent/config.json and
re-pairing.
Audit log
Privileged, state-changing actions — file writes (POST /file), folder creation
(/mkdir), and session launches (/new-session) — are appended to
~/.bro-agent/audit.log (one redacted JSON line each: timestamp, action, target
path/cwd, result status). File contents, tokens, and account keys are never written —
only what was done and where — so the log makes a compromise visible without itself
becoming a secret. It rotates at ~2 MB (audit.log.1). Config + audit files are locked to
the current user (POSIX chmod 600; Windows icacls, current user only).
