Install the Cursor plugin
The cardinal-cursor-plugin puts your Cursor sessions on the Agent Outcomes dashboard, matching the Claude Code and Codex CLI plugins:
- Telemetry — your Cursor sessions stream to Cardinal, attributed to engineer, branch, PR, and initiative, with per-tool activity and subagent lifecycle events.
- MCP tools — a managed
cardinalMCP server entry in~/.cursor/mcp.json, exposing whichever tools your org has integrations for. Pass--telemetry-onlyto skip this side.
Sessions in a git repo receive the initiative branch-naming convention at start, and org spend-limit policies are enforced in-session — quiet context at notify, a visible block at block. Cursor’s beforeSubmitPrompt hook has no allow-with-message channel, so warn falls back to notify (agent-only) by default; set CARDINAL_CURSOR_STRICT_WARN=1 in your environment to escalate warn to a hard block instead.
Reach out to support@cardinalhq.io for support or to ask questions not answered in our documentation.
Requirements
- Cursor with hooks (v1) support.
- Python 3.11+ on your
PATH. - A Cardinal account on
app.cardinalhq.io, or a self-hosted Cardinal UI your operator has prepared (see Connect AI clients).
1. Install
Cursor doesn’t have a plugin marketplace, so the install is a git clone + run:
git clone https://github.com/cardinalhq/cardinal-cursor-plugin.git ~/workspace/cardinal-cursor-plugin2. Connect
python3 ~/workspace/cardinal-cursor-plugin/plugins/cardinal-cursor-plugin/scripts/cardinal-connectThe connect script prints a URL like https://app.cardinalhq.io/connect?code=ABCD-EFGH. Open it in your browser, sign in if you aren’t already, pick the org to connect, and click Approve. The plugin picks up your consent within a few seconds and writes:
| File | What gets written |
|---|---|
~/.cursor/mcp.json | A managed mcpServers.cardinal entry (tagged cardinalManaged: true). |
~/.cursor/hooks.json | Managed Cardinal hook entries for sessionStart, beforeSubmitPrompt, postToolUse, preCompact, stop, and subagentStop. |
~/.cursor/cardinal.json | Non-secret connection state for status/disconnect. |
~/.cursor/cardinal-secrets.json | Your minted keys, written mode 0600. |
For self-hosted Cardinal UI, add --host:
python3 scripts/cardinal-connect --host https://ui.example.internalThen restart Cursor so it reloads the MCP and hook configuration.
3. Verify
python3 scripts/cardinal-statusYou’ll see the connected org, both endpoints, key prefixes, and a reachability probe against each side. Run a session in any git repo and it appears on the Outcomes dashboard within a few minutes.
Cloud agents
Cursor cloud agents do not load ~/.cursor/hooks.json or ~/.cursor/mcp.json — cloud VMs have no access to your home directory. To send Cardinal telemetry from cloud-agent runs, install the plugin at the project level from inside your repo:
cd path/to/your/repo
python3 /path/to/plugins/cardinal-cursor-plugin/scripts/cardinal-connect --projectThis additionally writes .cursor/mcp.json and .cursor/hooks.json at the repo root. Commit both files so cloud agents pick them up. Cursor cloud agents don’t run sessionStart (per Cursor’s hooks docs ), so the initiative-convention prompt and the decision-capture instructions don’t reach them. beforeSubmitPrompt, postToolUse, subagentStop, preCompact, and stop do run, so the spend gate and tool-level telemetry work there. PR lookups need gh signed in inside the cloud VM.
Variants
python3 scripts/cardinal-connect --telemetry-only # Outcomes dashboard only; skip the MCP tools
python3 scripts/cardinal-connect --rotate # Mint fresh keys, overwrite an existing connection
python3 scripts/cardinal-connect --project # Also install at .cursor/ for cloud-agent coverage
python3 scripts/cardinal-connect --host https://… # Point at a self-hosted Cardinal UI
python3 scripts/cardinal-connect --dry-run # Walk the consent flow, write nothingGetting attributed correctly
Sessions are attributed to an initiative by branch name: <type>/<kebab-name>, where the type prefix is one of feat, fix, refactor, infra, chore, research, or spike (for example fix/login-crash → initiative login-crash, type bugfix). Sessions on main/master/develop/trunk are treated as research/scoping work. The plugin surfaces this convention to Cursor at session start, so branches it cuts for you classify cleanly.
Pull requests and decisions
Each prompt’s branch state includes the branch’s pull request when gh is installed and signed in and a PR exists.
Decision capture is off by default. Turn it on from your own terminal:
python3 scripts/cardinal-decision onWhile it’s on, Cursor’s agent is told at session start to record each material choice with cardinal-decision record …. Since Cursor 3.6 the agent’s shell commands run in a sandbox by default, so that command only checks its arguments and prints them; Cardinal’s postToolUse hook records the decision, sends it tagged with the session, repo, branch, and PR, and tells the agent the recorded id or why nothing was recorded. If the sandbox blocks the command, approve running it outside the sandbox, or add the plugin directory to additionalReadonlyPaths in your sandbox settings. python3 scripts/cardinal-decision off turns it off.
Upgrading to 0.18.0 from an earlier version? Re-run cardinal-connect so the postToolUse hook gets its longer timeout.
Privacy
The plugin captures tool names, command lines, and file paths so Cardinal can tell which repo and service a session worked on. The contents of your prompts are never captured. Per-model-call token counts are not currently emitted from Cursor sessions (Cursor’s transcript format for that data is undocumented; see the parity spec for the open spike).
Disconnect
python3 scripts/cardinal-disconnectThis revokes your keys with Cardinal and removes the managed MCP entry, hooks, and local state at both ~/.cursor/ and (if you used --project) the repo root. Everything else in your Cursor config is left as it was.