Python library for Cursor Agent Client Protocol (ACP) integration.
Project description
pycursor-acp
Python async library for driving Cursor CLI ACP mode (agent acp): JSON-RPC 2.0 over stdio, aligned with the Agent Client Protocol.
Supported Python: 3.11 or newer (requires-python = ">=3.11").
PyPI name vs other projects
The distribution on PyPI for this repo is pycursor-acp. The importable Python package is cursor_acp (underscore).
The unrelated PyPI project cursor-acp (import cursor_agent, different API) is not this library. Install with pip install pycursor-acp for this codebase.
Prerequisites
-
Cursor CLI with ACP — the
agentexecutable from Cursor’s CLI distribution must be installed and discoverable onPATH(often under~/.local/bin). This library spawns:- executable:
agent - arguments:
acp
Official behavior, transport, and RPC flow are documented at Cursor CLI: ACP.
- executable:
-
Python 3.11+
Installation
From PyPI:
pip install pycursor-acp
uv pip install pycursor-acp
From this repository:
pip install "pycursor-acp @ git+https://github.com/Marcelo-Barella/cursor-acp.git@main"
uv pip install "pycursor-acp @ git+https://github.com/Marcelo-Barella/cursor-acp.git@main"
Editable install from a local clone:
pip install -e .
uv pip install -e .
Import vs distribution: after installation, import cursor_acp. The published wheel/sdist name is pycursor-acp.
Minimal async example
import asyncio
from pathlib import Path
from cursor_acp import CursorAcpClient
async def main() -> None:
your_key = "…" # application-supplied; injected only into the CLI child env by the library
async with CursorAcpClient(api_key=your_key, cwd=Path(".")) as client:
result = await client.prompt("Say hello in one line.")
print(result["stopReason"])
asyncio.run(main())
CursorAcpClient requires a non-empty api_key string; the library does not read secrets from the parent process environment for session auth.
Credentials and environment variables (official names)
Per Cursor CLI ACP authentication (verified against this implementation’s subprocess env builder in cursor_acp.env), the exact environment variable names recognized for CLI auth are:
| Variable | Role (per Cursor docs) |
|---|---|
CURSOR_API_KEY |
API key; CLI also accepts --api-key |
CURSOR_AUTH_TOKEN |
Auth token; CLI also accepts --auth-token |
What this library does: build_cursor_acp_subprocess_environ copies a snapshot of the parent environment (or a caller-supplied source mapping), removes both CURSOR_API_KEY and CURSOR_AUTH_TOKEN so ambient credentials cannot silently override the explicit api_key argument, then sets CURSOR_API_KEY in the child environment to the validated constructor api_key. It does not mutate os.environ in the parent process.
Reproducibility: record cursor_acp.__version__ and the Cursor CLI build reported by your installation (for example agent --version when supported) alongside any bug reports; this repository does not pin a single Cursor CLI version—behavior should track https://cursor.com/docs/cli/acp and your installed binary.
Security
- Child-only injection: API keys are passed to the
agent acpsubprocess via that process’s environment dict. Do not rely on (or implement) parent-processos.environmutation to “inject” credentials for this client. - No logging of secrets: do not log API keys or tokens; avoid putting secrets in exception messages or user-visible
repr()output. Library errors follow that boundary (seecursor_acp.exceptions). - Explicit
api_key: supply credentials from your app’s secret store or config; treat them like any other high-entropy secret.
Implementation strategy
Chosen fork: (A) — Prefer contributing upstream to github.com/azgo14/cursor-agent while keeping pycursor-acp contracts: constructor-required api_key, subprocess-isolated environment (no parent env mutation), and documentation / tests parity with Cursor’s official ACP docs and verified CLI behavior.
Rationale (brief): The protocol and transport are specified by Cursor’s CLI and ACP documentation; this package uses a distinct PyPI name (pycursor-acp) so installs are unambiguous vs the separate cursor-acp distribution.
Upstream reference (not a shipping name): use github.com/azgo14/cursor-agent as a comparison and contribution target when proposing protocol or packaging changes; it is not the import path for this tree.
Development
pip install -e ".[dev]"
Lint and format: this repository uses Ruff for lint (E,F,I,UP,W) and formatting.
python3 -m ruff check .
python3 -m ruff format --check .
Static typing: checked with mypy in strict mode on the packaged sources under src/.
python3 -m mypy src
Tests: CI and local default runs omit integration tests (marked integration; require real Cursor CLI and credentials).
python3 -m pytest -m "not integration"
To include integration gates when you have agent on PATH and credentials, see CURSOR_ACP_INTEGRATION / CURSOR_API_KEY in pyproject.toml markers.
See CHANGELOG.md for release notes.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pycursor_acp-0.1.0.tar.gz.
File metadata
- Download URL: pycursor_acp-0.1.0.tar.gz
- Upload date:
- Size: 17.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88d8fd9be347e98ca28992a51f0ceac6f7e0a5e42a34aa9041d2d0807f40ddd8
|
|
| MD5 |
1f4041db08b09da0f505b8a8c0d7de78
|
|
| BLAKE2b-256 |
cdedf5cd153963d9e5fc1366da6918fc564edef5d8dd6d1aa3813b428df044e1
|
File details
Details for the file pycursor_acp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pycursor_acp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68e0a84e308f1e2f1eccb1bc473b937264a7aba607fed72b7a02cc3a7c0a6b55
|
|
| MD5 |
6220122b43e3e884032c43cc94bb939e
|
|
| BLAKE2b-256 |
d9a1bd27a7ba90b81cc4f4e14cbbf0500bc9ff99eb89d91b8133a0226f764b07
|