What a self-hosted runner actually is
A self-hosted runner is a claude process, the same binary you already run locally, started in a special mode on a machine or container your organisation controls. Once it registers, Claude Code sessions started from claude.ai, the Claude mobile or desktop apps, or claude --cloud can pick your environment from the environment selector instead of an Anthropic-hosted one, and that session then runs inside your network with access to whatever internal services the host can reach.
This shipped as a public beta on Team and Enterprise plans with Claude Code v2.1.224, in the week of 3 to 7 August 2026, alongside two other features from the same release: auto mode becoming the default permission mode and cross-session messaging between your open sessions. The Week 32 changelog and the self-hosted environments quickstart are the two Anthropic pages this guide is verified against.
The point of running your own runner instead of an Anthropic-hosted cloud session is network access. A cloud session on Anthropic's infrastructure can't reach a service that only exists behind your VPN or inside your cloud VPC, an internal package registry, a staging database, an on-prem CI system. A self-hosted runner puts the session physically inside that boundary, so it can.
Before you start: prerequisites
There are two separate sides to get right: the claude.ai organisation settings, and the host that will actually run the runner process.
Organisation side
- An Owner or admin has to turn on Allow self-hosted environments on the Cloud environments admin page first. The New button for creating an environment doesn't appear until this is on.
- Your organisation needs a GitHub connection set up, so developers starting sessions can pick a repository.
Host side
- Linux or macOS. Windows is not supported as a runner host. If your fleet is Windows-based, Anthropic's guidance is to run the runner inside a Linux container instead. This is only about where the runner process lives, developer workstations aren't affected, since sessions still start from a browser or app.
- Outbound HTTPS to
api.anthropic.com, toclaude.aiand its download hosts, and to your git host for cloning repositories. - A synchronised clock. Authentication fails if the host's clock is more than five minutes off real time, an easy thing to overlook on a container that doesn't run NTP by default.
- Claude Code v2.1.224 or later, installed with any standard install method. The
self-hosted-runnersubcommand doesn't exist on older versions, the command just prints ordinaryclaude --helpoutput instead. Note that Homebrew'sclaude-codecask and the stable apt, dnf and apk repositories trail thelatestinstall channel by about a week, so pin explicitly if you need the exact version now. - Git 2.24 or newer.
Confirm the host is actually ready before going further:
claude self-hosted-runner --help
A ready host prints the runner's own usage text, including flags like --environment-secret-file. If you instead see the general claude --help output, the installed version predates 2.1.224. Run claude update or reinstall from the latest channel.
Setting up the environment and runner
Claude Code ships a guided setup that walks you through all of this in one interactive session, creating the environment in the admin UI, starting a local runner with the secret you save, confirming registration, and writing a cheat sheet to ./runner-setup/CHEAT-SHEET.md.
claude self-hosted-runner setup
Run it signed in with claude auth login as an account holding an Owner or admin role. It's not available with an API key or a third-party model provider, and it needs to run interactively, so it won't work unattended in something like a headless provisioning script.
If an interactive session isn't possible on the host you're targeting, or you'd rather see every step explicitly, here's the manual version:
1. Create the environment. On the Cloud environments page, under Self-hosted environments, select New, name it, and select Create. On the second step of the wizard, select Copy environment key, this is your environment secret, and claude.ai shows it exactly once. It expires 365 days after creation, and the environment's ccpool_... ID stays visible later in its detail dialog if you need it for anything else.
2. Start the runner. On the host, write the secret to a file that stays out of shell history:
mkdir -p /etc/claude
(umask 077 && cat > /etc/claude/environment-secret)
# paste the secret, press Enter, then Ctrl-D
Then start the runner, pointing --base-dir at a path it can write to (it defaults to /workspace, which only works if that directory already exists and is writable, or you're running as root):
claude self-hosted-runner \
--environment-secret-file '/etc/claude/environment-secret' \
--base-dir '/srv/claude-runner'
The runner registers and starts polling for work. If it can't create or write to --base-dir, it exits immediately at startup with an error naming the directory, rather than registering silently and failing later.
3. Verify it registered. Back on the Cloud environments page, the environment's status should move from No runners deployed to Healthy within a few seconds. Open the environment and select Activity to see the runner itself.
4. Route a session to it. Start a session at claude.ai/code and pick your environment from the environment selector, where self-hosted environments show up alongside Anthropic-hosted ones. The runner clones with whatever git credentials the host already has, so either pick a repository the host can already reach, or a public one, private-repo credentials for production use are covered in Anthropic's production deployment guide. Watch the runner's own log for Picked up session <session-id> to confirm which host actually took it.
runner-setup/
├── CHEAT-SHEET.md # written by the guided setup
/etc/claude/
└── environment-secret # the copied environment key, root-readable only
One thing worth planning for from the start: the runner exits by design once its active sessions finish. That's fine for a quick test, but a production deployment needs an orchestrator (Kubernetes, Compose, or whatever your team already runs) that restarts the runner process automatically, normally with a fresh filesystem on each restart.
Sending a follow-up to a session running on your runner
Once a session is running, you can post a message to it from the claude CLI on any machine where you're logged in, it doesn't have to be the machine that started the session:
claude -p "your message" --cloud <session-id>
<session-id> accepts the bare session_... or cse_... ID, or the session's claude.ai/code URL. A successful send prints Sent to cloud session. with a view link. This works identically against Anthropic-hosted and self-hosted sessions, since the command doesn't care where the session physically executes.
What changes for agent skills
Nothing changes about how Agent Skills are discovered, because a self-hosted runner is running the same claude binary as everywhere else. Two practical points follow from that:
Project-scoped skills need no extra step. A skill committed to a repository's .claude/skills/ directory is part of the checkout the runner clones for the session, exactly as it would be on your own laptop. Nothing about self-hosting changes how Claude Code discovers project skills, because the skill folder travels with the repository, not with the machine.
Personal-scoped skills live on the runner host, not on your laptop. ~/.claude/skills/ on your own machine has no bearing on a session routed to a self-hosted runner, that session runs on the runner host's filesystem, not yours. If you want a skill available to every session that lands on a given runner, it needs to be installed at ~/.claude/skills/ on the runner host itself, under whichever OS user the runner process runs as. For a team standardising on a shared set of skills across a fleet of runners, checking them into the repository at project scope is the more reliable route regardless, since it travels with the code and shows up as an ordinary, reviewable diff rather than something an admin has to keep synchronised by hand across every host.
If you're not yet sure which skills are worth installing anywhere, browse the current catalog at getclaudeskills.com/platforms/claude-code, and read the security guide before trusting anything you didn't write, that advice applies at least as much on a runner with access to your internal network as it does on a personal laptop.
Self-hosted vs Anthropic-hosted cloud sessions
| Anthropic-hosted | Self-hosted runner | |
|---|---|---|
| Where it executes | Anthropic's infrastructure | Your own machine or container |
| Network access | Public internet only | Anything the host can reach, including internal services |
| Setup | None, pick it and go | claude self-hosted-runner setup, or the manual steps above |
| Availability | All plans | Team and Enterprise, public beta |
| Who keeps it running | Anthropic | Your orchestrator (Kubernetes, Compose, etc.) |
| Personal-scope skills | Follow your account, wherever a session runs | Tied to the specific runner host's filesystem |
Neither replaces the other. Anthropic-hosted sessions are the simpler default for anything that only needs public internet access. Self-hosted runners exist specifically for the case where a session needs to reach something a cloud session physically can't.
Troubleshooting
The runner exits immediately instead of registering. Check the error message first, it names the failing directory when --base-dir can't be created or written to. Fix the permissions or point at a different path rather than assuming the secret is wrong.
The environment stays on "No runners deployed." Confirm the runner process is actually still running (it exits once its active sessions finish, by design, so a runner that isn't under an orchestrator can look dead when it's actually just idle and exited cleanly), and that the host's clock is within five minutes of real time. Authentication fails silently past that skew.
A session sits queued and never picks up. No healthy runner is currently available to take it. Check the environment's Activity tab for the runner's own status, and confirm the runner registered against the same environment the session was routed to.
claude self-hosted-runner --help prints ordinary claude --help output. The installed version predates 2.1.224. Run claude update, or reinstall targeting the latest channel rather than stable, which trails by about a week.
The guided setup won't run. It requires an interactive session and an Owner or admin login via claude auth login, it explicitly does not work with an API key or a third-party model provider. Use the manual setup steps on a host where an interactive session isn't possible.
Where to go next
For hardening a runner beyond this initial setup (egress control, git credentials for private repositories, running a fleet under Kubernetes or Compose) see Anthropic's production deployment guide. For the permission model governing what a session can do once it's running, see Claude Code's auto mode explainer. For the skill format itself, What Are Agent Skills? and How to Install Skills in Claude Code cover the basics this guide assumes. Browse the current Claude Code skill catalog at getclaudeskills.com/platforms/claude-code, or everything cataloged at getclaudeskills.com/skills.
