概述¶
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 傳輸方式、配置及服務器設置