🚀 Intelligent API proxy for Anthropic Claude with automatic failover and model mapping
- Automatic Failover: Primary Anthropic API with intelligent fallback to Claude Subscription and Z.AI
- Quota Management: Automatic provider switching when weekly token limits are reached
- Model Mapping: Automatically maps unsupported model names to compatible alternatives
- Streaming Support: Full support for streaming responses
- Request Cleaning: Sanitizes requests to ensure Anthropic API compatibility
- TypeScript: Written in TypeScript for type safety and better development experience
- Structured Logging: Color-coded, level-based logging for debugging
- Configuration: Flexible configuration via environment variables or config object
# Clone the repository
git clone https://github.com/0xPuncker/claude-code-proxy.git
cd claude-code-proxy
# Install dependencies
npm install
# Build the project
npm run build
# Start the server
npm start# Clone the repository
git clone https://github.com/0xPuncker/claude-code-proxy.git
cd claude-code-proxy
# Install dependencies and build
npm install
npm run build
# Set your API keys
export ZAI_API_KEY="your-zai-api-key"
export ANTHROPIC_API_KEY="your-anthropic-api-key"
# Start the proxy (defaults to port 4181)
npm start
# Or use a custom port
PROXY_PORT=8080 npm startThe proxy includes a PowerShell setup script that auto-detects your Windows user profile and Claude credentials:
# Clone the repository
git clone https://github.com/0xPuncker/claude-code-proxy.git
cd claude-code-proxy
# Run the automatic setup script
powershell -ExecutionPolicy Bypass -File scripts/setup-docker.ps1
# Start the containers
docker-compose --env-file .env.docker up -dThe setup script automatically:
- Detects your Windows user profile directory
- Converts Windows paths to Docker format
- Configures Claude subscription credentials mount
- Generates
.env.dockerwith proper configuration
~/.claude/.credentials.json) cannot be read from inside the container. The proxy will work fine with Z.AI as your primary provider. To enable a fallback provider, add your Anthropic API key to .env.docker.
# Clone the repository
git clone https://github.com/0xPuncker/claude-code-proxy.git
cd claude-code-proxy
# Create environment file from Docker example
cp .env.docker.example .env.docker
# Edit .env.docker and add your API keys
# nano .env.docker or code .env.docker
# Build and run with Docker Compose using custom env file
docker-compose --env-file .env.docker up -d
# View logs
docker-compose --env-file .env.docker logs -f cc-proxy
# Stop the container
docker-compose --env-file .env.docker downThe proxy supports multiple environment file patterns:
.env.docker.example: Comprehensive Docker environment template with all available configuration options.env.example: Basic environment template for local development.env.docker: Your custom Docker environment (not tracked in git)
# Using default .env file
docker-compose up -d
# Using custom environment file
docker-compose --env-file .env.docker up -d
# Using specific environment file
docker-compose --env-file .env.production up -d
# Build the Docker image
docker-compose build
# Start the container
docker-compose up -d
# View logs for specific service
docker-compose logs -f cc-proxy
docker-compose logs -f cc-db
docker-compose logs -f cc-adminer
# View all logs
docker-compose logs -f
# Stop the container
docker-compose down
# Stop and remove volumes
docker-compose down -v
# Restart the container
docker-compose restart cc-proxy
# Remove containers and images
docker-compose down --rmi all -vKey Docker environment variables (see .env.docker.example for complete list):
# Required
ZAI_API_KEY=your-zai-api-key-here
ANTHROPIC_API_KEY=your-anthropic-api-key-here
# Optional (with defaults)
PROXY_PORT=4181 # Proxy server port
POSTGRES_VERSION=15 # PostgreSQL version
POSTGRES_DB=claude_proxy # Database name
POSTGRES_USER=postgres # Database user
POSTGRES_PASSWORD=postgres # Database password
ADMINER_PORT=8080 # Adminer UI port
LOG_LEVEL=info # Logging level
NODE_ENV=production # Node environment
RESTART_POLICY=unless-stopped # Container restart policyThe docker-compose setup includes three services:
- cc-proxy: Main proxy server (port 4181)
- cc-db: PostgreSQL database (port 5432)
- cc-adminer: Database management UI (port 8080)
Via Adminer Web UI:
- URL:
http://127.0.0.1:8080 - System: PostgreSQL
- Server:
cc-db - Username:
postgres - Password:
postgres - Database:
claude_proxy
Via psql command:
docker-compose exec cc-db psql -U postgres -d claude_proxyDatabase Backup/Restore:
# Backup
docker-compose exec cc-db pg_dump -U postgres claude_proxy > backup.sql
# Restore
docker-compose exec -T cc-db psql -U postgres claude_proxy < backup.sql// Use the proxy with any Claude API client
const response = await fetch('http://127.0.0.1:4181/v1/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'your-anthropic-api-key',
},
body: JSON.stringify({
model: 'claude-sonnet-4-6',
messages: [{ role: 'user', content: 'Hello, Claude!' }],
max_tokens: 1024,
}),
});import { ClaudeCodeProxy } from './src/index.js';
const proxy = new ClaudeCodeProxy({
port: 4181,
zai: {
baseUrl: 'https://api.z.ai/api/anthropic',
apiKey: process.env.ZAI_API_KEY || '',
},
anthropic: {
baseUrl: 'https://api.anthropic.com',
apiKey: process.env.ANTHROPIC_API_KEY || '',
},
modelFallbackMap: {
'claude-sonnet-4-6': 'claude-sonnet-4-20250514',
'claude-opus-4-6': 'claude-sonnet-4-20250514',
},
fallbackOnCodes: [429, 503, 502],
logLevel: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'silent'
});
proxy.start();PROXY_PORT: Port for the proxy server (default:4181)ZAI_API_KEY: API key for Z.AI serviceANTHROPIC_API_KEY: API key for Anthropic Claude API
The proxy automatically maps newer model names to their compatible equivalents:
{
"glm-5": "claude-sonnet-4-20250514",
"glm-4.7": "claude-sonnet-4-20250514",
"glm-4.6": "claude-sonnet-4-20250514",
"glm-4.5": "claude-sonnet-4-20250514",
"glm-4.5-air": "claude-haiku-4-5-20251001",
"claude-sonnet-4-6": "claude-sonnet-4-20250514",
"claude-opus-4-6": "claude-sonnet-4-20250514",
"claude-haiku-4-5": "claude-haiku-4-5-20251001"
}Main proxy server class.
new ClaudeCodeProxy(config?: Partial<ProxyConfig>)start(): Start the proxy serverstop(): Stop the proxy server
interface ProxyConfig {
port: number;
zai: {
baseUrl: string;
apiKey: string;
};
anthropic: {
baseUrl: string;
apiKey: string;
};
modelFallbackMap: Record<string, string>;
fallbackOnCodes: number[];
logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'silent';
}- Request Interception: The proxy receives requests destined for the Anthropic API
- Primary Attempt: Forwards requests to Anthropic API first (primary provider)
- Quota Tracking: Monitors weekly token usage and automatically switches when limit is reached
- Smart Fallback: Automatic fallback chain: Anthropic API → Claude Subscription → Z.AI
- Circuit Breaker: Monitors provider health and handles failures (429, 502, 503)
- Request Cleaning: Ensures all requests are Anthropic-compatible
- Model Mapping: Maps unsupported model names to compatible alternatives
- Response Proxying: Returns the response to the client transparently
The proxy uses this priority order for automatic failover:
- Anthropic API (Primary) - Used first, subject to weekly quota limits
- Claude Subscription (Fallback) - Used when Anthropic API fails or quota exceeded
- Z.AI (Last Resort) - Used when both Anthropic and Subscription fail
Automatic swap triggers:
- Quota exceeded (e.g., 90% of weekly limit)
- Rate limiting (HTTP 429)
- Service unavailable (HTTP 502, 503)
- Network errors
- Consecutive failures
The proxy provides structured, color-coded logging:
[12:34:56] [INFO] → Z.AI POST /v1/messages
[12:34:57] [OK] ← Z.AI 200
[12:34:58] [INFO] model remap: claude-sonnet-4-6 → claude-sonnet-4-20250514
Log levels:
- DEBUG: Detailed information for debugging
- INFO: General informational messages
- WARN: Warning messages for fallbacks
- ERROR: Error messages
- SILENT: Disable all logging
# Install dependencies
npm install
# Run in development mode with watch
npm run dev
# Run tests
npm test
# Run linter
npm run lint
# Format code
npm run format
# Using Makefile
make build # Build TypeScript
make dev # Run in development mode
make test # Run tests
make docker-build # Build Docker image
make docker-run # Run Docker container
make docker-stop # Stop Docker containers
make help # Show all available commandsgraph TB
Client[Client Application] -->|HTTP Request| Proxy[Claude Code Proxy]
subgraph "Proxy Internal Processing"
Proxy -->|1. Intercept| Request[Request Handler]
Request -->|2. Clean| Cleaning[Request Cleaning]
Cleaning -->|3. Map| Mapping[Model Mapping]
Mapping -->|4. Check| CircuitBreaker{Circuit Breaker}
end
subgraph "Provider Priority Chain"
CircuitBreaker -->|Primary| Anthropic[Anthropic API]
CircuitBreaker -->|Fallback 1| Subscription[Claude Subscription]
CircuitBreaker -->|Fallback 2| ZAI[Z.AI API]
end
subgraph "Health Monitoring"
Health[Provider Health Monitor]
Health -->|Track| Anthropic
Health -->|Track| Subscription
Health -->|Track| ZAI
end
subgraph "Quota Tracking"
Quota[Usage Tracker]
Quota -->|Weekly Limits| Database[(PostgreSQL)]
end
Anthropic -->|Response| Response[Response Handler]
Subscription -->|Response| Response
ZAI -->|Response| Response
Response -->|Return| Client
CircuitBreaker -.->|Monitor| Health
Anthropic -.->|Token Usage| Quota
Subscription -.->|Token Usage| Quota
ZAI -.->|Token Usage| Quota
style Proxy fill:#4A90E2,color:#fff
style Anthropic fill:#50C878,color:#fff
style Subscription fill:#FFB347,color:#000
style ZAI fill:#FF6B6B,color:#fff
style Health fill:#9B59B6,color:#fff
style Quota fill:#3498DB,color:#fff
- Request Interception: Client sends HTTP request to proxy
- Request Processing:
- Request cleaning (ensure Anthropic compatibility)
- Model mapping (convert unsupported models)
- Circuit breaker check (provider health)
- Provider Selection:
- Primary: Anthropic API (subject to quota limits)
- Fallback 1: Claude Subscription (if Anthropic fails/quota exceeded)
- Fallback 2: Z.AI (if both above fail)
- Health Monitoring: Circuit breaker tracks provider health
- Quota Tracking: Usage tracker logs token consumption
- Response Return: Response sent back to client
- Quota exceeded (e.g., 90% of weekly limit)
- Rate limiting (HTTP 429)
- Service unavailable (HTTP 502, 503)
- Network errors
- Consecutive failures (3 = degraded, 5 = unavailable)
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE file for details.
For issues and questions, please use the GitHub issue tracker.
- Built for the Anthropic Claude ecosystem
- Inspired by the need for reliable API failover in production environments