claude-computer
GitHub

A GitHub template · MIT

Install the operator first.
Then hand it the machine.

claude-computer makes Claude Code the operator of your Mac, and of every other machine you own. You install four things and paste one prompt. From then on you authenticate, set the mode and decide; Claude sets up and runs the rest — a laptop, a Mac Studio running local models, a headless Pi in a cupboard. That's my fleet; yours will differ.

  • you authenticate
  • you set the mode
  • you decide
Terminal.app
# 1 — install the operator
$ xcode-select --install
$ /bin/bash -c "$(curl -fsSL \
      https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
$ brew install gh && gh auth login
$ brew install --cask claude-code

# 2 — create your private copy and open it
$ cd ~ && gh repo create claude-computer \
      --template narendranag/claude-computer --private --clone
$ cd ~/claude-computer && claude

then paste docs/FIRST-PROMPT.md

01

The idea

The usual order

  1. Set up the machine
  2. Install your tools
  3. Maybe add an AI assistant to help you code

This order

  1. Xcode command line tools, Homebrew, gh, Claude Code
  2. Hand it the machine
  3. Everything else is a conversation

From that point, anything I would once have taken to an IT help desk goes to Claude: install this, configure that, why is this port open, set up the new box in the cupboard, archive last year's projects, rotate this key. Not ordinary app use — system changes and bulk work.

A coding assistant sees one repo. An operator sees the system the repos live in: which machine this is, what's installed, where secrets come from, how things sync, what runs on a schedule. Give it that context once, written down in files it maintains, and every later session — including every coding session — starts from a true picture instead of a guess.

The three jobs you keep

Authenticate
Every login, every password typed, every OAuth consent screen, every "allow" on a macOS permission prompt. Claude never handles a credential.
Set the mode
Claude Code runs in auto mode: a classifier model reviews each action instead of you, and your ask and deny rules still hold. Never bypass permissions.
Decide
Claude proposes; you choose. Anything destructive, anything touching credentials, anything that costs money — it asks first, every time.
02

How it works

The map, and map-check

One file per machine records what is installed, what is listening, what is scheduled, where the keys live (never the keys). bin/map-check diffs those sections against reality — brew leaves, the LaunchAgents directories, lsof, the VS Code extension list — and then runs security-check. Drift is a bug: fix the machine or fix the map, in the same session.

Diagram of the home directory: claude-computer, projects, products, personal and vault sync with git to GitHub; archive, library/camera and library/books sync one-way to Cloudflare R2; resources syncs two-way, encrypted. Manager machines on a Tailscale tailnet reach headless boxes over SSH. Bitwarden feeds every script; a Telegram bot receives from every machine.
Where everything lives, and the one way each folder leaves the machine. Scroll sideways to read it all.

The session loop

~/claude-computer is your private repo, cloned on every machine that runs Claude Code. The SessionStart hook pulls with --rebase --autostash and reports whether Bitwarden is unlocked. The Stop hook commits any docs/ change as [host] update … and pushes, at the end of every turn — because sessions get killed far more often than they get exited. Each machine writes only its own file, so conflicts are rare by construction and DECISIONS.md is append-only, so it always merges.

The session loop: the SessionStart hook pulls the repo and checks Bitwarden; Claude orients by reading CLAUDE.md, the machine file and FLEET.md; work happens; changes are recorded in the machine file, DECISIONS.md and TASKS.md; the Stop hook commits docs as [host] and pushes.
Hooks do the syncing, not discipline.

Trust

Auto mode is only sane with guard rails. git push, rm, rclone, sudo and the storage scripts sit on the ask list, which prompts even in auto mode; force-push, raw bw get and reading browser profiles sit on the deny list, which blocks in every mode. One SSH key per machine, generated on it and never copied. Bitwarden is the only secret store — no .env with keys, no rclone.conf with credentials on disk, no secret on a command line. Time Machine is the net: auto mode on a machine you care about needs a whole-machine rollback.

CLI first, MCP last

An MCP server loads its full tool schemas into every session's context, whether you use it or not. So each service gets a thin wrapper in bin/ instead — tavily, exa, firecrawl, jina, browse, gcal, gmail, gdrive — that reads its key from Bitwarden and prints markdown. Standing context cost: one paragraph in CLAUDE.md. MCP is reserved for things that are stateful or OAuth-bound in a way a wrapper can't handle.

A brain per folder

Any folder that needs automation gets its own CLAUDE.md — a brain — and a TASKS.md. You start Claude where the work is; that brain says what to do here and points at the fleet repo for what the system looks like. archive/ archives and retrieves. library/camera ingests cards and finds photos by metadata. Folders that just hold files have no brain.

If it can be a script, it is one

Slash commands are for steps that need judgment, and they orchestrate scripts rather than reimplement them. Hooks are for what must happen every time. Scheduled launchd jobs are for what must happen without a session. Everything deterministic lives in bin/, answers --help, and returns exit codes instead of prose.

03

What this isn't

Read this before you run it on a machine you care about.

  • It is one person's opinionated setup, not a neutral framework. Bitwarden, Tailscale, Cloudflare R2, Obsidian, Ghostty, Homebrew. Swap what doesn't fit — but you are swapping, not configuring.
  • Permission rules are pattern matches, not a sandbox. The ask and deny lists are string and glob rules on commands; auto mode adds a classifier on top. Both reduce prompts and mistakes. Neither is a security boundary, and nothing here contains a program that has already decided to do something else.
  • macOS first; Linux is thin. Headless Linux boxes are managed over SSH, but /setup, the Brewfiles and the macOS defaults assume a Mac.
  • It expects you to keep doing the three jobs. If you turn on bypass permissions, skip Time Machine, or let the map drift, none of the rest of this helps you.
  • It is young. I have run this approach on my own machines for about a year; the template is that approach written down, and it is days old. /setup has been dry-run and read end to end, but it has not yet built a machine from scratch — including mine. If you try it, you may be the first. That's exactly why I want your /setup report.

The Trust section of the README is the part to read closely: README · Trust

04

Quick start

Before you start

  • A Mac on a recent macOS.
  • A GitHub account.
  • A Claude plan that includes Claude Code (Pro, or Max for all-day sessions).
  • After the Homebrew installer finishes, run the shellenv lines it prints — nothing else works until brew is on your PATH.
  1. Install the operator

    Four commands in stock Terminal.app.

    xcode-select --install
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    brew install gh && gh auth login
    brew install --cask claude-code
  2. Create your private copy

    Your instance is a private repo made from the template, cloned into your home directory.

    cd ~ && gh repo create claude-computer --template narendranag/claude-computer --private --clone
    cd ~/claude-computer && claude
  3. Hand over

    Log in to Claude Code and check the status line reads ⏵⏵ auto mode on (Shift+Tab cycles modes). Then paste the first prompt and do what it asks: log in, grant, decide.

    You are the operator for this computer, my network and the devices on it. Your
    brain is this repo: read CLAUDE.md now and follow it.
    
    Start with this computer. This is a new machine, so run /setup:
    
    1. Identify this machine (hostname, hardware, macOS version) and ask me its role
       (client, build, server) and a one-line purpose. Write
       docs/machines/<host>.md from docs/machines/_example.md, add it to
       docs/FLEET.md, and append the decision to docs/DECISIONS.md.
    2. Create an SSH key for this machine only, add it to GitHub with gh, and push
       this repo.
    3. Install Tailscale and walk me through logging in. Record the
       Tailscale name in the map.
    4. Install the Bitwarden CLI and walk me through `bw login`. Confirm
       bin/secrets-unlock works.
    5. Link claude-global/ into ~/.claude so the hooks and commands are live.
    6. Install the Brewfile layers for this role, link dotfiles, run
       macos-defaults.sh. Tell me before each step that needs a password or a
       macOS permission prompt.
    7. Run bin/map-check and bin/security-check, fix what fails, and update the map.
    
    Rules for the whole session: ask before anything destructive, anything that
    touches credentials, and anything that costs money. I will do every login and
    every step that handles a password myself. Record every decision we make in
    docs/DECISIONS.md. When something is deferred, put it in TASKS.md under Later.
    At the end, commit and push docs/ and tell me what is left.

A second machine is much shorter: the four commands, gh repo clone <you>/claude-computer ~/claude-computer, then /setup — which reads the repo, finds everything already decided, and asks only what is specific to this machine.

05

Help wanted

This is the point where it stops being one machine's setup. The most useful thing you can send me is what happened when you ran /setup on yours.

  • Setup reports What broke, what asked for a password it shouldn't have, what map-check got wrong on your hardware and macOS version.
  • Other cameras The camera brain reads my RAW workflow. Other bodies, other card layouts, other sidecar conventions.
  • Linux Headless boxes are managed over SSH today. A real Linux /setup — packages, dotfiles, the security baseline — is the biggest open gap.
  • Equivalents 1Password instead of Bitwarden, Backblaze instead of R2, WireGuard instead of Tailscale, iTerm2 instead of Ghostty — as clean swaps, not forks.
  • Another agent Fork it for Codex, Gemini CLI or a local model. The brains are markdown and the work is in bin/, so most of it ports. Tell me and I'll link it here.