CursorCliSdk

GitHub MIT License

CursorCliSdk

Elixir SDK for the Cursor Agent CLI (agent). It runs Cursor's headless stream-json mode through cli_subprocess_core, projects NDJSON into typed Elixir events, exposes synchronous and streaming APIs, and provides governed launch, MCP, model, session, and ASM integration helpers.

Documentation Menu

Features

  • Lazy streaming with CursorCliSdk.execute/2
  • One-shot text responses with CursorCliSdk.run/2
  • Typed event projection for init, assistant message, thinking, tool use, tool result, result, and error events
  • Shared Cursor parser and invocation contract from CliSubprocessCore.ProviderProfiles.Cursor
  • Governed launch validation that rejects caller command, cwd, env, API key, and execution-surface smuggling
  • Cursor command helpers for version, models, status, chat creation, sessions, and MCP commands
  • Session resume and continue helpers
  • Runtime configuration for timeouts, stderr buffering, and headless spawn staggering
  • ASM SDK lane support through agent_session_manager

Installation

CursorCliSdk 0.1.0 requires Elixir 1.19 or later.

def deps do
  [
    {:cursor_cli_sdk, "~> 0.1.0"}
  ]
end

The agent binary must be available on PATH, or pass cli_command: in standalone options. Authenticate with Cursor's CLI login flow or materialize CURSOR_API_KEY through CursorCliSdk.Options.api_key, Options.env, or a governed launch authority.

The package depends on cli_subprocess_core ~> 0.2.0. That lower package must be available before a Hex-only installation can resolve.

Authentication

Standalone callers provide credentials explicitly:

options =
  CursorCliSdk.Options.new!(
    api_key: System.fetch_env!("CURSOR_API_KEY"),
    permission_mode: :bypass
  )

The library never reads System.get_env/1 from lib/**. Application code owns environment lookup. In governed mode, credentials come from CliSubprocessCore.GovernedAuthority; caller-supplied api_key, cwd, env, cli_command, and execution_surface are rejected.

See Authentication and Governed Launch.

Quick Start

Streaming:

options = CursorCliSdk.Options.new!(permission_mode: :bypass)

CursorCliSdk.execute("Reply with exactly: OK", options)
|> Enum.each(fn event ->
  IO.inspect(event)
end)

Synchronous:

{:ok, text} =
  CursorCliSdk.run(
    "Reply with exactly: OK",
    CursorCliSdk.Options.new!(permission_mode: :bypass)
  )

Workspace placement:

options =
  CursorCliSdk.Options.new!(
    cwd: "/workspace/app",
    model: "composer-2.5-fast",
    permission_mode: :plan
  )

cwd is the only workspace field. It becomes the process cwd and Cursor's --workspace <cwd> argv pair.

Sessions:

{:ok, sessions} = CursorCliSdk.Session.list_sessions()

events =
  CursorCliSdk.Session.resume_session(
    hd(sessions).id,
    CursorCliSdk.Options.new!(permission_mode: :bypass),
    "Continue with a one-sentence summary."
  )

Enum.to_list(events)

Examples

Run the SDK-owned example suite with:

~/scripts/with_bash_secrets bash examples/run_all.sh

See Examples for the full inventory. These are direct SDK examples; ASM provider examples live in agent_session_manager/examples.

Event Types

StructMeaning
CursorCliSdk.Types.InitEventCursor system/init metadata such as session, model, and cwd
CursorCliSdk.Types.MessageEventUser or assistant message content; assistant deltas set delta?: true
CursorCliSdk.Types.ThinkingEventCursor thinking/progress text when emitted
CursorCliSdk.Types.ToolUseEventTool call name, call id, and input
CursorCliSdk.Types.ToolResultEventTool call result payload
CursorCliSdk.Types.ResultEventFinal status, stop reason, result text, usage, and timing
CursorCliSdk.Types.ErrorEventStream or CLI error projected into a typed event

Headless Invocation Contract

The canonical streaming command shape is:

agent -p --trust --output-format stream-json --stream-partial-output [options] "prompt text"

The prompt is positional. There is no --prompt flag in this SDK contract.

ASM Integration

agent_session_manager can run Cursor through either lane:

See ASM Integration.

Troubleshooting

SymptomCheck
agent not foundInstall Cursor Agent CLI or pass cli_command:
Auth failure / exit 41Confirm CLI login or materialized CURSOR_API_KEY
Immediate exit in many concurrent runsLower app concurrency or increase spawn_stagger_ms
Stream timeoutIncrease timeout_ms on CursorCliSdk.Options
No assistant text from run/2Inspect streaming events with execute/2 and stderr diagnostics