Skip to main content

Auto OAuth Token Refresh

Keep your OpenClaw bots online 24/7 — a background system that refreshes and syncs OAuth tokens before they expire.

Auto OAuth Token Refresh — OpenClaw Clawdbot keeping your bot fleet alive with automated token rotation

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?

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

1

Knows when your token is about to expire and refreshes it automatically — checks every 5 minutes, only acts when needed

2

Syncs the fresh token to all your bots every 2 minutes

3

Restarts your bot fleet automatically when tokens rotate

4

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

5

Automatically discovers all your bots — even ones you add later. No manual registry needed.

6

Detects rate limit issues and walks you through your options (switch model, clear cooldown, or wait)

7

Runs diagnostics on your machine to verify your Keychain, launchd services, and bot processes are all working correctly

8

Takes a snapshot before any change so you can always roll back

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

check-token-health outputv2.2.0
================================================================================ 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 ================================================================================
Sign in to keep track of what you've copied

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

What it won't save you from

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.

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 Auto OAuth Token Refresh v1.1

Previous versions — v1.0 (March 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 Auto OAuth Token Refresh v1.0

What exactly does this install?

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
~/.clawdbot/scripts/sync-token.sh — Token sync script. Runs every 2 min. Reads Keychain, compares to auth-profiles, syncs if different, restarts fleet. ~/.clawdbot/scripts/heartbeat-monitor.sh — Watchdog 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.py — Health check script (Python 3, no dependencies). 7-source diagnostic across your fleet. ~/.clawdbot/fleet.json — Bot registry. Names, ports, directories for all discovered bots. ~/.clawdbot/.token-sync-heartbeat — Heartbeat file. Touched every 2 min by the sync daemon. Age = daemon health. ~/.clawdbot/.last-gateway-restart — Timestamp of last fleet restart. Used by the circuit breaker. ~/.clawdbot/.last-synced-token-hash — SHA-256 hash (16 chars) of the token at last restart. Prevents unnecessary restarts. ~/.clawdbot/alerts/token-sync-down.alert — JSON alert written by heartbeat monitor if sync daemon is dead. Deleted when healthy. ~/.clawdbot/logs/token-sync.log — Sync daemon log. Rotated at 5MB (one .old backup). ~/.clawdbot/scripts/token-refresh.sh — Expiry-aware refresh wrapper. Checks token TTL from Keychain, only invokes CLI when near expiry. ~/.clawdbot/.token-expiry-state — Written 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.log — Token refresh daemon log. Rotated at 1MB (one .old backup). ~/.clawdbot/logs/heartbeat-monitor.log — Heartbeat monitor log. ~/.clawdbot/logs/last-health-check.txt — Full text output of the last health check run. ~/.clawdbot/logs/last-health-findings.json — Structured findings from the last health check (for the slash command to parse). ~/.clawdbot/logs/health-check-history.csv — One-line append per health check run. Fleet status over time. ~/.claude/commands/check-token-health.md — The /check-token-health slash command for Claude Code.
Sign in to keep track of what you've copied

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

launchd daemons installed
Token Sync — every 2 minutes (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 (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 (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
Sign in to keep track of what you've copied

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.

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.

Symlink architecture
Keychain (macOS) ↓ (sync daemon reads every 2 min) Steve's auth-profiles.json ← real file (source of truth) ↑ ↑ ↑ | | | Elaine Jerry Kramer ... (symlinks)
Sign in to keep track of what you've copied

The /check-token-health slash command runs 9 diagnostic sources, plus 4 more checks below.

The health check — 9 diagnostic sources, plus 4 more

1macOS KeychainIs your OAuth token present? Is it expired?
2auth-profiles.jsonDoes the file match the Keychain token?
3launchd servicesAre all bot gateways running?
4Per-bot tokensDoes each bot's auth-profiles match the Keychain? Catches broken symlinks.
5Per-bot symlinksIs each bot properly linked to the source file?
6HTTP /healthz probesIs each bot's gateway process alive and accepting connections? Parallel, 3-second timeout, zero API calls.
7Session sizesIs any bot's session approaching the context overflow threshold?
8Token expiryIs the Keychain token expired or about to expire? Catches dead tokens even when keychain and auth-profiles match.
9Refresh daemon healthIs the .token-expiry-state file stale? If older than 15 min, the refresh daemon may be dead.
10Model distributionHow many bots are on each model. Flags if too many share one model (rate limit risk).
11Rate limit detectionScans each bot's error log for recent rate limit events. Shows when it happened and on which model.
12Cache stalenessCompares current token hash against hash at last fleet restart. Catches bots with stale tokens in memory.
13Three-tier bot discoveryFinds bots from fleet.json, launchctl services, AND directory scanning. Catches unregistered bots.

Why this system exists — token lifecycle. Claude Code uses rotating OAuth tokens — a security feature from Anthropic.

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.

Your terminal picks up the new token automatically. Your OpenClaw bots don't — they read from auth-profiles.json, not the Keychain.

Without the sync daemon, your bots are stuck authenticating with a revoked credential.

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
Writes auth-profiles.json — Destructive? No, atomic write. Worst case: if write fails, original unchanged. Undo: file is rewritten every sync cycle anyway. Creates symlinks — Destructive? No, backs up originals first. Worst case: bot reads from wrong file. Undo: rm symlink && mv .pre-symlink.bak original. Restarts bot gateways — Destructive? Briefly, 2-3s downtime per bot. Worst case: bot misses a message during restart. Undo: bot auto-recovers on next message. Installs launchd daemons — Destructive? No, user-level LaunchAgents only. Worst case: daemon runs when you don't want it. Undo: launchctl bootout gui/$(id -u)/<label>. Reads Keychain — Destructive? Read-only, never writes to Keychain. Worst case: Keychain permission popup. Undo: Grant or deny in System Settings. Health check diagnostics — Destructive? Read-only, no side effects. Worst case: None. Undo: Delete the script.
Sign in to keep track of what you've copied

Every step above is reversible. Here's the exact teardown if you want everything gone.

Complete uninstall commands

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
Sign in to keep track of what you've copied

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

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."

Get notified about updates

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

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

Changelog

1.12026-03-25Current

Expiry-aware refresh, launchd daemons, and a full fleet dashboard

— 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

1.02026-03-23

Initial release

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.