{"id":47817335,"url":"https://github.com/in-jun/cc-relay-proxy","last_synced_at":"2026-04-03T18:48:13.782Z","repository":{"id":346078619,"uuid":"1188173874","full_name":"in-jun/cc-relay-proxy","owner":"in-jun","description":"Claude Code account rotation proxy","archived":false,"fork":false,"pushed_at":"2026-03-22T16:10:02.000Z","size":175,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-22T19:43:21.099Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/in-jun.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-21T18:03:25.000Z","updated_at":"2026-03-22T16:10:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/in-jun/cc-relay-proxy","commit_stats":null,"previous_names":["in-jun/cc-relay-proxy"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/in-jun/cc-relay-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/in-jun%2Fcc-relay-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/in-jun%2Fcc-relay-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/in-jun%2Fcc-relay-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/in-jun%2Fcc-relay-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/in-jun","download_url":"https://codeload.github.com/in-jun/cc-relay-proxy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/in-jun%2Fcc-relay-proxy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31370203,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T17:53:18.093Z","status":"ssl_error","status_checked_at":"2026-04-03T17:53:17.617Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-03T18:48:13.221Z","updated_at":"2026-04-03T18:48:13.774Z","avatar_url":"https://github.com/in-jun.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cc-relay-proxy\n\nA local proxy that sits between Claude Code and the Anthropic API, transparently rotating between multiple accounts to avoid rate limits. Claude Code never sees a 429 — the proxy absorbs it and retries with a different account.\n\n```\nClaude Code  →  cc-relay-proxy :9999  →  api.anthropic.com\n                 ├─ Route to best available account\n                 ├─ On 429 → switch account and retry\n                 └─ GET /status\n```\n\n## Installation\n\n### Docker (recommended)\n\n```bash\nmkdir -p config logs\n# put your accounts.json inside config/\ndocker run -d \\\n  -p 9999:9999 \\\n  -v $(pwd)/config:/app/config \\\n  -v $(pwd)/logs:/app/logs \\\n  --name cc-relay-proxy \\\n  injundev/cc-relay-proxy\n```\n\n### Build from source\n\n```bash\ngit clone https://github.com/in-jun/cc-relay-proxy\ncd cc-relay-proxy\ngo build -o cc-relay-proxy ./cmd/cc-relay-proxy\n```\n\nRequires Go 1.21+. No external dependencies.\n\n## Setup\n\n### 1. Create config/accounts.json\n\n```bash\nmkdir -p config\n```\n\n```json\n[\n  {\"name\": \"acct1\", \"refreshToken\": \"rt_...\"},\n  {\"name\": \"acct2\", \"refreshToken\": \"rt_...\"}\n]\n```\n\nGet your refresh token from the local Claude Code credentials:\n\n```bash\ncat ~/.claude/.credentials.json | python3 -c \"\nimport json, sys\nd = json.load(sys.stdin)\nprint(d['claudeAiOauth']['refreshToken'])\n\"\n```\n\n### 2. Connect Claude Code\n\nAdd to `~/.claude/settings.json`:\n\n```json\n{\n  \"env\": {\n    \"ANTHROPIC_BASE_URL\": \"http://localhost:9999\"\n  }\n}\n```\n\nOr use an alias to keep the original `claude` command available:\n\n```bash\nalias claudep='ANTHROPIC_BASE_URL=http://localhost:9999 claude'\n```\n\n## Configuration\n\n| Variable | Default | Description |\n|---|---|---|\n| `CC_ACCOUNTS_FILE` | `config/accounts.json` | Path to accounts file |\n| `CC_PROXY_PORT` | `9999` | Port to listen on |\n| `CC_PROXY_BIND` | `127.0.0.1` | Bind address (`0.0.0.0` to expose on LAN) |\n| `CC_LOG_PATH` | `logs/proxy.log` | JSONL log file |\n| `CC_LOG_LEVEL` | — | Set to `debug` to log auth headers |\n\n## How account selection works\n\nEach account gets a water score (lower = more available):\n\n```\nwater = max(5h_util × time_left / 300min,\n            7d_util × time_left / 168hr)\n```\n\nTime-decay is the key insight: an account at 90% 5h utilization that resets in 10 minutes scores near 0 and floats to the top of the pool — the proxy will start using it the moment quota resets. An account is only hard-blocked when the API explicitly returns `rejected`; high utilization alone just raises the score.\n\nWith multiple accounts, the proxy switches proactively if a better option scores at least 10% lower than the current one.\n\n## Status endpoint\n\n```bash\ncurl -s http://localhost:9999/status | python3 -m json.tool\n```\n\n```json\n{\n  \"active\": \"acct1\",\n  \"uptime\": \"2h34m\",\n  \"accounts\": [\n    {\n      \"name\": \"acct1\",\n      \"isActive\": true,\n      \"status\": \"allowed\",\n      \"water\": 0.133,\n      \"fiveHour\": { \"utilization\": 0.0, \"percent\": \"0%\", \"resetsInMins\": 254 },\n      \"sevenDay\":  { \"utilization\": 0.67, \"percent\": \"67%\", \"resetsInHours\": 33 },\n      \"tokenExpiresIn\": \"7h40m\",\n      \"lastSeen\": \"just now\"\n    }\n  ]\n}\n```\n\n## Logs\n\nEvery significant event is written as a JSONL line to `logs/proxy.log`:\n\n```\nrequest           — account, latency, water score per request\naccount_switched  — switch reason and water scores before/after\n429_received      — action taken: switch / hold / forward\nrate_limit_update — utilization parsed from API response headers\ntoken_refreshed   — OAuth token renewal\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fin-jun%2Fcc-relay-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fin-jun%2Fcc-relay-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fin-jun%2Fcc-relay-proxy/lists"}