claude-code-openai-wrapper

repository·main·Indexed 20 days ago

https://github.com/richardatct/claude-code-openai-wrapper

An OpenAI API-compatible wrapper for Claude Code (version 2.3.0) that allows developers to use Claude Code's capabilities with any OpenAI client library. It leverages the official Claude Agent SDK to provide chat completions, streaming, and session management. The wrapper supports Claude 4.0, 4.1, 4.5, and 4.6 model families, and includes features such as API key protection, rate limiting, and session continuity via session_id.

Tokens
16.5K
Snippets
57
Records
77
Agent score
69%

What's inside claude-code-openai-wrapper

  1. How session continuity works

    main

    By default, the wrapper is stateless (standard OpenAI behavior). However, you can enable Session Mode by providing a session_id in the request body. This allows Claude to maintain conversation history across multiple requests.

    Using Sessions with OpenAI SDK

    Pass the session_id via extra_body.

    import openai
    
    client = openai.OpenAI(
        base_url="http://localhost:8000/v1",
        api_key="not-needed"
    )
    
    # Request 1: Start session
    client.chat.completions.create(
        model="claude-sonnet-4-6",
        messages=[{"role": "user", "content": "My name is Alice."}],
        extra_body={"session_id": "my-learning-session"}
    )
    
    # Request 2: Claude remembers context
    response = client.chat.completions.create(
        model="claude-sonnet-4-6",
        messages=[{"role": "user", "content": "What is my name?"}],
        extra_body={"session_id": "my-learning-session"}
    )
    # Output: "Your name is Alice."

    Session Management API

    You can manage active sessions using the following endpoints:

    • 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

    Note: Sessions expire after 1 hour of inactivity.

    client.chat.completions.create(
        model="claude-sonnet-4-6",
        messages=[{"role": "user", "content": "Hello!"}],
        extra_body={"session_id": "my-session"}
    )
  2. Configure the Claude Code Working Directory

    main

    By default, the wrapper runs Claude Code in an isolated temporary directory to prevent it from accessing the wrapper's own source code. This is a security feature.

    To use a specific workspace instead of the temporary directory, use one of the following methods:

    1. Environment Variable: export CLAUDE_CWD=/path/to/your/project
    2. .env file: Add CLAUDE_CWD=/home/user/my-workspace to your .env file.
    3. Command line: (Implicitly handled by the server startup logic).
    CLAUDE_CWD=/home/user/my-workspace
  3. Handle OpenAI Max Tokens Evolution

    main

    To support reasoning models (like the o1-series), the max_tokens parameter is being deprecated in favor of max_completion_tokens.

    When mapping OpenAI requests to the Claude wrapper, you should prioritize max_completion_tokens and map it to Claude's max_thinking_tokens:

    # Mapping logic for ChatCompletionRequest
    max_tok = self.max_completion_tokens or self.max_tokens
    if max_tok:
        options['max_thinking_tokens'] = max_tok
    # Map to Claude options
    def to_claude_options(self):
        options = {}
        # Prefer max_completion_tokens if available
        max_tok = self.max_completion_tokens or self.max_tokens
        if max_tok:
            options['max_thinking_tokens'] = max_tok  # Map to Claude
        return options
  4. Choose an authentication method based on use case

    main

    The wrapper provides an OpenAI-compatible interface to Claude services. You must use your own valid Claude subscription or API access. The recommended method depends on your scale and use case:

    Use CaseRecommended AuthenticationNotes
    Personal projectsCLI Auth (Pro/Max) or API KeyAcceptable at moderate scale
    Business/CommercialAPI Key, Bedrock, or Vertex AIUse platform.claude.com
    High-scale applicationsBedrock or Vertex AIEnterprise authentication recommended

    Authentication Details

    • ANTHROPIC_API_KEY: Explicitly allowed for programmatic access under Commercial Terms.
    • AWS Bedrock / Google Vertex AI: Explicitly allowed for programmatic access under Commercial Terms.
    • CLI Auth (claude auth login): Uses the official Claude Agent SDK with your personal Claude Pro/Max subscription. This is functionally equivalent to using Claude Code directly.
  5. Update ClaudeAgentOptions and System Prompt Configuration

    main

    When migrating to claude-agent-sdk, note the following breaking changes in how options and system prompts are handled:

    Rename Options Class

    ClaudeCodeOptions has been renamed to ClaudeAgentOptions.

    Structured System Prompts

    System prompts no longer default to the Claude Code preset. You must use a structured dictionary format:

    • To use a custom text prompt:
      options.system_prompt = {
          "type": "text",
          "text": "Your custom prompt"
      }
    • To restore Claude Code default behavior (Recommended):
      options.system_prompt = {
          "type": "preset",
          "preset": "claude_code"
      }
    • To use vanilla Claude behavior: Omit the system_prompt field entirely.
    # New structured system prompt format
    options.system_prompt = {
        "type": "text",
        "text": system_prompt
    }
  6. Run the Server in Development or Production Mode

    main

    Depending on your use case, choose one of the following execution methods:

    Development Mode

    Recommended for local development. It uses uvicorn with --reload to automatically restart the server when code changes are detected.

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

    Production Mode

    Use the standard entry point. This mode supports specifying a custom port as a positional argument or via the PORT environment variable.

    # Default port (8000)
    poetry run python main.py
    
    # Custom port via argument
    poetry run python main.py 9000
    
    # Custom port via environment variable
    PORT=9000 poetry run python main.py
    # Development mode
    poetry run uvicorn src.main:app --reload --port 8000
    
    # Production mode
    poetry run python main.py
  7. Build and run the wrapper with Docker

    main

    You can containerize the Claude Code OpenAI API Wrapper using Docker. This includes options for production, custom workspaces, and development with hot reloading.

    Build the image

    docker build -t claude-wrapper:latest .

    Run modes

    Production: Runs in detached mode, mapping port 8000 and mounting the .claude directory for authentication persistence.

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

    With custom workspace: Use this to allow the agent to access specific project files. Set CLAUDE_CWD to the mounted path.

    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): Mounts the current directory to /app and uses poetry to run uvicorn with the --reload flag.

    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
  8. Test the wrapper endpoints and functionality

    main

    After starting the server, you can verify the installation and functionality using the provided test scripts.

    Quick Test

    Run the quick test suite to verify all endpoints are responding:

    poetry run python test_endpoints.py

    Basic Test

    Run the comprehensive test suite. If you have enabled API key protection, you must provide the TEST_API_KEY environment variable:

    # Standard run
    poetry run python test_basic.py
    
    # With API key protection
    TEST_API_KEY=your-generated-key poetry run python test_basic.py

    Verify Authentication Status

    You can check the current authentication status via a curl command:

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

    Expected Results

    Successful tests should indicate:

    • 4/4 endpoint tests passing
    • 4/4 basic tests passing
    • Detected authentication method (e.g., claude_cli, anthropic, bedrock, or vertex)
    • Real cost tracking and accurate token counts
    # Quick Test
    poetry run python test_endpoints.py
    
    # Basic Test with API key
    TEST_API_KEY=your-generated-key poetry run python test_basic.py
    
    # Check auth status
    curl http://localhost:8000/v1/auth/status | python -m json.tool
  9. Migrate from Claude Code SDK to Claude Agent SDK

    main

    When upgrading to version 2.0.0+, the project migrates from the legacy claude-code-sdk to the new claude-agent-sdk. This involves updating imports, dependency management, and the configuration object structure.

    Dependency Update

    Replace the old SDK with the new version using Poetry:

    poetry remove claude-code-sdk
    poetry add claude-agent-sdk@^0.1.6
    poetry lock
    poetry install

    Code Changes

    1. Update Imports: Change the import source from claude_code_sdk to claude_agent_sdk.
    2. Update Options Class: Replace ClaudeCodeOptions with ClaudeAgentOptions.
    3. System Prompt Configuration: The system prompt now uses a structured format. To restore the default Claude Code behavior, use the preset key.

    Example Migration

    # Before
    from claude_code_sdk import query, ClaudeCodeOptions, Message
    options = ClaudeCodeOptions(max_turns=1, cwd="/path")
    
    # After
    from claude_agent_sdk import query, ClaudeAgentOptions, Message
    options = ClaudeAgentOptions(
        max_turns=1,
        cwd="/path",
        system_prompt={"type": "preset", "preset": "claude_code"}
    )
  10. Set up development environment

    main

    If you are contributing to the project or developing locally, use the following commands to set up your environment:

    • Install dependencies: Use poetry install --with dev to include development tools.
    • Code formatting: Use poetry run black . to format the codebase.
    • Run tests: Use poetry run pytest tests/ to execute the full test suite.
    poetry install --with dev
    poetry run black .
    poetry run pytest tests/
  11. Quick Start: Install and Run the Wrapper

    main

    Follow these steps to get an OpenAI-compatible Claude Code API running locally in under 2 minutes.

    1. Clone and setup: Clone the repository and use Poetry to install dependencies (this includes the Claude Code CLI).
    2. Authenticate: Set your ANTHROPIC_API_KEY or use claude auth login.
    3. Start the server: Run the server using uvicorn in development mode.
    4. Test: Run the provided test script to verify connectivity.
    # 1. Clone and setup the wrapper
    git clone https://github.com/RichardAtCT/claude-code-openai-wrapper
    cd claude-code-openai-wrapper
    poetry install
    
    # 2. Authenticate
    export ANTHROPIC_API_KEY=your-api-key
    
    # 3. Start the server
    poetry run uvicorn src.main:app --reload --port 8000
    
    # 4. Test it works
    poetry run python test_endpoints.py
  12. Secure your API with API Key Protection

    main

    If you are accessing the server remotely, you can enable API key protection.

    1. Interactive Setup: If API_KEY is not set in your environment, the server will prompt Enable API key protection? (y/N) on startup. If you select y, it will generate a secure token.
    2. Using the Key: Once generated, include the key in your requests using the Authorization header.

    Example Request:

    curl -H "Authorization: Bearer YOUR_GENERATED_KEY" http://localhost:8000/v1/models
    # Example usage with a generated key
    curl -H "Authorization: Bearer Xf8k2mN9-vLp3qR5_zA7bW1cE4dY6sT0uI" \
         http://localhost:8000/v1/models