claude-code-fix

skill
Security Audit
Fail
Health Warn
  • No license — Repository has no license file
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Fail
  • child_process — Shell command execution capability in ccf.js
  • child_process — Shell command execution capability in index.js
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

修复ClaudeCode更新到最新版本后,无法使用第三方模型的问题。Fix the issue where Claude Code can't use third-party models after updating to the latest version.

README.md

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 / settings.json
                                      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

Disguise System

The proxy uses a disguise system so that Claude Code believes it's communicating with Anthropic's official API.

How Disguise Works

Claude Code        Proxy                Third-party API
──────────         ─────                ───────────────
model:             model:
"Opus 4.8[1m]" ──▶ "deepseek-chat" ──▶ "deepseek-chat"
                   (TARGET_MODEL)       (actual call)

"Opus 4.8[1m]" ◄── "Opus 4.8[1m]" ◄── "deepseek-chat"
                   (DISGUISE_MODEL)     (OpenAI response)

Disguise Value Resolution

Both disguise_model and disguise_api_base follow the same priority chain:

┌─────────────────────────────────────────────────────────────────┐
│  disguise_model:                                                │
│    .env DISGUISE_MODEL > ~/.claude/settings.json ANTHROPIC_MODEL│
│                                                                 │
│  disguise_api_base:                                             │
│    .env DISGUISE_API_BASE > ~/.claude/settings.json             │
│    ANTHROPIC_BASE_URL > https://api.anthropic.com               │
└─────────────────────────────────────────────────────────────────┘

If you configure ~/.claude/settings.json with ANTHROPIC_MODEL, the proxy automatically reads it as the disguise model name. No extra .env configuration needed.

Extra Fields in Every Request

Every request sent to the third-party API carries two additional fields:

{
  "model": "deepseek-chat",
  "messages": [...],
  "ANTHROPIC_BASE_URL": "https://api.anthropic.com",
  "ANTHROPIC_MODEL": "Opus 4.8[1m]"
}

For detailed flow, see docs/disguise-flow.md.

Feature Support

  • Text chat (stream / non-stream)
  • Tool Use (function calling)
  • System Prompt
  • Temperature / Top-P / Max-Tokens
  • Stop Sequences
  • Streaming response (SSE)
  • Model list endpoint (GET /v1/models)
  • Request/response logging
  • Proxy authentication (optional)
  • Image input (base64 / URL)
  • Auto-disguise from ~/.claude/settings.json
  • SQLite response cache (non-stream + streaming)
  • Token auto-reset on cache hit (cross-provider safe)
  • Cache management API (stats/clear/clear-expired)

Cache System

SQLite-backed response cache with two modes for non-streaming and streaming.

Why Cache Matters

Claude Code sends the full conversation history every turn. If you hash the entire request body, you almost never get a cache hit (was only 3% before). The prefix mode fixes this by only hashing the system prompt + last user message + tools, ignoring conversation history.

Cache Key Modes

Configure via CACHE_KEY_MODE:

Mode What Gets Hashed Hit Rate Notes
prefix system + last user message + tools + model High Same question across different turns hits cache
full Entire request body (excl. stream/temperature etc.) Low Exact match only
none Disabled 0 No caching

Token Consistency

Different providers (OpenAI, DeepSeek, Qwen) count tokens differently. On cache hit, token counts are automatically zeroed out so you never get stale provider data.

Cache Management API

# View stats
curl http://localhost:8080/cache/stats

# Clear all cache
curl -X POST http://localhost:8080/cache/clear

# Clear expired only
curl -X POST http://localhost:8080/cache/clear-expired

Project Structure

.
├── .env.example           # Environment variable template
├── .env                   # Actual config (after cp .env.example .env)
├── cache.py               # SQLite cache layer (response + streaming)
├── converter.py           # Anthropic ↔ OpenAI format conversion
├── server.py              # FastAPI proxy server (CLI + config + disguise)
├── start.bat              # Windows startup script
├── claude-settings-example.json  # Claude Code settings example
├── docs/
│   ├── disguise-flow.md   # Disguise logic flowchart
│   └── README.zh-CN.md    # Chinese documentation
├── 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
GET /cache/stats Cache statistics
POST /cache/clear Clear all cache entries
POST /cache/clear-expired Clear only expired entries

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 (overrides settings.json) No
DISGUISE_API_BASE Disguised API base (overrides settings.json) 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
CACHE_ENABLED Enable cache (true/false) No (default: false)
CACHE_KEY_MODE Cache key mode (prefix/full/none) No (default: prefix)
CACHE_TTL Cache TTL in seconds No (default: 3600)
CACHE_DIR Cache database directory No (default: .cache)
LOG_LEVEL Log level No (default: info)

Auto-read from ~/.claude/settings.json

The proxy automatically reads these fields from your Claude Code settings:

settings.json field Used as
env.ANTHROPIC_MODEL Fallback for DISGUISE_MODEL
env.ANTHROPIC_BASE_URL Fallback for DISGUISE_API_BASE

Priority: .env CLI arg > .env file > ~/.claude/settings.json > default.

How It Works

The proxy acts as an intermediary:

  1. Receive -- Claude Code sends requests to /v1/messages in Anthropic format
  2. Convert -- converter.py transforms Anthropic format to OpenAI format, replaces model with TARGET_MODEL
  3. Attach -- Adds ANTHROPIC_BASE_URL and ANTHROPIC_MODEL to request body
  4. Forward -- Proxy sends the request to the configured third-party API
  5. Convert Back -- OpenAI-format responses are converted back to Anthropic format, model replaced with DISGUISE_MODEL
  6. 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,
  "ANTHROPIC_BASE_URL": "https://api.anthropic.com",
  "ANTHROPIC_MODEL": "Opus 4.8[1m]"
}

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

Reviews (0)

No results found