# Cursor

> Set up Comity for Cursor with native .cursor/hooks.json hooks, .cursor/mcp.json and an always-on rule.

Cursor gets native hooks on session start, prompts, tool calls (shell, file writes, deletes) and stop, plus the Comity MCP server and an always-on rule. The same project hooks run in the Cursor IDE agent, the Cursor CLI and Cursor cloud agents.

## Set up

```sh
cd your-repo
comity init --tools cursor
git add .cursor/hooks.json .cursor/mcp.json .cursor/rules/comity.mdc
git commit -m "Set up Comity for Cursor"
```

Then:

1. Open the repo in Cursor and trust the workspace. Cursor loads project hooks only in trusted workspaces; **Customize → Hooks** lists them.
2. Run `comity login` once on each machine (see [Authentication for MCP](#authentication-for-mcp)).
3. In **Cursor Settings → MCP**, enable the `comity` server.

## What init writes

### `.cursor/hooks.json`

Shown for one event; the others differ only in event name, matcher and timeout. Your own hooks in the file are kept.

```json
{
  "version": 1,
  "hooks": {
    "preToolUse": [
      {
        "command": "comity hook --tool cursor --event PreToolUse",
        "timeout": 5,
        "matcher": "Shell|Write|Edit|Delete"
      }
    ]
  }
}
```

| Cursor event | Comity event | Matcher | Timeout (s) |
|---|---|---|---|
| `sessionStart` | `SessionStart` | | 5 |
| `beforeSubmitPrompt` | `UserPromptSubmit` | | 5 |
| `preToolUse` | `PreToolUse` | `Shell\|Write\|Edit\|Delete` | 5 |
| `postToolUse` | `PostToolUse` | `Shell\|Write\|Edit\|Delete` | 10 |
| `stop` | `Stop` | | 10 |
| `sessionEnd` | `SessionEnd` | | 10 |

The command is a plain `comity hook` call because Cursor runs hook commands through PowerShell on Windows and a POSIX shell elsewhere, and both parse it. On a machine without the CLI, the command fails with a non-zero exit code other than 2. Cursor treats that as a failed hook, logs it in the **Hooks** output channel and lets the action continue.

### `.cursor/mcp.json`

```json
{
  "mcpServers": {
    "comity": { "command": "node", "args": ["-e", "<launcher>", "mcp"] }
  }
}
```

Cursor starts `comity mcp`, a local stdio bridge to the Comity server, through a short `node -e` launcher that finds `comity` on any OS. The file is identical for every teammate, whatever OS ran `comity init`. Node must be on PATH; the CLI needs it anyway. `comity doctor` warns about `comity mcp` or `cmd /c comity mcp` entries written by an earlier init, because each works on one OS only. Rerun `comity init --tools cursor` to replace them.

### `.cursor/rules/comity.mdc`

An `alwaysApply: true` rule with Comity's coordination instructions (declare intent, check scope, answer conflicts).

## Authentication for MCP

No token is written to the repo, and `comity login` is enough: `comity mcp` and `comity hook` both use the login stored on the machine. `COMITY_TOKEN` and `COMITY_SERVER`, if set, override it.

An older entry with `"url"` and `"Bearer ${env:COMITY_TOKEN}"` still works if `COMITY_TOKEN` is exported before Cursor starts. `comity doctor` warns when it isn't, and rerunning `comity init --tools cursor` replaces it with the bridge.

## What your agent sees

- **Session start**: the briefing as `additional_context`.
- **Before a shell command, file write or delete**: a block denies the call (`permission: "deny"`) and shows Comity's reason to you and the agent. Otherwise the hook prints nothing and Cursor proceeds as usual.
- **After a tool call**: new conflicts, messages and notices as `additional_context`.
- **Prompts and pre-tool warnings**: Cursor's `beforeSubmitPrompt` and `preToolUse` can't add context. These warnings are queued and delivered after the next tool call.

## Claude Code hooks in Cursor

Cursor also runs the Claude Code hooks in `.claude/settings.json` (see [Cursor's third-party hooks docs](https://cursor.com/docs/reference/third-party-hooks)). If the repo has both, the invocation from `.claude/settings.json` steps aside whenever a Cursor `hooks.json` (repo or `~/.cursor/`) calls `comity hook`, so each event is evaluated once. Repos set up only with `comity init --tools claude_code` keep working in Cursor through that import.

## Cloud agents

Cursor cloud agents run `.cursor/hooks.json` from the repo, except `sessionStart` and `sessionEnd`. The hooks only do anything if the cloud environment has the `comity` CLI installed and `COMITY_TOKEN` set. Sessions report the `cloud` surface (`CURSOR_CODE_REMOTE=true`).

## Verify

```sh
comity doctor
```

Expect `cursor hooks  all 6 events installed (Cursor runs project hooks in trusted workspaces)` and `cursor mcp  configured in …/.cursor/mcp.json`. In Cursor, open the **Hooks** output channel and start an agent chat; the hooks should run without errors.

## Limits

- `beforeSubmitPrompt` can't add context, so prompt-time briefings arrive after the next tool call.
- The matcher uses the tool names Cursor documents for `preToolUse` (`Shell`, `Write`, `Delete`, plus `Edit`). Reads, searches and MCP calls aren't evaluated.
