A fresh Claude Code install is useful. A configured one is a different tool entirely. The gap between the two is maybe fifteen minutes of setup — a code index, a handful of MCP servers, two plugin marketplaces, a spec workflow, and a runtime to keep it all alive — and I keep re-doing it every time I move to a new machine. So here it is written down, in the order I run it.

1. Install Claude Code

Start from the official docs — code.claude.com/docs — because the installer is the one thing you don’t want a blog post to be the source of truth for. The short version, for macOS, Linux, and WSL:

curl -fsSL https://claude.ai/install.sh | bash

On macOS I use Homebrew instead, since it’s already managing everything else on the machine:

brew install --cask claude-code

Note the tradeoff: the native installer auto-updates in the background, Homebrew does not (brew upgrade claude-code is on you).

Then check the install and launch it in a project:

claude --version
claude doctor
claude

claude doctor is the one to remember. It prints read-only diagnostics — install health, settings files that fail to parse, plugins whose binaries are missing — without starting a session. It’s the first thing I run when something in this setup misbehaves.

Claude Code needs a Pro, Max, Team, Enterprise, or Console account; the free claude.ai plan doesn’t include it. First run opens a browser to log in.


2. CodeGraph — stop making the agent grep

The default discovery loop is grep, then read a file, then read three more files it referenced. It works, and it burns a lot of tokens on navigation rather than on thinking. CodeGraph replaces that loop with a real index: it parses your repo with tree-sitter into a symbol/dependency/call graph in local SQLite, and answers “where is this defined, who calls it, what breaks if I change it” from the index instead of from file reads.

Three steps — install the CLI, wire up the agent, index the project:

# 1. install the CLI
curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh | sh
# or, any OS with node:  npm i -g @colbymchenry/codegraph

# 2. detect and configure installed agents (Claude Code among them)
codegraph install

# 3. index a project
cd your-project
codegraph init

codegraph install writes the MCP wiring itself, so there’s no claude mcp add to run here. After init, a file watcher keeps the index in sync (FSEvents on macOS, inotify on Linux) — you don’t re-run anything after editing code.

There’s no configuration to do: it respects .gitignore, skips node_modules, vendor, dist, build, target and friends, and ignores files over 1 MB. It’s fully local — no API keys, no external service — and covers 30+ languages, including all the ones I care about here (Go, TypeScript, Python, Rust, Terraform).

Two honest caveats. First, the headline numbers on that README (88% fewer tool calls, 62% fewer tokens) are the author’s benchmarks, not mine — treat them as a direction, not a promise. Second, the README is upfront that dense index responses leave roughly 80% more context resident across a long session than file reads do. On a 200k window that’s a fine trade; on a small one, less so.

To back it out cleanly:

codegraph uninstall

3. MCP servers

MCP is how Claude Code talks to things that aren’t your filesystem: GitHub, GitLab, a Postgres database, a browser. I keep my working list in sgaunet/tips → claude/10-mcp.md, which is the page I actually copy-paste from. The management commands:

claude mcp list              # what's configured
claude mcp get my-server     # details for one server
claude mcp remove my-server  # drop it

The ones I add on a new machine:

# GitHub — HTTP transport, no local binary needed
claude mcp add --transport http github https://api.githubcopilot.com/mcp \
  -H "Authorization: Bearer $GITHUB_TOKEN"

# context7 — up-to-date library documentation
claude mcp add --transport http context7 https://api.context7.com

# Atlassian — Jira and Confluence
claude mcp add --transport http atlassian https://mcp.atlassian.com/v1/mcp

# gitlab-mcp — needs the binary installed and GITLAB_TOKEN set
claude mcp add gitlab-mcp -s user -- gitlab-mcp

For Postgres, scope it to the project that needs it rather than to your user, because the connection string belongs to that project:

claude mcp add -s project \
  --env "POSTGRES_URL=postgres://postgres:password@localhost:5432/postgres?sslmode=disable" \
  --transport stdio postgresql postgresql-mcp

Two rules I hold to here. Check the code, or at least trust the source — an MCP server runs on your machine with your tokens. And for anything that reaches a database, give it a read-only user. An agent that can’t issue a DELETE is much more relaxing to work with than one you’re hoping won’t.

Browser automation is worth a note. There’s a Playwright MCP server, but the CLI is noticeably more token-efficient for the same work, so that’s what I install:

npm install -g @playwright/cli@latest
playwright-cli install --skills

A last alternative to keep in mind for SQL work: instead of connecting an agent to the database at all, generate the schema documentation once with tbls and let Claude read the markdown.

tbls doc --rm-dist --dsn "postgresql://postgres:password@localhost:5432/postgres?sslmode=disable"

4. Plugins

The official marketplace

Claude Code adds claude-plugins-official by itself the first time you start it interactively. If something blocked that, add it by hand:

claude plugin marketplace add anthropics/claude-plugins-official

Then the two I install everywhere:

claude plugin install frontend-design@claude-plugins-official
claude plugin install gopls-lsp@claude-plugins-official

Both also work as slash commands inside a session (/plugin install frontend-design@claude-plugins-official). The shell form doesn’t run in a session, so plugins it installs load on next start, or after /reload-plugins.

The Go LSP plugin, specifically

gopls-lsp is the one I’d argue is non-optional for Go work. It turns on Claude Code’s built-in LSP tool, which means jump-to-definition, find-references, and real type errors surfaced immediately after an edit — not on the next build, and not via a guess.

The catch: the plugin does not install the language server for you. You need gopls on your PATH first:

go install golang.org/x/tools/gopls@latest
gopls version

If you skip that, the plugin installs fine and then shows Executable not found in $PATH in the /plugin Errors tab. Same pattern for the other languages — pyright-lsp wants pyright-langserver, rust-analyzer-lsp wants rust-analyzer, typescript-lsp wants typescript-language-server.

My own marketplace

sgaunet/claude-plugins is the marketplace I maintain — I wrote about what’s in it in a separate post. Adding it and installing the collections:

claude plugin marketplace add sgaunet/claude-plugins

claude plugin install software-engineering@sylvain-marketplace
claude plugin install devops-infrastructure@sylvain-marketplace
claude plugin install go-specialist@sylvain-marketplace

Note the marketplace is added by repo (sgaunet/claude-plugins) but plugins install against its declared name (sylvain-marketplace). Those don’t have to match, and here they don’t.

There’s a bash-specialist plugin in there too, worth adding if you write shell:

claude plugin install bash-specialist@sylvain-marketplace

/plugin with no arguments lists everything installed, per marketplace.

The extras

The extras/ directory in that repo is deliberately not plugins — they’re two standalone helper scripts, installed independently:

git clone https://github.com/sgaunet/claude-plugins.git
cd claude-plugins

./extras/statusline/configure-statusline.sh
./extras/no-leak/configure-no-leak.sh

statusline puts the active model and context-window usage in front of you, which changes how you work — you stop being surprised by a compaction:

[Opus] ▓▓▓░░░░░░░ 30% | 200k ctx

no-leak is a PreToolUse hook that blocks reads and writes on .env files, credentials, private keys, and vault files. The reason it’s a hook and not a line in CLAUDE.md is the whole point: hooks are enforced by the harness, so the model cannot talk itself past one. Instructions are a request; hooks are a wall.


5. GitHub Spec Kit

Everything above makes Claude Code better at executing. Spec Kit is about deciding what to execute, before any code exists. It’s a workflow of layered documents — constitution, spec, plan, tasks — that lands in your repo as /speckit-* slash commands. My notes on using it, with ready-to-paste constitutions per project type, are in claude/55-github-spec-kit.md.

Install with uv, pinning a release tag rather than tracking main:

uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z
specify version

Then initialize in an existing project and check the wiring:

specify init --here --integration claude
specify check

To move to the latest stable release later:

SPECIFY_VERSION=$(curl -fsSL https://api.github.com/repos/github/spec-kit/releases/latest | jq -r .tag_name)
uv tool install specify-cli --force --from "git+https://github.com/github/spec-kit.git@${SPECIFY_VERSION}"

Launch claude in that directory and the commands are there, in order:

/speckit-constitution   project principles — the rules that apply when the spec is silent
/speckit-specify        what to build, in user-facing terms
/speckit-clarify        structured questioning of the underspecified parts (optional)
/speckit-plan           the tech stack and architecture decisions
/speckit-tasks          an actionable task list
/speckit-analyze        cross-document consistency check (optional)
/speckit-implement      execute

The constitution is where the value is, and it’s the part people write badly. Four rules from my notes that make one actually binding:

  • MUST is a rule, SHOULD is a preference. Without the distinction, the assistant can’t tell “single static binary” (non-negotiable) from “chi or similar” (taste).
  • Every MUST carries its why (... so that ...). The rationale is what the model reasons from when it hits a case you never anticipated.
  • Every MUST names the check that fails when it’s broken — task lint, govulncheck ./..., shellcheck, hugo --panicOnWarning. A rule nothing enforces is a wish.
  • State a dependency policy. May the assistant add a module on its own, or does that need your approval? For AI-generated changes this is one of the most useful lines in the document.

And write one per repo. Don’t factor out a shared base you then have to keep in sync — duplication is much cheaper than drift here.


6. Herdr — the terminal the agents live in

Everything above configures Claude Code. This one configures where it runs, and it’s the piece I added last and now install first on any machine I don’t sit in front of.

The problem is mundane: a long agent run is tied to the terminal that started it. Close the laptop, drop off the wifi, or let SSH time out, and the work goes with it. tmux solves the persistence half of that and I used it for a year, but it has nothing to say about the half that actually costs me time — knowing which of six panes has stopped and is waiting on an answer.

Herdr is a single Rust binary (Apache-2.0) that runs as a background server and owns the terminals rather than living inside one:

curl -fsSL https://herdr.dev/install.sh | sh

On macOS brew install herdr works, and since this machine already pins its toolchain with mise, mise use -g herdr is the option I actually take. Windows is a PowerShell one-liner from the same page.

Then start it where the work lives:

herdr

Run claude inside a pane exactly as before — Herdr doesn’t wrap or replace the agent CLIs, it just owns their terminals, so nothing about the previous five sections changes. Codex, Cursor, opencode and the rest work the same way.

Three things earn it a place here:

  • The work survives the lid closing. The server keeps running; panes come back after a network drop or a reboot. ctrl+b q detaches, herdr reattaches — from another terminal, or over SSH from a different machine entirely.
  • Every pane is marked working, blocked, or idle. This is the real feature. When an agent stops to ask a question, you’re told, instead of discovering it twenty minutes later while cycling through panes.
  • Agents can drive it. There’s a CLI and a matching socket API, so an agent can spawn a pane, prompt another agent, and wait until that one is genuinely blocked rather than polling.

The keybindings are tmux-style prefix keys, and the mouse works too — click, drag, split — which matters more than it sounds when you’re triaging several panes at once.

Two caveats worth knowing before you commit to it. It’s young: the repository was created in March 2026, so treat the API surface as still moving. And the curl | sh installer is the usual bargain — the releases page has plain binaries if you’d rather read the script first or skip it entirely.


The whole thing, in order

# Claude Code
curl -fsSL https://claude.ai/install.sh | bash   # or: brew install --cask claude-code
claude doctor

# code intelligence
curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh | sh
codegraph install && codegraph init

# MCP
claude mcp add --transport http context7 https://api.context7.com
claude mcp add --transport http github https://api.githubcopilot.com/mcp \
  -H "Authorization: Bearer $GITHUB_TOKEN"

# plugins
go install golang.org/x/tools/gopls@latest
claude plugin install gopls-lsp@claude-plugins-official
claude plugin install frontend-design@claude-plugins-official
claude plugin marketplace add sgaunet/claude-plugins
claude plugin install software-engineering@sylvain-marketplace
claude plugin install devops-infrastructure@sylvain-marketplace
claude plugin install go-specialist@sylvain-marketplace

# spec workflow
uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z
specify init --here --integration claude

# the runtime the agents live in
curl -fsSL https://herdr.dev/install.sh | sh   # or: brew install herdr / mise use -g herdr
herdr

Then claude mcp list and /plugin to confirm everything landed, and claude doctor if it didn’t.

References