Python client for the Cursor CLI Agent Client Protocol (ACP) / agent acp
Project description
cursor-agent
Standalone Python client for Cursor CLI in ACP mode (agent acp): JSON-RPC over stdio to drive Composer from your own code — similar in spirit to anthropic or google-genai, but talking to the local agent binary instead of a hosted HTTP API.
Requirements
- Python 3.11+
- Cursor CLI with
agentonPATH(often~/.local/bin) CURSOR_API_KEYorCURSOR_AUTH_TOKENin the environment (or pass explicitly). From a checkout of this repo, you can pass the key inline (replacexwith your real key):
CURSOR_API_KEY=x python examples/quickstart.py
Install
From this monorepo (path dependency):
uv add "cursor-agent @ file:./packages/cursor-agent"
Or from PyPI:
pip install cursor-acp
The import name is still cursor_agent (package directory unchanged).
Quick start
Run the included example from the repo (after an editable install):
pip install -e .
CURSOR_API_KEY=x python examples/quickstart.py
Optional prompt and working directory:
CURSOR_API_KEY=x python examples/quickstart.py --cwd /path/to/project "What does this codebase do?"
Equivalent minimal script:
import asyncio
from pathlib import Path
from cursor_agent import CursorAgent
async def main():
agent = CursorAgent(cwd=Path("."))
result = await agent.prompt("Summarize this repository")
print(result.text)
print(result.completed_tool_rounds)
await agent.shutdown()
asyncio.run(main())
Hooks
All extension points live in a single CursorAgentHooks dataclass — pass only
the hooks you need:
from cursor_agent import CursorAgent, CursorAgentHooks
hooks = CursorAgentHooks(
before_process_start=my_setup, # async (cwd: Path) -> None
wrap_command=my_sandbox_wrapper, # async (argv, cwd_str) -> str
on_opaque_tool_call=my_mcp_bridge, # async (conversation_id, on_event) -> None
)
agent = CursorAgent(cwd=Path("."), hooks=hooks)
before_process_start— called with the working directory before the ACP subprocess spawns (e.g. write config files).wrap_command— transformsargv+ working-directory string into a shell command (e.g. sandbox wrapping). Defaults toshlex.join(argv).on_opaque_tool_call— invoked when the ACP stream reports a tool call the package cannot handle natively (title starts with"MCP:"). Receives(conversation_id, on_event)so the caller can bridge the call and emit real events.
License
MIT
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 cursor_acp-0.1.1.tar.gz.
File metadata
- Download URL: cursor_acp-0.1.1.tar.gz
- Upload date:
- Size: 10.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8cb7a6398a348baec671bd13935a7932a6c96e1c1d700200884abee2fe2cb353
|
|
| MD5 |
c6d8ad6180b8f50035d0f855d4ff74f2
|
|
| BLAKE2b-256 |
1c9bf5c7054ede28304f2ae4bd6fa37504e4317e57b8692610fdcdcfe49b23ea
|
File details
Details for the file cursor_acp-0.1.1-py3-none-any.whl.
File metadata
- Download URL: cursor_acp-0.1.1-py3-none-any.whl
- Upload date:
- Size: 12.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62fdebefcd6fb6d4b3bd2a67a4ee4f7f6be4a4029eb85d926da3f4b966214304
|
|
| MD5 |
30e444b8d3303247228b1787ada5f731
|
|
| BLAKE2b-256 |
2dd2ee811967230a5b82888b00e88521192b27afd9adefcd70e62a2d7ea400a7
|