Skip to content
Pere Villega
Go back

Your First Day With Claude Code

12 min read

A colleague showed me his first Claude Code session last year. He’d opened a terminal in his home directory, typed a prompt, and was watching the agent happily read his .env files and get confused by three unrelated projects in adjacent folders. Two hours later he told me the technology was overhyped.

His setup was wrong. The agent wasn’t bad; the environment around it was a trap.

I’ve seen versions of that pattern more than once. This chapter is the checklist I wish I’d had on day one.

Account Options

You have a few paths to using Claude Code.

Claude offers subscription plans with usage limits, while API access is billed by usage. The names, limits, and prices change, so check the current pricing rather than treating figures in a setup guide as permanent.

The API option, paying per token, makes more sense for very heavy use when a subscription is not enough, particularly when you’re running multiple sessions in parallel or when using third-party clients. For serious daily use, Requesty is worth evaluating: it’s a proxy that optimises token costs across providers.

The choice depends on your usage pattern. Set a budget, measure what you consume, and avoid judging the whole tool from a rate-limited session.

Isolation First

This is the most important section of this chapter. I’m putting it second instead of fifth because if you get this wrong, nothing else matters.

Every agent session should run inside a container or isolated VM. No mounts to your host filesystem. No production tokens in environment variables. Dev-scoped everything. Sounds paranoid. It isn’t.

A coding agent with access to your .ssh keys, .aws credentials, .kube config, and shell configuration can turn a bad command or prompt injection into a security incident. Trail of Bits documents this risk explicitly. Repository content should be treated as untrusted input when an agent can run commands or reach the network.

Claude Setup

The Trail of Bits production setup uses two layers of defence. Layer 1: deny rules in settings.json that block reads of sensitive paths like SSH keys, cloud credentials, package registry tokens, git credentials, shell config, macOS keychains, and even crypto wallets. Layer 2: the /sandbox command, which enforces those rules at the OS level using Seatbelt on macOS or bubblewrap on Linux.

What most people miss is that without /sandbox, deny rules only block Claude’s Read tool. A Bash command like cat ~/.ssh/id_rsa still works. The deny rules and the sandbox complement each other. Use both.

Which Container

There are many options to wrap your Claude Code environment, and it seems everybody is creating their own sandbox, even me. A few alternatives follow.

DevContainers are useful here. Configure them without host mounts and be deliberate about Docker access. Anthropic ships an official devcontainer feature (ghcr.io/anthropics/devcontainer-features/claude-code:1.0) that you can add to a devcontainer.json. Treat it as a starting point and inspect the mounts, credentials, network access, and Docker configuration before relying on the boundary.

Trail of Bits has gone further with devc, a dedicated CLI for managing sandboxed Claude Code environments. devc . installs the template and starts the container. devc shell drops you in. Their workspace pattern is clean: create a directory, run devc ., clone repos inside the container. Full isolation, shared volumes across repos, disposable when done.

For stronger separation, Trail of Bits also offers dropkit, a CLI tool for spinning up disposable DigitalOcean droplets with automated setup, SSH config, and Tailscale VPN. Create a droplet, SSH in, run Claude Code, then destroy it when finished. Provider logs, snapshots, or copied credentials may still outlive the VM.

Codespaces offer good isolation and don’t require your laptop to be on. You can work on parallel branches, but a disposable environment does not make --dangerously-skip-permissions safe by itself. Use that mode only when the codespace has no sensitive credentials or host mounts, its network access is restricted, and it cannot reach staging or production services. The downside: no ~/.claude/CLAUDE.md, so you need to keep all guidelines in the repo. First startup is slow; subsequent runs are faster. Limited free tier: remember to delete unused codespaces.

Even a low-cost VPS can work. Chris Parsons runs Claude Code on an Ubuntu VPS, keeps sessions alive with tmux, and connects over SSH. That is a pragmatic option if you are willing to patch and secure another machine.

A note on Lima and Colima for macOS users: Lima’s default instance template mounts host paths, often from $HOME, as read-only. For normal development, that’s a convenience feature. For Claude Code with --dangerously-skip-permissions, it’s a security hole. SSH keys, .env files, cloud credentials, all potentially readable inside the VM. If you’re using Colima, Trail of Bits recommends vz + virtiofs + rosetta for performance, and cloning repos inside the VM where you get native ext4 speed rather than relying on bind mounts.

Five minutes on isolation saves the incident response you’ll never have to write.

The Native Sandbox

Since mid-2025, Claude Code ships with a built-in sandbox that provides filesystem and network isolation using OS-level primitives: Seatbelt on macOS, bubblewrap on Linux. Type /sandbox in a session to enable it. Anthropic’s engineering team reports that sandboxing reduces permission prompts by 84% in their internal usage. That’s a number worth paying attention to.

The sandbox enforces two boundaries: filesystem isolation (writes restricted to the current working directory, reads unrestricted except for explicitly denied paths) and network isolation (connections only to approved domains, everything else blocked). Critically, all child processes inherit these restrictions: a subprocess spawned by a build script can’t circumvent the rules.

With the sandbox enabled, you can run in auto-allow mode: sandboxed Bash commands execute without permission prompts, while anything that tries to reach outside the boundary triggers a notification. This addresses what I’d call “approval fatigue”, the pattern where constant “approve this command” prompts train you to click through reflexively. You get the worst of both worlds: interrupted flow and reduced security.

The sandbox doesn’t replace container isolation for high-risk scenarios. The VM boundary is the stronger security boundary; everything inside it is defence-in-depth. For day-to-day development on trusted repositories, /sandbox with auto-allow offers a useful layer with modest setup. I still use stronger isolation when the repository or credentials raise the stakes.

Terminal Setup

Claude Code is a terminal application, and the terminal you use matters more than you’d think.

Ghostty is Trail of Bits’ recommendation, and I agree. Native Metal GPU rendering handles high-volume Claude Code output without lag. Built-in split panes with Cmd+D. Shift+Enter and key bindings work without needing /terminal-setup.

Session management is essential. You’ll be running multiple Claude sessions simultaneously at some point. Use tmux or zellij for persistent sessions. When you close your laptop or lose connection, your sessions keep running. This is not a nice-to-have; it’s infrastructure the moment you run parallel agents.

Notifications matter because you’ll be multitasking. Enable system notifications so you know when Claude needs input or has finished a task. On macOS, a simple hook configuration can send a notification via osascript. Andrew Ford documented an even better pattern using ntfy.sh, a free, self-hostable HTTP notification service that pushes alerts to your phone the instant Claude needs attention. The notification hook fires when Claude needs permission or when prompt input has been idle for 60 seconds or more.

Dictation is useful when a prompt needs more context than you would comfortably type. wisprflow.ai is one option; macOS dictation is another. Claude also has a /voice command, although it still has rough edges. Dictation is faster for me on longer prompts, but the value comes from clearer detail rather than speed alone.

Add Code Intelligence

This is the single highest-impact configuration change you can make, and it takes two minutes. If you only do one thing from this entire chapter, set up your sandbox. If you do two, make this the second one.

Without LSP, Claude Code navigates your codebase using text search: Grep, Glob, and Read. It treats code as text. When you ask “where is this function defined?”, Claude greps across the entire codebase. For a common symbol like User, that might mean hundreds of matches across dozens of files. Claude reads through each to narrow it down. Tens of seconds and many tokens consumed.

With LSP, the same query can return the exact file and line directly. This is the same code intelligence your IDE uses.

The context window savings are significant. Instead of reading dozens of files to find a definition, Claude gets a precise answer and reads only the one file it needs.

The killer feature is self-correcting edits. After every file edit, the language server pushes diagnostics: type errors, missing imports, undefined variables. Claude sees them immediately and fixes them in the same turn, before you see the result. Without LSP, you’d get the result, try to compile, see errors, paste them back. Each round trip consumes more context. With LSP, that entire loop collapses into one step.

Setup

Step 1: Add to ~/.claude/settings.json:

{
  "env": {
    "ENABLE_LSP_TOOL": "1"
  }
}

Also add export ENABLE_LSP_TOOL=1 to your shell profile as fallback.

Step 2: Install the language server binary for your stack. Some common ones are:

Step 3: Install and enable the plugin:

claude plugin marketplace update claude-plugins-official
claude plugin install pyright-lsp
claude plugin list  # verify enabled

Step 4: Restart Claude Code. LSP servers initialise at startup and index the full project. Verify by asking “What type is [some variable]?”. If it uses LSP hover instead of reading the file, it’s working.

An issue to take into account: a plugin can be installed but disabled. This accounts for most “LSP isn’t working” reports. I’ve been bitten by this myself.

Even with LSP enabled, Claude may default to Grep/Read/Glob out of habit. It’s a stochastic machine after all. Add a nudge to your CLAUDE.md:

### Code Intelligence

Prefer LSP over Grep/Glob/Read for code navigation:

- goToDefinition / goToImplementation to jump to source
- findReferences to see all usages across the codebase
- hover for type info without reading the file
  After writing or editing code, check LSP diagnostics before moving on.

Token Monitoring

Tokens are your currency, and like any currency, it’s worth knowing how much you’re spending.

The longer a conversation runs, the more each message costs, because each new request sends the entire previous conversation. This is not linear growth. It creeps up on you.

I use ccstatusline to track token consumption and session resets. Run /context regularly to see how much of your window is actually free. You might be surprised at how little room you have after tools, MCPs, and CLAUDE.md files load. Yes, MCPs and other bits now load dynamically, not at the start. That is a trap: you expect a session to have plenty of room until an MCP with terrible token efficiency loads and takes half of what you had left.

We’ll cover context management in depth later in this series. For now, just be aware that context is finite and precious, and start building the habit of checking /context.

The New Project Checklist

When starting a new project, or introducing Claude Code to an existing one, verify these before writing a single prompt:

Which MCPs may be useful? Postgres, SQLite, Slack, Honeycomb… think about what external tools the agent might need. But be judicious: each MCP consumes context tokens just by existing (when loaded). It’s a trade-off.

Which CLI tools should be available? Document them in CLAUDE.md if they are not common tools, so the agent knows they exist.

Is the DevContainer or isolation setup configured? Are secrets scoped to development only? Is there a risk of someone accessing staging or production data through that token in .env?

Does a CLAUDE.md exist? This is something that has evolved recently. Traditionally people recommended even a minimal one with linter commands, test commands, files not to read, etc. Recent research leans towards files that do not duplicate what Claude can read by itself. For example, your linter configuration may be defined in package.json, no need to tell Claude twice by adding it to CLAUDE.md. This file is valuable; just add important data: ask Claude not to use patterns it tries to use often, mention things that are not obvious from the codebase, etc.

Is there a testing framework in place? If the agent can’t verify its work, the quality drops dramatically. Give Claude a way to check its own work and quality improves noticeably. I’d go further: without tests, you’re asking the agent to code blindfolded. Not everybody tests as much as they should; that’s something to correct if you expect any success from your AI experiments.

What NOT to Install

The pace of activity around Claude Code is extraordinary. Check the commit activity on awesome-claude-code and you’ll see what I mean. There’s a natural temptation to install everything that looks promising.

Resist it. Every skill, MCP, and configuration file loaded into the context window reduces the space available for actual work. Run /context after installing anything new and see the impact. Be very deliberate about what’s enabled.

Start Lean on Purpose

I have a setup I use and would recommend, but I am not listing it here on purpose. If you are starting with Claude, start minimal. The model is very capable on its own, and if you add a lot of tooling you may not get to understand what it can or can’t do.

Add tools as you discover you need them. An MCP to let the model drive Chrome against your app. A skill or two to enforce TDD. Grow it incrementally.

The best setup is the one where you understand every piece and why it’s there. My colleague, the one from the opening, eventually went back to Claude Code. He started with a container, an LSP, and nothing else. He hasn’t called it overhyped since.


Share this post on:

Previous Post
The One File That Makes or Breaks Your AI Workflow
Next Post
AI Is an Exoskeleton, Not a Coworker