Claude setup-token: the one-year token and what it can't do
claude setup-token prints a one-year Claude subscription token for scripts and CI. It can't run Remote Control, so a lapsed login needs /login on the machine.
claude setup-token runs the same browser sign-in as /login, then prints a Claude subscription token that lasts one year and is saved nowhere. You set it as the CLAUDE_CODE_OAUTH_TOKEN environment variable wherever Claude Code has to run without a browser, such as a CI job or a script calling claude -p, or paste it into a tool that accepts one, such as OpenClaw. It needs a Pro, Max, Team or Enterprise plan, and it can only make model requests: it can’t start Remote Control or load claude.ai connectors.
So it won’t fix “Login expired · Please run /login” on a machine you drive by Remote Control. Remote Control runs only on the full login, and /login can’t be sent from the phone, so the login is renewed in a terminal on the machine itself: keep Claude Code in tmux, SSH in from your phone, attach, and run /login.
What the command does
claude setup-tokenIt opens the same authorization flow as /login. Once you approve in the browser, the token prints to the terminal, once; Claude Code keeps no copy. Anthropic’s authentication docs call it a “one-year OAuth token” for “CI pipelines, scripts, or other environments where interactive browser login isn’t available.” If the machine that needs it can’t complete a browser sign-in, the errors reference suggests running the command on a machine where sign-in works and carrying the token over. The tokens start with sk-ant-oat01-, as OpenClaw’s docs note.
The token is your subscription, not a separate account. It authenticates as whoever ran the command and draws on that plan’s usage limits, which is why Anthropic’s GitHub Actions docs recommend a Console API key instead for a secret shared across repositories, “since an OAuth token is tied to the subscription of the person who ran claude setup-token.”
Using it in scripts and CI
Claude Code reads it from CLAUDE_CODE_OAUTH_TOKEN. For a script or a scheduled job on a server, store it once in a file only your user can read, and load it in the job that needs it:
# once: paste the token at the silent prompt
(umask 077; read -rs t; printf 'CLAUDE_CODE_OAUTH_TOKEN=%s\n' "$t" > ~/.claude-token.env)
# in the script or cron job
set -a; . ~/.claude-token.env; set +a
claude -p "summarise yesterday's failed builds"read -rs takes the pasted value without echoing it or writing it to your shell history, and umask 077 makes the file readable by you alone.
In GitHub Actions it goes in a repository secret named CLAUDE_CODE_OAUTH_TOKEN, passed to Anthropic’s action as claude_code_oauth_token. Running /install-github-app inside Claude Code offers to create the token and save the secret for you.
Scope it to the job rather than exporting it from ~/.bashrc. In Anthropic’s authentication precedence the variable ranks above your /login, so every interactive session started with it set runs on the token. Running /login switches only the current session; each new session reads the variable again until you remove it from your shell profile or the env block of a settings file.
What it can’t do
- Remote Control. The token “can only make model requests, so it can’t establish Remote Control sessions.” With it set, starting Remote Control fails with:
The Remote Control troubleshooting fix is to sign in withRemote Control requires a full-scope login tokenclaude auth logininstead. API keys aren’t accepted either: Remote Control needs the claude.ai login. - claude.ai connectors. Connectors you added on claude.ai don’t load. MCP servers configured on the machine itself still work.
- Bare mode.
claude --barenever reads the variable; bare mode needsANTHROPIC_API_KEYor anapiKeyHelper.
When it expires
A year after you made it. Anthropic’s docs describe a warning three days before an ordinary /login sign-in expires, and none for this token, so put the date somewhere you will see it. Once it lapses or is revoked, requests fail with:
Please run /login · API Error: 401 OAuth token has expired ...Despite the wording, /login is not the fix for a session that gets its credential from the variable. The errors reference says Claude Code keeps sending the value you set after a 401: generate a fresh token, replace it wherever you stored it, and restart.
Keeping it out of the wrong places
Whoever holds the token can make model requests on your plan until it expires. Besides shell history, which the read -rs above keeps it out of, it tends to end up in two places:
- Scrollback. It prints once into your terminal. Clear the screen after copying it; inside tmux,
tmux clear-historydrops the pane’s scrollback too. - A committed settings file. Claude Code applies the
envblock of its settings files, and a project’s.claude/settings.jsonis usually in the repository. Keep the token in your CI’s secret store or a file outside the repo.
Searching your repositories and dotfiles for sk-ant-oat01- finds stray copies. Deleting a stored copy doesn’t invalidate the token: the GitHub Actions docs say a deleted secret’s credential “stays valid.” Anthropic’s docs give no command to list or revoke these tokens; users have reported finding them under Authorization tokens at claude.ai/settings/claude-code.
Using it with OpenClaw
OpenClaw’s authentication page, read on October 1, 2026, says “Anthropic setup-token auth remains a supported path.” Run claude setup-token on any machine, then store the token on the gateway host with this command, which needs an interactive terminal:
openclaw models auth login --provider anthropic --method setup-tokenOpenClaw keeps the token in its own credential store and sends model requests with it. The other subscription route OpenClaw’s Anthropic page documents works differently: with --method cli, OpenClaw drives the Claude Code installed on the gateway host and leaves the login to Claude Code. That is the ordinary /login, and when it lapses OpenClaw’s fix is claude auth login as the gateway’s user on that host, then openclaw gateway restart. For an always-on gateway, OpenClaw’s docs still call an Anthropic API key “the most predictable choice.”
Anthropic’s position on subscriptions in third-party tools has changed several times in 2026, and using a Claude subscription with OpenClaw walks through the changes. The latest note on Anthropic’s Agent SDK support page, dated June 15, 2026 and unchanged on October 1, says claude -p “and third-party app usage still draw from your subscription’s usage limits.” Its legal and compliance page describes subscription sign-in as “designed to support ordinary use of Claude Code and other native Anthropic applications.”
“Login expired” over Remote Control: why the token isn’t the fix
Remote Control keeps its connection on short-lived credentials that Claude Code obtains and renews from your saved claude.ai login, the one /login creates. That login is the only credential it accepts. Anthropic doesn’t publish how long it lasts. Claude Code renews it in the background, and when a renewal is rejected, it clears the saved credentials. From then on every model request stops on the machine with:
Login expired · Please run /loginThat is what the phone shows. When the connection’s own credential next comes due, Claude Code drops Remote Control as well, with a line in the session such as:
Remote Control disconnected — Claude.ai login expired — run /login to restore Remote ControlThe authentication docs are plain about an unattended session: a Remote Control session “that outlives the login stops making progress once the credential expires and can’t recover until you sign in again.”
The phone can’t do the signing in. /login is not among the commands the Remote Control docs list as working from mobile and web, and a screenshot posted on X on September 27, 2026 shows the app’s answer when you send it anyway:
/login isn't available over Remote Control.The post’s author reports the login lapsing every one to two weeks on a home PC left running as a server.
Signing in again from your phone
The fix is /login typed into Claude Code on the machine, so the setup that survives a lapse is one where your phone can reach that terminal. The Remote Control docs already say to start a session on a remote machine inside tmux or screen so it outlives your SSH connection, and tmux also gives you something to attach to later:
tmux new -s claude
claude --remote-control
# detach with Ctrl-b d; the session keeps runningWhen the login lapses, connect from the phone with an SSH client (the iPhone options), over a private network such as Tailscale if the machine has no public SSH port, and attach:
ssh you@your-machine
tmux attach -t claudeThen, in the Claude Code session:
- Type
/loginand choose the sign-in with your Claude subscription. - Claude Code shows a sign-in link. On a phone-width terminal it wraps across lines; the troubleshooting page says pressing
ccopies it “when the URL wraps across lines in a narrow or SSH terminal.” Open it in the phone’s browser and sign in. - The browser can’t hand the result back to a server, so it shows a code. Paste it at the
Paste code here if promptedprompt. - If the disconnect line ended “run /login, then /remote-control”, run
/remote-control. A line ending “run /login to restore Remote Control” reconnects by itself once you are signed in.
In server mode (claude remote-control) there is no prompt to type into. Stop the server with Ctrl+C, run claude auth login, which takes the pasted code the same way, and start claude remote-control again in the same directory: for about four hours after it stopped, it brings back the sessions it was serving.
Fewer lapses at awkward moments
Renew while you are at the machine anyway: running /login renews the login, and Anthropic names unattended Remote Control sessions as the ones where renewing early matters most. Claude Code does warn three days before the login expires, but the docs place that warning at startup, so a session that has been running for weeks would not show it.
If you are asked to sign in again often, the troubleshooting page names two causes. One is a wrong system clock, because “token validation depends on correct timestamps”; on Linux, timedatectl shows whether the clock is synchronized. The other is Claude Code older than v2.1.211, where two sessions renewing the same login after the machine woke from sleep could revoke it for every open session; claude update rules that out.
If you’d rather not depend on the login
Cloud sessions run on Anthropic-managed machines by default, started from the app or claude.ai, so they don’t depend on a login saved on a machine of yours, though the work no longer happens on your machine either. Using Claude Code from your phone compares them with Remote Control. Channels, which bring Telegram or Discord into a Claude Code session on your machine, accept a Console API key according to the channels docs; an API key is a static credential with no login to renew, billed per token rather than from your plan, and channels are still a research preview. And if the machine’s real job is scheduled or scripted work rather than a session you steer, the setup token is the credential built for it.