@ericzakariasson:你现在可以用 Rust、Go 或任何其他语言构建 Cursor 智能体!我们正在开源 SDK Bridge,以便你可以编写……

X AI KOLs Timeline 工具

摘要

Cursor 开源了 SDK Bridge,这是一种基于 protobuf 的协议,允许开发者用任何语言(例如 Rust、Go、Java)构建 Cursor 智能体,而无需依赖官方的 TypeScript 或 Python SDK。

你现在可以用 Rust、Go 或任何其他语言构建 Cursor 智能体! 我们正在开源 SDK Bridge,这样你就可以用你所用的语言编写一个轻量适配器,在我们在添加智能体功能时保持同步。 请访问 https://t.co/EiwhExk2MV 体验! https://t.co/ncvUmP7sIO
查看原文
查看缓存全文

缓存时间: 2026/08/05 16:26

您现在可以在 Rust、Go 或任何其他语言中构建 Cursor 智能体了!我们正在开源 SDK Bridge,这样您就可以用您的语言编写一个轻量适配器,当我们添加智能体功能时它也能保持同步。立即试用:https://t.co/EiwhExk2MV!https://t.co/ncvUmP7sIO


cursor/sdk-bridge

来源:https://github.com/cursor/sdk-bridge

Cursor SDK Bridge

Cursor SDK bridge 协议的公共家园:稳定的 sdk.v1 protobuf 契约,让您可以从任何语言驱动 Cursor 智能体(https://cursor.com/docs),而无需直接依赖 TypeScript(@cursor/sdk(https://www.npmjs.com/package/@cursor/sdk))或 Python(cursor-sdk(https://pypi.org/project/cursor-sdk/))SDK。

Bridge 是一个小型本地服务器,将 TypeScript SDK(@cursor/sdk)作为库嵌入,并通过 Connect(https://connectrpc.com/)/gRPC-Web 使用本仓库中的 protobuf 定义公开其全部功能——创建智能体、发送消息、流式运行、自定义工具、产物等。

*适配器(adapter)*是任何启动 bridge 并与之通信 sdk.v1 协议的东西:新语言的 SDK、服务集成或一次性脚本。

┌────────────────-┐ spawn + Connect RPCs ┌────────────────────┐ HTTPS ┌─────────────┐
│ your adapter │ ──────────────────────► │ cursor-sdk-bridge │ ─────────► │ Cursor API │
│ (any language) │ ◄────────────────────── │ (local process) │ │ │
└────────────────-┘ callback RPCs (tools, └────────────────────┘ └─────────────┘
 custom stores)

如何使用本仓库

您可以使用本仓库为 Go、Rust、Java 等语言创建适配器。具体做法:将编码智能体指向本仓库,并告诉它遵循下面的 智能体:从这里开始——这是一份完整的、逐里程碑构建的计划,引导智能体从代码生成走向一个完整、经过验证的、针对您语言的 SDK。

  • 正在为新语言构建适配器? 将本仓库和 智能体:从这里开始 指南交给 Cursor 智能体。
  • 从 TypeScript 或 Python 编写智能体脚本? 请使用官方 SDK——npm 上的 @cursor/sdk(https://www.npmjs.com/package/@cursor/sdk)或 PyPI 上的 cursor-sdk(https://pypi.org/project/cursor-sdk/)。您不需要本仓库。

仓库结构

路径内容
proto/sdk/v1/sdk.v1 protobuf 契约。自动生成——请勿编辑。 每次 SDK 发布时自动重新生成。
proto/manifest.json发布元数据:protocol"sdk.v1")、sdkVersion 和源提交。
docs/协议指南:生命周期、服务、流式传输、错误、版本控制。
examples/其他语言的最小适配器,每个都有各自的 buf.gen.yaml

注意: proto/ 由 Cursor 的发布自动化工具管理,每次发布都会重写。 每次发布都会推送一个与已发布的 @cursor/sdk npm / cursor-sdk PyPI 版本匹配的注释标签 vX.Y.Z,并在 GitHub Release 中附带独立的 bridge 归档文件。 拉取请求绝不能触及 proto/

获取 bridge

从本仓库的最新 Release(https://github.com/cursor/sdk-bridge/releases/latest)下载适用于您平台的 cursor-sdk-bridge-standalone--.tar.gz(操作系统 linux|darwin|win32,架构 x64|arm64,win32 仅支持 x64)——每个 Release 都会附带独立的 bridge 归档文件和 SHA256SUMS.txt。相同的 bridge 也嵌入在 PyPI 上的 cursor-sdk Python wheel 中。

有关归档布局以及启动与握手生命周期的说明,请参阅 docs/protocol.md

文档

  • docs/protocol.md——启动与握手生命周期、身份验证、CLI 标志、分发
  • docs/services.md——每个服务的作用,包括由适配器实现的回调服务
  • docs/streaming.md——运行流语义:信封、偏移量、恢复、心跳
  • docs/errors.md——来自 sdk_errors.proto 的结构化错误模型
  • docs/smoke-test.md——仅使用 curl 对每个核心 RPC 进行冒烟测试:“是 bridge 的问题还是我的问题?”的判断依据
  • docs/versioning.md——标签策略和 sdk.v1 兼容性承诺

智能体:从这里开始

本节是为编码智能体(以及人类)准备的构建计划,目标是在 sdk.v1 bridge 协议之上为新语言构建完整的 Cursor SDK——代码生成、受管的 bridge 生命周期、客户端/智能体/运行 API 设计、流式传输、错误处理以及适配器端的回调服务。

适配器启动 cursor-sdk-bridge 并与之通信 sdk.v1 Connect 协议。本指南的最终状态不是一个演示脚本,而是一个真正的 SDK:一个其他开发者可以安装并使用它来编写 Cursor 智能体脚本的库,而无需知道 bridge 的存在。

首先阅读 docs/protocol.mdexamples/python-adapter/ 是目标形态的一个可运行微缩版——架构表中的每个组件对应一个模块,构建在保持线上格式可见的手写传输层之上——而 docs/streaming.md / docs/errors.md 涵盖流和故障。

契约一览

proto/sdk/v1/ 下共有七个文件,包名为 sdk.v1,除 Google well-known types 外完全自包含:

文件作用
sdk_agent_service.protoSdkAgentService——创建/恢复智能体、发送消息、流式运行、产物、用量。
sdk_cursor_service.protoSdkCursorService——客户端级操作(身份、模型、仓库)。
sdk_bridge_control_service.protoSdkBridgeControlService——bridge 生命周期(ping、版本、关闭)。
sdk_custom_tool_callback_service.protoSdkCustomToolCallbackService——由适配器实现;bridge 回调它来执行用户定义的自定义工具。
sdk_store_callback_service.protoSdkStoreCallbackService——由适配器为自定义智能体存储实现。
sdk_messages.proto共享消息、枚举和运行流信封。
sdk_errors.proto结构化错误详情和稳定的错误码分类。

目标架构

Cursor 的官方 SDK 都收敛到相同的形态。以此为方向,并适配您语言的习惯用法:

组件职责
Bridge 管理器定位 bridge(环境变量覆盖 → 捆绑/下载的归档),启动它,执行就绪握手,暴露端点,关闭它(RPC → 等待 → 强制终止)。每个客户端一个受管 bridge,在首次使用时惰性创建;也允许附加到外部提供的端点。
传输层Connect-over-HTTP/1.1 客户端:一元 POST 和服务器流帧,每个请求都携带 Bearer 身份验证,将 Connect 错误转换为您的错误类型。使用生成的桩或手写(参见 examples/python-adapter/)。
Client拥有 bridge 管理器 + 传输层。镜像 SdkAgentService 的类型化底层方法(create_agentsendwait_live_runobserve_runcancel_runlist_agents 等)。其他一切都在此之上构建。
Agent 句柄create(options) / resume(id) / get / list 构造函数;send(message) -> Runclosearchivedelete;自定义工具注册。持有 agent_id + 模型。
Run 句柄流式传输表面:迭代事件;便捷访问器(助手文本迭代器、阻塞式 wait() → 结果、最终 text());用于恢复的 observe(after_offset)cancel()。跟踪最后看到的 offset
Cursor 目录来自 SdkCursorServiceme()models()repositories()
错误一个基础错误加上从 Connect 代码 + SdkErrorDetails.sdk_error_code 映射的分类(身份验证、未找到、限流、忙碌、校验失败等)。在错误对象上保留 request_idretry_afterrate_limit
回调服务器可选的回环 Connect 服务器,实现 SdkCustomToolCallbackServiceSdkStoreCallbackService,这样用户就可以用您的语言定义工具和存储。

一个北极星用法草图(转换为您的语言):

client = Client()  # 惰性启动/附加 bridge
agent = client.agents.create(model="composer-2", local={"cwd": ["/repo"]})
run = agent.send("Summarize this repository.")
for text in run.iter_text():
    print(text)
result = run.wait()
agent.close()
client.close()  # 关闭 bridge

另外提供最简单场景的一行代码(prompt(...):创建 → 发送 → 等待 → 关闭),以及上下文管理器/defer/RAII 形式,确保 bridge 永远不会泄漏。

前置条件和约束

  • 将契约固定到本仓库的最新 Release:最新的 vX.Y.Z 标签(https://github.com/cursor/sdk-bridge/tags)。从该标签的 proto/sdk/v1/ 获取 protos(如果您不在本仓库的检出环境中工作,请将它们复制到您的项目中——相同版本的 bridge 归档也附带一份完全相同的 proto/sdk/v1/)。永远不要编辑 proto/ 下的任何内容——它是自动生成的。
  • 目标语言需要 (a) protobuf 运行时和 (b) HTTP/1.1 客户端。Connect(https://connectrpc.com/docs/)客户端库是理想选择但不是必需的——每个 RPC 都是 POST http://:/sdk.v1./,请求体为 protobuf(content-type: application/proto)或 JSON(application/json)。经典 gRPC 不适用:bridge 仅提供 HTTP/1.1 服务。
  • 运行一次真实的对话轮次需要 CURSOR_API_KEY(cursor.com/dashboard(https://cursor.com/dashboard))——将它设置在 bridge 的环境中并且显式地作为 options.api_key / 每次调用的 api_key 传递(参见里程碑 4 和 docs/protocol.md)。

按顺序完成以下里程碑,并在每个里程碑保持一个可运行的演示/测试——每一步都构建在已验证的上一层之上。

里程碑 1——代码生成

复制 examples/python-adapter/buf.gen.yaml 作为模板:将 inputs 指向您的 protos 副本(在本仓库内工作时为 directory: ../../proto),并将插件替换为目标语言的 protobuf + Connect 插件。对于编译型语言,使用 buf 的 managed 模式覆盖语言包选项——已发布的 protos 携带 Cursor 内部使用的 go_packagejava_package 等值。只涉及 sdk/v1/*.proto 和 Google well-known types;没有其他依赖。提交 buf.gen.yaml,将 gen/ 输出加入 gitignore。

如果目标语言没有 Connect 插件,则只生成普通的 protobuf 消息,并手写那个小型 HTTP 层(一元 = 一次 POST;服务器流 = Connect 流式信封:1 字节标志 + 4 字节大端长度帧,结束流标志 0x02 携带一个 JSON EndStreamResponse 及任何错误)。examples/python-adapter/cursor_adapter/_transport.py 用大约 100 行代码精确地完成了这一点。

里程碑 2——Bridge 管理器

  • 定位 bridge:首先使用 CURSOR_SDK_BRIDGE_BIN 等环境变量覆盖,然后使用您的包中捆绑/下载的归档。独立归档附加在本仓库的 GitHub Release 上(cursor-sdk-bridge-standalone--.tar.gz,操作系统:linux|darwin|win32,架构:x64|arm64)——从您固定的 vX.Y.Z 标签对应的 Release 下载。每个归档都解压为扁平结构:可执行文件是 bin/cursor-sdk-bridge,Windows 上是 .exe
  • 在环境中设置 CURSOR_API_KEY 后启动,本地智能体加上 --workspace ,并设置 CURSOR_SDK_CLIENT_LANGUAGE= 以便归因。
  • 握手:捕获 stderr,扫描字面前缀 cursor-sdk-bridge ready (带尾随空格),解析其后的 JSON,验证 schemaVersion == 1transport == "tcp"protocol == "connect",忽略未知字段。设置约 30 秒的启动超时;如果进程先退出,则输出捕获到的 stderr。之后永远持续排空 stderr——管道满会阻塞 bridge。绝不要记录原始发现行(旧版 bridge 会在其中内联令牌)。
  • authTokenFile 路径读取 Bearer 令牌并去除空白。
  • 关闭:SdkBridgeControlService.Shutdown(或 SIGTERM),等待约 5 秒,然后强制终止。确保这在客户端关闭以及解释器/进程退出时执行,这样崩溃的调用方也不会泄漏 bridge。
  • 支持附加到已在运行的 bridge(显式 URL + 令牌)——这对测试和自行管理进程的主机很有用。

里程碑 3——传输层、身份验证和错误

  • 每个请求上发送 Authorization: Bearer ——一元流式请求都如此(一个常见 bug:拦截器 API 通常只覆盖一元请求)。缺失/错误的令牌 ⇒ UNAUTHENTICATED
  • SdkBridgeControlService.Ping 验证,然后 GetVersion(期望 protocol_version == "sdk.v1";能力标志用于门控可选功能)。
  • 当 RPC 失败且您怀疑是自己的编码或传输层问题时,在二分定位代码之前,先用 docs/smoke-test.md 中仅使用 curl 的序列运行同一个 RPC——它可以在一次操作中将适配器 bug 与 bridge/密钥/环境问题区分开来。
  • 现在就开始构建错误层,而不是最后才做:从失败的 RPC 中解码 sdk.v1.SdkErrorDetailsdocs/errors.md 有分类和线上编码),并将 sdk_error_code + Connect 代码映射到您语言的异常/错误层次结构上。公开完整的 request_idretry_afterrate_limit。在任何地方都以容忍未知字段的方式解析 protobuf JSON。

里程碑 4——第一次对话轮次:Agent.sendRun

  1. 使用 options.local.cwd = [""] 调用 SdkAgentService.CreateAgent,同时显式传入 options.model——本地智能体必须指定模型;通过 SdkCursorService.ListModels 发现 ID(目录调用要求每次调用都带 api_key;没有环境变量回退)——并显式传入 options.api_key始终设置 options.api_key:bridge 的 CURSOR_API_KEY 环境变量不能替代它——并非每个操作都会在所有 bridge 构建上回退到该环境变量,并且没有此选项时第 2 步可能因 Invalid User API Key 失败。
  2. 使用 agent_idUserMessage{text} 调用 SdkAgentService.Send;按照 docs/streaming.md 将服务器流包装在您的 Run 句柄中:
    • 根据 envelope oneof 分派;忽略未设置 case 的消息(心跳)和未知 case;
    • sdk_message:根据 type 分派(systemassistanttool_callstatus 等);负载是 JSON 对象(google.protobuf.Struct)。失败时的人类可读原因出现在 status 负载的 message 中——请将其呈现出来,因为 RunStreamResult.error_code 可能为空;
    • 跟踪最后一个非空 offsetresult 然后是 done 结束本次运行;
    • 流被丢弃不会取消运行——Run.observe() 通过 ObserveRun + after_offset 恢复(只传递来自 ObserveRun 本身的偏移量;实时 Send 偏移量是另一种编号——参见 docs/streaming.md),而 wait() 回退到 WaitLiveRun
  3. 在原始事件流之上添加便捷层:助手文本迭代器、阻塞式 wait()、最终 text()cancel()

里程碑 5——管理面与目录

Client/Agent 上补齐 SdkAgentService 的其余部分:ResumeAgentGetAgent/ListAgents(分页游标)、ArchiveAgent/Unarchive/Delete/CloseListRuns/GetRun/GetRunConversationListAgentMessages、产物(ListArtifacts + 分块 DownloadArtifact)、GetUsage(仅云端),以及 Cursor 目录(MeListModelsListRepositories)。一旦里程碑 1–4 工作正常,这些都是机械性的工作。

里程碑 6——回调服务(自定义工具 / 存储)

这些服务反转了方向:SDK 运行一个回环 Connect 服务器,bridge 用 SDK 选择的 Bearer 令牌向它进行身份验证。在每个回调上都验证该令牌,就像 bridge 验证您的令牌一样。有一些会消耗大量真实调试时间的坑(详见 docs/services.md):回调 POST 可能使用分块传输编码(要解码它——最小 HTTP 服务器通常不支持);存储输出必须是裸记录,而不是包装后的输入信封;工具结果是 Struct,因此标量返回值需要包装在对象中。

  • 自定义工具——实现 SdkCustomToolCallbackService.CallCustomTool(使用 Struct 参数执行指定的用户函数,返回 Struct 结果)。声明太

相似文章