npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

claude-code-fix-400

v1.0.2

Published

Fix Claude Code 400 error when using third-party models

Readme

Claude Code Proxy

English | 中文

A proxy server that enables Claude Code to use any third-party OpenAI-compatible model.

Claude Code  ──(Anthropic format)──▶  Proxy Server  ──(OpenAI format)──▶  Third-party API
                                          │
                                      Read from .env / CLI
                                      actual API Key / Model

Claude Code thinks it's talking to Anthropic's official API, but requests are transparently forwarded to your configured third-party API.

Quick Start

# 1. Install dependencies
pip install -r requirements.txt

# 2. Start the proxy (choose one)

# Option A: CLI arguments (most flexible, recommended)
python server.py -k "sk-xxxx" -m "deepseek-chat" -b "https://api.deepseek.com/v1"

# Option B: .env file
cp .env.example .env
# Edit .env, fill in TARGET_API_KEY / TARGET_MODEL / TARGET_API_BASE
python server.py

# Option C: Mix (CLI overrides .env)
# .env has OpenAI configured, but you want to use DeepSeek temporarily:
python server.py -k "sk-deepseek" -m "deepseek-chat" -b "https://api.deepseek.com/v1"

Command Line Arguments

| Argument | Description | Default | |----------|-------------|---------| | -m, --model | Target model name | TARGET_MODEL from .env | | -b, --api-base | Target API base URL | TARGET_API_BASE from .env | | -k, --api-key | Target API key | TARGET_API_KEY from .env | | -p, --port | Proxy listen port | 8080 | | -H, --host | Proxy listen address | 0.0.0.0 |

Connecting Claude Code to the Proxy

After starting the proxy, set environment variables to point Claude Code to the proxy:

# Linux / macOS
export ANTHROPIC_BASE_URL=http://localhost:8080
export ANTHROPIC_API_KEY=placeholder  # Any value, proxy skips validation by default

claude

PowerShell:

$env:ANTHROPIC_BASE_URL = "http://localhost:8080"
$env:ANTHROPIC_API_KEY = "placeholder"

claude

Common Examples

# DeepSeek
python server.py -k "sk-xxx" -m "deepseek-chat" -b "https://api.deepseek.com/v1"

# Qwen (Alibaba)
python server.py -k "sk-xxx" -m "qwen-plus" -b "https://dashscope.aliyuncs.com/compatible-mode/v1"

# Ollama (local)
python server.py -k "ollama" -m "llama3" -b "http://localhost:11434/v1"

# OpenAI GPT-4o
python server.py -k "sk-xxx" -m "gpt-4o" -b "https://api.openai.com/v1"

Supported Backends

| Service | TARGET_API_BASE | TARGET_MODEL | |---------|-------------------|----------------| | OpenAI | https://api.openai.com/v1 | gpt-4o | | DeepSeek | https://api.deepseek.com/v1 | deepseek-chat | | Qwen (Alibaba) | https://dashscope.aliyuncs.com/compatible-mode/v1 | qwen-plus | | Ollama (local) | http://localhost:11434/v1 | llama3 | | vLLM (local) | http://localhost:8000/v1 | your-model | | Any OpenAI-compatible API | corresponding URL | corresponding model |

Feature Support

  • [x] Text chat (stream / non-stream)
  • [x] Tool Use (function calling)
  • [x] System Prompt
  • [x] Temperature / Top-P / Max-Tokens
  • [x] Stop Sequences
  • [x] Streaming response (SSE)
  • [x] Model list endpoint (GET /v1/models)
  • [x] Request/response logging
  • [x] Proxy authentication (optional)
  • [x] Image input (base64 / URL)

Project Structure

.
├── .env.example           # Environment variable template
├── .env                   # Actual config (after cp .env.example .env)
├── converter.py           # Anthropic ↔ OpenAI format conversion
├── server.py              # FastAPI proxy server (CLI + config)
├── start.bat              # Windows startup script
├── settings-example.json  # Claude Code settings example
├── requirements.txt
├── package.json           # npm package for global installation
├── ccf.js                 # CLI entry point
└── README.md

Install as Global CLI

npm install -g claudecode-fix

# Then run:
ccf

This installs the ccf command globally and opens the project page in browser.

API Endpoints

| Method | Path | Description | |--------|------|-------------| | POST | /v1/messages | Main endpoint, Claude Code sends messages here | | GET | /v1/models | Model list (for compatibility) | | GET | /health | Health check | | GET | / | Service info and status |

Configuration

Environment Variables (.env)

| Variable | Description | Required | |----------|-------------|----------| | TARGET_API_KEY | Target API key | Yes | | TARGET_API_BASE | Target API base URL | No (default: OpenAI) | | TARGET_MODEL | Actual model to call | No (default: gpt-4o) | | DISGUISE_MODEL | Disguised model name (shown to Claude Code) | No | | DISGUISE_API_BASE | Disguised API base (in response) | No | | TARGET_TIMEOUT | Request timeout in seconds | No (default: 300) | | PROXY_HOST | Proxy listen address | No (default: 0.0.0.0) | | PROXY_PORT | Proxy listen port | No (default: 8080) | | ANTHROPIC_API_KEY | Proxy auth key (empty to skip) | No | | LOG_LEVEL | Log level | No (default: info) |

How It Works

The proxy acts as an intermediary:

  1. Receive — Claude Code sends requests to /v1/messages in Anthropic format
  2. Convertconverter.py transforms Anthropic format to OpenAI format
  3. Forward — Proxy sends the request to the configured third-party API
  4. Convert Back — OpenAI-format responses are converted back to Anthropic format
  5. Return — Claude Code receives responses in the exact official API format

Request Conversion Example

Anthropic format (Claude Code → Proxy):

{
  "model": "claude-opus-4",
  "messages": [{"role": "user", "content": "Hello"}],
  "max_tokens": 1024
}

OpenAI format (Proxy → Third-party API):

{
  "model": "deepseek-chat",
  "messages": [{"role": "user", "content": "Hello"}],
  "max_tokens": 1024
}

Security Notes

  • Never commit .env.gitignore is configured to prevent TARGET_API_KEY leakage
  • Enable auth in production — Set ANTHROPIC_API_KEY to require Claude Code to send the matching key
  • Restrict proxy access — Use firewall rules to limit access to the proxy port

License

MIT