- 当前版本已稳定,若发现响应出现缺字漏字,与本程序无关。
- 若发现首字慢,与本程序无关。
- 若发现响应出现乱码,也与本程序无关。
- 属于官方的问题,请不要像作者反馈。
- 本程序拥有堪比客户端原本的速度,甚至可能更快。
- 本程序的性能是非常厉害的。
- 根据本项目开源协议,Fork的项目不能以作者的名义进行任何形式的宣传、推广或声明。原则上希望低调使用。
- 更新的时间跨度达近10月了,求赞助,项目不收费,不定制。
- 推荐自部署,官方网站 仅用于作者测试,不保证稳定性。
- 访问 www.cursor.com 并完成注册登录
- 在浏览器中打开开发者工具(F12)
- 在 Application-Cookies 中查找名为
WorkosCursorSessionToken的条目,并复制其第三个字段。请注意,%3A%3A 是 :: 的 URL 编码形式,cookie 的值使用冒号 (:) 进行分隔。
PORT: 服务器端口号(默认:3000)AUTH_TOKEN: 认证令牌(必须,用于API认证)ROUTE_PREFIX: 路由前缀(可选)
更多请查看 /env-example
.tokens 文件:每行为token和checksum的对应关系:
# 这里的#表示这行在下次读取要删除
token1,checksum1
token2,checksum2
该文件可以被自动管理,但用户仅可在确认自己拥有修改能力时修改,一般仅有以下情况需要手动修改:
- 需要删除某个 token
- 需要使用已有 checksum 来对应某一个 token
写死了,后续也不会会支持自定义模型列表,因为本身就支持动态更新,详见更新模型列表说明
打开程序自己看,以实际为准,这里不再赘述。
- 接口地址:
/v1/chat/completions - 请求方法: POST
- 认证方式: Bearer Token
- 使用环境变量
AUTH_TOKEN进行认证 - 使用
/build-key构建的动态密钥认证 - 使用
/config设置的共享Token进行认证 (关联:环境变量SHARED_TOKEN) - 日志中的缓存 token key 的两种表示方式认证 (
/build-key同时也会给出这两种格式作为动态密钥的别名,该数字key本质为一个192位的整数)
- 使用环境变量
{
"model": string,
"messages": [
{
"role": "system" | "user" | "assistant", // "system" 也可以是 "developer"
"content": string | [
{
"type": "text" | "image_url",
"text": string,
"image_url": {
"url": string
}
}
]
}
],
"stream": bool,
"stream_options": {
"include_usage": bool
}
}如果 stream 为 false:
{
"id": string,
"object": "chat.completion",
"created": number,
"model": string,
"choices": [
{
"index": number,
"message": {
"role": "assistant",
"content": string
},
"finish_reason": "stop" | "length"
}
],
"usage": {
"prompt_tokens": 0,
"completion_tokens": 0,
"total_tokens": 0
}
}如果 stream 为 true:
data: {"id":string,"object":"chat.completion.chunk","created":number,"model":string,"choices":[{"index":number,"delta":{"role":"assistant","content":string},"finish_reason":null}]}
data: {"id":string,"object":"chat.completion.chunk","created":number,"model":string,"choices":[{"index":number,"delta":{"content":string},"finish_reason":null}]}
data: {"id":string,"object":"chat.completion.chunk","created":number,"model":string,"choices":[{"index":number,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
- 接口地址:
/v1/models - 请求方法: GET
- 认证方式: Bearer Token
可选的 JSON 请求体用于作为请求模型列表的参数:
{
"is_nightly": bool, // 是否包含 nightly 版本模型,默认 false
"include_long_context_models": bool, // 是否包含长上下文模型,默认 false
"exclude_max_named_models": bool, // 是否排除 max 命名的模型,默认 true
"additional_model_names": [string] // 额外包含的模型名称列表,默认空数组
}注意: 认证可选,查询参数可选且认证时生效,未提供时使用默认值。
{ object: "list", data: [ { id: string, display_name: string, created: number, created_at: string, object: "model", type: "model", owned_by: string, supports_thinking: bool, supports_images: bool, supports_max_mode: bool, supports_non_max_mode: bool } ] }
每次携带Token时都会拉取最新的模型列表,与上次更新需距离至少30分钟。additional_model_names 可以用添加额外模型。
- 接口地址:
/tokens/get - 请求方法: POST
- 认证方式: Bearer Token
- 响应格式:
{ status: "success", tokens: [ [ number, string, { primary_token: string, secondary_token?: string, checksum: { first: string, second: string, }, client_key?: string, config_version?: string, session_id?: string, proxy?: string, timezone?: string, gcpp_host?: "Asia" | "EU" | "US", user?: { user_id: int32, email?: string, first_name?: string, last_name?: string, workos_id?: string, team_id?: number, created_at?: string, is_enterprise_user: bool, is_on_new_pricing: bool, privacy_mode_info: { privacy_mode: "unspecified" | "no_storage" | "no_training" | "usage_data_training_allowed" | "usage_codebase_training_allowed", is_enforced_by_team?: bool } }, status: { enabled: bool }, usage?: { billing_cycle_start: string, billing_cycle_end: string, membership_type: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise", limit_type: "user" | "team", is_unlimited: bool, individual_usage: { plan?: { enabled: bool, used: int32, limit: int32, remaining: int32, breakdown: { included: int32, bonus: int32, total: int32 } }, on_demand?: { enabled: bool, used: int32, limit?: int32, remaining?: int32 } }, team_usage: { plan?: { enabled: bool, used: int32, limit: int32, remaining: int32, breakdown: { included: int32, bonus: int32, total: int32 } }, on_demand?: { enabled: bool, used: int32, limit?: int32, remaining?: int32 } }, }, stripe?: { membership_type: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise", payment_id?: string, days_remaining_on_trial: int32, subscription_status?: "trialing" | "active" | "incomplete" | "incomplete_expired" | "past_due" | "canceled" | "unpaid" | "paused", verified_student: bool, trial_eligible: bool, trial_length_days: int32, is_on_student_plan: bool, is_on_billable_auto: bool, customer_balance?: double, trial_was_cancelled: bool, is_team_member: bool, team_membership_type?: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise", individual_membership_type?: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise" }, sessions?: [ { session_id: string, type: "unspecified" | "web" | "client" | "bugbot" | "background_agent", created_at: string, expires_at: string } ] } ] ], tokens_count: uint64 }
- 接口地址:
/tokens/set - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
[ [ string, { primary_token: string, secondary_token?: string, checksum: { first: string, second: string, }, client_key?: string, config_version?: string, session_id?: string, proxy?: string, timezone?: string, gcpp_host?: "Asia" | "EU" | "US", user?: { user_id: int32, email?: string, first_name?: string, last_name?: string, workos_id?: string, team_id?: number, created_at?: string, is_enterprise_user: bool, is_on_new_pricing: bool, privacy_mode_info: { privacy_mode: "unspecified" | "no_storage" | "no_training" | "usage_data_training_allowed" | "usage_codebase_training_allowed", is_enforced_by_team?: bool } }, status: { enabled: bool }, usage?: { billing_cycle_start: string, billing_cycle_end: string, membership_type: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise", limit_type: "user" | "team", is_unlimited: bool, individual_usage: { plan?: { enabled: bool, used: int32, limit: int32, remaining: int32, breakdown: { included: int32, bonus: int32, total: int32 } }, on_demand?: { enabled: bool, used: int32, limit?: int32, remaining?: int32 } }, team_usage: { plan?: { enabled: bool, used: int32, limit: int32, remaining: int32, breakdown: { included: int32, bonus: int32, total: int32 } }, on_demand?: { enabled: bool, used: int32, limit?: int32, remaining?: int32 } }, }, stripe?: { membership_type: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise", payment_id?: string, days_remaining_on_trial: int32, subscription_status?: "trialing" | "active" | "incomplete" | "incomplete_expired" | "past_due" | "canceled" | "unpaid" | "paused", verified_student: bool, trial_eligible: bool, trial_length_days: int32, is_on_student_plan: bool, is_on_billable_auto: bool, customer_balance?: double, trial_was_cancelled: bool, is_team_member: bool, team_membership_type?: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise", individual_membership_type?: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise" } } ] ]
- 响应格式:
{ status: "success", tokens_count: uint64, message: "Token files have been updated and reloaded" }
- 接口地址:
/tokens/add - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
{ tokens: [ { alias?: string, // 可选,无则自动生成 token: string, checksum?: string, // 可选,无则自动生成 client_key?: string, // 可选,无则自动生成 session_id?: string, // 可选 config_version?: string, // 可选 proxy?: string, // 可选 timezone?: string, // 可选 gcpp_host?: string // 可选 } ], enabled: bool }
- 响应格式:
{ status: "success", tokens_count: uint64, message: string // "New tokens have been added and reloaded" 或 "No new tokens were added" }
- 接口地址:
/tokens/del - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
{
"aliases": [string], // 要删除的token列表
"include_failed_tokens": bool // 默认为false
}- 响应格式:
{
"status": "success",
"failed_tokens": [string] // 可选,根据include_failed_tokens返回,表示未找到的token列表
}- expectation说明:
- simple: 只返回基本状态
- updated_tokens: 返回更新后的token列表
- failed_tokens: 返回未找到的token列表
- detailed: 返回完整信息(包括updated_tokens和failed_tokens)
- 接口地址:
/tokens/tags/set - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
{
"tokens": [string],
"tags": {
string: null | string // 键可以为 timezone: 时区标识符 或 proxy: 代理名称
}
}- 响应格式:
{
"status": "success",
"message": string // "标签更新成功"
}- 接口地址:
/tokens/profile/update - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
[
string // aliases
]- 响应格式:
{
"status": "success",
"message": "已更新{}个令牌配置, {}个令牌更新失败"
}- 接口地址:
/tokens/config-version/update - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
[
string // aliases
]- 响应格式:
{
"status": "success",
"message": "已更新{}个令牌配置版本, {}个令牌更新失败"
}- 接口地址:
/tokens/refresh - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
[
string // aliases
]- 响应格式:
{
"status": "success",
"message": "已刷新{}个令牌, {}个令牌刷新失败"
}- 接口地址:
/tokens/status/set - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
{ "aliases": [string], "enabled": bool }
- 响应格式:
{
"status": "success",
"message": "已设置{}个令牌状态, {}个令牌设置失败"
}- 接口地址:
/tokens/alias/set - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
{
"{old_alias}": "{new_alias}"
}- 响应格式:
{
"status": "success",
"message": "已设置{}个令牌别名, {}个令牌设置失败"
}- 接口地址:
/tokens/proxy/set - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
{
"aliases": [string],
"proxy": string // 可选,代理地址,null表示清除代理
}- 响应格式:
{
"status": "success",
"message": "已设置{}个令牌代理, {}个令牌设置失败"
}- 接口地址:
/tokens/timezone/set - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
{
"aliases": [string],
"timezone": string // 可选,时区标识符(如"Asia/Shanghai"),null表示清除时区
}- 响应格式:
{
"status": "success",
"message": "已设置{}个令牌时区, {}个令牌设置失败"
}- 接口地址:
/tokens/merge - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
{
"{alias}": { // 以下至少其一存在,否则会失败
"primary_token": string, // 可选
"secondary_token": string, // 可选
"checksum": { // 可选
"first": string,
"second": string,
},
"client_key": string, // 可选
"config_version": string, // 可选
"session_id": string, // 可选
"proxy": string, // 可选
"timezone": string, // 可选
"gcpp_host": object, // 可选
}
}- 响应格式:
{
"status": "success",
"message": "已合并{}个令牌, {}个令牌合并失败"
}- 接口地址:
/build-key - 请求方法: POST
- 认证方式: Bearer Token (当SHARE_AUTH_TOKEN启用时需要)
- 请求格式:
{
"token": string, // 格式: JWT
"checksum": {
"first": string, // 格式: 长度为64的Hex编码字符串
"second": string, // 格式: 长度为64的Hex编码字符串
},
"client_key": string, // 格式: 长度为64的Hex编码字符串
"config_version": string, // 格式: UUID
"session_id": string, // 格式: UUID
"proxy_name": string, // 可选,指定代理
"timezone": string, // 可选,指定时区
"gcpp_host": string, // 可选,代码补全区域
"disable_vision": bool, // 可选,禁用图片处理能力
"enable_slow_pool": bool, // 可选,启用慢速池
"include_web_references": bool,
"usage_check_models": { // 可选,使用量检查模型配置
"type": "default" | "disabled" | "all" | "custom",
"model_ids": string // 当type为custom时生效,以逗号分隔的模型ID列表
}
}- 响应格式:
{
"keys": [string] // 成功时返回生成的key
}或出错时:
{
"error": string // 错误信息
}说明:
-
此接口用于生成携带动态配置的API Key,是对直接传token与checksum模式的升级版本,在0.3起,直接传token与checksum的方式已经不再适用
-
生成的key格式为:
sk-{encoded_config},其中sk-为默认前缀(可配置) -
usage_check_models配置说明:
- default: 使用默认模型列表(同下
usage_check_models字段的默认值) - disabled: 禁用使用量检查
- all: 检查所有可用模型
- custom: 使用自定义模型列表(需在model_ids中指定)
- default: 使用默认模型列表(同下
-
在当前版本,keys数组长度总为3,后2个基于缓存,仅第1个使用过才行:
- 完整key,旧版本也存在
- 数字key的base64编码版本
- 数字key的明文版本
-
数字key是一个128位无符号整数与一个64位无符号整数组成的,比通常使用的uuid更难破解。
- 接口地址:
/proxies/get - 请求方法: POST
- 响应格式:
{
"status": "success",
"proxies": {
"proxies": {
"proxy_name": "non" | "sys" | "http://proxy-url",
},
"general": string // 当前使用的通用代理名称
},
"proxies_count": number,
"general_proxy": string,
"message": string // 可选
}- 接口地址:
/proxies/set - 请求方法: POST
- 请求格式:
{
"proxies": {
"{proxy_name}": "non" | "sys" | "http://proxy-url"
},
"general": string // 要设置的通用代理名称
}- 响应格式:
{
"status": "success",
"proxies_count": number,
"message": "代理配置已更新"
}- 接口地址:
/proxies/add - 请求方法: POST
- 请求格式:
{
"proxies": {
"{proxy_name}": "non" | "sys" | "http://proxy-url"
}
}- 响应格式:
{
"status": "success",
"proxies_count": number,
"message": string // "已添加 X 个新代理" 或 "没有添加新代理"
}- 接口地址:
/proxies/del - 请求方法: POST
- 请求格式:
{
"names": [string], // 要删除的代理名称列表
"expectation": "simple" | "updated_proxies" | "failed_names" | "detailed" // 默认为simple
}- 响应格式:
{
"status": "success",
"updated_proxies": { // 可选,根据expectation返回
"proxies": {
"proxy_name": "non" | "sys" | "http://proxy-url"
},
"general": string
},
"failed_names": [string] // 可选,根据expectation返回,表示未找到的代理名称列表
}- 接口地址:
/proxies/set-general - 请求方法: POST
- 请求格式:
{
"name": string // 要设置为通用代理的代理名称
}- 响应格式:
{
"status": "success",
"message": "通用代理已设置"
}non: 表示不使用代理sys: 表示使用系统代理- 其他: 表示具体的代理URL地址(如
http://proxy-url)
- 代理名称必须是唯一的,添加重复名称的代理会被忽略
- 设置通用代理时,指定的代理名称必须存在于当前的代理配置中
- 删除代理时的 expectation 参数说明:
- simple: 只返回基本状态
- updated_proxies: 返回更新后的代理配置
- failed_names: 返回未找到的代理名称列表
- detailed: 返回完整信息(包括updated_proxies和failed_names)
所有接口在发生错误时会返回统一的错误格式:
{
"status": "error",
"code": number, // 可选
"error": string, // 可选,错误详细信息
"message": string // 错误提示信息
}- 接口地址:
/config/get - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式: 无
- 响应格式:
x-config-hash+ 文本
- 接口地址:
/config/set - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
x-config-hash+ 文本 - 响应格式: 204表示已变更,200表示未变更,其余为错误
- 接口地址:
/config/reload - 请求方法: GET
- 认证方式: Bearer Token
- 请求格式:
x-config-hash - 响应格式: 204表示已变更,200表示未变更,其余为错误
- 接口地址:
/logs - 请求方法: GET
- 响应格式: 根据配置返回不同的内容类型(默认、文本或HTML)
- 接口地址:
/logs/get - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
{ "query": { // 分页与排序控制 "limit": number, // 可选,返回记录数量限制 "offset": number, // 可选,起始位置偏移量 "reverse": bool, // 可选,反向排序,默认false(从旧到新),true时从新到旧 // 时间范围过滤 "from_date": string, // 可选,开始日期时间,RFC3339格式 "to_date": string, // 可选,结束日期时间,RFC3339格式 // 用户标识过滤 "user_id": string, // 可选,按用户ID精确匹配 "email": string, // 可选,按用户邮箱过滤(支持部分匹配) "membership_type": string, // 可选,按会员类型过滤 ("free"/"free_trial"/"pro"/"pro_plus"/"ultra"/"enterprise") // 核心业务过滤 "status": string, // 可选,按状态过滤 ("pending"/"success"/"failure") "model": string, // 可选,按模型名称过滤(支持部分匹配) "include_models": [string], // 可选,包含特定模型 "exclude_models": [string], // 可选,排除特定模型 // 请求特征过滤 "stream": bool, // 可选,是否为流式请求 "has_chain": bool, // 可选,是否包含对话链 "has_usage": bool, // 可选,是否有usage信息 // 错误相关过滤 "has_error": bool, // 可选,是否包含错误 "error": string, // 可选,按错误过滤(支持部分匹配) // 性能指标过滤 "min_total_time": number, // 可选,最小总耗时(秒) "max_total_time": number, // 可选,最大总耗时(秒) "min_tokens": number, // 可选,最小token数(input + output) "max_tokens": number // 可选,最大token数 } }
- 响应格式:
{ status: "success", total: uint64, active?: uint64, error?: uint64, logs: [ { id: uint64, timestamp: string, model: string, token_info: { key: string, usage?: { billing_cycle_start: string, billing_cycle_end: string, membership_type: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise", limit_type: "user" | "team", is_unlimited: bool, individual_usage: { plan?: { enabled: bool, used: int32, limit: int32, remaining: int32, breakdown: { included: int32, bonus: int32, total: int32 } }, on_demand?: { enabled: bool, used: int32, limit?: int32, remaining?: int32 } }, team_usage: { plan?: { enabled: bool, used: int32, limit: int32, remaining: int32, breakdown: { included: int32, bonus: int32, total: int32 } }, on_demand?: { enabled: bool, used: int32, limit?: int32, remaining?: int32 } }, }, stripe?: { membership_type: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise", payment_id?: string, days_remaining_on_trial: int32, subscription_status?: "trialing" | "active" | "incomplete" | "incomplete_expired" | "past_due" | "canceled" | "unpaid" | "paused", verified_student: bool, trial_eligible: bool, trial_length_days: int32, is_on_student_plan: bool, is_on_billable_auto: bool, customer_balance?: double, trial_was_cancelled: bool, is_team_member: bool, team_membership_type?: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise", individual_membership_type?: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise" } }, chain: { delays?: [ string, [ number, // chars count number // time ] ], usage?: { input: int32, output: int32, cache_write: int32, cache_read: int32, cents: float } }, timing: { total: double }, stream: bool, status: "pending" | "success" | "failure", error?: string | { error:string, details:string } } ], timestamp: string }
- 说明:
- 所有查询参数都是可选的
- 管理员可以查看所有日志,普通用户只能查看与其token相关的日志
- 如果提供了无效的状态或会员类型,将返回空结果
- 日期时间格式需遵循 RFC3339 标准,如:"2024-03-20T15:30:00+08:00"
- 邮箱和模型名称支持部分匹配
- 接口地址:
/logs/tokens/get - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
[ string ]
- 响应格式:
{ status: "success", tokens: { {key}: { primary_token: string, secondary_token?: string, checksum: { first: string, second: string, }, client_key?: string, config_version?: string, session_id?: string, proxy?: string, timezone?: string, gcpp_host?: "Asia" | "EU" | "US", user?: { user_id: int32, email?: string, first_name?: string, last_name?: string, workos_id?: string, team_id?: number, created_at?: string, is_enterprise_user: bool, is_on_new_pricing: bool, privacy_mode_info: { privacy_mode: "unspecified" | "no_storage" | "no_training" | "usage_data_training_allowed" | "usage_codebase_training_allowed", is_enforced_by_team?: bool } } } }, total: uint64, timestamp: string }
- 接口地址:
/env-example - 请求方法: GET
- 响应格式: 文本
- 接口地址:
/config-example - 请求方法: GET
- 响应格式: 文本
- 接口地址:
/readme - 请求方法: GET
- 响应格式: HTML
- 接口地址:
/license - 请求方法: GET
- 响应格式: HTML
- 接口地址:
/health - 请求方法: GET
- 认证方式: 无需
- 响应格式: 根据配置返回不同的内容类型(默认JSON、文本或HTML)
{
"status": "success",
"service": {
"name": "cursor-api",
"version": "1.0.0",
"is_debug": false,
"build": {
"version": 1,
"timestamp": "2024年01月15日T10:30:00Z",
"is_debug": false,
"is_prerelease": false
}
},
"runtime": {
"started_at": "2024年01月15日T10:00:00+08:00",
"uptime_seconds": 1800,
"requests": {
"total": 1250,
"active": 3,
"errors": 12
}
},
"system": {
"memory": {
"used_bytes": 134217728,
"used_percentage": 12.5,
"available_bytes": 1073741824
},
"cpu": {
"usage_percentage": 15.2,
"load_average": [0.8, 1.2, 1.5]
}
},
"capabilities": {
"models": ["gpt-4", "claude-3"],
"endpoints": ["/v1/chat/completions", "/v1/messages"],
"features": [".."]
}
}| 字段 | 类型 | 说明 |
|---|---|---|
status |
string | 服务状态: "success", "warning", "error" |
service.name |
string | 服务名称 |
service.version |
string | 服务版本 |
service.is_debug |
bool | 是否为调试模式 |
service.build.version |
number | 构建版本号(仅preview功能启用时) |
service.build.timestamp |
string | 构建时间戳 |
service.build.is_prerelease |
bool | 是否为预发布版本 |
runtime.started_at |
string | 服务启动时间 |
runtime.uptime_seconds |
number | 运行时长(秒) |
runtime.requests.total |
number | 总请求数 |
runtime.requests.active |
number | 当前活跃请求数 |
runtime.requests.errors |
number | 错误请求数 |
system.memory.used_bytes |
number | 已使用内存(字节) |
system.memory.used_percentage |
number | 内存使用率(%) |
system.memory.available_bytes |
number | 可用内存(字节,可选) |
system.cpu.usage_percentage |
number | CPU使用率(%) |
system.cpu.load_average |
array | 系统负载[1分钟,5分钟,15分钟] |
capabilities.models |
array | 支持的模型列表 |
capabilities.endpoints |
array | 可用的API端点 |
capabilities.features |
array | 支持的功能特性 |
- 接口地址:
/gen-uuid - 请求方法: GET
- 响应格式:
string
- 接口地址:
/gen-hash - 请求方法: GET
- 响应格式:
string
- 接口地址:
/gen-checksum - 请求方法: GET
- 响应格式:
string
- 接口地址:
/gen-token - 请求方法: GET
- 响应格式:
string
- 接口地址:
/get-checksum-header - 请求方法: GET
- 响应格式:
string
- 接口地址:
/token-profile/get - 请求方法: POST
- 认证方式: Bearer Token
- 请求格式:
{ session_token: string, web_token: string, proxy_name?: string, include_sessions: bool }
- 响应格式:
{ token_profile: [ null | { billing_cycle_start: string, billing_cycle_end: string, membership_type: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise", limit_type: "user" | "team", is_unlimited: bool, individual_usage: { plan?: { enabled: bool, used: int32, limit: int32, remaining: int32, breakdown: { included: int32, bonus: int32, total: int32 } }, on_demand?: { enabled: bool, used: int32, limit?: int32, remaining?: int32 } }, team_usage: { plan?: { enabled: bool, used: int32, limit: int32, remaining: int32, breakdown: { included: int32, bonus: int32, total: int32 } }, on_demand?: { enabled: bool, used: int32, limit?: int32, remaining?: int32 } }, }, null | { membership_type: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise", payment_id?: string, days_remaining_on_trial: int32, subscription_status?: "trialing" | "active" | "incomplete" | "incomplete_expired" | "past_due" | "canceled" | "unpaid" | "paused", verified_student: bool, trial_eligible: bool, trial_length_days: int32, is_on_student_plan: bool, is_on_billable_auto: bool, customer_balance?: double, trial_was_cancelled: bool, is_team_member: bool, team_membership_type?: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise", individual_membership_type?: "free" | "free_trial" | "pro" | "pro_plus" | "ultra" | "enterprise" }, null | { user_id: int32, email?: string, first_name?: string, last_name?: string, workos_id?: string, team_id?: number, created_at?: string, is_enterprise_user: bool, is_on_new_pricing: bool, privacy_mode_info: { privacy_mode: "unspecified" | "no_storage" | "no_training" | "usage_data_training_allowed" | "usage_codebase_training_allowed", is_enforced_by_team?: bool } }, null | [ { session_id: string, type: "unspecified" | "web" | "client" | "bugbot" | "background_agent", created_at: string, expires_at: string } ] ] }
如果发生错误,响应格式为:
{
"error": string
}- 接口地址:
/config-version/get - 请求方法: POST
- 认证方式: Bearer Token (当SHARE_AUTH_TOKEN启用时需要)
- 请求格式:
{
"token": string, // 格式: JWT
"checksum": {
"first": string, // 格式: 长度为64的Hex编码字符串
"second": string, // 格式: 长度为64的Hex编码字符串
},
"client_key": string, // 格式: 长度为64的Hex编码字符串
"session_id": string, // 格式: UUID
"proxy_name": string, // 可选,指定代理
"timezone": string, // 可选,指定时区
"gcpp_host": string // 可选,代码补全区域
}- 响应格式:
{
"config_version": string // 成功时返回生成的UUID
}或出错时:
{
"error": string // 错误信息
}- 接口地址:
/token-upgrade - 请求方法: POST
- 认证方式: 请求体中包含token
- 请求格式:
{
"token": string
}- 响应格式:
{
"status": "success" | "failure" | "error",
"message": string,
"result": string // optional
}- 相关接口都需要
x-client-key, 格式请见/gen-hash(32字节)。 - Cookie
FilesyncCookie是16字节,工作区不变即不变。 - 关于形如
AWSALBAPP-0的 Cookie 具有7天有效期,可能变化,详情请查阅 Amazon 相关文档。 FilesyncCookie和AWSALBAPP总是被/file/upload或/file/sync。- 以下所有接口都使用 POST 方法,且都需要认证。
- 接口地址:
/cpp/config
{
"is_nightly": bool, // 可选,是否使用nightly版本
"model": string, // 模型名称
"supports_cpt": bool // 可选,是否支持CPT
}{
"above_radius": number, // 可选,上方扫描半径
"below_radius": number, // 可选,下方扫描半径
"merge_behavior": { // 可选,合并行为
"type": string,
"limit": number, // 可选,限制
"radius": number // 可选,半径
},
"is_on": bool, // 可选,是否开启
"is_ghost_text": bool, // 可选,是否使用幽灵文本
"should_let_user_enable_cpp_even_if_not_pro": bool, // 可选,非专业用户是否可以启用
"heuristics": [ // 启用的启发式规则列表
"lots_of_added_text",
"duplicating_line_after_suggestion",
"duplicating_multiple_lines_after_suggestion",
"reverting_user_change",
"output_extends_beyond_range_and_is_repeated",
"suggesting_recently_rejected_edit"
],
"exclude_recently_viewed_files_patterns": [string], // 最近查看文件排除模式
"enable_rvf_tracking": bool, // 是否启用RVF跟踪
"global_debounce_duration_millis": number, // 全局去抖动时间(毫秒)
"client_debounce_duration_millis": number, // 客户端去抖动时间(毫秒)
"cpp_url": string, // CPP服务URL
"use_whitespace_diff_history": bool, // 是否使用空白差异历史
"import_prediction_config": { // 导入预测配置
"is_disabled_by_backend": bool, // 是否被后端禁用
"should_turn_on_automatically": bool, // 是否自动开启
"python_enabled": bool // Python是否启用
},
"enable_filesync_debounce_skipping": bool, // 是否启用文件同步去抖动跳过
"check_filesync_hash_percent": number, // 文件同步哈希检查百分比
"geo_cpp_backend_url": string, // 地理位置CPP后端URL
"recently_rejected_edit_thresholds": { // 可选,最近拒绝编辑阈值
"hard_reject_threshold": number, // 硬拒绝阈值
"soft_reject_threshold": number // 软拒绝阈值
},
"is_fused_cursor_prediction_model": bool, // 是否使用融合光标预测模型
"include_unchanged_lines": bool, // 是否包含未更改行
"should_fetch_rvf_text": bool, // 是否获取RVF文本
"max_number_of_cleared_suggestions_since_last_accept": number, // 可选,上次接受后清除建议的最大数量
"suggestion_hint_config": { // 可选,建议提示配置
"important_lsp_extensions": [string], // 重要的LSP扩展
"enabled_for_path_extensions": [string] // 启用的路径扩展
}
}- 接口地址:
/cpp/models
无
{
"models": [string], // 可用模型列表
"default_model": string // 可选,默认模型
}- 接口地址:
/file/upload
{
"uuid": string, // 文件标识符
"relative_workspace_path": string, // 文件相对于工作区的路径
"contents": string, // 文件内容
"model_version": number, // 模型版本
"sha256_hash": string // 可选,文件的SHA256哈希值
}{
"error": string // 错误类型:unspecified, non_existant, hash_mismatch
}- 接口地址:
/file/sync
{
"uuid": string, // 文件标识符
"relative_workspace_path": string, // 文件相对于工作区的路径
"model_version": number, // 模型版本
"filesync_updates": [ // 文件同步更新数组
{
"model_version": number, // 模型版本
"relative_workspace_path": string, // 文件相对于工作区的路径
"updates": [ // 单个更新请求数组
{
"start_position": number, // 更新开始位置
"end_position": number, // 更新结束位置
"change_length": number, // 变更长度
"replaced_string": string, // 替换的字符串
"range": { // 简单范围
"start_line_number": number, // 开始行号
"start_column": number, // 开始列
"end_line_number_inclusive": number, // 结束行号(包含)
"end_column": number // 结束列
}
}
],
"expected_file_length": number // 预期文件长度
}
],
"sha256_hash": string // 文件的SHA256哈希值
}{
"error": string // 错误类型:unspecified, non_existant, hash_mismatch
}- 接口地址:
/cpp/stream
{ current_file: { // 当前文件信息 relative_workspace_path: string, // 文件相对于工作区的路径 contents: string, // 文件内容 rely_on_filesync: bool, // 是否依赖文件同步 sha_256_hash?: string, // 可选,文件内容SHA256哈希值 top_chunks: [ // BM25检索的顶级代码块 { content: string, // 代码块内容 range: { // SimplestRange 最简单范围 start_line: int32, // 开始行号 end_line_inclusive: int32 // 结束行号(包含) }, score: int32, // BM25分数 relative_path: string // 代码块所在文件相对路径 } ], contents_start_at_line: int32, // 内容开始行号(一般为0) cursor_position: { // CursorPosition 光标位置 line: int32, // 行号(0-based) column: int32 // 列号(0-based) }, dataframes: [ // DataframeInfo 数据框信息(用于数据分析场景) { name: string, // 数据框变量名 shape: string, // 形状描述,如"(100, 5)" data_dimensionality: int32, // 数据维度 columns: [ // 列定义 { key: string, // 列名 type: string // 列数据类型 } ], row_count: int32, // 行数 index_column: string // 索引列名称 } ], total_number_of_lines: int32, // 文件总行数 language_id: string, // 语言标识符(如"python", "rust") selection?: { // 可选,CursorRange 当前选中范围 start_position: { // CursorPosition 开始位置 line: int32, // 行号 column: int32 // 列号 }, end_position: { // CursorPosition 结束位置 line: int32, // 行号 column: int32 // 列号 } }, alternative_version_id?: int32, // 可选,备选版本ID diagnostics: [ // Diagnostic 诊断信息数组 { message: string, // 诊断消息内容 range: { // CursorRange 诊断范围 start_position: { // CursorPosition 开始位置 line: int32, // 行号 column: int32 // 列号 }, end_position: { // CursorPosition 结束位置 line: int32, // 行号 column: int32 // 列号 } }, severity: "error" | "warning" | "information" | "hint", // DiagnosticSeverity 严重程度 related_information: [ // RelatedInformation 相关信息 { message: string, // 相关信息消息 range: { // CursorRange 相关信息范围 start_position: { // CursorPosition 开始位置 line: int32, // 行号 column: int32 // 列号 }, end_position: { // CursorPosition 结束位置 line: int32, // 行号 column: int32 // 列号 } } } ] } ], file_version?: int32, // 可选,文件版本号(用于增量更新) workspace_root_path: string, // 工作区根路径(绝对路径) line_ending?: string, // 可选,行结束符("\n" 或 "\r\n") file_git_context: { // FileGit Git上下文信息 commits: [ // GitCommit 相关提交数组 { commit: string, // 提交哈希 author: string, // 作者 date: string, // 提交日期 message: string // 提交消息 } ] } }, diff_history: [string], // 差异历史(已弃用,使用file_diff_histories代替) model_name?: string, // 可选,指定使用的模型名称 linter_errors?: { // 可选,LinterErrors Linter错误信息 relative_workspace_path: string, // 错误所在文件相对路径 errors: [ // LinterError 错误数组 { message: string, // 错误消息 range: { // CursorRange 错误范围 start_position: { // CursorPosition 开始位置 line: int32, // 行号 column: int32 // 列号 }, end_position: { // CursorPosition 结束位置 line: int32, // 行号 column: int32 // 列号 } }, source?: string, // 可选,错误来源(如"eslint", "pyright") related_information: [ // Diagnostic.RelatedInformation 相关信息 { message: string, // 相关信息消息 range: { // CursorRange 相关信息范围 start_position: { // CursorPosition 开始位置 line: int32, // 行号 column: int32 // 列号 }, end_position: { // CursorPosition 结束位置 line: int32, // 行号 column: int32 // 列号 } } } ], severity?: "error" | "warning" | "information" | "hint" // 可选,DiagnosticSeverity 严重程度 } ], file_contents: string // 文件内容(用于错误上下文) }, context_items: [ // CppContextItem 上下文项数组 { contents: string, // 上下文内容 symbol?: string, // 可选,符号名称 relative_workspace_path: string, // 上下文所在文件相对路径 score: float // 相关性分数 } ], diff_history_keys: [string], // 差异历史键(已弃用) give_debug_output?: bool, // 可选,是否输出调试信息 file_diff_histories: [ // CppFileDiffHistory 文件差异历史数组 { file_name: string, // 文件名 diff_history: [string], // 差异历史数组,格式:"行号-|旧内容\n行号+|新内容\n" diff_history_timestamps: [double] // 差异时间戳数组(Unix毫秒时间戳) } ], merged_diff_histories: [ // CppFileDiffHistory 合并后的差异历史 { file_name: string, // 文件名 diff_history: [string], // 合并后的差异历史 diff_history_timestamps: [double] // 时间戳数组 } ], block_diff_patches: [ // BlockDiffPatch 块级差异补丁 { start_model_window: { // ModelWindow 模型窗口起始状态 lines: [string], // 窗口内的代码行 start_line_number: int32, // 窗口起始行号 end_line_number: int32 // 窗口结束行号 }, changes: [ // Change 变更数组 { text: string, // 变更后的文本 range: { // IRange 变更范围 start_line_number: int32, // 起始行号 start_column: int32, // 起始列号 end_line_number: int32, // 结束行号 end_column: int32 // 结束列号 } } ], relative_path: string, // 文件相对路径 model_uuid: string, // 模型UUID(用于追踪补全来源) start_from_change_index: int32 // 从第几个change开始应用 } ], is_nightly?: bool, // 可选,是否为nightly构建版本 is_debug?: bool, // 可选,是否为调试模式 immediately_ack?: bool, // 可选,是否立即确认请求 enable_more_context?: bool, // 可选,是否启用更多上下文检索 parameter_hints: [ // CppParameterHint 参数提示数组 { label: string, // 参数标签(如"x: int") documentation?: string // 可选,参数文档说明 } ], lsp_contexts: [ // LspSubgraphFullContext LSP子图上下文 { uri?: string, // 可选,文件URI symbol_name: string, // 符号名称 positions: [ // LspSubgraphPosition 位置数组 { line: int32, // 行号 character: int32 // 字符位置 } ], context_items: [ // LspSubgraphContextItem 上下文项 { uri?: string, // 可选,URI type: string, // 类型(如"definition", "reference") content: string, // 内容 range?: { // 可选,LspSubgraphRange 范围 start_line: int32, // 起始行 start_character: int32, // 起始字符 end_line: int32, // 结束行 end_character: int32 // 结束字符 } } ], score: float // 相关性分数 } ], cpp_intent_info?: { // 可选,CppIntentInfo 代码补全意图信息 source: "line_change" | "typing" | "option_hold" | // 触发来源 "linter_errors" | "parameter_hints" | "cursor_prediction" | "manual_trigger" | "editor_change" | "lsp_suggestions" }, workspace_id?: string, // 可选,工作区唯一标识符 additional_files: [ // AdditionalFile 附加文件数组 { relative_workspace_path: string, // 文件相对路径 is_open: bool, // 是否在编辑器中打开 visible_range_content: [string], // 可见范围的内容(按行) last_viewed_at?: double, // 可选,最后查看时间(Unix毫秒时间戳) start_line_number_one_indexed: [int32], // 可见范围起始行号(1-based索引) visible_ranges: [ // LineRange 可见范围数组 { start_line_number: int32, // 起始行号 end_line_number_inclusive: int32 // 结束行号(包含) } ] } ], control_token?: "quiet" | "loud" | "op", // 可选,ControlToken 控制标记 client_time?: double, // 可选,客户端时间(Unix毫秒时间戳) filesync_updates: [ // FilesyncUpdateWithModelVersion 文件同步增量更新 { model_version: int32, // 模型版本号 relative_workspace_path: string, // 文件相对路径 updates: [ // SingleUpdateRequest 更新操作数组 { start_position: int32, // 起始位置(字符偏移量,0-based) end_position: int32, // 结束位置(字符偏移量,0-based) change_length: int32, // 变更后的长度 replaced_string: string, // 替换的字符串内容 range: { // SimpleRange 变更范围 start_line_number: int32, // 起始行号 start_column: int32, // 起始列号 end_line_number_inclusive: int32, // 结束行号(包含) end_column: int32 // 结束列号 } } ], expected_file_length: int32 // 应用更新后预期的文件长度 } ], time_since_request_start: double, // 从请求开始到当前的时间(毫秒) time_at_request_send: double, // 请求发送时的时间戳(Unix毫秒时间戳) client_timezone_offset?: double, // 可选,客户端时区偏移(分钟,如-480表示UTC+8) lsp_suggested_items?: { // 可选,LspSuggestedItems LSP建议项 suggestions: [ // LspSuggestion 建议数组 { label: string // 建议标签 } ] }, supports_cpt?: bool, // 可选,是否支持CPT(Code Patch Token)格式 supports_crlf_cpt?: bool, // 可选,是否支持CRLF换行的CPT格式 code_results: [ // CodeResult 代码检索结果 { code_block: { // CodeBlock 代码块 relative_workspace_path: string, // 文件相对路径 file_contents?: string, // 可选,完整文件内容 file_contents_length?: int32, // 可选,文件内容长度 range: { // CursorRange 代码块范围 start_position: { // CursorPosition 开始位置 line: int32, // 行号 column: int32 // 列号 }, end_position: { // CursorPosition 结束位置 line: int32, // 行号 column: int32 // 列号 } }, contents: string, // 代码块内容 signatures: { // Signatures 签名信息 ranges: [ // CursorRange 签名范围数组 { start_position: { // CursorPosition 开始位置 line: int32, // 行号 column: int32 // 列号 }, end_position: { // CursorPosition 结束位置 line: int32, // 行号 column: int32 // 列号 } } ] }, override_contents?: string, // 可选,覆盖内容 original_contents?: string, // 可选,原始内容 detailed_lines: [ // DetailedLine 详细行信息 { text: string, // 行文本 line_number: float, // 行号(浮点数用于支持虚拟行) is_signature: bool // 是否为签名行 } ], file_git_context: { // FileGit Git上下文 commits: [ // GitCommit 提交数组 { commit: string, // 提交哈希 author: string, // 作者 date: string, // 提交日期 message: string // 提交消息 } ] } }, score: float // 检索相关性分数 } ] }
服务器通过 Server-Sent Events (SSE) 返回流式响应。每个事件包含 type 字段区分消息类型。
1. model_info - 模型信息
{ type: "model_info", is_fused_cursor_prediction_model: bool, is_multidiff_model: bool }
2. range_replace - 范围替换
{ type: "range_replace", start_line_number: int32, // 起始行(1-based) end_line_number_inclusive: int32, // 结束行(1-based,包含) binding_id?: string, should_remove_leading_eol?: bool }
注意:替换的文本内容通过后续的
text事件发送
3. text - 文本内容
{ type: "text", text: string }
说明:流式输出的主要内容,客户端应累积
4. cursor_prediction - 光标预测
{ type: "cursor_prediction", relative_path: string, line_number_one_indexed: int32, expected_content: string, should_retrigger_cpp: bool, binding_id?: string }
5. done_edit - 编辑完成
{ type: "done_edit" }
6. begin_edit - 编辑开始
{ type: "begin_edit" }
7. done_stream - 内容阶段结束
{ type: "done_stream" }
说明:之后可能会有
debug消息
8. debug - 调试信息
{ type: "debug", model_input?: string, model_output?: string, stream_time?: string, total_time?: string, ttft_time?: string, server_timing?: string }
说明:可能出现多次,前端可累积用于统计
9. error - 错误
{ type: "error", error: { code: uint16, // 非零错误码 type: string, // 错误类型 details?: { // 可选的详细信息 title: string, detail: string, additional_info?: Record<string, string> } } }
10. stream_end - 流结束
{ type: "stream_end" }
基础场景:
model_info
range_replace // 指定范围
text (×ばつN) // 流式文本
done_edit
done_stream
debug (×ばつN) // 可选的多个调试消息
stream_end
多次编辑:
model_info
range_replace
text (×ばつN)
done_edit
begin_edit // 下一次编辑
range_replace
text (×ばつN)
cursor_prediction // 可选
done_edit
done_stream
stream_end
-
累积文本
range_replace指定范围- 累积后续所有
text内容 done_edit时应用变更
-
换行符处理
should_remove_leading_eol=true时移除首个换行符
-
多编辑会话
begin_edit标记新会话开始binding_id用于关联同一补全的多个编辑
-
错误处理
- 流中出现
error时,客户端应中止当前操作
- 流中出现
-
调试信息
done_stream后可能有多个debug消息- 前端可累积用于性能分析
感谢以下项目和贡献者:
- cursor-api - 本项目本身
- zhx47/cursor-api - 提供了本项目起步阶段的主要参考
- luolazyandlazy/cursorToApi - zhx47/cursor-api基于此项目优化
非常感谢我自己持续8个多月的更新和大家的支持!你想赞助的话,清直接联系我,我一般不会拒绝。
有人说少个二维码来着,还是算了。如果觉得好用,给点支持。没啥大不了的,有空尽量做一点,只是心力确实消耗很大。
(削除) 要不给我邮箱发口令红包? (削除ここまで)
赞助一定要是你真心想给,也不强求。
就算你给我赞助,我可能也不会区别对待你。我不想说你赞助多少就有什么,不想赞助失去本来的意味。
纯粹!