A drop-in proxy that turns one Claude API key into managed access for your whole team — with per-user auth, fair queuing, rate limiting, and usage tracking.
Team member A (Claude Code) ──┐
Team member B (Claude Code) ──┤──▶ claudepool ──▶ Anthropic API
CI/CD pipeline ───────────────┤ (auth · queue · (single key)
Internal service ─────────────┘ track · limit)
You have one Anthropic API key. You have a team. You need answers to:
- Who is making requests?
- How much is each person or service consuming?
- How do you prevent one runaway script from burning through your rate limits?
- How do you give and revoke access without rotating the upstream key?
claudepool solves all of this with a single binary and zero external dependencies.
- Full Anthropic API compatibility — drop-in replacement. Works with Claude Code, the Anthropic SDK, raw HTTP, anything that speaks the Messages API
- Per-user API keys — issue individual keys, revoke them independently, never expose your upstream key
- Fair request queue — round-robin scheduling across users with configurable concurrency limits
- Per-user rate limiting — sliding-window rate limits prevent any single user from monopolizing access
- Usage tracking — per-user token counts (input, output, cache) stored in SQLite
- Streaming support — full SSE pass-through for streaming responses, no buffering
- Lightweight — Hono + SQLite, no Redis, no Postgres, no external services
- Privacy-first — only token counts are logged, never message content
- Node.js 18+
- An Anthropic API key
git clone https://github.com/YOUR_USERNAME/claudepool.git
cd claudepool
npm install
npm run buildConfigure your environment:
cp .env.example .envEdit .env:
ANTHROPIC_API_KEY=sk-ant-your-key-here
ADMIN_API_KEY=some-strong-random-stringCreate your first user and start the server:
npx claudepool admin add-user "Alice"
npx claudepool startcp .env.example .env
# edit .env with your keys
docker compose up -dManage users from the host:
docker compose exec claudepool node dist/index.js admin add-user "Alice"When you create a user, claudepool prints their API key and the exact config to hand them:
User created successfully!
ID: d97f7cf4-2482-443d-8284-d97f4bc09e81
Name: Alice
API Key: cp_Q-wKbKEUGXnOYQkTep3YK3VNT0kGeU1PQW7jnBagwH0
The user adds this to their ~/.claude/settings.json:
{
"env": {
"ANTHROPIC_BASE_URL": "https://your-server.example.com",
"ANTHROPIC_API_KEY": "cp_Q-wKbKEUGXnOYQkTep3YK3VNT0kGeU1PQW7jnBagwH0"
}
}Or as environment variables:
export ANTHROPIC_BASE_URL=https://your-server.example.com
export ANTHROPIC_API_KEY=cp_Q-wKbKEUGXnOYQkTep3YK3VNT0kGeU1PQW7jnBagwH0That's it. Claude Code works exactly as normal — the user doesn't need to know there's a proxy in between.
claudepool start Start the proxy server
claudepool admin add-user <name> Create a user and print their API key
claudepool admin list-users List all users
claudepool admin disable-user <id> Revoke a user's access
claudepool admin enable-user <id> Restore a user's access
claudepool admin reset-key <id> Rotate a user's API key
claudepool admin delete-user <id> Permanently remove a user
claudepool admin usage Show usage stats for all users
claudepool admin usage --user <id> Show usage for a specific user
claudepool admin usage --days 7 Show last 7 days (default: 30)
All configuration is via environment variables (or .env file):
| Variable | Default | Description |
|---|---|---|
ANTHROPIC_API_KEY |
required | Upstream Anthropic API key |
ADMIN_API_KEY |
required | Key for admin CLI operations |
PORT |
3000 |
Server port |
HOST |
0.0.0.0 |
Server bind address |
MAX_CONCURRENT_REQUESTS |
5 |
Max parallel requests to upstream |
QUEUE_TIMEOUT_MS |
300000 |
How long a request can wait in queue (ms) |
DB_PATH |
./data/claudepool.db |
SQLite database path |
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/v1/messages |
User API key | Proxied Messages API (streaming + non-streaming) |
POST |
/v1/messages/count_tokens |
User API key | Proxied token counting |
GET |
/health |
None | Health check |
The proxy forwards anthropic-version and anthropic-beta headers to the upstream API, ensuring full compatibility with all Claude features including extended thinking and tool use.
┌──────────────────────────────────────────────────────┐
│ claudepool │
│ │
│ Request ──▶ Auth ──▶ Rate Limit ──▶ Queue ──▶ Proxy │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ Validate Sliding Fair round Forward │
│ API key window robin with to │
│ (SHA-256 per-user concurrency upstream │
│ lookup) limits control + stream │
│ │ │
│ Usage Tracker ◀─────┘ │
│ (SQLite) │
└──────────────────────────────────────────────────────┘
- Auth: Extracts key from
x-api-keyorAuthorization: Bearerheader, validates against SHA-256 hashes in SQLite - Rate Limiter: Sliding-window counter per user (configurable requests/minute)
- Queue: Fair round-robin scheduling — no single user can starve others. Configurable max concurrency and timeout
- Proxy: Forwards requests upstream, pipes SSE streams directly to clients, extracts token usage from responses
- Usage Tracker: Logs input/output/cache tokens per request per user. No message content is ever stored
- User API keys are prefixed (
cp_) for easy identification and stored as SHA-256 hashes — the plaintext is shown once at creation and never stored - No message content is logged — only token counts and metadata
- Upstream API key is never exposed to end users
- Per-user rate limiting and access control (disable/enable)
- Request body size limited to 32MB (matching Anthropic's limit)
- HTTPS termination should be handled by a reverse proxy (nginx, Caddy, etc.) in production
For production use, put claudepool behind a reverse proxy with TLS:
Internet ──▶ Caddy/nginx (TLS) ──▶ claudepool:3000
Example Caddyfile:
claude.yourdomain.com {
reverse_proxy localhost:3000
}
This software is provided as-is under the MIT License.
claudepool is a general-purpose API gateway and request proxy. It is the sole responsibility of the user to ensure that their use of this software complies with all applicable terms of service, licensing agreements, and laws — including but not limited to the Anthropic Terms of Service and any API usage policies.
The authors and contributors of this project:
- Make no representations about the legality of any specific use case
- Do not endorse or encourage any use that violates third-party terms of service
- Accept no liability for how this software is used
- Provide no warranty, express or implied
You are responsible for ensuring your usage is compliant with your API provider's terms.
Contributions are welcome. Please open an issue first to discuss what you'd like to change.