Claude Gateway

Use your Claude Code subscription with any OpenAI-compatible tool

Views1
PublishedJan 14, 2026

Loading actions...

5 minBeginnerpromptSingle file

Skill content

Main instructions and any bundled files for this skill.

markdown

Claude Gateway

Use your Claude Code subscription with any OpenAI-compatible tool

License: MIT TypeScript Node OpenAI Compatible

What is Claude Gateway?

Claude Gateway is an OpenAI-compatible HTTP proxy that lets you use your Claude Code subscription with any tool built for OpenAI's API.

Features

  • OpenAI-compatible API - Drop-in replacement for OpenAI endpoints
  • Automatic authentication - OAuth flow handled for you
  • Streaming support - Full streaming response support
  • Image support - Send images via URL or base64 encoding
  • Zero code changes - Just point your tool to the gateway
  • Token auto-refresh - Handles 8-hour token expiration automatically
  • Model listing - Query available Claude models via /v1/models
  • Automatic prompt caching - 90% cost reduction on repeated requests

Requirements

  • Claude Code subscription from claude.ai
  • Node.js 18+

Quick Start

No installation needed - run directly with npx:

npx claude-gateway start

That's it! The gateway will:

  1. Authenticate you via OAuth (first run only)
  2. Start the proxy server on http://localhost:45554
  3. Let you use your Claude Code subscription from any OpenAI-compatible tool!

CLI Commands

npx claude-gateway start                           # Start the gateway server
npx claude-gateway start --port 8080               # Use custom port
npx claude-gateway start --api-key my-secret-key   # Enable API key authentication
npx claude-gateway start --verbose                 # Full request logging
npx claude-gateway login                           # Authenticate with OAuth
npx claude-gateway status                          # Check authentication status

Alternative: Clone and Run

git clone https://gitlab.com/soapbox-pub/claude-gateway.git
cd claude-gateway
npm install
npm start

Usage Examples

Python (OpenAI SDK)

from openai import OpenAI

client = OpenAI(
    api_key="not-used",  # Can be anything - gateway handles auth
    base_url="http://localhost:45554/v1",
)

response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Hello!"}
    ]
)

print(response.choices[0].message.content)

JavaScript/TypeScript (OpenAI SDK)

import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'not-used',  // Can be anything - gateway handles auth
  baseURL: 'http://localhost:45554/v1',
});

const response = await client.chat.completions.create({
  model: 'claude-sonnet-4-5-20250929',
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'Hello!' }
  ]
});

console.log(response.choices[0].message.content);

cURL

curl -X POST http://localhost:45554/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-api-key-here" \
  -d '{
    "model": "claude-sonnet-4-5-20250929",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "Hello!"}
    ]
  }'

Note: The Authorization header is only required if you started the server with --api-key

Streaming

from openai import OpenAI

client = OpenAI(
    api_key="not-used",
    base_url="http://localhost:45554/v1",
)

stream = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[{"role": "user", "content": "Write a story"}],
    stream=True
)

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

Images

Claude Gateway supports sending images in your messages using the same format as OpenAI's API:

from openai import OpenAI

client = OpenAI(
    api_key="not-used",
    base_url="http://localhost:45554/v1",
)

# Option 1: Image from URL
response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What's in this image?"},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://example.com/image.jpg"
                    }
                }
            ]
        }
    ]
)

# Option 2: Base64-encoded image
response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What's in this image?"},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "data:image/jpeg;base64,/9j/4AAQSkZJRg..."
                    }
                }
            ]
        }
    ]
)

Supported formats:

  • JPEG, PNG, GIF, WebP
  • URLs (automatically fetched and converted)
  • Base64 data URLs (data:image/...;base64,...)

More examples: See the examples/ directory for complete vision examples in both Python and JavaScript.

How It Works

┌─────────────────────────┐
│  OpenAI-compatible Tool │
│  (Python SDK, etc.)     │
└───────────┬─────────────┘
            │ POST /v1/chat/completions
            │ OpenAI format request

┌──────────────────────────────────────────┐
│  Claude Gateway                          │
│  1. Translate OpenAI → Anthropic format  │
│  2. Inject required system prompt        │
│  3. Authenticate with OAuth              │
│  4. Forward to Anthropic API             │
│  5. Translate response back to OpenAI    │
└───────────┬──────────────────────────────┘
            │ Authenticated request

┌──────────────────────────┐
│  Anthropic API           │
│  (Claude Code billing)   │
└──────────────────────────┘

Available Models

Models can be discovered through the /v1/models endpoint.

Available Claude models:

  • claude-opus-4-5-20251101 - Most capable
  • claude-sonnet-4-5-20250929 - Balanced performance
  • claude-haiku-4-5-20251001 - Fast and efficient
  • And older versions...

To get the current model list:

curl http://localhost:45554/v1/models \
  -H "x-api-key: sk-ant-api03-..."

Security

API Key Authentication

By default, the gateway runs without authentication. To add basic security, use the --api-key flag:

npx claude-gateway start --api-key your-secret-key-here

When API key authentication is enabled, all requests to /v1/chat/completions must include the key in the Authorization header:

from openai import OpenAI

client = OpenAI(
    api_key="your-secret-key-here",  # Must match the --api-key value
    base_url="http://localhost:45554/v1",
)

Important Notes:

  • The API key is checked for all chat completion requests
  • Both Bearer <key> and raw key formats are supported
  • The /v1/models endpoint does not require authentication
  • This provides basic protection but should not be considered enterprise-grade security
  • For production use, consider running behind a reverse proxy with proper TLS/SSL

Configuration

Command Line Options

npx claude-gateway start [options]
OptionShortDescription
--port PORT-pSet port (default: 45554)
--api-key KEYRequire API key for authentication (optional)
--verbose-VFull request/response logging
--minimal-mOne line per request
--quiet-qNo request logging
--help-hShow help

API Endpoints

POST /v1/chat/completions

OpenAI Chat Completions API - the main endpoint you'll use.

GET /v1/models

List available models (requires Anthropic API key in x-api-key header).

Authentication

Claude Gateway uses OAuth to authenticate with your Claude Code subscription.

First run:

  1. Gateway displays an authorization URL
  2. Visit the URL and authorize
  3. Copy the code#state from the page
  4. Paste it back into the terminal
  5. Done! Tokens are saved for future use

Subsequent runs:

  • Gateway loads saved tokens automatically
  • Tokens are auto-refreshed when needed (8-hour expiration)

Troubleshooting

"No OAuth tokens found" → Gateway will automatically prompt you to authenticate on first run.

Port already in use → Use npx claude-gateway start --port 8080

Authentication fails → Delete .oauth-tokens.json and restart to re-authenticate.

Want to see what's happening? → Use npx claude-gateway start --verbose

Tool calling behaves differently → Anthropic's tool calling is more strict than OpenAI's. Some parallel tool calls may not work.

"Multiple completions (n > 1) not supported" → Anthropic only returns one completion. Set n=1 or omit the parameter.

What's Supported

Supported:

  • ✅ Message format translation (system/user/assistant roles)
  • ✅ Streaming responses
  • ✅ Tool/function calling
  • ✅ Vision (images via URL or base64)
  • ✅ Token usage reporting
  • ✅ Temperature, max_tokens, stop sequences
  • ✅ Automatic prompt caching

Not Supported (Anthropic limitations):

  • ❌ Multiple completions (n > 1)
  • ❌ Log probabilities (logprobs)
  • presence_penalty / frequency_penalty (ignored with warning)

Credits

Claude Gateway is a fork of anthropic-max-router by David Whatley, simplified to focus on OpenAI compatibility.

Original Author: nsxdavid (David Whatley)
Fork Maintainer: Alex Gleason [email protected]

Special thanks to OpenCode for OAuth implementation reference.

License

MIT

Disclaimer

⚠️ EDUCATIONAL AND RESEARCH PURPOSES

This project is provided for educational, research, and entertainment purposes only. It is not affiliated with, endorsed by, or sponsored by Anthropic PBC. Use of this software is at your own risk. The authors and contributors make no warranties and accept no liability for any damages or issues arising from use of this code. Users are responsible for ensuring their use complies with Anthropic's Terms of Service and all applicable laws. This software is provided "as-is" without any express or implied warranties.

Share: