概述¶
Cursor 命令行界面支持用于高级集成的 ACP (智能体客户端协议) 。您可以运行 agent acp,并通过 JSON-RPC 在 stdio 上连接自定义客户端。
更多信息请参阅官方 智能体客户端协议文档。
ACP 旨在用于构建自定义客户端和集成。对于常规终端
工作流,请使用带 agent 的交互式命令行界面。
启动 ACP 服务器¶
以 ACP 模式启动 Cursor 命令行界面:
agent acp
传输与消息格式¶
- 传输方式:
stdio - 协议封装:JSON-RPC 2.0
- 分帧:以换行符分隔的 JSON (每行一条消息)
- 方向:
- 客户端将请求/通知写入
stdin - Cursor 命令行界面将响应/通知写入
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 认证方法提供。实际上,你可以在启动前通过现有的 CLI 认证方式预先完成认证:
agent login--api-key(或CURSOR_API_KEY)--auth-token(或CURSOR_AUTH_TOKEN)
你还可以通过根 CLI 命令传入端点和 TLS 选项:
agent --api-key "$CURSOR_API_KEY" acp
agent -e https://api2.cursor.sh acp
agent -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,然后批准要使用的服务器。
ACP 模式不支持通过 Cursor 仪表盘配置的团队级 MCP 服务器。
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 string。phases:可选。对于较大的方案,可将 todos 按命名阶段分组。
响应:
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 智能体能够在 Cursor 桌面端应用以外的编辑器中工作。您可以为偏好的开发环境构建或使用第三方集成。
使用示例¶
-
JetBrains IDEs — 将 IntelliJ IDEA、WebStorm、PyCharm 或其他 JetBrains IDE 连接到 Cursor 智能体。设置说明请参阅 JetBrains 集成指南。
-
Neovim (avante.nvim) — 使用 avante.nvim 通过 ACP 将 Neovim 连接到 Cursor 智能体。请参阅下方的 Neovim 设置。
-
Zed — 启动
agent acp并通过 stdio 通信,即可与 Zed 的现代编辑器集成。Zed 扩展可以实现 ACP 客户端协议,将 AI 请求路由至 Cursor。 -
自定义编辑器 — 任何支持扩展的编辑器都可以实现 ACP 客户端。启动智能体进程,通过 stdio 发送 JSON-RPC 消息,并在编辑器 UI 中处理响应。
Neovim (avante.nvim)¶
avante.nvim 是一款提供 AI 编程助手的 Neovim 插件。它支持 ACP,因此你可以将其连接到 Cursor 智能体,在 Neovim 中进行智能体编程。
在你的 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 的智能体。mode:设为"agentic"以获得完整工具访问权限 (文件编辑、终端命令) 。仅聊天模式请使用"normal"。command:指向agent二进制文件。默认安装路径为~/.local/bin/agent。如果安装在其他位置,请相应调整。auth_method:使用"cursor_login"。请先在终端中运行agent login进行认证。
构建集成¶
- 将
agent acp作为子进程启动 - 通过 stdin/stdout 使用 JSON-RPC 进行通信
- 处理
session/update通知以显示流式响应 - 当工具需要批准时,响应
session/request_permission - 可选择实现 Cursor 扩展方法,以提供更丰富的用户体验
可参考上方的最简 Node.js 客户端,了解可运行的参考实现。
相关内容¶
CLI 中的 MCP¶
在 Cursor 命令行界面中管理和使用 MCP 服务器
MCP 概览¶
了解 MCP 传输方式、配置及服务器设置