概览

Cursor 命令行界面支持 ACP (Agent Client Protocol) 以实现高级集成能力。你可以运行 agent acp,并通过 stdio 使用 JSON-RPC 连接自定义客户端。

在官方 Agent Client Protocol 文档 中了解更多信息。

ACP 适用于构建自定义客户端和集成。对于普通的终端 工作流程,请使用交互式命令行界面命令 agent

启动 ACP 服务器

以 ACP 模式启动 Cursor 命令行界面:

agent acp

传输和消息格式

  • 传输方式:stdio
  • 协议封套:JSON-RPC 2.0
  • 消息分帧:按行分隔的 JSON(每行一条消息)
  • 传输方向:
    • 客户端将请求和通知写入 stdin
    • Cursor 命令行界面(CLI)将响应和通知写入 stdout
    • 日志可能会写入 stderr

请求流程

典型的 ACP 会话流程:

  1. initialize
  2. 使用 methodId: "cursor_login" 进行 authenticate
  3. session/new(或 session/load
  4. session/prompt
  5. 在模型流式输出时处理 session/update 通知
  6. 通过返回决策结果来处理 session/request_permission
  7. 可选地发送 session/cancel

身份验证

Cursor 命令行界面会将 cursor_login 宣称为 ACP 的认证方式。实际使用中,你可以通过现有的命令行界面认证方式,在启动前预先完成认证:

  • agent login
  • --api-key(或 CURSOR_API_KEY
  • --auth-token(或 CURSOR_AUTH_TOKEN

也可以在根命令行界面命令中传递 endpoint 和 TLS 选项:

agent --api-key "$CURSOR_API_KEY" acpagent -e https://api2.cursor.sh acpagent -k acp

会话、模式和权限

会话

  • 使用 session/new 创建会话
  • 使用 session/load 恢复现有会话

模式

ACP 会话支持与命令行界面 (CLI) 相同的核心模式:

  • agent(可使用全部工具)
  • plan(用于规划的只读模式)
  • ask(用于问答的只读模式)

权限

当工具需要授权时,Cursor 会发送 session/request_permission。客户端应返回以下之一:

  • allow-once
  • allow-always
  • reject-once

如果客户端不响应权限请求,工具执行可能会被阻塞。

MCP 服务器

ACP 支持使用在项目级或用户级 .cursor/mcp.json 中定义的 MCP 服务器。在你的项目目录中启动 agent,然后批准要使用的服务器。

通过 Cursor 仪表盘配置的团队级 MCP 服务器在 ACP 模式下不受支持。

Cursor 扩展方法

Cursor 会发送 ACP 扩展方法,以提供更丰富的客户端体验。分为两种类型:

  • 阻塞方法 (cursor/ask_questioncursor/create_plan):智能体会在继续前等待响应。你的客户端必须返回 JSON-RPC 响应。
  • 通知方法 (cursor/update_todoscursor/taskcursor/generate_image):智能体会以发出后无需回复的通知形式发送这些方法。你的客户端可以显示它们,但无需响应。
方法 类型 用途
cursor/ask_question 阻塞 向用户提出多项选择题
cursor/create_plan 阻塞 请求对方案进行明确批准
cursor/update_todos 通知 通知客户端待办事项状态更新
cursor/task 通知 通知客户端子智能体任务已完成
cursor/generate_image 通知 通知客户端已生成的图像输出

cursor/ask_question

向用户展示多项选择题。智能体会阻塞,直到客户端响应。

请求:

interface CursorAskQuestionRequest {  toolCallId: string;  title?: string;  questions: Array<{    id: string;    prompt: string;    options: Array<{ id: string; label: string }>;    allowMultiple?: boolean;  }>;}

响应:

interface CursorAskQuestionResponse {  outcome:    | {        outcome: "answered";        answers: Array<{          questionId: string;          selectedOptionIds: string[];        }>;      }    | { outcome: "skipped"; reason?: string }    | { outcome: "cancelled" };}

请求示例:

{  "toolCallId": "call_123",  "title": "Need input",  "questions": [    {      "id": "q1",      "prompt": "Which mode should I use?",      "options": [        { "id": "agent", "label": "Agent" },        { "id": "plan", "label": "Plan" }      ],      "allowMultiple": false    }  ]}

cursor/create_plan

请求用户批准方案。智能体会阻塞,直到客户端接受或拒绝该方案。

请求:

interface CursorCreatePlanRequest {  toolCallId: string;  name?: string;  overview?: string;  plan: string;  todos: Array<{    id: string;    content: string;    status: "pending" | "in_progress" | "completed" | "cancelled";  }>;  isProject?: boolean;  phases?: Array<{    name: string;    todos: Array<{      id: string;      content: string;      status: "pending" | "in_progress" | "completed" | "cancelled";    }>;  }>;}
  • plan:描述完整方案的 Markdown 字符串。
  • phases:可选,用于将待办事项按命名阶段分组,适用于较大的方案。

返回:

interface CursorCreatePlanResponse {  outcome:    | { outcome: "accepted"; planUri?: string }    | { outcome: "rejected"; reason?: string }    | { outcome: "cancelled" };}

请求示例:

{  "toolCallId": "call_124",  "name": "Refactor tabs layout",  "overview": "Tighten layout behavior and preserve existing UX.",  "plan": "1. Inspect current tab sizing logic.\n2. Update layout calculations.\n3. Verify editor behavior.",  "todos": [    { "id": "todo-1", "content": "Inspect current tab sizing logic", "status": "completed" },    { "id": "todo-2", "content": "Update layout calculations", "status": "in_progress" },    { "id": "todo-3", "content": "Verify editor behavior", "status": "pending" }  ],  "isProject": false}

cursor/update_todos

更新客户端的待辦事項列表。以通知形式發送,無需響應。

請求:

interface CursorUpdateTodosRequest {  toolCallId: string;  todos: Array<{    id: string;    content: string;    status: "pending" | "in_progress" | "completed" | "cancelled";  }>;  merge: boolean;}
  • merge:当为 true 时,将这些待办事项并入现有列表。当为 false 时,替换整个列表。

响应:

interface CursorUpdateTodosResponse {  outcome:    | {        outcome: "accepted";        todos: Array<{          id: string;          content: string;          status: "pending" | "in_progress" | "completed" | "cancelled";        }>;      }    | { outcome: "rejected"; reason?: string }    | { outcome: "cancelled" };}

请求示例:

{  "toolCallId": "call_125",  "todos": [    { "id": "1", "content": "Set up project structure", "status": "completed" },    { "id": "2", "content": "Add authentication", "status": "in_progress" },    { "id": "3", "content": "Write unit tests", "status": "pending" }  ],  "merge": true}

cursor/task

通知客户端子智能体任务。以通知形式发送;无需响应。

请求:

interface CursorTaskRequest {  toolCallId: string;  description: string;  prompt: string;  subagentType:    | "unspecified"    | "computer_use"    | "explore"    | "video_review"    | "browser_use"    | "shell"    | "vm_setup_helper"    | { custom: string };  model?: string;  agentId?: string;  durationMs?: number;}
  • subagentType:要运行的子智能体类型。自定义子智能体类型请使用 { custom: "your_type" }
  • agentId:设置此项以继续之前创建的子智能体。
  • durationMs:任务运行时长,会包含在响应中。

响应:

interface CursorTaskResponse {  outcome:    | { outcome: "completed"; agentId?: string; durationMs?: number }    | { outcome: "rejected"; reason?: string }    | { outcome: "cancelled" };}

请求示例:

{  "toolCallId": "call_126",  "description": "Explore codebase",  "prompt": "Find where authentication is handled and report the file paths.",  "subagentType": "explore"}

cursor/generate_image

通知客户端图像已生成。作为通知发送,无需响应。

请求:

interface CursorGenerateImageRequest {  toolCallId: string;  description: string;  filePath?: string;  referenceImagePaths?: string[];}
  • filePath:生成图像的建议文件路径。
  • referenceImagePaths:作为输入的参考图像路径。

响应:

interface CursorGenerateImageResponse {  outcome:    | { outcome: "generated"; filePath: string; imageData?: string }    | { outcome: "rejected"; reason?: string }    | { outcome: "cancelled" };}

请求示例:

{  "toolCallId": "call_127",  "description": "Minimal flat app icon for a note-taking app",  "filePath": "/tmp/icon.png",  "referenceImagePaths": ["/tmp/reference.png"]}

最简 Node.js 客户端

此示例展示了自定义 ACP 客户端的最基本控制流程:

import { spawn } from "node:child_process";import readline from "node:readline";const agent = spawn("agent", ["acp"], { stdio: ["pipe", "pipe", "inherit"] });let nextId = 1;const pending = new Map();function send(method, params) {  const id = nextId++;  agent.stdin.write(JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n");  return new Promise((resolve, reject) => pending.set(id, { resolve, reject }));}function respond(id, result) {  agent.stdin.write(JSON.stringify({ jsonrpc: "2.0", id, result }) + "\n");}const rl = readline.createInterface({ input: agent.stdout });rl.on("line", line => {  const msg = JSON.parse(line);  if (msg.id && (msg.result || msg.error)) {    const waiter = pending.get(msg.id);    if (!waiter) return;    pending.delete(msg.id);    msg.error ? waiter.reject(msg.error) : waiter.resolve(msg.result);    return;  }  if (msg.method === "session/update") {    const update = msg.params?.update;    if (update?.sessionUpdate === "agent_message_chunk" && update.content?.text) {      process.stdout.write(update.content.text);    }    return;  }  if (msg.method === "session/request_permission") {    respond(msg.id, { outcome: { outcome: "selected", optionId: "allow-once" } });  }});const init = async () => {  await send("initialize", {    protocolVersion: 1,    clientCapabilities: { fs: { readTextFile: false, writeTextFile: false }, terminal: false },    clientInfo: { name: "acp-minimal-client", version: "0.1.0" }  });  await send("authenticate", { methodId: "cursor_login" });  const { sessionId } = await send("session/new", { cwd: process.cwd(), mcpServers: [] });  const result = await send("session/prompt", {    sessionId,    prompt: [{ type: "text", text: "Say hello in one sentence." }]  });  console.log(`\n\n[stopReason=${result.stopReason}]`);};init().finally(() => {  agent.stdin.end();  agent.kill();});

IDE 集成

ACP 让 Cursor 的 AI Agent 能够在 Cursor 桌面应用之外的其他编辑器中工作。你可以为自己的首选开发环境构建或使用第三方集成。

示例用例

  • JetBrains IDEs — 将 IntelliJ IDEA、WebStorm、PyCharm 或其他 JetBrains IDE 连接到 Cursor 的 agent。有关安装说明,请参见 JetBrains 集成指南

  • Neovim (avante.nvim) — 使用 avante.nvim 通过 ACP 将 Neovim 连接到 Cursor 的 agent。参见下方的 Neovim 设置

  • Zed — 通过启动 agent acp 并使用 stdio 通信,与现代编辑器 Zed 集成。Zed 扩展可以实现 ACP 客户端协议,将 AI 请求路由到 Cursor。

  • 自定义编辑器 — 任何支持扩展的编辑器都可以实现 ACP 客户端。启动 agent 进程,通过 stdio 发送 JSON-RPC 消息,并在你的编辑器 UI 中处理响应。

Neovim (avante.nvim)

avante.nvim 是一个为 Neovim 提供 AI 驱动编码助手的插件。它支持 ACP,因此你可以在 Neovim 中将其连接到 Cursor 的 Agent,进行基于 Agent 的编程。

将以下内容添加到你的 lazy.nvim 插件配置中 (例如 ~/.config/nvim/lua/plugins/avante.lua) :

return {  {    "yetone/avante.nvim",    event = "VeryLazy",    version = false,    build = "make",    opts = {      provider = "cursor",      mode = "agentic",      acp_providers = {        cursor = {          command = os.getenv("HOME") .. "/.local/bin/agent",          args = { "acp" },          auth_method = "cursor_login",          env = {            HOME = os.getenv("HOME"),            PATH = os.getenv("PATH"),          },        },      },    },    dependencies = {      "nvim-lua/plenary.nvim",      "MunifTanjim/nui.nvim",      "nvim-tree/nvim-web-devicons",      {        "MeanderingProgrammer/render-markdown.nvim",        opts = {          file_types = { "markdown", "Avante" },        },        ft = { "markdown", "Avante" },      },    },  },}

关键设置:

  • provider:设置为 "cursor",以通过 Cursor 的 agent 路由请求。
  • mode:设置为 "agentic" 以获得全部工具功能访问权限 (文件编辑、终端命令) 。仅聊天模式请使用 "normal"
  • command:指向 agent 可执行文件。默认安装路径为 ~/.local/bin/agent。如果安装在其他位置,请相应调整。
  • auth_method:使用 "cursor_login"。请先在终端中运行 agent login 完成登录认证。

构建集成

  1. 将 agent acp 作为子进程启动
  2. 使用 JSON-RPC 通过 stdin/stdout 通信
  3. 处理 session/update 通知以显示流式响应
  4. 当工具需要批准时,响应 session/request_permission
  5. 可选地实现 Cursor 扩展方法,以提供更丰富的用户体验

请参考上文的最简 Node.js 客户端,作为可运行的参考实现。

 

《动手学PyTorch建模与应用:从深度学习到大模型》是一本从零基础上手深度学习和大模型的PyTorch实战指南。全书共11章,前6章涵盖深度学习基础,包括张量运算、神经网络原理、数据预处理及卷积神经网络等;后5章进阶探讨图像、文本、音频建模技术,并结合Transformer架构解析大语言模型的开发实践。书中通过房价预测、图像分类等案例讲解模型构建方法,每章附有动手练习题,帮助读者巩固实战能力。内容兼顾数学原理与工程实现,适配PyTorch框架最新技术发展趋势。

 

Logo

更多推荐