Cursor智能体开发:命令行界面支持 ACP
Cursor 命令行界面支持 ACP (Agent Client Protocol) 以实现高级集成能力。你可以运行 agent acp,并通过 stdio 使用 JSON-RPC 连接自定义客户端。
概览
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 会话流程:
initialize- 使用
methodId: "cursor_login"进行authenticate session/new(或session/load)session/prompt- 在模型流式输出时处理
session/update通知 - 通过返回决策结果来处理
session/request_permission - 可选地发送
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-onceallow-alwaysreject-once
如果客户端不响应权限请求,工具执行可能会被阻塞。
MCP 服务器
ACP 支持使用在项目级或用户级 .cursor/mcp.json 中定义的 MCP 服务器。在你的项目目录中启动 agent,然后批准要使用的服务器。
通过 Cursor 仪表盘配置的团队级 MCP 服务器在 ACP 模式下不受支持。
Cursor 扩展方法
Cursor 会发送 ACP 扩展方法,以提供更丰富的客户端体验。分为两种类型:
- 阻塞方法 (
cursor/ask_question,cursor/create_plan):智能体会在继续前等待响应。你的客户端必须返回 JSON-RPC 响应。 - 通知方法 (
cursor/update_todos,cursor/task,cursor/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完成登录认证。
构建集成
- 将
agent acp作为子进程启动 - 使用 JSON-RPC 通过 stdin/stdout 通信
- 处理
session/update通知以显示流式响应 - 当工具需要批准时,响应
session/request_permission - 可选地实现 Cursor 扩展方法,以提供更丰富的用户体验
请参考上文的最简 Node.js 客户端,作为可运行的参考实现。
《动手学PyTorch建模与应用:从深度学习到大模型》是一本从零基础上手深度学习和大模型的PyTorch实战指南。全书共11章,前6章涵盖深度学习基础,包括张量运算、神经网络原理、数据预处理及卷积神经网络等;后5章进阶探讨图像、文本、音频建模技术,并结合Transformer架构解析大语言模型的开发实践。书中通过房价预测、图像分类等案例讲解模型构建方法,每章附有动手练习题,帮助读者巩固实战能力。内容兼顾数学原理与工程实现,适配PyTorch框架最新技术发展趋势。

更多推荐


所有评论(0)