Why does this exist? Cursor published their own ACP client (docs), but using it in Zed was rough as I somehow had to permit tool calls the whole time.
Disclaimer: I am not affiliated with Cursor or Zed. This project is a personal experiment and should not be considered an official product of either company. I am a big fan of both products and wanted to combine what I like with both of them: An amazing editor and a great AI coding agent (and composer-1, holy this model flies xD).
An Agent Client Protocol (ACP) adapter for the Cursor SDK, enabling Cursor's coding agent in Zed and other ACP-compatible clients.
This is an ai-assisted personal project aimed at bringing Cursor's agent into Zed. Prompt execution uses @cursor/sdk; the adapter adds ACP session persistence, history replay, model and mode controls, and Zed-friendly configuration options.
Based on claude-code-acp by Zed Industries - the original ACP adapter for Claude Code that served as the architectural foundation for this project.
- Smart Auto Review by default: New sessions create local SDK agents with
local.autoReview: true. Cursor's classifier runs approved calls and fails closed on the rest. - ACP permission fallback: A call stopped by Auto Review is surfaced to the client. “Allow once” retries that turn with Auto Review disabled; “Always allow” switches the session to Yolo.
- Correct SDK mode lifecycle: Auto Review is an agent-level SDK option. Switching review policy closes and resumes the same SDK agent with the new policy; the SDK's unrelated crash-recovery
forceflag is never used as an approval bypass. - Model parameters: Canonical SDK model IDs, thinking/reasoning/effort levels, fast values, and variants flow into SDK model selections. The adapter keeps the catalog's original parameter ids.
- MCP and images: ACP-provided stdio/HTTP/SSE MCP servers and image chunks are forwarded to the SDK.
- Agent, Plan, and Ask: Plan uses the SDK's
plansend mode. Ask creates a no-tools SDK agent.
- ACP session lifecycle: Supports
new,resume, andfork(best-effort) session operations - Session persistence & history replay: Stores visible history locally and replays it on resume/load
- Session listing: Lists past local sessions with optional cwd filtering and pagination
- Model listing and selection:
/modeland ACP config options use the SDK catalog. - ACP 1.4 controls: Clients that advertise boolean config support render Fast as a toggle; older clients receive a select fallback. Thinking remains a model-specific selector that maps SDK
thinking,reasoning, oreffortparameters. Aftersession/set_config_option, the adapter sendsconfig_option_updateso dependent Fast and Thinking controls appear immediately. - SDK authentication:
/login,/logout,/status,CURSOR_API_KEY, and ACP terminal authentication use Cursor SDK credentials. Browser login is stored under~/.cursor/sdk/auth.json. - Optional Yolo mode (
yolo): Disables Auto Review for unrestricted local SDK execution. - Commit and PR attribution: Honors Cursor's global
cli-config.jsonattribution flags. Project.cursor/cli.jsondoes not override them.
- Cursor SDK authentication is separate from
cursor-agentCLI authentication. Run/login,cursor-acp login, or setCURSOR_API_KEY. - The SDK exposes no interactive per-tool approval callback. ACP approval therefore retries the complete turn without Auto Review; work completed before the blocked call may be repeated.
- Auto Review reduces confirmation noise but is not a security boundary. Use sandboxing and normal least-privilege practices for untrusted workspaces.
debugmode is not exposed.
Version 0.9.0 moves prompt turns to @cursor/sdk instead of cursor-agent --print. SDK authentication is separate from Cursor CLI authentication, and Auto Review is the shipped default for new sessions.
Use ACP default_config_options with Zed versions that support ACP config defaults. The adapter still accepts legacy inline defaults and reads CURSOR_ACP_DEFAULT_MODE, CURSOR_ACP_DEFAULT_MODEL, and CURSOR_ACP_DEFAULT_THINKING as fallbacks.
Older builds accepted bypassPermissions and autoRunAllCommands as synonyms for yolo in default_mode and in /mode. Those names are no longer accepted—use yolo (or pick Yolo in the client).
- What it is: Cursor SDK Smart Auto Review, enabled with
local.autoReview: trueon local agents. - Default: The adapter starts in
auto-reviewunless the client or environment explicitly chooses another mode. Legacydefaultvalues normalize toauto-review. - Remaining prompts: Calls the classifier stops are offered to the ACP client. Choosing “Always allow” upgrades the session to Yolo.
- What it is not: Not Yolo, Bugbot/PR review, or a sandbox/security boundary.
- What it does: Creates/resumes the local SDK agent with Auto Review disabled. This is the SDK's headless “run everything” behavior.
- Configuration: Set
default_config_options.modetoyoloor choose Yolo in the mode picker. Do not use removed aliases such asbypassPermissionsorautoRunAllCommands.
The same notice is linked from docs/breaking-changes.md.
| Command | Description |
|---|---|
/help | Show available commands |
/model | Switch or display the current model |
/mode | Switch or display the current mode |
/status | Show authentication and session status |
/login | Authenticate with Cursor |
/logout | Sign out of Cursor |
Project and user slash commands/skills discovered by the adapter are added to the ACP command list.
nub install
nub run buildThis compiles the project and produces the cursor-acp binary entry point at ./dist/index.js. nub install also runs a guarded postinstall patch so the pinned @cursor/sdk honors global commit and PR attribution settings. If Cursor changes that runtime code, installation fails instead of silently ignoring the settings.
For Zed to find the cursor-acp command, it needs to be available on your PATH. Choose one of the following options:
Option A — npm link (recommended)
Run npm link inside the repository root to symlink the cursor-acp binary globally:
npm linkOption B — manual symlink
Create a symlink manually:
ln -s "$(pwd)/dist/index.js" /usr/local/bin/cursor-acpVerify the binary is accessible:
which cursor-acpnub run startOr use the binary:
cursor-acpAuthenticate the Cursor SDK in a browser before starting a session:
cursor-acp loginRun cursor-acp logout to remove the stored SDK credential. If CURSOR_API_KEY is set, it remains active until removed from the adapter process environment.
Open your Zed settings file via the Command Palette (zed: open settings) and add a custom agent server entry under agent_servers:
{
"agent_servers": {
"Cursor": {
"type": "custom",
"command": "cursor-acp",
"args": [],
"default_config_options": {
"mode": "auto-review",
"fast": false
}
}
}
}If cursor-acp is not on your PATH, use the full absolute path to the entry point instead:
{
"agent_servers": {
"Cursor": {
"type": "custom",
"command": "/absolute/path/to/cursor-acp/dist/index.js",
"args": [],
"default_config_options": {
"mode": "auto-review",
"fast": false
}
}
}
}Zed versions with ACP config defaults apply initial controls from default_config_options; they may send these as follow-up session/set_config_option requests after creating the session. The adapter then sends a config_option_update so dependent Fast and Thinking controls appear immediately. When the client also advertises boolean config support, Fast appears as a native toggle in the agent panel:
{
"agent_servers": {
"Cursor": {
"type": "custom",
"command": "cursor-acp",
"args": [],
"default_config_options": {
"mode": "auto-review",
"model": "composer-2.5",
"fast": false,
"thinking": "high"
}
}
}
}mode— one ofauto-review,yolo,plan, orask. Omit it to use the shippedauto-reviewdefault; legacydefaultvalues still work as an alias.model— optional canonical model ID from the Cursor SDK catalog.fast— boolean toggle when the selected model advertises afastparameter.thinking— ACP config id for the selected model'sthinking,reasoning, oreffortparameter. Values and the picker label come from the SDK catalog (for examplenone/low/medium/high/xhigh/max, or Effortlow/high).
Legacy Zed fields (default_mode, default_model, default_fast, and default_thinking) remain accepted for compatibility. There is no adapter-specific config file. Environment fallbacks are CURSOR_ACP_DEFAULT_MODE, CURSOR_ACP_DEFAULT_MODEL, and CURSOR_ACP_DEFAULT_THINKING.
The mode picker lists Auto-review, Yolo, Ask, and Plan. Model-specific Fast and Thinking controls appear when the SDK catalog advertises fast, thinking, reasoning, or effort parameters. The ACP config id stays thinking even when the SDK parameter is reasoning or effort; the picker label follows the catalog (for example Effort). Clients that advertise boolean config support receive Fast as a toggle; other clients receive an On/Off select.
- Open the Agent Panel with
Cmd+?(macOS) orCtrl+?(Linux) - Click the
+button in the top right and select Cursor - On first use, select the Cursor SDK login method or run
/login - Auto Review is already the default. Choose Yolo only when you explicitly want unrestricted local tool execution.
You can also bind a keyboard shortcut to quickly open a new Cursor thread by adding the following to your keymap.json (open via zed: open keymap file):
[
{
"bindings": {
"cmd-alt-u": ["agent::NewExternalAgentThread", { "agent": "Cursor" }]
}
}
]If something isn't working, open Zed's Command Palette and run dev: open acp logs to inspect the ACP messages being sent between Zed and cursor-acp.
Set CURSOR_ACP_DEBUG_LOG=1 if you also want the adapter to write extra debug traces to ~/.cursor-acp/logs/debug.log.
nub run devnub run test# Run tests in watch mode
nub run test:run # Run tests oncenub run lint # Check with Oxlint
nub run lint:fix # Apply safe Oxlint fixes
nub run format # Format with Oxfmt
nub run format:check # Verify formatting without writing files
nub run check # Run lint and format checksOxlint and Oxfmt use their repository-level configurations. Source indentation uses tabs rendered at a width of four spaces, as configured in .oxfmtrc.json and .editorconfig.
- See Breaking changes (SDK backend and Auto Review default) when upgrading from the CLI-backed adapter.
- Commit and PR attribution is read only from the global Cursor CLI config; project
.cursor/cli.jsonattribution is ignored. auto-review,yolo,ask, andplanare the advertised modesdefault,acceptEdits,agent, andautoRevieware accepted as compatibility aliases forauto-review. For Yolo, useyolo—bypassPermissionsandautoRunAllCommandsare no longer accepted (see Legacy Yolo mode name aliases removed)debugis not exposed- SDK user settings are loaded from Cursor's user setting source.
src/
├── index.ts # CLI entry point
├── lib.ts # Library exports
├── cursor-acp-agent.ts # ACP lifecycle, persistence, and permissions
├── cursor-runner.ts # Prompt execution interface
├── cursor-sdk-runner.ts # Cursor SDK implementation
├── model-id.ts # SDK model ids, thinking/reasoning/effort, and fast variants
├── cursor-cli-config.ts # Global CLI attribution and config paths
├── cursor-sdk-event-adapter.ts # SDK-to-ACP event compatibility
├── prompt-conversion.ts # ACP text, context, and image conversion
├── auth.ts # Cursor SDK authentication
├── settings.ts # Mode ids and normalization helpers
├── session-storage.ts # Session persistence and history replay
├── slash-commands.ts # Slash command handlers
├── tools.ts # Tool definitions
├── utils.ts # Utility functions
└── tests/ # Test files
scripts/
└── patch-cursor-sdk-attribution.mjs # Postinstall SDK attribution patch
The adapter uses local Cursor SDK agents and keeps wrapper-level compatibility logic for ACP resume, list, and visible-history replay.
cursor-acp honors Cursor's global CLI attribution settings. Defaults match the SDK: both commit trailers and PR attribution are enabled. To disable them, put this in ~/.cursor/cli-config.json (or $CURSOR_CONFIG_DIR/cli-config.json):
{
"attribution": {
"attributeCommitsToAgent": false,
"attributePRsToAgent": false
}
}Attribution is global-only; Cursor project .cursor/cli.json files support permissions, not attribution.
Sessions are persisted under ~/.cursor-acp/sessions/ (or $CURSOR_ACP_CONFIG_DIR/sessions/ if set). Each project has an encoded subdirectory; session history is stored as JSONL files with user and assistant messages for resume and replay.
- Zed
- Node.js 22.13+ (required by the SDK's default local SQLite store)
- Nub (for package management and scripts)
- Valid Cursor subscription
This project is based on claude-code-acp by Zed Industries. Their work on the original Claude Code ACP adapter provided the architectural patterns and protocol implementation that made this project possible.
Copyright 2026 Raphael Lüthy. Licensed under the Apache License, Version 2.0. See LICENSE for the full license text. Third-party attributions are listed in NOTICE.