# LLM-INSTALL-CLAUDEHACK.md Use this guide when an AI agent (OpenClaw, Claude Code, Codex, etc.) is asked to install the OAuth token sync system from this repo onto a fresh or existing OpenClaw host, and to expose a separate optional `claudehack` model provider. ## Goal Install the OAuth token sync system from: `https://git.eeqj.de/ROOH/openclaw_oauth_sync` onto the target OpenClaw machine, without using the repo's interactive installer, and with these additional requirements: - install the token sync manually by reading this repo's `setup.sh`, `scripts/`, `templates/`, and `docs/` - **skip webhook security entirely** (Step 11 in `setup.sh`) - add a **new optional provider** named `claudehack` - do **not** replace or modify existing providers beyond what is required to add `claudehack` - do **not** set `claudehack` as the system primary or fallback default - keep all existing OpenClaw behavior intact unless explicitly required below --- ## Hard Rules 1. **Do NOT run `setup.sh` interactively.** - Read it to understand the system. - Perform the installation manually. 2. **Do NOT modify webhook security.** - Skip webhook security completely. - Skip Step 11 in `setup.sh`. 3. **Do NOT remove or overwrite existing providers, auth profiles, defaults, or models unless explicitly required below.** - This install is additive. 4. **Do NOT make `claudehack` the default model or fallback model.** - It must remain an optional selectable provider. 5. **Do NOT guess paths.** - Detect actual paths on the machine first. 6. **Do NOT assume all per-agent files already exist.** - Create missing `models.json` or `auth-profiles.json` files where required. --- ## Prerequisites Run: ```bash apt-get update apt-get install -y inotify-tools python3 curl ``` Verify Docker and Docker Compose v2 are available: ```bash docker compose version ``` If Node.js is not installed on the host, install it: ```bash curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - apt-get install -y nodejs ``` Then install Claude CLI on the host: ```bash npm install -g @anthropic-ai/claude-code ``` --- ## Step 1 — Identify OpenClaw Paths Find the actual OpenClaw paths on the machine. Defaults are usually: - `OPENCLAW_CONFIG_DIR=/root/.openclaw` - `COMPOSE_DIR=/root/openclaw` These should contain: - `/root/.openclaw/openclaw.json` - `/root/openclaw/docker-compose.yml` - `/root/openclaw/.env` Find the gateway container name: ```bash docker ps --filter name=openclaw --format '{{.Names}}' | grep gateway ``` Set and verify: - `OPENCLAW_CONFIG_DIR` - `COMPOSE_DIR` - `GATEWAY_CONTAINER` Do not continue until these are confirmed. --- ## Step 2 — Install and Authenticate Claude CLI Claude CLI must be authenticated on the **host**, because this install relies on the Claude CLI OAuth credentials file and its token refresh behavior. Run: ```bash claude ``` This opens the OAuth login flow. Complete the authentication in the browser. Verify CLI access works: ```bash claude -p "say hello" --no-session-persistence ``` Locate the credentials file: ```bash ls -la ~/.claude/.credentials.json ``` On a standard root-based install, this file is usually: ```bash /root/.claude/.credentials.json ``` Set: - `CLAUDE_CREDS_FILE=/root/.claude/.credentials.json` or the actual discovered path Do not continue unless the file exists and contains valid OAuth credentials. --- ## Step 3 — Install the Sync Script Use the repo's `scripts/sync-oauth-token.sh` as the base. Substitute these placeholders: - `@@CLAUDE_CREDS_FILE@@` → credentials file path from Step 2 - `@@OPENCLAW_OAUTH_FILE@@` → `/root/.openclaw/credentials/oauth.json` - `@@OPENCLAW_ENV_FILE@@` → `/root/openclaw/.env` - `@@COMPOSE_DIR@@` → `/root/openclaw` Install the rendered script to: ```bash /root/sync-oauth-token.sh ``` Then: ```bash chmod +x /root/sync-oauth-token.sh ``` ### Required custom addition After the `.env` update section in the sync script, and **before** the gateway recreate section, add this logic: ```bash FRESH_TOKEN=$(python3 -c "import json; d=json.load(open('$CLAUDE_CREDS_FILE')); print(d['claudeAiOauth']['accessToken'])") if [ -n "$FRESH_TOKEN" ]; then python3 /root/update-claudehack-profiles.py "$FRESH_TOKEN" 2>&1 | sed "s/^/$LOG_PREFIX /" fi ``` ### Create the helper profile updater Create: ```bash /root/update-claudehack-profiles.py ``` Make it executable: ```bash chmod +x /root/update-claudehack-profiles.py ``` This script must: - take the access token as its first argument - iterate over every: ```bash /root/.openclaw/agents/*/agent/auth-profiles.json ``` - create missing files if needed - update the `"access"` field inside the `"claudehack:default"` profile - preserve other profile data - use the auth profile structure described in `setup.sh` Step 6 --- ## Step 4 — Install the Trigger Script Use the repo's `scripts/trigger-claude-refresh.sh` as the base. Substitute: - `@@CREDS_FILE@@` → the credentials file path from Step 2 - `@@REAUTH_FLAG@@` → `/root/openclaw/REAUTH_NEEDED` - `@@CLI_MODE@@` → `host` - `@@CLI_CONTAINER@@` → empty / unused - `@@CLI_BASE_URL_OVERRIDE@@` → `false` Why `false`: - Claude CLI runs directly on the host - it is not running inside the proxy container - no container-local base URL override is needed Install to: ```bash /root/trigger-claude-refresh.sh ``` Then: ```bash chmod +x /root/trigger-claude-refresh.sh ``` --- ## Step 5 — Install Systemd Units Use the repo's `templates/` directory as the base for these units: - `sync-oauth-token.service` - `trigger-claude-refresh.service` - `trigger-claude-refresh.timer` Substitute: - `@@SYNC_SCRIPT_PATH@@` → `/root/sync-oauth-token.sh` - `@@TRIGGER_SCRIPT_PATH@@` → `/root/trigger-claude-refresh.sh` Install them to: ```bash /etc/systemd/system/ ``` Then run: ```bash systemctl daemon-reload systemctl enable --now sync-oauth-token.service systemctl enable --now trigger-claude-refresh.timer ``` --- ## Step 6 — Configure the `claudehack` Provider This is a **new provider** separate from OpenClaw’s built-in `anthropic` provider. Do **not** modify existing provider identities beyond adding the new provider and related model entries. Three separate configuration locations must be updated. ### 6.1 Global `openclaw.json` → `models.providers` Add a new provider entry named: ```json "claudehack" ``` Provider requirements: - `baseUrl`: `"https://api.anthropic.com"` - `api`: `"anthropic-messages"` Add two models: 1. `claude-opus-4-6` - name: `"ClaudeHack Opus 4.6"` - contextWindow: `200000` - maxTokens: `32000` - input: `["text", "image"]` - costs: all zero 2. `claude-sonnet-4-6` - name: `"ClaudeHack Sonnet 4.6"` - contextWindow: `200000` - maxTokens: `32000` - input: `["text", "image"]` - costs: all zero ### 6.2 Global `openclaw.json` → `agents.defaults.models` Add these model registrations: - `claudehack/claude-opus-4-6` - alias: `"ClaudeHack Opus 4.6"` - `claudehack/claude-sonnet-4-6` - alias: `"ClaudeHack Sonnet 4.6"` These are additive registrations only. ### 6.3 Per-agent `models.json` For every agent directory: ```bash /root/.openclaw/agents/*/agent/models.json ``` Add the same `claudehack` provider block to the file’s `providers` object. If the file does not exist, create it. Do not delete existing providers. --- ## Step 7 — Configure Auth Profiles For **every**: ```bash /root/.openclaw/agents/*/agent/auth-profiles.json ``` add a new profile entry. If the file does not exist, create it. Read the fresh token from: ```json claudeAiOauth.accessToken ``` inside the Claude CLI credentials file. ### Required structure Under `profiles`, add: ```json "claudehack:default": { "type": "oauth", "provider": "claudehack", "access": "" } ``` Under `lastGood`, add: ```json "claudehack": "claudehack:default" ``` Under `usageStats`, add: ```json "claudehack:default": { "errorCount": 0 } ``` Preserve all existing profile entries. --- ## Step 8 — Initial Sync and Verify Restart the sync service to trigger the initial sync: ```bash systemctl restart sync-oauth-token.service ``` Check logs: ```bash journalctl -u sync-oauth-token.service --since "1 min ago" --no-pager ``` Expected successful behavior should include log output indicating: - updated `oauth.json` - updated `.env` - updated `N` claudehack auth profiles - gateway recreated ### Verify service state ```bash systemctl is-active sync-oauth-token.service ``` Expected: ```bash active ``` Check timer registration: ```bash systemctl list-timers --all | grep trigger-claude-refresh ``` Expected: - `trigger-claude-refresh.timer` is installed - next run time is visible Check gateway container health: ```bash docker ps ``` Confirm the OpenClaw gateway is up and healthy. Check gateway logs for config reload / startup success and `claudehack` availability: ```bash docker logs "$GATEWAY_CONTAINER" --tail 200 ``` --- ## Critical Gotchas These are mandatory. If any of these are wrong, the install may silently fail. ### 1. Auth profile field must be `access`, not `key` Correct: ```json "access": "" ``` Wrong: ```json "key": "" ``` Using `key` causes OpenClaw to silently skip the profile. --- ### 2. Auth profile type must be `oauth`, not `token` Correct: ```json "type": "oauth" ``` Wrong: ```json "type": "token" ``` Why: - `oauth` tells the gateway to attach Claude Code identity headers - without those headers, Anthropic rejects the request with errors like: > "Third-party apps now draw from your extra usage" --- ### 3. The sync script must use `docker compose down` then `up`, not `restart` Do **not** use: ```bash docker compose restart ``` Use a full recreate flow so updated environment values are picked up. Reason: - `restart` can reuse cached environment variables - the updated `ANTHROPIC_OAUTH_TOKEN` from `.env` may not be applied --- ### 4. `oauth.json` field mapping is different from Claude CLI credentials Claude CLI credentials file uses: - `accessToken` - `refreshToken` - `expiresAt` OpenClaw `oauth.json` expects: - `access` - `refresh` - `expires` The sync script must translate these correctly. --- ### 5. All three model registration points are required You must update all three: 1. global `models.providers` 2. global `agents.defaults.models` 3. per-agent `models.json` If any of these are missing: - models may not appear in the UI - model selection may fail - requests may error with `"Unknown model"` --- ### 6. Do not set `claudehack` as primary or fallback defaults This install is additive only. The system’s existing primary/fallback models must remain unchanged unless explicitly requested by the human operator. --- ## Definition of Done The install is complete only when **all** of the following are true: 1. Claude CLI is installed and authenticated on the host 2. `~/.claude/.credentials.json` exists and contains valid OAuth data 3. `/root/sync-oauth-token.sh` exists, is executable, and includes the `update-claudehack-profiles.py` call 4. `/root/update-claudehack-profiles.py` exists and is executable 5. `/root/trigger-claude-refresh.sh` exists and is executable 6. all required systemd units are installed and enabled 7. `claudehack` exists in global `openclaw.json` 8. `claudehack` model aliases exist in global `agents.defaults.models` 9. every agent has `claudehack` provider entries in `models.json` 10. every agent has `claudehack:default` in `auth-profiles.json` 11. sync service runs successfully 12. timer is active 13. gateway is healthy 14. `claudehack/claude-opus-4-6` and `claudehack/claude-sonnet-4-6` are visible as optional models 15. existing defaults and providers were preserved 16. webhook security was not installed or modified --- ## Final Notes for the Installing Agent - Be conservative. - Preserve existing config. - Make additive changes only. - Do not silently skip missing files; create them correctly. - Validate every file written. - Validate service state after installation. - Validate the gateway actually sees the new models. - Skip webhook security entirely.