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 | bashOn macOS I use Homebrew instead, since it’s already managing everything else on the machine:
brew install --cask claude-codeNote 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
claudeclaude 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 initcodegraph 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 uninstall3. 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 itThe 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-mcpFor 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-mcpTwo 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 --skillsA 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-officialThen the two I install everywhere:
claude plugin install frontend-design@claude-plugins-official
claude plugin install gopls-lsp@claude-plugins-officialBoth 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 versionIf 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-marketplaceNote 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.shstatusline 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 ctxno-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 versionThen initialize in an existing project and check the wiring:
specify init --here --integration claude
specify checkTo 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 executeThe 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 | shOn 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:
herdrRun 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 qdetaches,herdrreattaches — 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
herdrThen claude mcp list and /plugin to confirm everything landed, and claude doctor if it didn’t.