Skip to content

Repository files navigation

CodingPlanProxy

伪装成 Claude Code CLI 客户端,从只对 Agent 开放的 Coding Plan API 骗取服务。

核心问题:部分 Coding Plan API 对 Claude Code 等 Coding Agent 开放,普通 API 调用直接拒绝服务。本代理将请求头伪装为 Claude Code CLI,骗过上游的身份检查,让任何 OpenAI 格式客户端都能接入。

功能特性

  • Claude Code 伪装 — 请求头 1:1 模拟 Claude Code CLI(User-Agent、anthropic-version、anthropic-beta),骗过上游的 Agent 身份校验,拿到服务资格
  • 自动模型发现 — 启动时从上游拉取可用模型列表,/v1/models 自动同步,无需手动配置
  • 零过滤透传 — 请求中的 model 字段不做任何校验,爱传啥传啥,上游自行裁决
  • OpenAI 格式兼容 — 实现 /v1/chat/completions/v1/models 端点,所有 OpenAI SDK 客户端开箱即用
  • 双向格式转换 — 请求/响应自动转换,覆盖 tool calls、tool results、图片输入等复杂场景
  • 流式输出 — SSE 流式响应,逐 token 实时返回
  • 可选鉴权 — 支持为代理设置 API Key,防止蹭网
  • System Prompt 注入 — 可选在无 system 消息时自动注入默认 system prompt

目标用户

  • 手上有 OpenAI 兼容客户端,但上游 Coding Plan API 只认 Claude Code / Agent 请求,普通调用直接拒
  • 需要 prompt caching、computer-use 等 Claude Code 独占特性,但不想用 Claude Code CLI 的开发者

安装

前置要求

安装步骤

  1. 克隆仓库:
git clone https://github.com/lvysssss/codingplanproxy.git
cd codingplanproxy
  1. 安装依赖:
pip install -r requirements.txt

依赖列表:

最低版本用途
fastapi0.110.0Web 框架
uvicorn0.29.0ASGI 服务器
httpx0.27.0异步 HTTP 客户端
python-dotenv1.0.0.env 文件加载
  1. 配置环境变量:
cp .env.example .env

编辑 .env 文件,填入你的 Anthropic API Key(必填),其余按需配置。

  1. 启动服务:
python main.py

Windows 用户可双击 startcodingplanproxy.bat 一键启动。

启动成功后会看到:

代理启动 → 上游: https://api.anthropic.com, 端口: 8000

配置

所有配置通过项目根目录的 .env 文件管理,参考 .env.example

变量必填默认值说明
BASE_URLhttps://api.anthropic.comAnthropic API 上游地址,可改为中转地址
API_KEY上游 API Key
AVAILABLE_MODELS(空)本地补充模型列表(逗号分隔),留空则仅使用远端自动获取的模型;上游不展示但实际可用的模型可手动在此添加
DEFAULT_MAX_TOKENS16384默认最大输出 token 数
SYSTEM_PROMPT(空)注入的默认 system prompt,仅在请求无 system 消息时生效
PORT8000代理服务监听端口
PROXY_API_KEY(空)客户端调用代理时需提供的 API Key,留空则不校验

配置示例

最简配置(只需 API Key):

API_KEY=sk-ant-api03-your-key-here

完整配置:

BASE_URL=https://api.anthropic.comAPI_KEY=sk-ant-api03-your-key-hereAVAILABLE_MODELS=DEFAULT_MAX_TOKENS=16384SYSTEM_PROMPT=You are a helpful assistant.PORT=8000PROXY_API_KEY=my-proxy-secret

使用

代理启动后,所有端点兼容 OpenAI API 格式。将你的 OpenAI 客户端 base_url 指向代理地址即可:

http://localhost:8000/v1

端点列表

方法路径说明
POST/v1/chat/completions核心端点,聊天补全
GET/v1/models返回可用模型列表
GET/health健康检查,含模型来源统计

自动模型发现

服务启动时自动从上游 GET /v1/models(Anthropic 格式)获取可用模型列表,与本地 AVAILABLE_MODELS 合并后通过 /v1/models(OpenAI 格式)暴露。上游模型列表缓存 30 分钟,过期自动刷新。

# 查看当前可用模型(本地 + 远端合并)
curl http://localhost:8000/v1/models
# 查看模型来源统计
curl http://localhost:8000/health
# → {"local_models": 0, "remote_models": 120, ...}

如果上游不支持 Models API,remote_models 为 0,仅使用本地 AVAILABLE_MODELS 配置。

基础对话

curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{ "model": "claude-sonnet-4-20250514", "messages": [ {"role": "user", "content": "Hello, who are you?"} ] }'

流式输出

添加 "stream": true 即可启用 SSE 流式响应:

curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{ "model": "claude-sonnet-4-20250514", "messages": [ {"role": "user", "content": "Write a poem about coding"} ], "stream": true }'

带 System Prompt

curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{ "model": "claude-sonnet-4-20250514", "messages": [ {"role": "system", "content": "You are a Python expert."}, {"role": "user", "content": "How to read a file in Python?"} ] }'

Tool Calling

curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{ "model": "claude-sonnet-4-20250514", "messages": [ {"role": "user", "content": "What is the weather in Beijing?"} ], "tools": [ { "type": "function", "function": { "name": "get_weather", "description": "Get current weather for a city", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "City name"} }, "required": ["city"] } } } ], "tool_choice": "auto" }'

返回 tool_calls 后,提交 tool 结果继续对话:

curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{ "model": "claude-sonnet-4-20250514", "messages": [ {"role": "user", "content": "What is the weather in Beijing?"}, {"role": "assistant", "content": null, "tool_calls": [ {"id": "call_abc123", "type": "function", "function": {"name": "get_weather", "arguments": "{\"city\": \"Beijing\"}"}} ]}, {"role": "tool", "tool_call_id": "call_abc123", "content": "25°C, sunny"} ] }'

图片输入(Base64)

curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{ "model": "claude-sonnet-4-20250514", "messages": [ {"role": "user", "content": [ {"type": "text", "text": "What is in this image?"}, {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,/9j/4AAQ..."}} ]} ] }'

使用代理鉴权

配置 PROXY_API_KEY 后,请求需携带 Authorization 头:

curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer my-proxy-secret" \
-d '{ "model": "claude-sonnet-4-20250514", "messages": [ {"role": "user", "content": "Hello"} ] }'

Python SDK 接入

fromopenaiimportOpenAIclient=OpenAI(
base_url="http://localhost:8000/v1",
api_key="any-string"# 未配置 PROXY_API_KEY 时可填任意值
)
response=client.chat.completions.create(
model="claude-sonnet-4-20250514",
messages=[{"role": "user", "content": "Hello!"}],
stream=True
)
forchunkinresponse:
ifchunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")

Node.js 接入

importOpenAIfrom"openai";constclient=newOpenAI({baseURL: "http://localhost:8000/v1",apiKey: "any-string",});conststream=awaitclient.chat.completions.create({model: "claude-sonnet-4-20250514",messages: [{role: "user",content: "Hello!"}],stream: true,});forawait(constchunkofstream){process.stdout.write(chunk.choices[0]?.delta?.content||"");}

动态模型选择

请求中的 model 字段不作任何校验,任意值均直接透传上游。使用 /v1/models 端点可查看当前可用模型列表(本地配置 + 远端自动获取)。

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

支持的请求参数

OpenAI 参数Anthropic 映射说明
modelmodel模型名称,支持动态选择
messagesmessages + systemsystem 消息提取为顶层字段
max_tokens / max_completion_tokensmax_tokens最大输出 token
temperaturetemperature采样温度
top_ptop_p核采样
streamstream是否流式输出
stopstop_sequences停止序列,字符串或数组
toolstools工具定义,function → input_schema
tool_choicetool_choiceauto/required/none/function

故障排除

启动时提示 "API_KEY 未设置"

确认 .env 文件存在于项目根目录,且 API_KEY 已填入有效值:

请求返回 401 Unauthorized

  • 如果配置了 PROXY_API_KEY,请求需携带 Authorization: Bearer <your-proxy-key>
  • 如果未配置 PROXY_API_KEY 仍返回 401,确认请求头格式正确

请求返回 502 Bad Gateway

  • 检查 BASE_URL 是否正确,网络是否能访问上游 API
  • 如果在国内,可能需要设置 HTTP 代理或使用中转地址:
BASE_URL=https://your-proxy-domain.com

/v1/models 返回空列表

可能原因及解决:

  • 上游不支持 Models API(/healthremote_models: 0)→ 手动在 AVAILABLE_MODELS 中添加模型
  • 上游鉴权失败 → 检查 API_KEY 是否正确
  • 网络不通 → 检查 BASE_URL 和网络

流式响应中断 / 无 [DONE] 标记

上游连接断开时,流式响应可能缺少 [DONE] 标记。检查:

  • 网络稳定性
  • 上游 API 是否超时(代理默认 300 秒超时)
  • 是否触发了 Anthropic API 的速率限制

Tool Calling 不生效

  • 确认 tools 参数格式符合 OpenAI 规范(type: "function" + function 对象)
  • tool_choicenone 在 Anthropic 中无直接对应,代理映射为 auto
  • 返回的 tool result 消息需使用 role: "tool" 并携带 tool_call_id

请求头版本过旧

claudecode_headers.py 中硬编码了 Claude Code 的请求头版本。如果 Anthropic 更新了 API,可能需要手动更新以下常量:

CLAUDE_CODE_USER_AGENT="claude-code/x.x.xxx (node/xx.x.x; darwin; amd64)"ANTHROPIC_VERSION="2026-04-14"ANTHROPIC_BETA="prompt-caching-2026-04-14,computer-use-2026-04-14"

贡献指南

欢迎贡献!请遵循以下流程:

  1. Fork 本仓库
  2. 创建功能分支:git checkout -b feature/your-feature
  3. 提交改动:git commit -m "feat: description of your change"
  4. 推送分支:git push origin feature/your-feature
  5. 创建 Pull Request

提交信息请使用 Conventional Commits 格式:

  • feat: 新功能
  • fix: 修复
  • refactor: 重构
  • docs: 文档
  • chore: 杂项

许可证

MIT

About

🎭 精准伪造 Claude Code 请求指纹,欺骗 CodingPlan API 端点,解锁 prompt caching / computer-use ▎ 等限客户端特性。对外暴露 OpenAI 兼容接口,即插即用。

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Contributors

Languages