> ## Documentation Index
> Fetch the complete documentation index at: https://arize-ax.mintlify.site/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Cursor

> Trace Cursor IDE and CLI conversations, shell commands, MCP tools, and file operations in Arize AX using the Arize Coding Harness Tracing.

> Trace Cursor IDE and CLI conversations, shell commands, MCP tools, and file operations in Arize AX for full observability.

[Cursor](https://cursor.com/) is an AI code editor for agentic software development. The [Arize Coding Harness Tracing](https://github.com/Arize-ai/coding-harness-tracing) instruments Cursor IDE and CLI hook events and exports [OpenInference](https://github.com/Arize-ai/openinference) spans to Arize AX. A Cursor conversation maps to a session, and each message turn maps to a trace.

## Launch Arize AX

To get started, sign up for a free [Arize AX account](https://app.arize.com/auth/join) and get your Space ID and API Key:

1. Log in at [app.arize.com](https://app.arize.com)
2. Click **Settings** and copy the **Space ID**
3. Open the **API Keys** tab and create or copy an API key

## Install

### Curl installer

**macOS / Linux:**

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
curl -sSL https://raw.githubusercontent.com/Arize-ai/coding-harness-tracing/main/install.sh | bash -s -- cursor
```

**Windows (PowerShell):**

```powershell theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
iwr -useb https://raw.githubusercontent.com/Arize-ai/coding-harness-tracing/main/install.bat -OutFile $env:TEMP\install.bat
& $env:TEMP\install.bat cursor
```

### Local clone

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
git clone https://github.com/Arize-ai/coding-harness-tracing.git
cd coding-harness-tracing
./install.sh cursor        # macOS / Linux
install.bat cursor         # Windows
```

The installer writes credentials to `~/.arize/harness/config.json` and registers the hooks in `~/.cursor/hooks.json`. Both Cursor IDE and Cursor CLI sessions are instrumented from the same configuration.

### Cursor plugin

Cursor 2.5 and later can install tracing as a marketplace plugin instead. The `cursor-tracing` plugin registers every hook event automatically, then run the bundled `manage-cursor-tracing` skill once to write backend credentials to `~/.arize/harness/config.json`. See [Cursor IDE Tracing](https://github.com/Arize-ai/coding-harness-tracing/blob/main/tracing/cursor/README.md#plugin-install) for the full flow.

The installer runs a short interactive setup. Every harness in the Arize Coding Harness Tracing repo asks the same questions, in the same order.

### Setup walkthrough

#### 1. Backend selection

Choose where spans are sent:

* **Phoenix** — your own [Phoenix](https://github.com/Arize-ai/phoenix) instance.
* **Arize AX** — the hosted Arize platform.

#### 2. Credentials

The prompts depend on the backend you picked.

<Tabs>
  <Tab title="Arize AX">
    * **API key** — create one on the [API keys](/docs/ax/security-and-settings/api-keys) tab.
    * **Space ID** — shown on the same settings tab as your API keys.
    * **OTLP endpoint** — defaults to `otlp.arize.com:443`. Override it only for a hosted or dedicated instance.
  </Tab>

  <Tab title="Phoenix">
    * **Endpoint** — defaults to `http://localhost:6006`.
    * **API key** — optional. Leave it blank when Phoenix runs without auth.
  </Tab>
</Tabs>

If you have already configured another harness against the same backend, the installer offers a copy-from menu so you can reuse those credentials instead of retyping them.

#### 3. Project name

The project that this harness's spans are grouped under. Defaults to the harness name.

#### 4. User ID (optional)

A free-form identifier attached to every span as `user.id`. Useful when teammates share one backend. Leave it blank to skip.

#### 5. Content logging

Three `[Y/n]` opt-outs that apply to **every** harness, not only the one you are installing:

* Log user prompts?
* Log what tools were asked to do (commands, file paths, URLs)?
* Log what tools returned (file contents, command output)?

You are asked these only the first time you install any harness. Later installs reuse the existing `logging` block in `~/.arize/harness/config.json`, which you can edit at any time.

### Install flags

| Flag                      | Effect                                                                                                                                   |
| :------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------- |
| `--with-skills`           | Symlink this harness's management skill into `.agents/skills/`, so a coding agent in the workspace can manage the tracing config for you |
| `--non-interactive`, `-y` | Ask nothing, and read every value from the environment instead                                                                           |
| `--branch NAME`           | Install from a specific branch instead of `main`                                                                                         |
| `--wheel-dir DIR`         | Install from local wheels in `DIR`: no network access and no remote code execution                                                       |

### Non-interactive install

Pass `--non-interactive` (or `-y`) to skip every prompt above and take each value from the environment instead. Nothing is asked, and a missing required value is an error rather than a prompt, which makes this the mode to use from a script, from CI, or when a coding agent is driving the install itself.

Values come from the environment, or from a dotenv file named explicitly with `ARIZE_ENV_FILE`. Naming a file keeps the API key out of the command line and your shell history.

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
ARIZE_ENV_FILE=~/.arize/onboarding.env ./install.sh <harness> --non-interactive
```

| Variable                              | Default                 | Description                                                                                                                                                                                                                           |
| :------------------------------------ | :---------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ARIZE_API_KEY` + `ARIZE_SPACE_ID`    | —                       | Arize AX credentials. Both are required for the Arize backend.                                                                                                                                                                        |
| `PHOENIX_ENDPOINT`, `PHOENIX_API_KEY` | `http://localhost:6006` | Phoenix endpoint and optional API key.                                                                                                                                                                                                |
| `ARIZE_BACKEND`                       | inferred                | `arize` or `phoenix`. A space ID implies Arize AX and a Phoenix endpoint implies Phoenix. When both are present the install stops and asks you to set this rather than guess, since guessing would discard one backend's credentials. |
| `ARIZE_PROJECT_NAME`                  | harness name            | Project that spans are grouped under. **Read from the dotenv file only.** An installed harness exports its own project name into every session, so an inherited environment value is ignored here.                                    |
| `ARIZE_USER_ID`                       | —                       | Optional `user.id` on every span.                                                                                                                                                                                                     |
| `ARIZE_OTLP_ENDPOINT`                 | `otlp.arize.com:443`    | Override for a hosted or dedicated Arize instance.                                                                                                                                                                                    |
| `ARIZE_LOG_PROMPTS`                   | `false`                 | Set `true` to capture prompt text.                                                                                                                                                                                                    |
| `ARIZE_LOG_TOOL_DETAILS`              | `false`                 | Set `true` to capture tool commands, file paths, and URLs.                                                                                                                                                                            |
| `ARIZE_LOG_TOOL_CONTENT`              | `false`                 | Set `true` to capture tool output.                                                                                                                                                                                                    |
| `ARIZE_ENV_FILE`                      | —                       | Dotenv file to read. No file is read unless this is set, and a path that is not a readable file is an error rather than a fallback to the environment.                                                                                |
| `ARIZE_WHEEL_DIR`                     | —                       | Same as `--wheel-dir`. Install from local wheels instead of downloading the repo.                                                                                                                                                     |

<Warning>
  A named `ARIZE_ENV_FILE` outranks the environment, and there is deliberately **no automatic `./.env` search**. Reading the working directory would let a cloned repository's dotenv choose `ARIZE_OTLP_ENDPOINT` or `PHOENIX_ENDPOINT` while your real credentials came from the environment, installing a config that ships spans and a bearer API key to an endpoint the repo picked, for every later session on that machine. Name the file you mean.
</Warning>

<Note>
  Content logging is **off by default** in this mode, unlike the interactive wizard where each question defaults to yes. A `[Y/n]` default is a person declining to change an answer they were shown; the same default unattended would capture prompts, commands, and file contents that nobody agreed to. Set the `ARIZE_LOG_*` variables you want to `true`.
</Note>

The API key is never echoed. The installer reports only that it found one and where it came from, and every resolved value is reported with its source, so a wrong-credentials install stays diagnosable:

```
[arize] Backend: Arize AX at otlp.arize.com:443 (from default)
[arize]   space ID: my-space (from /path/to/.env)
[arize]   API key: found (from /path/to/.env)
[arize] Project name: codex (from default)
```

### Check what's installed

`status` reports which harnesses are configured and whether their hooks are actually wired into each harness's own settings file. Both have to be true for traces to appear.

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
./install.sh status
./install.sh status --json    # machine-readable
```

`hooks: NOT registered` means credentials are saved but the harness was never wired up, or something removed the hooks. Re-run the install for that harness.

Use `--json` from a script or a coding agent to gate on the exit code without parsing output: `0` means every configured harness is wired up, `1` means nothing is configured, and `2` means at least one harness's hooks are missing. The payload contains no secrets — an API key appears only as `"api_key_present": true` — so it is safe to paste into a bug report.

### Keep it up to date

`update` pulls the latest code and re-registers every harness already in `config.json`.

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
./install.sh update
```

Re-registering runs each harness's installer, so in a terminal it still asks for each project name. With no terminal to answer on, in CI or a cron job, it takes the stored values instead of failing: credentials are not re-read on that path, and the project name keeps whatever is in `config.json`.

## Configuration

Credentials live in `~/.arize/harness/config.json`. Environment variables override values in `config.json` and can be set in your shell profile so they apply to Cursor IDE and Cursor CLI sessions.

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
export ARIZE_API_KEY="<your-api-key>"
export ARIZE_SPACE_ID="<your-space-id>"
export ARIZE_PROJECT_NAME="cursor"
export ARIZE_TRACE_ENABLED="true"
```

### Redaction controls

Each `ARIZE_LOG_*` flag accepts `"true"` or `"false"` and defaults to `"true"`. Set to `"false"` to opt out per category:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
export ARIZE_LOG_PROMPTS="false"
export ARIZE_LOG_TOOL_DETAILS="false"
export ARIZE_LOG_TOOL_CONTENT="false"
```

| Flag                     | Redacts                                                             |
| :----------------------- | :------------------------------------------------------------------ |
| `ARIZE_LOG_PROMPTS`      | User prompt and assistant response text                             |
| `ARIZE_LOG_TOOL_DETAILS` | Tool names and arguments                                            |
| `ARIZE_LOG_TOOL_CONTENT` | Tool call output content (shell output, MCP results, file contents) |

## Observe

Once tracing is enabled, Cursor activity is streamed to Arize AX. You'll see:

* **Session grouping** by `conversation_id` for each Cursor conversation
* **Turn traces** by `generation_id` for each message turn
* **User prompt spans** for submitted prompts
* **Agent response spans** with model output
* **Agent thinking spans** when Cursor emits reasoning/thought events
* **Shell spans** with command input and command output merged into a single tool span
* **MCP spans** named `MCP: {tool}` with tool input and result
* **File read and edit spans** for file operations, including tab reads and edits

The default project name is `cursor` unless you set `ARIZE_PROJECT_NAME`.

### Hooks Captured

Cursor IDE fires the full set of hooks. Cursor CLI fires a subset (no prompt/response, MCP, or file-read events).

| Hook                   | IDE | CLI | Captured Data                                            |
| :--------------------- | :-: | :-: | :------------------------------------------------------- |
| `sessionStart`         |  ✓  |  ✓  | Session boundary, state init                             |
| `sessionEnd`           |  ✓  |  ✓  | Session teardown                                         |
| `beforeSubmitPrompt`   |  ✓  |     | User prompt span for the turn root                       |
| `afterAgentResponse`   |  ✓  |     | Agent response text and model metadata                   |
| `afterAgentThought`    |  ✓  |     | Agent thinking output and duration                       |
| `beforeShellExecution` |  ✓  |  ✓  | Shell command state used for merge                       |
| `afterShellExecution`  |  ✓  |  ✓  | One `Shell` span with command, cwd, output, and duration |
| `beforeMCPExecution`   |  ✓  |     | MCP tool state used for merge                            |
| `afterMCPExecution`    |  ✓  |     | One `MCP: {tool}` span with input, result, and duration  |
| `beforeReadFile`       |  ✓  |     | Read file span                                           |
| `afterFileEdit`        |  ✓  |  ✓  | File edit span                                           |
| `beforeTabFileRead`    |  ✓  |     | Tab read file span                                       |
| `afterTabFileEdit`     |  ✓  |     | Tab file edit span                                       |
| `postToolUse`          |  ✓  |  ✓  | Generic tool span for non-shell, non-MCP tools           |
| `stop`                 |  ✓  |  ✓  | Stop span and state cleanup for the turn                 |

## How Shell and MCP Merge Works

Cursor emits separate `before*` and `after*` hook events for shell commands and MCP tools. The Arize AX hooks keep a small disk-backed state entry for the `before` event, then create a single span on the corresponding `after` event. That gives you one span with both the input and the output instead of two partial spans.

On `stop`, the hook handler cleans up any saved state for that turn so the state directory does not keep growing over time.

## Reference

For the full list of environment variables, default file paths, and troubleshooting steps, see the [Cursor tracing README](https://github.com/Arize-ai/coding-harness-tracing/blob/main/tracing/cursor/README.md).

## Fail-Open Behavior

If the tracing hook errors, Cursor continues running. The hook handler always returns the permissive response Cursor expects, so tracing failures do not block the editor or agent workflow.

## Uninstall

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
curl -sSL https://raw.githubusercontent.com/Arize-ai/coding-harness-tracing/main/install.sh | bash -s -- uninstall cursor
```

## Resources

<CardGroup>
  <Card icon="github" href="https://github.com/Arize-ai/coding-harness-tracing" title="Arize Coding Harness Tracing" horizontal />

  <Card icon="github" href="https://github.com/Arize-ai/openinference" title="OpenInference" horizontal />

  <Card icon="book-open" href="https://cursor.com/" title="Cursor" horizontal />
</CardGroup>
