The code is on the server. The database is on the server. The production logs are on the server. Pointing an agent at a stale checkout on your laptop and syncing changes up and down is busywork, and it gets the agent's context wrong. The fix is to run Claude Code on a remote Linux server — Anthropic's agentic CLI, sitting right next to the repo, the database, and the logs it needs to reason about. The setup is short: npm install, run the binary, log in. Two things bite people, and both are environmental rather than hard: headless authentication (there's no browser on the server) and persistence (a dropped SSH connection takes your session with it). Solve both up front and the rest is the same Claude Code you already use locally.
How do I install and run Claude Code on the server?
Claude Code installs from npm and runs as the `claude` command. SSH into the box as a normal deploy user (not root — more on that below), make sure you have a current Node.js, and install it globally. If npm's global prefix points at a system directory you'll hit EACCES permission errors; set the prefix to somewhere in your home directory first so you never need sudo for a global npm package.
# Keep global npm installs in your home dir — no sudo, no EACCES
mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global
export PATH="$HOME/.npm-global/bin:$PATH" # add this line to ~/.bashrc too
# Install the CLI and confirm it's on PATH
npm install -g @anthropic-ai/claude-code
claude --versionOnce `claude --version` prints, you're installed. Start it inside your project directory and run `/login` to authenticate. That's where the headless part comes in.
How do I log in when there's no browser on the server?
On your laptop, `/login` opens a browser tab and the OAuth flow completes on its own. On a headless server there's no browser to open, so Claude Code falls back to a URL-and-code flow: it prints a long authorize URL to the terminal, you open that URL on your laptop, approve, and paste the resulting code back into the SSH session. Don't try to forward a browser or set up X11 — the paste-back flow is the intended path and it's faster.
cd ~/projects/my-app
claude
# Inside the CLI:
/login
# Claude Code prints an authorize URL. Open it in your LAPTOP browser,
# approve, copy the code it gives you, and paste it back here at the prompt.Credentials get written to disk on the server after that, so you only do this once per profile. If you bounce between several accounts — a personal one and a client's, say — keep their credentials apart with a config directory per profile. That's the same isolation idea I covered for the desktop in running multiple Claude profiles on Windows; on Linux it's one environment variable.
How do I keep the session alive when SSH drops?
This is the gotcha that wastes the most time. Claude Code is a foreground process tied to your SSH session. Wi-Fi blips, your laptop sleeps, the VPN reconnects — the SSH connection dies, and your running Claude Code session dies with it, mid-task. The fix is to run it inside a terminal multiplexer so the process keeps running on the server even when your client disconnects. Start a tmux session, run Claude Code inside it, and reattach later from anywhere.
# Start (or reattach to) a named session
tmux new -As claude
# Inside tmux, run Claude Code as normal
cd ~/projects/my-app
claude
# Detach without killing it: Ctrl-b then d
# Later, from a fresh SSH connection:
tmux attach -t claude`screen` works the same way if that's what's already on the box (`screen -S claude` to start, `screen -r claude` to reattach). Either way, an agent running a long refactor or a test suite keeps going while you close your laptop, and you pick it back up exactly where it was.
The first time a dropped SSH connection kills a 20-minute agent run, you learn to start everything inside tmux. Do it from day one and save yourself the lesson.
How do I keep a separate config for the server?
Claude Code stores its credentials, history, and settings under a config directory, and the `CLAUDE_CONFIG_DIR` environment variable controls where. Point it at a per-profile path and you get clean isolation: a server profile that never collides with anything else, and multiple accounts on the same box without one stomping the other's tokens. Export it before launching, ideally wired into your shell profile or a small wrapper script.
# A dedicated config dir for this server profile
export CLAUDE_CONFIG_DIR="$HOME/.config/claude-prod"
claude # uses ~/.config/claude-prod for creds, history, settings
# A second account on the same machine? Different dir, different login:
export CLAUDE_CONFIG_DIR="$HOME/.config/claude-client-x"
claudeWhat else trips people up?
A handful of things, mostly around the user account and the network the agent can actually reach:
- Don't run as root. Run as the deploy user that owns the repo, so files Claude Code writes have the correct ownership and a misfired command can't touch the whole system. Log in as root and the agent's writes end up root-owned, leaving your app user unable to read them.
- Match file permissions to the deploy user. If the project is owned by `www-data` or a CI user, either run Claude Code as that user or fix ownership first — otherwise edits fail with permission errors mid-task.
- MCP servers have to be reachable from the box. An MCP server bound to your laptop's localhost is invisible to the remote machine; an MCP server exposes its tools, resources, and prompts to the client over a transport like stdio or Streamable HTTP, and the remote `claude` is the client here. Run the server on the box, or expose it over the network and point Claude Code at that address. If MCP is new to you, start with what an MCP server actually is.
- Lock the box down first. A server you SSH into and run an agent on is a real attack surface — SSH keys only, a firewall, and no extra exposed ports. The basics are in my server hardening guide for web developers.
- Mind the cost of a long run. A capable default model is exactly what you want for autonomous work, but a long unattended run on a server spends tokens whether you're watching or not — set a budget expectation before you let it go overnight.
The recipe is short: install under a non-root deploy user, authenticate once with the URL-and-code flow, run inside tmux so disconnects don't matter, and isolate each profile with `CLAUDE_CONFIG_DIR`. Get those four right and Claude Code on a remote Linux server behaves exactly like the local CLI — except it's sitting next to your production code instead of a stale checkout on your laptop. That proximity is the entire reason to do it, and once the persistence and auth are sorted, you stop thinking about the setup and just work.

