Skip to content
Β 
Β 

Latest commit

Β 

History

83 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Claude Code OpenAI API Wrapper

An OpenAI API-compatible wrapper for Claude Code, allowing you to use Claude Code with any OpenAI client library. Now powered by the official Claude Agent SDK v0.2.134+ with enhanced authentication and features.

Version

Current Version: 2.3.0

  • Live /v1/models discovery: When ANTHROPIC_API_KEY is set, the wrapper fetches Anthropic's live model list (cached) instead of serving the static fallback
  • Dynamic default Sonnet: DEFAULT_MODEL resolves to the latest Sonnet at startup when ANTHROPIC_API_KEY is configured; falls back to claude-sonnet-4-6 otherwise
  • Operator overrides: New CLAUDE_MODELS_OVERRIDE, FAST_MODEL, and MODEL_LIST_* env vars
  • Updated catalog: Claude 4.6 family added to the static fallback list
  • Bug fixes: continue_conversation SDK field corrected; max_thinking_tokens now wired through; real token counts from SDK; finish_reason mapped from actual stop_reason
  • Concurrent requests: Auth env vars passed via options.env β€” no more serialising lock
  • New parameters: reasoning_effort, response_format, max_budget_usd, thinking added to request models
  • Async session manager: threading.Lock replaced with asyncio.Lock for proper async safety
  • SDK options refactor: run_completion simplified to accept a claude_options dict, enabling generic passthrough of any SDK field

Upgrading from v2.2.0:

  1. Pull latest code: git pull origin main
  2. Update dependencies: poetry install
  3. Restart server β€” no breaking changes to the OpenAI/Anthropic API surface

Migration Resources:

Status

πŸŽ‰ Production Ready - All core features working and tested:

  • βœ… Chat completions endpoint with official Claude Agent SDK v0.2.134+
  • βœ… Anthropic Messages API (/v1/messages) for native compatibility
  • βœ… Streaming and non-streaming responses
  • βœ… Full OpenAI SDK compatibility
  • βœ… Interactive landing page with API explorer
  • βœ… Multi-provider authentication (API key, Bedrock, Vertex AI, CLI auth)
  • βœ… System prompt support via SDK options
  • βœ… Model selection support with validation
  • βœ… Fast by default - Tools disabled for OpenAI compatibility (5-10x faster)
  • βœ… Optional tool usage (Read, Write, Bash, etc.) when explicitly enabled
  • βœ… Real token counts from SDK metadata (no more estimates)
  • βœ… Accurate finish_reason mapped from SDK stop_reason
  • βœ… Fully concurrent requests β€” no serialising lock for auth env vars
  • βœ… Session continuity with conversation history across requests
  • βœ… Session management endpoints for full session control
  • βœ… Health, auth status, and models endpoints
  • βœ… Development mode with auto-reload

Features

πŸ”₯ Core API Compatibility

  • OpenAI-compatible /v1/chat/completions endpoint
  • Anthropic-compatible /v1/messages endpoint
  • Support for both streaming and non-streaming responses
  • Compatible with OpenAI Python SDK and all OpenAI client libraries
  • Automatic model validation and selection

πŸ›  Claude Agent SDK Integration

  • Official Claude Agent SDK integration (v0.2.134+) πŸ†•
  • Real-time cost tracking - actual costs from SDK metadata
  • Real token counting - input/output tokens directly from SDK (no estimation)
  • Accurate finish_reason - mapped from SDK stop_reason (end_turn β†’ stop, max_tokens β†’ length)
  • Session management - proper session IDs and continuity
  • Enhanced error handling with detailed authentication diagnostics
  • Fully concurrent - auth env vars passed via SDK options, no serialising mutex
  • Modern SDK features - Latest capabilities and improvements

πŸ” Multi-Provider Authentication

  • Automatic detection of authentication method
  • Claude CLI auth - works with existing claude auth setup
  • Direct API key - ANTHROPIC_API_KEY environment variable
  • AWS Bedrock - enterprise authentication with AWS credentials
  • Google Vertex AI - GCP authentication support

⚑ Advanced Features

  • System prompt support via SDK options
  • Optional tool usage - Enable Claude Code tools (Read, Write, Bash, etc.) when needed
  • Fast default mode - Tools disabled by default for OpenAI API compatibility
  • reasoning_effort - Map OpenAI reasoning_effort: "low"|"medium"|"high" to SDK effort
  • response_format - Pass {"type": "json_object"} or JSON Schema for structured outputs
  • thinking - Explicit thinking config {"type": "enabled", "budget_tokens": N} (overrides max_tokens mapping)
  • max_budget_usd - Per-request cost cap in USD
  • Development mode with auto-reload (uvicorn --reload)
  • Interactive API key protection - Optional security with auto-generated tokens
  • Comprehensive logging and debugging capabilities

🌐 Interactive Landing Page

  • API Explorer at root URL (http://localhost:8000/)
  • Live endpoint testing - Expandable accordions fetch real-time data
  • Light/dark theme toggle - Persists preference in localStorage
  • Copy-to-clipboard - One-click copy for Quick Start commands
  • Version badge and GitHub link

Quick Start

Get started in under 2 minutes:

# 1. Clone and setup the wrapper
git clone https://github.com/gustavokch/claude-code-openai-wrapper
cd claude-code-openai-wrapper
poetry install  # Installs SDK with bundled Claude Code CLI

# 2. Authenticate (choose one method)
export ANTHROPIC_API_KEY=your-api-key  # Recommended
# OR use CLI auth: claude auth login

# 3. Start the server
poetry run uvicorn src.main:app --reload --port 8000

# 4. Test it works
poetry run python test_endpoints.py

πŸŽ‰ That's it! Your OpenAI-compatible Claude Code API is running on http://localhost:8000

Prerequisites

  1. Python 3.10+: Required for the server (supports Python 3.10, 3.11, 3.12, 3.13)

  2. Poetry: For dependency management

    # Install Poetry (if not already installed)
    curl -sSL https://install.python-poetry.org | python3 -
  3. Authentication: Choose one method:

    • Option A: Set environment variable (Recommended)
      export ANTHROPIC_API_KEY=your-api-key
    • Option B: Authenticate via CLI
      claude auth login
    • Option C: Use AWS Bedrock or Google Vertex AI (see Configuration section)

Note: The Claude Code CLI is bundled with the SDK (v0.2.134+). No separate Node.js or npm installation required!

Installation

  1. Clone the repository:

    git clone https://github.com/gustavokch/claude-code-openai-wrapper
    cd claude-code-openai-wrapper
  2. Install dependencies with Poetry:

    poetry install

    This will create a virtual environment and install all dependencies.

  3. Configure environment:

    cp .env.example .env
    # Edit .env with your preferences

Configuration

Edit the .env file:

# Claude CLI path (usually just "claude")
CLAUDE_CLI_PATH=claude

# Explicit authentication method (optional)
# Options: cli, api_key, bedrock, vertex
# If not set, auto-detects based on available credentials
# CLAUDE_AUTH_METHOD=cli

# Optional API key for client authentication
# If not set, server will prompt for interactive API key protection on startup
# API_KEY=your-optional-api-key

# Server port
PORT=8000

# Timeout in milliseconds
MAX_TIMEOUT=600000

# CORS origins
CORS_ORIGINS=["*"]

# Working directory for Claude Code (optional)
# If not set, uses an isolated temporary directory for security
# CLAUDE_CWD=/path/to/your/workspace

πŸ“ Working Directory Configuration

By default, Claude Code runs in an isolated temporary directory to prevent it from accessing the wrapper's source code. This enhances security by ensuring Claude Code only has access to the workspace you intend.

Configuration Options:

  1. Default (Recommended): Automatically creates a temporary isolated workspace

    # No configuration needed - secure by default
    poetry run python main.py
  2. Custom Directory: Set a specific workspace directory

    export CLAUDE_CWD=/path/to/your/project
    poetry run python main.py
  3. Via .env file: Add to your .env file

    CLAUDE_CWD=/home/user/my-workspace

Important Notes:

  • The temporary directory is automatically cleaned up when the server stops
  • This prevents Claude Code from accidentally modifying the wrapper's own code
  • Cross-platform compatible (Windows, macOS, Linux)

πŸ” API Security Configuration

The server supports interactive API key protection for secure remote access:

  1. No API key set: Server prompts "Enable API key protection? (y/N)" on startup

    • Choose No (default): Server runs without authentication
    • Choose Yes: Server generates and displays a secure API key
  2. Environment API key set: Uses the configured API_KEY without prompting

# Example: Interactive protection enabled
poetry run python main.py

# Output:
# ============================================================
# πŸ” API Endpoint Security Configuration
# ============================================================
# Would you like to protect your API endpoint with an API key?
# This adds a security layer when accessing your server remotely.
# 
# Enable API key protection? (y/N): y
# 
# πŸ”‘ API Key Generated!
# ============================================================
# API Key: Xf8k2mN9-vLp3qR5_zA7bW1cE4dY6sT0uI
# ============================================================
# πŸ“‹ IMPORTANT: Save this key - you'll need it for API calls!
#    Example usage:
#    curl -H "Authorization: Bearer Xf8k2mN9-vLp3qR5_zA7bW1cE4dY6sT0uI" \
#         http://localhost:8000/v1/models
# ============================================================

Perfect for:

  • 🏠 Local development - No authentication needed
  • 🌐 Remote access - Secure with generated tokens
  • πŸ”’ VPN/Tailscale - Add security layer for remote endpoints

πŸ›‘οΈ Rate Limiting

Built-in rate limiting protects against abuse and ensures fair usage:

  • Chat Completions (/v1/chat/completions): 10 requests/minute
  • Debug Requests (/v1/debug/request): 2 requests/minute
  • Auth Status (/v1/auth/status): 10 requests/minute
  • Health Check (/health): 30 requests/minute

Rate limits are applied per IP address using a fixed window algorithm. When exceeded, the API returns HTTP 429 with a structured error response:

{
  "error": {
    "message": "Rate limit exceeded. Try again in 60 seconds.",
    "type": "rate_limit_exceeded",
    "code": "too_many_requests",
    "retry_after": 60
  }
}

Configure rate limiting through environment variables:

RATE_LIMIT_ENABLED=true
RATE_LIMIT_CHAT_PER_MINUTE=10
RATE_LIMIT_DEBUG_PER_MINUTE=2
RATE_LIMIT_AUTH_PER_MINUTE=10
RATE_LIMIT_HEALTH_PER_MINUTE=30

Running the Server

  1. Verify Claude Code is installed and working:

    claude --version
    claude --print --model claude-haiku-4-5-20251001 "Hello"  # Test with fastest model
  2. Start the server:

    Development mode (recommended - auto-reloads on changes):

    poetry run uvicorn src.main:app --reload --port 8000

    Production mode:

    poetry run python main.py

    Port Options for production mode:

    • Default: Uses port 8000 (or PORT from .env)
    • If port is in use, automatically finds next available port
    • Specify custom port: poetry run python main.py 9000
    • Set in environment: PORT=9000 poetry run python main.py

Docker

Build and run the wrapper in a Docker container.

Build

docker build -t claude-wrapper:latest .

Run

Production:

docker run -d -p 8000:8000 \
  -v ~/.claude:/root/.claude \
  --name claude-wrapper \
  claude-wrapper:latest

With custom workspace:

docker run -d -p 8000:8000 \
  -v ~/.claude:/root/.claude \
  -v /path/to/project:/workspace \
  -e CLAUDE_CWD=/workspace \
  claude-wrapper:latest

Development (hot reload):

docker run -d -p 8000:8000 \
  -v ~/.claude:/root/.claude \
  -v $(pwd):/app \
  claude-wrapper:latest \
  poetry run uvicorn src.main:app --host 0.0.0.0 --port 8000 --reload

Docker Compose

version: '3.8'
services:
  claude-wrapper:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - ~/.claude:/root/.claude
    environment:
      - PORT=8000
      - MAX_TIMEOUT=600
    restart: unless-stopped

Run: docker-compose up -d | Stop: docker-compose down

Environment Variables

Variable Description Default
PORT Server port 8000
MAX_TIMEOUT Request timeout (seconds) 300
CLAUDE_CWD Working directory temp dir
CLAUDE_AUTH_METHOD Auth method: cli, api_key, bedrock, vertex auto-detect
ANTHROPIC_API_KEY Direct Anthropic API key. Optional β€” also unlocks live /v1/models discovery and dynamic latest-Sonnet default. Not required when using Bedrock, Vertex, or Claude CLI subscription auth. -
API_KEYS Comma-separated client API keys -
DEFAULT_MODEL Override the default model. When unset and ANTHROPIC_API_KEY is configured, the wrapper resolves the latest Sonnet at startup; otherwise falls back to claude-sonnet-4-6. auto
FAST_MODEL Speed/cost-optimized model alias. claude-haiku-4-5-20251001
CLAUDE_MODELS_OVERRIDE Comma-separated model IDs to advertise via /v1/models. Takes precedence over both live and static lists. -
MODEL_LIST_CACHE_TTL_SECONDS Cache TTL for live /v1/models results. 3600
MODEL_LIST_ERROR_TTL_SECONDS Short cache TTL applied when the live fetch fails, so transient outages don't suppress live discovery for the full hour. 60
MODEL_LIST_REQUEST_TIMEOUT_SECONDS HTTP timeout for the live model fetch. 5

Management

docker logs -f claude-wrapper        # View logs
docker stop claude-wrapper           # Stop
docker start claude-wrapper          # Start
docker rm claude-wrapper             # Remove

Test

curl http://localhost:8000/health
curl http://localhost:8000/v1/models

Usage Examples

Using curl

# Basic chat completion (no auth)
curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "messages": [
      {"role": "user", "content": "What is 2 + 2?"}
    ]
  }'

# With API key protection (when enabled)
curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-generated-api-key" \
  -d '{
    "model": "claude-sonnet-4-6",
    "messages": [
      {"role": "user", "content": "Write a Python hello world script"}
    ],
    "stream": true
  }'

Using OpenAI Python SDK

from openai import OpenAI

# Configure client (automatically detects auth requirements)
client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="your-api-key-if-required"  # Only needed if protection enabled
)

# Alternative: Let examples auto-detect authentication
# The wrapper's example files automatically check server auth status

# Basic chat completion
response = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What files are in the current directory?"}
    ]
)

print(response.choices[0].message.content)
# Output: Fast response without tool usage (default behaviour)

# Enable tools when you need them (e.g., to read files)
response = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[
        {"role": "user", "content": "What files are in the current directory?"}
    ],
    extra_body={"enable_tools": True}  # Enable tools for file access
)
print(response.choices[0].message.content)
# Output: Claude will actually read your directory and list the files!

# Check real costs and tokens
print(f"Cost: ${response.usage.total_tokens * 0.000003:.6f}")  # Real cost tracking
print(f"Tokens: {response.usage.total_tokens} ({response.usage.prompt_tokens} + {response.usage.completion_tokens})")

# Streaming
stream = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[
        {"role": "user", "content": "Explain quantum computing"}
    ],
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")

Advanced Parameters

These extra fields extend the standard OpenAI request body and are passed through to the Claude Agent SDK.

reasoning_effort

Controls the depth of Claude's thinking. Maps to the SDK effort field.

response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[{"role": "user", "content": "Solve this math problem..."}],
    extra_body={"reasoning_effort": "high"}  # "low" | "medium" | "high"
)

response_format

Request structured output. Passed through as SDK output_format.

response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[{"role": "user", "content": "Return JSON with name and age fields."}],
    extra_body={"response_format": {"type": "json_object"}}
)

thinking

Explicit thinking configuration β€” takes precedence over the max_tokens β†’ max_thinking_tokens mapping.

response = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[{"role": "user", "content": "Hard reasoning task"}],
    extra_body={"thinking": {"type": "enabled", "budget_tokens": 8000}}
)
# Also: {"type": "adaptive"} or {"type": "disabled"}

max_budget_usd

Cap per-request cost in USD. The SDK will stop generation when the budget is reached.

response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[{"role": "user", "content": "Long task..."}],
    extra_body={"max_budget_usd": 0.05}  # stop at $0.05
)

max_tokens / max_completion_tokens

Maps to the SDK's max_thinking_tokens (best-effort). For precise control use thinking above.

response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[{"role": "user", "content": "Brief answer please"}],
    max_tokens=512
)

Supported Models

The wrapper exposes Claude's full model catalog. When ANTHROPIC_API_KEY is set, /v1/models returns Anthropic's live list (cached for 1 hour) and the wrapper picks the latest Sonnet as DEFAULT_MODEL at startup. When the key is absent β€” for example, when running with Bedrock, Vertex, or Claude CLI subscription auth β€” the static list below is served and claude-sonnet-4-6 is used as the fallback default. Operators who want a curated list regardless of auth can set CLAUDE_MODELS_OVERRIDE.

Claude 4.6 Family (Latest)

  • claude-opus-4-6 🎯 Most capable
  • claude-sonnet-4-6 ⭐ Recommended β€” best coding model

Claude 4.5 Family (Fall 2025)

  • claude-opus-4-5-20250929 β€” deep reasoning and coding
  • claude-sonnet-4-5-20250929 β€” agents and coding
  • claude-haiku-4-5-20251001 ⚑ Fast & cheap

Claude 4.1 & 4.0 Family

  • claude-opus-4-1-20250805 β€” upgraded Opus 4
  • claude-opus-4-20250514 β€” original Opus 4
  • claude-sonnet-4-20250514 β€” original Sonnet 4

Note: Claude 3.x models are not supported by the Claude Agent SDK. The model parameter is passed to Claude Code via the SDK's model selection.

Using non-Claude models via passthrough (e.g. GLM-5.2)

The wrapper can serve any model that your Claude Code installation can reach, including non-Anthropic models such as GLM-5.2. The wrapper does not call the model provider directly β€” it forwards the model name to Claude Code, which must already be configured to reach the provider.

Prerequisite β€” point Claude Code at the provider. Set these on the Claude Code process (your environment, not wrapper code):

  • ANTHROPIC_BASE_URL β€” your proxy that speaks the Anthropic API format and forwards to the provider (e.g. a GLM endpoint).
  • ANTHROPIC_AUTH_TOKEN or ANTHROPIC_API_KEY β€” the credential your proxy requires, if any.

Use it through the wrapper. Send the model name in the request:

curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"glm-5.2","messages":[{"role":"user","content":"hello"}]}'

To make GLM the default, set DEFAULT_MODEL=glm-5.2 for the wrapper. glm-5.2 is advertised in GET /v1/models.

Session Continuity πŸ†•

The wrapper now supports session continuity, allowing you to maintain conversation context across multiple requests. This is a powerful feature that goes beyond the standard OpenAI API.

How It Works

  • Stateless Mode (default): Each request is independent, just like the standard OpenAI API
  • Session Mode: Include a session_id to maintain conversation history across requests

Using Sessions with OpenAI SDK

import openai

client = openai.OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"
)

# Start a conversation with session continuity
response1 = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[
        {"role": "user", "content": "Hello! My name is Alice and I'm learning Python."}
    ],
    extra_body={"session_id": "my-learning-session"}
)

# Continue the conversation - Claude remembers the context
response2 = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[
        {"role": "user", "content": "What's my name and what am I learning?"}
    ],
    extra_body={"session_id": "my-learning-session"}  # Same session ID
)
# Claude will remember: "Your name is Alice and you're learning Python."

Using Sessions with curl

# First message (add -H "Authorization: Bearer your-key" if auth enabled)
curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "messages": [{"role": "user", "content": "My favourite color is blue."}],
    "session_id": "my-session"
  }'

# Follow-up message - context is maintained
curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "messages": [{"role": "user", "content": "What's my favourite color?"}],
    "session_id": "my-session"
  }'

Session Management

The wrapper provides endpoints to manage active sessions:

  • GET /v1/sessions - List all active sessions
  • GET /v1/sessions/{session_id} - Get session details
  • DELETE /v1/sessions/{session_id} - Delete a session
  • GET /v1/sessions/stats - Get session statistics
# List active sessions
curl http://localhost:8000/v1/sessions

# Get session details
curl http://localhost:8000/v1/sessions/my-session

# Delete a session
curl -X DELETE http://localhost:8000/v1/sessions/my-session

Session Features

  • Automatic Expiration: Sessions expire after 1 hour of inactivity
  • Streaming Support: Session continuity works with both streaming and non-streaming requests
  • Memory Persistence: Full conversation history is maintained within the session
  • Efficient Storage: Only active sessions are kept in memory

Examples

See examples/session_continuity.py for comprehensive Python examples and examples/session_curl_example.sh for curl examples.

API Endpoints

Core Endpoints

  • GET / - Interactive landing page with API explorer
  • POST /v1/chat/completions - OpenAI-compatible chat completions (supports session_id)
  • POST /v1/messages - Anthropic-compatible messages endpoint
  • GET /v1/models - List available models
  • GET /v1/auth/status - Check authentication status and configuration
  • GET /version - Get API version
  • GET /health - Health check endpoint

Session Management Endpoints πŸ†•

  • GET /v1/sessions - List all active sessions
  • GET /v1/sessions/{session_id} - Get detailed session information
  • DELETE /v1/sessions/{session_id} - Delete a specific session
  • GET /v1/sessions/stats - Get session manager statistics

Limitations & Roadmap

🚫 Current Limitations

  • Images in messages are converted to text placeholders
  • Function calling not supported (tools work automatically based on prompts)
  • OpenAI parameters not mapped: temperature, top_p, logit_bias, presence_penalty, frequency_penalty (ignored with a warning)
  • Multiple responses (n > 1) not supported

πŸ›£ Planned Enhancements

  • Token-level streaming - include_partial_messages for finer chunks
  • MCP integration - Model Context Protocol server support
  • Temperature/top_p - native SDK mapping when available

βœ… Recent Improvements (v2.3.0)

  • Bug fixes: continue_conversation field corrected; max_thinking_tokens now wired through to SDK
  • Real token counts: response usage comes from SDK metadata, not character estimation
  • Accurate finish_reason: mapped from SDK stop_reason (max_tokens β†’ length, etc.)
  • Concurrent requests: auth env vars via options.env β€” no serialising mutex
  • New parameters: reasoning_effort, response_format, max_budget_usd, thinking
  • Async session manager: threading.Lock β†’ asyncio.Lock for proper async safety

βœ… v2.2.0 Features

  • Interactive Landing Page: API explorer with live endpoint testing
  • Anthropic Messages API: Native /v1/messages endpoint
  • Explicit Auth Selection: CLAUDE_AUTH_METHOD env var
  • Tool Execution Fix: enable_tools: true now works correctly

βœ… v2.0.0 - v2.1.0 Features

  • Claude Agent SDK v0.2.134+ with bundled CLI
  • Multi-provider auth (CLI, API key, Bedrock, Vertex AI)
  • Session continuity and management
  • System prompt support

Troubleshooting

  1. Claude CLI not found:

    # Check Claude is in PATH
    which claude
    # Update CLAUDE_CLI_PATH in .env if needed
  2. Authentication errors:

    # Test authentication with fastest model
    claude --print --model claude-haiku-4-5-20251001 "Hello"
    # If this fails, re-authenticate if needed
  3. Timeout errors:

    • Increase MAX_TIMEOUT in .env
    • Note: Claude Code can take time for complex requests

Testing

πŸ§ͺ Quick Test Suite

Test all endpoints with a simple script:

# Make sure server is running first
poetry run python test_endpoints.py

πŸ“ Basic Test Suite

Run the comprehensive test suite:

# Make sure server is running first  
poetry run python test_basic.py

# With API key protection enabled, set TEST_API_KEY:
TEST_API_KEY=your-generated-key poetry run python test_basic.py

The test suite automatically detects whether API key protection is enabled and provides helpful guidance for providing the necessary authentication.

πŸ” Authentication Test

Check authentication status:

curl http://localhost:8000/v1/auth/status | python -m json.tool

βš™οΈ Development Tools

# Install development dependencies
poetry install

# Format code
poetry run black .

# Run unit tests (no server required)
PYTHONPATH=$(pwd) poetry run pytest tests/test_claude_cli_unit.py tests/test_session_manager_unit.py tests/test_models_unit.py -v

# Run full test suite (unit + integration, server must be running for integration tests)
PYTHONPATH=$(pwd) poetry run pytest tests/ -v

βœ… Expected Results

All tests should show:

  • 4/4 endpoint tests passing
  • 4/4 basic tests passing
  • Authentication method detected (claude_cli, anthropic, bedrock, or vertex)
  • Real cost tracking (e.g., $0.001-0.005 per test call)
  • Accurate token counts from SDK metadata

Terms Compliance

This wrapper is designed to be compliant with Anthropic's Terms of Service.

Requirements for Users

Important: You must have your own valid Claude subscription or API access to use this wrapper.

  • Claude Pro or Max subscription - For CLI authentication (claude auth login)
  • Anthropic API key - Available at platform.claude.com
  • AWS Bedrock or Google Vertex AI - For enterprise cloud authentication

This wrapper does not provide Claude access - it provides an OpenAI-compatible interface to Claude services you already have access to.

How This Wrapper Works

  • Uses the official Claude Agent SDK - The same SDK Anthropic provides for developers
  • Each user authenticates individually - No credential sharing or pooling
  • Format translation only - Converts OpenAI-format requests to Claude SDK calls
  • No reselling - Users access Claude through their own subscriptions/API keys

Personal vs Commercial Use

Use Case Recommended Authentication Notes
Personal projects CLI Auth (Pro/Max) or API Key Acceptable at moderate scale
Business/Commercial API Key, Bedrock, or Vertex AI Use platform.claude.com
High-scale applications Bedrock or Vertex AI Enterprise authentication recommended

Note on Consumer Plans: Claude Pro and Max subscriptions are primarily designed for individual, interactive use. Using them through wrappers or automated implementations is acceptable for personal projects at moderate scale. For business use or applications that scale significantly, Anthropic's commercial API offerings at platform.claude.com are more appropriate.

Authentication Methods

Method Terms Compliance
ANTHROPIC_API_KEY Commercial Terms Explicitly allowed for programmatic access
AWS Bedrock Commercial Terms Explicitly allowed for programmatic access
Google Vertex AI Commercial Terms Explicitly allowed for programmatic access
CLI Auth (Pro/Max) Consumer Terms Uses official SDK with official auth methods

CLI Authentication Note

Using CLI auth (claude auth login) with this wrapper is functionally equivalent to using Claude Code directly - both use the Claude Agent SDK with your personal subscription. Anthropic provides the SDK with CLI auth support, and this wrapper simply provides an alternative interface format.

What This Wrapper Does NOT Do

  • Does not share or pool credentials between users
  • Does not include or expose API keys or credentials
  • Does not resell API access
  • Does not train competing AI models
  • Does not scrape or harvest data
  • Does not bypass authentication or rate limits

User Responsibilities

By using this wrapper, you agree to:

Disclaimer

This is an independent open-source project, not affiliated with or endorsed by Anthropic. Users are responsible for ensuring their own usage complies with Anthropic's terms. Anthropic reserves the right to modify their Terms of Service at any time.

When in doubt, use ANTHROPIC_API_KEY authentication which is explicitly permitted for programmatic access under the Commercial Terms.

For Anthropic's official terms, see:

Licence

MIT Licence

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

About

OpenAI API-compatible wrapper for Claude Code

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages