Date: 2026-05-03
Owner: Harnoor Minhas
Goal: Run OpenClaw (open-source coding agent) against your Claude Max plan via a local proxy, so your $200/mo Max subscription powers OpenClaw the same way it powers Claude Code — no separate Anthropic API billing.
---
Claude Max is billed as a flat monthly subscription with usage limits, not per-token API billing. The OAuth credentials inside Claude Code's auth file map to the same backend that the Anthropic API uses — but with a different auth header (Authorization: Bearer <oauth-token> instead of x-api-key: <api-key>).
A small local proxy (LiteLLM, in this guide) accepts OpenAI-compatible chat completions on http://localhost:4000/v1, swaps the auth header to OAuth, and forwards to https://api.anthropic.com. Any tool that speaks the OpenAI Chat Completions API (OpenClaw, Cursor, Continue, Aider, Open WebUI) can now run on Max-plan inference.
Important caveats:
ANTHROPIC_API_KEY fallback ready.---
OpenClaw is a fork/clone of Claude Code's open architecture. Install it once:
# Windows PowerShell
npm install -g openclaw # if published as npm package
# OR clone from source if not on npm:
cd F:\projects
git clone https://github.com/openclaw/openclaw.git
cd openclaw
npm install
npm link # installs the `openclaw` CLI globally
Verify:
openclaw --version
If install fails, OpenClaw may be a TypeScript package without published binaries — npm run build then npm link from inside the cloned dir.
---
LiteLLM is the Python proxy that translates OpenAI-format requests into provider-specific calls. Install in an isolated venv so it doesn't pollute global Python:
# Create venv
python -m venv F:\projects\litellm-venv
F:\projects\litellm-venv\Scripts\Activate.ps1
# Install with proxy extras
pip install --upgrade "litellm[proxy]>=1.55.0"
LiteLLM ships an Anthropic provider out of the box but doesn't natively support OAuth headers — we'll wire that with a custom-header config.
---
The token lives in Claude Code's credential store:
Windows:
$creds = Get-Content "$env:USERPROFILE\.claude\credentials.json" | ConvertFrom-Json
$token = $creds.oauthAccessToken # field name may be 'access_token' or 'oauthAccessToken'
$token
macOS / Linux:
cat ~/.claude/credentials.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('oauthAccessToken') or d.get('access_token'))"
The token is a long string starting with sk-ant-oat... or similar. Treat it like a password. Save it as a local environment variable, never commit it.
[Environment]::SetEnvironmentVariable("ANTHROPIC_OAUTH_TOKEN", $token, "User")
# restart your shell so the env var loads
---
Create F:\projects\litellm\config.yaml:
model_list:
# Map OpenAI-compatible model names → real Anthropic models, signed with the OAuth token
- model_name: claude-sonnet-4-6
litellm_params:
model: anthropic/claude-sonnet-4-6-20251001
api_base: https://api.anthropic.com
api_key: "os.environ/ANTHROPIC_OAUTH_TOKEN"
extra_headers:
Authorization: "Bearer os.environ/ANTHROPIC_OAUTH_TOKEN"
anthropic-version: "2023-06-01"
anthropic-beta: "messages-2025-04-04" # adjust to current beta header
- model_name: claude-opus-4-7
litellm_params:
model: anthropic/claude-opus-4-7-20251001
api_base: https://api.anthropic.com
api_key: "os.environ/ANTHROPIC_OAUTH_TOKEN"
extra_headers:
Authorization: "Bearer os.environ/ANTHROPIC_OAUTH_TOKEN"
- model_name: claude-haiku-4-5
litellm_params:
model: anthropic/claude-haiku-4-5-20251001
api_base: https://api.anthropic.com
api_key: "os.environ/ANTHROPIC_OAUTH_TOKEN"
extra_headers:
Authorization: "Bearer os.environ/ANTHROPIC_OAUTH_TOKEN"
litellm_settings:
drop_params: true # silently drop OpenAI-only params (e.g. logit_bias)
request_timeout: 600
set_verbose: false
general_settings:
master_key: "sk-local-only-leave-empty-or-set-your-own"
# If left as-is, anyone hitting localhost:4000 can use your Max plan. Restrict in step 6.
Note: the Authorization: Bearer header overrides LiteLLM's default x-api-key flow. The api_key value is required by LiteLLM's schema but the extra_headers Authorization line is what actually authenticates.
---
F:\projects\litellm-venv\Scripts\Activate.ps1
litellm --config F:\projects\litellm\config.yaml --port 4000
You'll see:
LiteLLM Proxy Server is running on http://0.0.0.0:4000
Test it:
curl -s http://localhost:4000/v1/chat/completions `
-H "Content-Type: application/json" `
-H "Authorization: Bearer sk-local-only-leave-empty-or-set-your-own" `
-d '{"model":"claude-sonnet-4-6","messages":[{"role":"user","content":"Say hi in 3 words"}]}'
If you get a JSON response with choices[0].message.content, the bridge works.
If you get 401 / invalid_api_key from Anthropic: your OAuth token expired (Claude Code refreshes them on the fly — re-run step 3 to grab the fresh one). For long-running setups, write a small script that pulls ~/.claude/credentials.json every 30 min and updates the env var.
---
The proxy is now an unauthenticated gateway to your Max plan. Lock it before leaving it running:
1. Bind to localhost only — already default with --port 4000 if you didn't pass --host 0.0.0.0. Double-check netstat -an | findstr :4000 shows 127.0.0.1:4000, not 0.0.0.0:4000.
2. Set a master key — change the master_key in config.yaml to a long random string, and require it on every request via Authorization: Bearer <master_key>.
3. Don't run on a shared network — coffee-shop wifi can scan localhost via misconfigured firewalls. Run on your own machine, with Windows Firewall blocking inbound on port 4000.
4. Rotate the OAuth token if you ever suspect leak — sign out + back in to Claude Code, the old token is invalidated.
---
OpenClaw reads provider config from ~/.openclaw/config.json (or env vars). Set:
[Environment]::SetEnvironmentVariable("OPENAI_API_BASE", "http://localhost:4000/v1", "User")
[Environment]::SetEnvironmentVariable("OPENAI_API_KEY", "sk-local-only-leave-empty-or-set-your-own", "User")
[Environment]::SetEnvironmentVariable("OPENAI_MODEL", "claude-sonnet-4-6", "User")
# restart shell
OR write to ~/.openclaw/config.json:
{
"provider": "openai",
"baseURL": "http://localhost:4000/v1",
"apiKey": "sk-local-only-leave-empty-or-set-your-own",
"model": "claude-sonnet-4-6"
}
Now:
openclaw "explain what's in this folder"
It'll route through LiteLLM → OAuth-signed → Anthropic → Max plan inference. No API bill.
---
Both tools share rate limits because both ride the same Max plan. Tips:
~/.litellm/logs/ — tail it during heavy use to see token totals and avoid surprise rate-limit hits.---
So it auto-starts on boot:
# Install NSSM (Non-Sucking Service Manager)
choco install nssm
nssm install LiteLLMProxy `
"F:\projects\litellm-venv\Scripts\python.exe" `
"-m litellm --config F:\projects\litellm\config.yaml --port 4000"
nssm set LiteLLMProxy AppDirectory F:\projects\litellm
nssm set LiteLLMProxy Start SERVICE_AUTO_START
nssm start LiteLLMProxy
Now Get-Service LiteLLMProxy shows it running, and it'll boot with Windows.
---
| Symptom | Likely cause | Fix |
|---|---|---|
| 401 from Anthropic | OAuth token expired or rotated | Re-extract from ~/.claude/credentials.json |
| 429 rate-limit | Max plan hit cap | Pause one of (Claude Code, OpenClaw); wait 5–60 min |
| LiteLLM exits on startup | Wrong YAML syntax | litellm --config X --debug to see the parse error |
| OpenClaw says "model not found" | OPENAI_MODEL mismatched against model_name in config.yaml | Match exactly |
| Slow responses | Localhost bottleneck shouldn't add latency — check Anthropic status | Compare with direct Claude Code timing |
---
If you'd run OpenClaw against the standard Anthropic API for the same workload:
Through Max + proxy: $0 incremental — covered by the flat $200/month subscription.
---
When you have answers, append them to this doc. Future-you (and anyone you onboard) will thank you.
---
Files to create:
F:\projects\litellm\config.yaml — proxy configF:\projects\litellm-venv\ — Python venv~/.openclaw/config.json — OpenClaw provider configLiteLLMProxyFiles NOT to commit:
config.yaml if it contains the master_key (set master_key from a separate file or env)