lfg-cli
v2.4.0
Published
Persistent Claude Code agents on your VPS — set up tmux + Tailscale + ntfy + lfg-daemon in one command. Run agents 24/7, check from your phone.
Downloads
3,369
Maintainers
Readme
.-. ██╗ ███████╗ ██████╗
( O o) ██║ ██╔════╝██╔════╝
^_//|\\_^ ██║ █████╗ ██║ ███╗
/ / \ \ ██║ ██╔══╝ ██║ ██║
' ' ' ' ███████╗██║ ╚██████╔╝
` ` ` ╚══════╝╚═╝ ╚═════╝Your laptop sleeps. Otto doesn't.
Persistent Claude Code agents on your own VPS. Close your laptop, walk away, ship from your phone.
bun i -g lfg-cliYou're hiring lfg to do five jobs
| Job | What that looks like |
|---|---|
| Keep Claude running when I close the laptop | tmux + systemd on a real Ubuntu box. Agents survive your wifi, your trip, your Tuesday. |
| Onboard a fresh VPS to "ready for agents" in one command | lfg vps add walks you through it. tmux, Claude Code, gh, Tailscale, ntfy, lfg-daemon — installed, signed in, configured. |
| Tell me at a glance which boxes are doing real work | lfg status — every VPS, daemon health, auth state, active sessions. One screen, under 3 seconds. |
| Ping me when an agent needs me | ntfy push to your phone. Free, no app account, works from any browser too. |
| Be quiet and not break my flow | Zero-dep Node ESM. No telemetry. Your secrets stay in Keychain. LFG_NO_PETS=1 if you want Otto to clock out. |
Meet Otto
Otto is lfg's mascot. Six moods. Shows up beside CLI output at anchor moments — never spammy, never blocking. Set LFG_NO_PETS=1 (or pipe through CI) and Otto clocks out silently.
.-. .-. .-.
( O o) ( O O) ( o o)
^_//|\\_^ ^_//|\\_^ ^_/\|/\_^
/ / \ \ / / \ \ \ \ / /
' ' ' ' ' ' ' ' ' ' ' '
` ` ` ` ` ` ` ` `
default wide / happy worried
.-. .-. .-.
( x x) ( - -) ( o O)
^_/\|/\_^ ^_//|\\_^ ^_//|\\_^
\ / \ / | | | | / / \ \
' ' ' ' ' ' ' ' ' ' ' '
` ` ` ` ` ` ` ` `
error sleeping curiousCelebrating Otto (two outer tentacles raised) shows up when your VPS is freshly provisioned:
\ /
\ / ✓ VPS ready on main
.-. Provisioning took 4m 32s.
( O O) Claude is awake — let's go.
//|\\
/ / \ \ Next: lfg vps work main
' ' ' '
` ` `60 seconds to your first agent
You need: a Mac, an Ubuntu 22.04+ VPS (Hostinger, Hetzner, DigitalOcean — doesn't matter), bun or npm, an SSH key.
# 1. install (10 sec)
bun i -g lfg-cli
# 2. register your VPS — interactive, prompts for anything missing
lfg vps add
# What's the name for this VPS? > main
# SSH target (user@host)? > [email protected]
#
# ⚡ Probing SSH... ✓
# Start guided setup now? [Y/n]
#
# ┌─ Push your SSH key to the VPS
# │ Why: So lfg can run commands on the VPS without a password.
# │ Takes: about 30 seconds
# │ After: lfg can SSH into the VPS using your key.
# └─
# 3. one continuous walkthrough does the rest:
# bootstrap → setup (3-5 min) → Claude login → GitHub login → first launch
# Each step is skippable. Skip prints 3 ways to resume.
# 4. once provisioned, your daily loop
lfg vps work # multi-select project picker
lfg vps attach # re-attach to a running session
lfg status # cross-everything dashboardWhat it actually looks like
lfg status — one screen for every VPS:
⚡ lfg v2.4.0
Local
✓ cmux installed (local multi-pane workspace)
✓ Claude Code on PATH
✓ 49 projects in ~/projects
VPS targets
● main ([email protected])
✓ Daemon ✓ Claude ✓ GitHub
2 active sessions: lfg, prisma-ghc
Next
lfg vps work launch a project on main
lfg vps attach re-attach to a running session
lfg vps doctor per-VPS health + what to do nextlfg vps doctor — discovery surface, not a diagnostic dump:
Doctor: main ([email protected])
Live probes + cached state. Always ends with "what to do next."
1. Provisioning
✓ System packages + non-root lfg user
✓ tmux ✓ Claude ✓ GitHub ✓ Tailscale ✓ ntfy ✓ daemon
All steps complete.
2. Authentication
✓ Claude: signed in
✓ GitHub: signed in
3. Active work
✓ 2 active sessions: lfg, prisma-ghc
4. Daemon health
✓ /health responds (v2.4.0)
✓ /status accepts the bearer token
✓ /notify relayed a test event
5. Next steps
1. lfg vps attach main
You have 2 active sessions — re-attach.
2. lfg vps work main
Launch a project (or pick one from your GitHub repos).Errors come with Otto:
.-. ✗ SSH unreachable
( o o) Why: Connection refused on port 22
^_/\|/\_^ Fix: lfg vps test main
\ \ / / More: Check Hostinger firewall
' ' ' '
` ` `What you actually get on the VPS
Your Mac Your VPS (Ubuntu 22.04+)
┌────────────┐ ┌─────────────────────────────────┐
│ │ │ │
│ lfg vps │ SSH + Tailscale │ tmux: myrepo │
│ add │ ─────────────────→│ └─ claude (autonomous mode) │
│ work │ │ │
│ attach │ attach from here │ tmux: side-project │
│ doctor │ attach from phone │ └─ claude (also running) │
│ │ │ │
└────────────┘ │ lfg-daemon (systemd, on tailnet)│
│ │ /health /status /notify │
↓ │ │
Keychain │ /home/lfg ← non-root user, │
(bearer tokens) │ passwordless sudo │
└─────────────────────────────────┘
│
↓
☎ ntfy push → your phoneWhy each piece exists
| Component | Why it's there |
|---|---|
| non-root lfg user | Claude refuses --dangerously-skip-permissions as root |
| /usr/local npm prefix | One canonical install location, accessible to every user |
| Tailscale (optional) | Reach the daemon from anywhere without exposing a public port |
| ntfy | Free push notifications, no app account required |
| lfg-daemon (systemd) | HTTP service for lfg notify, future remote operations |
| macOS Keychain | Daemon bearer tokens never touch your filesystem |
| Otto | Cost signal — sleeping Otto on a forgotten VPS = "use it or uninstall" |
Command reference
Provisioning (one-time per VPS)
lfg vps add [<name> <user@host>] # interactive if args omitted
lfg vps resume <name> # re-enter guided onboarding
lfg vps bootstrap <name> # push your SSH key (asks for password once)
lfg vps setup <name> # the 7-step installer pipeline
lfg vps claude-login <name> # re-auth Claude
lfg vps gh-login <name> # re-auth GitHub
lfg vps configure-claude <name> # autonomous-mode settingsDaily
lfg vps work # picker: VPS projects + GitHub fallback
lfg vps work <name> <project> # direct launch
lfg vps work <name> <p> --from <repo> # clone + launch
lfg vps attach [name] [session] # attach to tmux
lfg vps sessions [name] # list active sessions
lfg vps stop [name] # multi-select kill pickerDiscovery
lfg status # cross-everything dashboard
lfg vps doctor [name] # per-VPS state + next steps
lfg vps logs [name] --follow # tail the daemon journal
lfg vps test [name] # SSH + sudo + OS smoke testOperations / Teardown
lfg vps restart [name] # bounce lfg-daemon
lfg vps refresh [name] # re-sync local target from VPS state
lfg vps remove <name> # forget locally (VPS untouched)
lfg vps uninstall <name> # clean the VPS + remove locally
lfg notify "build done" # push to your phoneSmart default: when you only have one VPS registered, <name> is optional everywhere except remove and uninstall.
Security: lfg never sees your secrets
Every credential prompt flows your Mac TTY → SSH → remote tool directly. stdio: 'inherit' for ssh-copy-id, ssh-add, claude, gh. The bytes never enter Node's memory.
What lfg stores:
- Target metadata at
~/.config/lfg/targets/<name>.json(host, user, SSH key path — never the key itself) - Daemon bearer tokens in macOS Keychain (not on disk)
- ntfy topic IDs in Keychain
What lfg references (paths only, never read):
- Your SSH key at
~/.ssh/id_ed25519 - Tailscale auth keys (if you provide one)
Audit the full trust contract for any target: lfg vps connection <name>.
Requirements
- macOS (Apple Silicon or Intel) — uses Keychain
- Ubuntu 22.04 or 24.04 on the VPS
- bun ≥ 1.3 OR node ≥ 22 to install
- An SSH key — the wizard sets up
ssh-copy-idif you need to push it - A GitHub account for
gh repo clone - An Anthropic account for Claude
Troubleshooting
lfg status # first stop for "what's the state of everything?"
lfg vps doctor [name] # per-VPS deep dive + next steps
lfg vps logs --follow # tail the daemon journal
lfg vps test # SSH + sudo + OS smoke test
lfg vps refresh # re-sync if you changed things on the VPS manuallyEvery failure includes the recovery command. Errors are the kind you copy-paste, not the kind you interpret.
Roadmap
- v2.4 (shipped) — guided onboarding chain ·
lfg status·lfg vps doctorrewrite · Otto the octopus - v2.5 (next) —
lfg vps sync --pull(git pull Claude's commits back to your Mac) ·lfg vps upgrade(daemon hot-swap) · setup-step timestamps in doctor - v3.0 — smart
lfgno-args routing · GitHub Actions binary releases · Homebrew tap · ephemeral-VM e2e CI ·lfg vps backup / restore
Full queue in PENDING.md.
For contributors
ARCHITECTURE.md— how the system works, the 7-step pipeline, data model, security architecture, decisionsPENDING.md— queued work + decision logCHANGELOG.md— full release history- Tests:
npm testruns 123 tests across 16 files.node --test test/<name>.test.mjsfor a single suite.
Built with this stack
lfg itself is zero-dependency Node ESM. The remote stack:
- Bun for the daemon runtime
- Claude Code — the agent
- GitHub CLI — git auth + repo ops
- Tailscale — private networking
- ntfy.sh — pub-sub notifications
- tmux — session persistence
Local mode is built on cmux (macOS terminal multiplexer).
Uninstall
lfg vps uninstall <name> # clean the VPS first (optional)
lfg uninstall # remove local config
bun uninstall -g lfg-cli # remove the CLILicense
MIT — see LICENSE.
.-.
( O o) Made by Luis Huayaney
^_//|\\_^ github.com/huayaney-exe
/ / \ \
' ' ' ' Issues + ideas welcome
` ` ` github.com/huayaney-exe/lfg/issues