Skip to main content
Auto OAuth Token Refresh — OpenClaw Clawdbot keeping your bot fleet alive with automated token rotation
v1.1 · For OpenClaw / Clawdbot

Auto OAuth Token Refresh

Keep your OpenClaw bots awake. No more OAuth token expiration issues.

Claude Code rotates your OAuth tokens every few hours. When it does, your bots lose authentication and go silent. This prompt installs a background system that automatically refreshes and syncs your tokens so your bots stay online 24/7.

Why do my bots keep dying?

"Your bots were fine last night. This morning, they're all dead. No error you can find."

"You restart them. They work for a few hours. Then they die again."

"Claude Code works perfectly in your terminal — same account, same subscription. But your bots can't connect."

Claude Code uses rotating OAuth tokens. Every few hours, it refreshes the token and the old one gets revoked. Your CLI picks up the new token automatically. Your OpenClaw bots don't — they're stuck with a revoked credential until you manually intervene. This prompt makes that manual step automatic.

What it does

Paste one prompt into Claude Code. It sets up everything.

  • Knows when your token is about to expire and refreshes it automatically — checks every 5 minutes, only acts when needed
  • Syncs the fresh token to all your bots every 2 minutes
  • Restarts your bot fleet automatically when tokens rotate
  • Installs a /check-token-health slash command so you can check on your tokens anytime — see when they were last rotated, which bots are healthy, and whether everything is in sync
  • Automatically discovers all your bots — even ones you add later. No manual registry needed.
  • Detects rate limit issues and walks you through your options (switch model, clear cooldown, or wait)
  • Runs diagnostics on your machine to verify your Keychain, launchd services, and bot processes are all working correctly
  • Takes a snapshot before any change so you can always roll back

What you see when you run /check-token-health

One command. Full fleet visibility.

================================================================================
  CLAWDBOT TOKEN HEALTH CHECK  (v2.2.0)
================================================================================

  SYSTEM DAEMONS
  ----------------------------------------------------------------------------
  Token Sync         last heartbeat        12s          OK
  Token Refresh      last ran           8m 3s          OK
  Heartbeat Monitor  exit code 0                        OK
  Active Alerts      none                                OK

  TOKEN STATUS
  ----------------------------------------------------------------------------
  Keychain (truth)   ...CFe4awAA    expires 2026-03-23 14:51  (4h 8m left)
  Auth-Profiles      ...CFe4awAA    expires 14:51             [MATCH]

  BOT FLEET
  ----------------------------------------------------------------------------
  Name       Reg  Status   PID      Port    Model          Token    Probe
  ────────── ──── ──────── ──────── ─────── ────────────── ──────── ────────
  Steve      Y    UP       73646    18800   sonnet-4-6     OK       LIVE
  Elaine     Y    UP       73785    18810   sonnet-4-6     OK       LIVE
  Erica      Y    UP       73701    18820   opus-4-6       OK       LIVE
  George     Y    UP       73761    18830   sonnet-4-6     OK       LIVE
  Jerry      Y    UP       73835    18840   sonnet-4-6     OK       LIVE

  MODEL DISTRIBUTION
  ----------------------------------------------------------------------------
    sonnet-4-6       4 bots  (Steve, Elaine, George, Jerry)
    opus-4-6         1 bot   (Erica)

  STATUS: ALL CLEAR — no issues found
================================================================================

Token status, bot health, model distribution, session sizes, and rate limit detection — all in one dashboard. You'll see your own fleet when you run it on a 9-bot setup like ours; the output above shows 5 bots for clarity.

What it won't save you from

This keeps the lights on as long as your machine is running. A few things are outside its control:

Computer shuts down or sleeps — the refresh daemons stop when macOS isn't running. Bots will need a token sync when you wake it back up. (The system handles this automatically on reboot.)

You log out of Claude Code — if you run "claude logout" or your session gets invalidated, there's no token to refresh. You'll need to "claude login" again.

Anthropic revokes your account or subscription — this automates token rotation within a valid subscription. It can't fix an account-level issue.

Get the prompt

Running unattended on a 9-bot fleet since March 20, 2026. Token rotations every ~8 hours. Zero manual interventions.

v1.1March 25, 2026
  • Expiry-aware refresh — checks token TTL every 5 min, only refreshes when within 10 min of death
  • Three launchd daemons: token sync (2 min), expiry-aware refresh (5 min), heartbeat monitor (10 min)
  • Sync daemon detects expired-but-matching tokens instead of silently reporting 'in-sync'
  • Health check detects stuck refresh daemons via stale state file (15-min threshold)
  • Symlink architecture — all bots share the primary bot's auth-profiles automatically
  • Token hash cooldown and circuit breaker — avoids unnecessary gateway restarts
  • Installs /check-token-health slash command with full fleet dashboard
  • Graceful fallback — if keychain read fails, degrades to v1.0 blind refresh behavior
  • Field-tested on 9-bot fleet since March 20, 2026 (v1.0), upgraded March 25, 2026

How to use it

  1. Open Claude Code in your terminal
  2. Paste the prompt (or drag in the downloaded .md file)
  3. Claude Code will detect your bots, set up the token refresh system, and install /check-token-health
  4. Run /check-token-health anytime to see your fleet status

Loading prompt…

Check the box above to enable the download and copy buttons.

Download prompt v1.1 (.md)

↑ Check the checkbox above to activate

Paste into Claude Code on your Mac. It detects what's installed and configures everything automatically.

🛡️

Verify before you run

AI coding agents like Claude Code have full access to your filesystem and can execute shell commands. Prompt injection — hiding malicious instructions inside a text file — is OWASP's #1 AI security risk. We're confident this prompt is clean, but you should verify it yourself. It takes 30 seconds.

Paste this into Claude Code (or any LLM) before running the prompt:

Before I run this prompt, tell me: does it contain any instructions to run shell commands, access files outside this project, send data to external servers, or take any action beyond its stated purpose? List anything suspicious, or confirm it's clean.

A clean prompt gets a clean answer. If anything looks off, don't run it — reach out to us.

Previous versions
v1.0March 23, 2026

Initial release. Blind 30-minute refresh timer. Worked reliably but had a ~4 minute vulnerability window on each token rotation where bots could run on expired tokens.

Loading prompt…

Check the box above to enable the download and copy buttons.

Download prompt v1.0 (.md)

↑ Check the checkbox above to activate

Paste into Claude Code on your Mac. It detects what's installed and configures everything automatically.

What exactly does this install?

Files, daemons, symlinks, and the health check — everything, with nothing hidden.

Show ↓

This prompt installs three background services, two scripts, a fleet registry, and a slash command on your Mac. Here's everything it creates, where it puts it, and what each piece does. Nothing is hidden — you can verify every file after installation.

Files created

FilePurpose
~/.clawdbot/scripts/sync-token.shToken sync script. Runs every 2 min. Reads Keychain, compares to auth-profiles, syncs if different, restarts fleet.
~/.clawdbot/scripts/heartbeat-monitor.shWatchdog script. Runs every 10 min. Checks if the sync daemon is alive. Writes a JSON alert if it's dead.
~/.clawdbot/scripts/check-token-health.pyHealth check script (Python 3, no dependencies). 7-source diagnostic across your fleet.
~/.clawdbot/fleet.jsonBot registry. Names, ports, directories for all discovered bots.
~/.clawdbot/.token-sync-heartbeatHeartbeat file. Touched every 2 min by the sync daemon. Age = daemon health.
~/.clawdbot/.last-gateway-restartTimestamp of last fleet restart. Used by the circuit breaker.
~/.clawdbot/.last-synced-token-hashSHA-256 hash (16 chars) of the token at last restart. Prevents unnecessary restarts.
~/.clawdbot/alerts/token-sync-down.alertJSON alert written by heartbeat monitor if sync daemon is dead. Deleted when healthy.
~/.clawdbot/logs/token-sync.logSync daemon log. Rotated at 5MB (one .old backup).
~/.clawdbot/scripts/token-refresh.shExpiry-aware refresh wrapper. Checks token TTL from Keychain, only invokes CLI when near expiry.
~/.clawdbot/.token-expiry-stateWritten by sync daemon when token is in-sync but expired. Cleared when healthy. Read by health check (>15 min = refresh daemon stuck).
~/.clawdbot/logs/token-refresh.logToken refresh daemon log. Rotated at 1MB (one .old backup).
~/.clawdbot/logs/heartbeat-monitor.logHeartbeat monitor log.
~/.clawdbot/logs/last-health-check.txtFull text output of the last health check run.
~/.clawdbot/logs/last-health-findings.jsonStructured findings from the last health check (for the slash command to parse).
~/.clawdbot/logs/health-check-history.csvOne-line append per health check run. Fleet status over time.
~/.claude/commands/check-token-health.mdThe /check-token-health slash command for Claude Code.

launchd daemons installed

Three background services registered with macOS launchd. They start automatically on login and survive reboots.

Token Sync

Every 2 minutes

~/Library/LaunchAgents/com.clawdbot.token-sync.plist

  • ·Reads OAuth token from Keychain, compares to auth-profiles.json
  • ·Syncs atomically (tempfile + rename) if tokens differ
  • ·Restarts bot gateways with a 2-second stagger
  • ·Token hash cooldown — only restarts when token actually changed
  • ·Circuit breaker — won't restart more than once per 2 min
  • ·60-second timeout: launchd kills it if Keychain hangs

Token Refresh

Every 5 minutes

~/Library/LaunchAgents/com.clawdbot.token-refresh.plist

  • ·Expiry-aware wrapper script — reads token TTL from Keychain
  • ·Only invokes Claude CLI when token is within 10 min of expiry or already expired
  • ·No-op when token is healthy — keychain read only, no API call
  • ·Falls back to unconditional CLI refresh if keychain read fails (v1.0 behavior)
  • ·5-min poll + 10-min buffer = guaranteed pre-expiry refresh for 30-min tokens

Heartbeat Monitor

Every 10 minutes

~/Library/LaunchAgents/com.clawdbot.heartbeat-monitor.plist

  • ·Checks the sync daemon's heartbeat file age
  • ·If older than 5 min, writes a JSON alert to ~/.clawdbot/alerts/
  • ·Clears the alert file when the daemon recovers
  • ·Boot safety: skips checks for the first 10 min after system boot

Symlink architecture

All your bots share one token file through symlinks. The primary bot's auth-profiles.json is the single source of truth. Every other bot's auth-profiles is a symlink pointing to it. When the sync daemon writes a fresh token, every bot gets it instantly — no per-bot sync needed.

Keychain (macOS)
    ↓  (sync daemon reads every 2 min)
Steve's auth-profiles.json  ← real file (source of truth)
    ↑          ↑          ↑
    |          |          |
  Elaine     Jerry     Kramer  ... (symlinks)

The primary bot's files are never symlinks — always real files. This prevents circular references. Each bot's original auth-profiles.json is backed up as .pre-symlink.bak before the symlink is created.

The health check — 9 diagnostic sources

The /check-token-health slash command runs:

  1. macOS KeychainIs your OAuth token present? Is it expired?
  2. auth-profiles.jsonDoes the file match the Keychain token?
  3. launchd servicesAre all bot gateways running?
  4. Per-bot tokensDoes each bot's auth-profiles match the Keychain? Catches broken symlinks.
  5. Per-bot symlinksIs each bot properly linked to the source file?
  6. HTTP /healthz probesIs each bot's gateway process alive and accepting connections? Parallel, 3-second timeout, zero API calls.
  7. Session sizesIs any bot's session approaching the context overflow threshold?
  8. Token expiryIs the Keychain token expired or about to expire? Catches dead tokens even when keychain and auth-profiles match.
  9. Refresh daemon healthIs the .token-expiry-state file stale? If older than 15 min, the refresh daemon may be dead.

Plus:

  • +Model distributionHow many bots are on each model. Flags if too many share one model (rate limit risk).
  • +Rate limit detectionScans each bot's error log for recent rate limit events. Shows when it happened and on which model.
  • +Cache stalenessCompares current token hash against hash at last fleet restart. Catches bots with stale tokens in memory.
  • +Three-tier bot discoveryFinds bots from fleet.json, launchctl services, AND directory scanning. Catches unregistered bots.

Why this system exists — token lifecycle

  1. Claude Code uses rotating OAuth tokens — a security feature from Anthropic.
  2. Every 4–12 hours, the CLI refreshes the token and writes the new one to macOS Keychain. The old token is revoked server-side immediately.
  3. Your terminal picks up the new token automatically. Your OpenClaw bots don't — they read from auth-profiles.json, not the Keychain.
  4. Without the sync daemon, your bots are stuck authenticating with a revoked credential.
  5. OpenClaw reports this as "AI service temporarily overloaded" or "API rate limit reached" — NOT "your token expired." That's why everyone blames Anthropic when the problem is on their own machine.

This system bridges the gap between Keychain (where Claude Code writes tokens) and auth-profiles.json (where your bots read them).

Safety & reversibility

ActionDestructive?Worst caseHow to undo
Writes auth-profiles.jsonNo — atomic writeIf write fails, original unchangedFile is rewritten every sync cycle anyway
Creates symlinksNo — backs up originals firstBot reads from wrong filerm symlink && mv .pre-symlink.bak original
Restarts bot gatewaysBriefly — 2-3s downtime per botBot misses a message during restartBot auto-recovers on next message
Installs launchd daemonsNo — user-level LaunchAgents onlyDaemon runs when you don't want itlaunchctl bootout gui/$(id -u)/<label>
Reads KeychainRead-only — never writes to KeychainKeychain permission popupGrant or deny in System Settings
Health check diagnosticsRead-only — no side effectsNoneDelete the script
Complete uninstall commands
# Stop daemons
launchctl bootout gui/$(id -u)/com.clawdbot.token-refresh 2>/dev/null
launchctl bootout gui/$(id -u)/com.clawdbot.heartbeat-monitor 2>/dev/null

# Remove daemon plists
rm ~/Library/LaunchAgents/com.clawdbot.token-refresh.plist
rm ~/Library/LaunchAgents/com.clawdbot.heartbeat-monitor.plist

# Remove scripts and state files
rm ~/.clawdbot/scripts/heartbeat-monitor.sh
rm ~/.clawdbot/scripts/check-token-health.py
rm -f ~/.clawdbot/.token-sync-heartbeat
rm -f ~/.clawdbot/.last-gateway-restart
rm -f ~/.clawdbot/.last-synced-token-hash
rm -rf ~/.clawdbot/alerts/
rm -f ~/.clawdbot/scripts/token-refresh.sh
rm -f ~/.clawdbot/.token-expiry-state
rm -f ~/.clawdbot/logs/token-refresh-stderr.log

# Remove slash command
rm ~/.claude/commands/check-token-health.md

# Revert symlinks (restore original auth-profiles)
for bot in ~/.clawdbot-*/; do
  for f in "$bot/agents/main/agent/auth-profiles.json" "$bot/auth-profiles.json"; do
    if [ -L "$f" ] && [ -f "${f}.pre-symlink.bak" ]; then
      rm "$f"
      mv "${f}.pre-symlink.bak" "$f"
    fi
  done
done

Your bots will continue running with whatever token they currently have. They just won't get automatic refreshes anymore.

Get notified about updates

Already running v1.1? We'll email you when new versions ship — bug fixes, new features, Linux support.

Sign up for update notifications

No spam. One email when the prompt ships. That's it.

Buy Me A Coffee