Skip to content

NickJerome/CursorProxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NewCursorProxy

一个轻量级反向代理,让 Cursor(及其他 OpenAI 兼容客户端)能够对接任意 LLM 后端——Anthropic、Gemini、OpenAI Responses API 或标准 OpenAI Chat——自动完成 API 格式转换,内置管理后台、请求日志和逐模型配置。

功能特性

  • 多格式请求转换 —— 接收 Anthropic Messages、Gemini Contents、OpenAI Responses、OpenAI Chat Completions 四种格式,统一转换为 OpenAI Chat 格式后转发至上游。
  • 逐模型配置 —— 为每个模型名称单独定义输入格式和 body 修改规则。
  • <think> 标签处理 —— 自动将 reasoning_content 字段转换为 <think>...</think> 标签(流式和非流式响应均支持),让 Cursor 正确显示思维链内容。
  • 流式支持 —— 完整的 SSE 透传,使用状态机在 chunk 边界正确处理 <think> 标签的开闭。
  • Body 修改 —— 支持对转发请求体进行 set(设置/覆盖字段)和 delete(删除字段,值为 null)操作,例如注入 reasoning_effort、删除 temperature 等。
  • 请求日志 —— 每个请求/响应对均记录到按配置分表、按日期分库的 SQLite 数据库中,包含原始和转换后的 body、headers 及耗时数据。
  • 管理后台 —— Vue 3 + Tailwind CSS 单页应用,用于管理配置、模型映射、查看日志和监控使用统计。
  • Token 认证 —— 管理 API 通过可配置的 ADMIN_TOKEN 保护;代理端点保持开放。
  • 单文件部署 —— 前端在构建时嵌入 Go 二进制文件,无需额外 Web 服务器。
  • Docker 就绪 —— 包含多阶段 Dockerfile 和 docker-compose;CI 在每次推送到 main 时自动发布到 GHCR。

架构

Cursor IDE
  |
  |  POST /{config_id}/v1/chat/completions
  v
+----------------------------------------------------------+
|                     NewCursorProxy                       |
|                                                          |
|  1. 路由匹配 config_id                                    |
|     查找 Config(upstream_url)和 ModelMapping            |
|                                                          |
|  2. 匹配模型名 --> 确定 input_format                      |
|                                                          |
|  3. 入站转换(Inbound Transform)                         |
|     anthropic/messages    \                              |
|     openai/responses       }-->  统一 LLM 请求            |
|     gemini/contents       /                              |
|     openai/chat_completions  (直接透传)                   |
|                                                          |
|  4. 出站转换(Outbound Transform)                        |
|     统一 LLM 请求  -->  OpenAI Chat 格式 body             |
|                                                          |
|  5. 应用 body_modifications                               |
|     set: 设置/覆盖字段    delete: 值为 null 删除字段       |
|                                                          |
|  6. 转发至上游                                             |
|     Headers 透传(去除 hop-by-hop 头)                     |
|     可选: UPSTREAM_AUTHORIZATION 覆盖                     |
|                                                          |
|  7. 响应处理                                               |
|     流式:  SSE 状态机将                                    |
|            reasoning_content --> <think> 标签              |
|     非流式: JSON 重写 reasoning_content                    |
|                                                          |
|  8. 记录到 SQLite(按配置分表,按日期分库)                  |
|                                                          |
+----------------------------------------------------------+
  |
  v
上游 LLM 服务(OpenAI、Azure、本地部署等)

快速开始

Docker(推荐)

一条命令启动:

docker run -d \
  --name newcursorproxy \
  -p 8080:8080 \
  -e ADMIN_TOKEN=your-secret \
  -v proxy-data:/app/data \
  ghcr.io/nickjerome/newcursorproxy:latest

Docker Compose

仓库中已包含 docker-compose.yml

services:
  proxy:
    image: ghcr.io/nickjerome/newcursorproxy:latest
    ports:
      - "8080:8080"
    environment:
      - PORT=8080
      - DATA_DIR=/app/data
      - ADMIN_TOKEN=${ADMIN_TOKEN:-changeme}
    volumes:
      - proxy-data:/app/data
    restart: unless-stopped

volumes:
  proxy-data:

启动:

ADMIN_TOKEN=your-secret docker compose up -d

管理后台:http://localhost:8080 代理端点:http://localhost:8080/{config_id}/v1/chat/completions

从源码构建

前置要求

工具 版本
Go 1.25+
Node 22+
pnpm latest

步骤

  1. 克隆仓库

    git clone https://github.com/NickJerome/NewCursorProxy.git
    cd NewCursorProxy
  2. 安装前端依赖并构建

    cd frontend
    pnpm install
    pnpm build
    cd ..
  3. 构建 Go 二进制

    开发模式(前端由 pnpm dev 单独启动):

    go build -o proxy ./cmd/proxy/

    生产模式(前端嵌入二进制):

    cp -r frontend/dist cmd/proxy/frontend/dist
    go build -tags embed_frontend -ldflags="-s -w" -o proxy ./cmd/proxy/
  4. 运行

    ADMIN_TOKEN=your-secret ./proxy

环境变量

变量 默认值 说明
PORT 8080 服务监听端口
DATA_DIR data SQLite 数据目录(配置库 + 日志库),自动创建
ADMIN_TOKEN (无) /api/* 管理端点的 Bearer Token;未设置时管理 API 不做认证
UPSTREAM_INSECURE_SKIP_VERIFY (无) 设为 1true 跳过上游 TLS 证书验证(用于自签名证书)
UPSTREAM_AUTHORIZATION (无) 设置后覆盖所有上游请求的 Authorization

使用指南

1. 打开管理后台

浏览器访问 http://localhost:8080

2. 登录

输入 ADMIN_TOKEN 即可登录。Token 以 Bearer 方式通过 Authorization 头发送。

3. 创建配置(Config)

一个 配置 代表一个上游 LLM 服务端点:

字段 说明
id URL 安全的短标识符(如 openaiazure-gpt4local),用于代理 URL 路径
name 显示名称
upstream_url 上游服务地址。代理会自动拼接 /v1/chat/completions(如果路径中尚未包含)

示例:配置 ID 为 mycloud,服务器地址为 proxy.example.com,则 Cursor 请求地址为: http://proxy.example.com/mycloud/v1/chat/completions

4. 添加模型映射(Model Mapping)

每个配置可包含多个 模型映射。请求到达时,代理根据请求体中的 model 字段匹配对应的模型配置。

字段 说明
model_name 要匹配的模型名(如 claude-3.5-sonnetgpt-4o
input_format 入站请求的 API 格式(见下表)
body_modifications 对转发请求体的修改规则(见下方说明)
header_modifications 对转发请求头的修改规则(与请求体规则相同,见下方说明)

5. 配置 Cursor

在 Cursor 设置中,将 API 基础 URL 设为:

http://your-server:8080/{config_id}/v1/chat/completions

{config_id} 替换为你创建的配置 ID。

输入格式(Input Format)

input_format 告诉代理入站请求体使用的格式,代理会将其转换为 OpenAI Chat Completions 格式后转发上游。

格式 说明
openai/chat_completions 标准 OpenAI Chat Completions API,无需转换(直接透传)
openai/responses OpenAI Responses API 格式,转换为 Chat Completions
anthropic/messages Anthropic Messages API 格式(messagessystemmax_tokens 等)
gemini/contents Google Gemini API 格式(contentsgenerationConfig 等)

如果请求中的模型名没有对应的模型映射,请求体将原样转发,不做转换。

Body 修改规则(Body Modifications)

body_modifications 是一个 JSON 对象,在格式转换 之后 应用到转发的请求体上:

  • 设置字段(set){"reasoning_effort": "high", "temperature": 0.7} —— 添加或覆盖这些字段
  • 删除字段(delete){"stream_options": null} —— 将值设为 null 表示从请求体中删除该字段

适用场景:注入 Cursor 不会发送的提供商专属参数,或移除上游不支持的字段。

请求头修改规则(Header Modifications)

header_modifications 是一个 JSON 对象,在复制完入站请求头 之后 应用到转发的请求头上,规则与请求体修改一致:

  • 设置/覆盖(set){"X-Custom-Header": "value", "Authorization": "Bearer xxx"} —— 添加或覆盖这些请求头
  • 删除(delete){"X-Unwanted": null} —— 将值设为 null 表示删除该请求头

适用场景:为上游设置固定或按模型区分的请求头(如 API 版本、自定义认证等)。

<think> 标签处理

许多推理模型在 reasoning_content 字段中返回思维链内容(与主 content 分开)。Cursor 期望这些内容以 <think>...</think> 标签包裹在 content 字段中。

NewCursorProxy 自动处理此转换:

  • 流式响应:状态机跟踪 <think> 标签是否已打开。当 reasoning_content chunk 到达时,自动注入 <think>\n 前缀;当普通 content 恢复或流结束时,注入 \n</think>\n 闭合标签。reasoning_content 字段从每个 chunk 中移除。
  • 非流式响应:如果响应 JSON 中包含 reasoning_content,将其作为 <think>\n...\n</think>\n 前置到 content 字段,并移除 reasoning_content 字段。

无需任何配置,此处理始终生效。

API 参考

所有管理端点位于 /api/ 下,需要 Authorization: Bearer <ADMIN_TOKEN> 头(ADMIN_TOKEN 未设置时无需认证)。

认证

方法 路径 说明
GET /api/auth/check 验证 token 是否有效,返回 {"status":"ok"}

配置管理

方法 路径 说明
GET /api/configs 列出所有配置
POST /api/configs 创建配置
GET /api/configs/{id} 获取单个配置
PUT /api/configs/{id} 更新配置
DELETE /api/configs/{id} 删除配置及其所有模型映射

创建/更新请求体:

{
  "id": "my-provider",
  "name": "My LLM Provider",
  "upstream_url": "https://api.example.com"
}

模型映射

方法 路径 说明
GET /api/configs/{id}/models 列出模型映射
POST /api/configs/{id}/models 创建模型映射
PUT /api/configs/{id}/models/{model_id} 更新模型映射
DELETE /api/configs/{id}/models/{model_id} 删除模型映射

创建/更新请求体:

{
  "model_name": "claude-3.5-sonnet",
  "input_format": "anthropic/messages",
  "body_modifications": {
    "reasoning_effort": "high",
    "stream_options": null
  }
}

日志查询

方法 路径 说明
GET /api/configs/{id}/logs 查询配置的请求日志

查询参数:

参数 默认值 说明
date 今天 按日期筛选(YYYY-MM-DD
page 1 页码
limit 20 每页条数

响应:

{
  "data": [ ... ],
  "total": 42,
  "page": 1,
  "limit": 20
}

使用统计

方法 路径 说明
GET /api/configs/{id}/overview 获取配置下所有模型的聚合统计(token 用量、请求数、平均 TTFT、平均 TPS)

项目结构

NewCursorProxy/
|-- cmd/proxy/
|   |-- main.go              # 入口
|   |-- embed_prod.go        # 生产构建:嵌入 frontend/dist
|   `-- embed_dev.go         # 开发构建:前端 FS 为 nil
|-- internal/
|   |-- config/
|   |   |-- model.go         # Config、ModelMapping 数据模型
|   |   `-- store.go         # SQLite 配置存储(CRUD)
|   |-- logging/
|   |   |-- model.go         # LogEntry 数据模型
|   |   `-- store.go         # SQLite 日志存储(按日期分库)
|   |-- proxy/
|   |   |-- handler.go       # 代理主处理器 + 格式转换
|   |   |-- forwarder.go     # 上游转发 + body_modifications 应用
|   |   `-- think.go         # <think> 标签处理(流式 + 非流式)
|   `-- web/
|       |-- router.go        # HTTP 路由、SPA 服务、CORS
|       |-- auth.go          # ADMIN_TOKEN 认证中间件
|       |-- config_handler.go # 配置和模型映射 API
|       |-- logs_handler.go  # 日志查询 API
|       `-- overview_handler.go # 使用统计 API
|-- llm/                     # 协议转换库(来自 axonhub)
|   |-- model.go             # 统一 LLM 请求/响应类型
|   |-- transformer/
|   |   |-- interfaces.go    # Inbound/Outbound 转换器接口
|   |   |-- anthropic/       # Anthropic Messages <-> 统一格式
|   |   |-- openai/          # OpenAI Chat <-> 统一格式
|   |   |   `-- responses/   # OpenAI Responses API <-> 统一格式
|   |   `-- gemini/          # Gemini Contents <-> 统一格式
|   `-- httpclient/          # HTTP 客户端工具
|-- frontend/                # Vue 3 + Tailwind CSS 管理后台
|-- Dockerfile               # 多阶段构建(Node + Go + Alpine)
|-- docker-compose.yml
`-- .github/workflows/docker.yml  # CI:构建并推送镜像到 GHCR

许可证

MIT License

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors