claude-rotator
Run Claude CLI (claude -p) subprocesses with automatic multi-account rotation and rate limit handling. Zero dependencies.
Available in Python, TypeScript, and Rust.
Install
pip install claude-rotator
Requires claude CLI installed and authenticated on at least one account.
Quick Start
from claude_rotator import ClaudeRunner
runner = ClaudeRunner(
accounts=[
None, # default (~/.claude/)
"/home/user/.claude_alt", # fallback account
],
)
result = runner.run(prompt="Explain this code", model="sonnet")
print(result.output)
print(f"Cost: ${result.cost_usd:.4f}")
print(f"Duration: {result.duration_seconds:.1f}s")
When the first account hits a rate limit, claude-rotator detects it, caches the cooldown, and retries with the next account.
Async
result = await runner.run_async(prompt="Summarize", model="opus")
API
ClaudeRunner
ClaudeRunner(accounts=[None])
accounts: List of HOME directory paths.Nonemeans the default HOME. Each directory should contain a.claude/folder with separate credentials.
runner.run() / runner.run_async()
runner.run(
prompt="...",
model="sonnet", # "sonnet", "opus", or full model ID
tools="Read,Write", # allowed tools (None to omit)
cwd=Path("."), # working directory
timeout=600, # seconds
)
Returns a ClaudeResult:
output: str- the response textcost_usd: float- total costduration_seconds: float- wall clock timemodel: str- model used
ClaudeError
Raised on subprocess failure, timeout, or when all accounts are rate-limited.
stderr: str- error outputreturncode: int- exit code (-1 for timeout)
How Account Rotation Works
- claude-rotator tries the first account in the list.
- If the output contains rate limit phrases ("usage limit", "rate limit", "out of extra usage"), it caches the cooldown time.
- It moves to the next account and retries.
- Cached accounts are skipped on subsequent calls until their cooldown expires.
- If all accounts are exhausted, it raises
ClaudeError.
How Accounts Work
Each account is a directory containing a .claude/ folder with its own OAuth credentials. Set up multiple accounts by logging in with different HOME directories:
# Account 1 (default)
claude login
# Account 2
HOME=/home/user/.claude_alt claude login
Then pass the directories to ClaudeRunner:
runner = ClaudeRunner(accounts=[None, "/home/user/.claude_alt"])
Security
Audit reports are in audits/. If you find a vulnerability, please open an issue or submit a PR. Independent audits and security contributions are welcome. See CONTRIBUTING.md for details.
License
MIT
Made with <3 at Bitcoin.com
Metadata
Release files for claude-rotator 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| claude_rotator-1.1.0.tar.gz | 49.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| claude_rotator-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 58.5 kB
Release files / claude_rotator-1.1.0.tar.gz
| Download URL | claude_rotator-1.1.0.tar.gz |
|---|---|
| Size | 49.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
37aa35e8eb614bb96505e79eda6329c5d2ddf16bfffeedd3873132abbebadf2c
|
|
BLAKE2b-256 checksum How to use checksums |
0a5a418bf7e40e2a51e6831b2b215617f3d09d1d7d31f3253cc371f4a18c81de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / claude_rotator-1.1.0-py3-none-any.whl
| Download URL | claude_rotator-1.1.0-py3-none-any.whl |
|---|---|
| Size | 9.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
15ac9e911f58861635c85b9a217a818acd589741cff6edfbd6618f33b9a3b6f9
|
|
BLAKE2b-256 checksum How to use checksums |
9e93f7333cee7ee8176521e3ab314b14eb5b02af95f699f58f8c9a18edc6e4e7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|