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

# Cursor plugin

> Install the Weave plugin on each machine for per-developer Cursor telemetry

The Weave Cursor plugin is a lightweight telemetry hook installed on each developer's machine. It captures per-session, per-developer activity directly from Cursor's hook events and sends it to Weave.

Unlike the [Cursor Admin API integration](/ai-tools/cursor) (which requires a **Team or Enterprise** plan and reports daily per-user totals), the plugin works on **any** Cursor plan and reports prompt-, edit-, and tool-level detail per developer.

<Note>
  The [Cursor](/ai-tools/cursor) page covers the Admin API integration (usage, costs, acceptance rates via API polling). This page covers the per-machine **Plugin**, which adds prompt-level telemetry and finer-grained activity signals, and works without an admin plan.
</Note>

## What's tracked

The plugin hooks into Cursor's agent lifecycle and reports:

* **Session activity** — session start/end, duration, model, composer mode, and whether it's a background agent
* **Prompts** — prompt submissions and (optionally) prompt text for activity classification
* **File edits** — files touched with lines added and removed
* **Shell commands** — command execution and exit codes
* **Tool & MCP calls** — tool name, inputs, results, and failures, including MCP executions
* **Subagents** — subagent start/stop, task, and message/tool-call counts
* **Agent output** — agent responses and reasoning/thoughts
* **Context compaction** — when context is compacted, with context usage %, token counts, and window size
* **Install health** — a per-machine install ping so you can confirm each developer is reporting

## What it unlocks

* **No Team/Enterprise requirement** — the Admin API is gated to paid org plans; the plugin works on any Cursor plan, including individual setups
* **Per-developer, per-session granularity** — attribute activity to individual machines and developers
* **File- and shell-level detail** — edits, line counts, and command execution the API doesn't expose
* **Context-window visibility** — track how often and when sessions hit compaction
* **Richer agent signals** — tool calls, subagents, and agent reasoning beyond API usage counts
* **[AI skills](/reports/ai-skills)** — per-session conversation scoring (planning, verification, ownership, and more) requires the plugin's session-level signals
* **Easy rollout** — a single install command per machine, with auto-update built in

## Prerequisites

* Cursor installed (the installer looks for `~/.cursor`)
* **Node.js 18 or later** on each machine
* A Weave plugin telemetry API key (created in the steps below)

## Setup

<Steps>
  <Step title="Create a plugin API key in Weave">
    Go to **Data** → **Cursor** → **Connect**, select **Weave Plugin Install**, and click **Install Weave Plugin**. If you can't open that page, open **Personal plugin setup** on the **Data** page and choose **Cursor**. Any signed-in member can click **Create my install command**. That command writes telemetry onto their own Weave account. **Revoke my install command** removes those personal commands. An admin can also click **Create API key** for a shared key that attributes by email. Weave shows the full key once.
  </Step>

  <Step title="Run the install command on each machine">
    Copy the command from the configuration modal and run it on each developer's machine.

    **macOS / Linux:**

    ```bash theme={null}
    curl -fsSL 'https://app.workweave.ai/api/cursor/plugin/install.sh' | bash -s -- \
      --token 'YOUR_TOKEN' --endpoint 'YOUR_ENDPOINT'
    ```

    **Windows (PowerShell):**

    ```powershell theme={null}
    $env:WEAVE_TOKEN='YOUR_TOKEN'; $env:WEAVE_ENDPOINT='YOUR_ENDPOINT'; iwr -useb 'https://app.workweave.ai/api/cursor/plugin/install.ps1' | iex
    ```

    To route telemetry through your redacting OpenTelemetry Collector, choose
    **Through an OpenTelemetry Collector** in the configuration modal. The
    generated command sets `--telemetry-mode collector` and the collector URL
    for you. The equivalent shell form is:

    ```bash theme={null}
    curl -fsSL 'https://app.workweave.ai/api/cursor/plugin/install.sh' | bash -s -- \
      --token 'YOUR_TOKEN' --endpoint 'YOUR_ENDPOINT' \
      --telemetry-mode collector --collector-endpoint 'http://127.0.0.1:4318'
    ```

    Remote collectors must use HTTPS. Redact prompt and tool content in the
    collector, but preserve the `weave.token` resource attribute so Weave can
    associate the records with the organization.

    The installer verifies your token, downloads `weave-telemetry.js` to `~/.weave/cursor-plugin/hooks/`, writes config to `~/.weave/cursor-plugin.json`, and merges Weave hooks into `~/.cursor/hooks.json`. It then fires an install ping. Direct mode confirms that Weave accepted it; collector mode confirms only collector receipt, so check the collector's Weave exporter for downstream delivery.
  </Step>

  <Step title="Restart Cursor">
    Quit Cursor completely and reopen it for the hooks to take effect, then run a session and confirm activity appears in Weave.
  </Step>
</Steps>

The plugin **auto-updates**: when Weave ships a new version, installed plugins pick it up automatically, so you don't need to re-run the installer on every release.

### Content settings

Five content categories control what the plugin sends. They are the same set the [Claude Code plugin](/ai-tools/claude-code-plugin) and [Codex plugin](/ai-tools/codex-plugin) use. The install command Weave generates already includes your organization's **Telemetry content retention** floor. Members can deny more categories, but can't turn back on a category the organization denies.

| Category | Covers | Install flag |
| - | - | - |
| `prompt_bodies` | Text of the prompts you send to Cursor | `--prompt-bodies` |
| `agent_messages` | Agent replies and reasoning | `--agent-messages` |
| `tool_io` | Tool and MCP inputs, results, shell commands, and error messages | `--tool-io` |
| `file_paths` | Workspace roots, working directory, and edited file paths | `--file-paths` |
| `git_context` | Branch name and repository remote | `--git-context` |

Pass `false` to deny a category, for example `--tool-io false`. `--privacy-mode true` denies all five at once. On Windows, set `WEAVE_PRIVACY_MODE`, `WEAVE_PROMPT_BODIES`, `WEAVE_AGENT_MESSAGES`, `WEAVE_TOOL_IO`, `WEAVE_FILE_PATHS`, or `WEAVE_GIT_CONTEXT` before running install.ps1.

The installer writes these choices to `~/.weave/cursor-plugin.json`. You can edit the file later; the hook reads it on every event:

```json theme={null}
{
  "privacy_mode": false,
  "content_policy": {
    "prompt_bodies": true,
    "agent_messages": true,
    "tool_io": true,
    "file_paths": true,
    "git_context": true
  }
}
```

`"privacy_mode": true` overrides `content_policy` and denies every category. Setting `WEAVE_PRIVACY_MODE=true` in the environment Cursor runs in does the same.

Some reports need specific categories:

* **Agent autonomy** and other prompt-pattern metrics need `prompt_bodies`. Weave classifies each prompt from its text, and leaves out sessions with no classified prompt.
* **[AI skills](/reports/ai-skills)** conversation scoring needs `prompt_bodies`. It also uses `agent_messages`: without reply text, Weave scores a session only from its tool calls, and turns where the agent only replied in text add no evidence.
* **Skill usage** records typed slash commands under any setting.

### Fleet / MDM rollout

For large teams, pre-deploy `~/.weave/cursor-plugin.json` (with the token and endpoint) via your MDM, then run the install command without arguments — it reuses the existing config. The installer is idempotent: re-running it updates the hook command and skips events that are already wired up.

On macOS and Linux, the installer must run **as the logged-in user**, not as root. MDM tools (Jamf, Kandji, Intune, Fleet, Addigy) run scripts as `root` in a minimal environment where `$HOME` is unset and the user's `node` isn't on `PATH`, so a root-context run either fails outright or installs the hooks into the wrong account. If your MDM has a "run as current user" (user-context) option, use it. Otherwise, wrap the install command so it drops into the console user's session:

```bash theme={null}
#!/bin/bash
set -euo pipefail

# The actual GUI-logged-in user (not root)
consoleUser=$(/usr/bin/stat -f%Su /dev/console)
if [ -z "$consoleUser" ] || [ "$consoleUser" = "root" ] || [ "$consoleUser" = "loginwindow" ]; then
  echo "No console user logged in; skipping."
  exit 0
fi

# Run the installer as that user, in a login shell so HOME and PATH (nvm/Homebrew) are populated
/usr/bin/sudo -u "$consoleUser" -i /bin/bash -c '
  export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"
  curl -fsSL "https://app.workweave.ai/api/cursor/plugin/install.sh" | bash -s --
'
```

This reuses the pre-deployed `~/.weave/cursor-plugin.json`. If you don't pre-deploy it, pass `--token` and `--endpoint` (plus any content flags such as `--privacy-mode`) to the install command instead; passing a token rewrites the config file, so don't combine it with a pre-deployed one.

Node.js 18 or later must be installed for the target user.

## Uninstall

Quit Cursor completely, then run the script for the environment where the plugin was installed. It needs Node.js 18 or later. The script backs up `hooks.json` under a unique name, removes Weave hooks that point at `~/.weave/cursor-plugin/`, preserves the original `hooks.json` permissions, and deletes `~/.weave/cursor-plugin/` and `~/.weave/cursor-plugin.json`.

Windows Cursor uses the PowerShell script, including when your projects live in WSL. Run the shell script inside WSL only if you installed the plugin in that Linux environment.

**macOS / Linux** (`cursor-plugin-uninstall.sh`):

```bash theme={null}
#!/usr/bin/env bash
set -euo pipefail

hooks_path="$HOME/.cursor/hooks.json"

if [[ -f "$hooks_path" ]]; then
  backup_path="$(mktemp "$hooks_path.weave-backup-$(date +%Y%m%d%H%M%S)-XXXXXX")"
  cp -p "$hooks_path" "$backup_path"

  node - "$hooks_path" <<'NODE'
const fs = require("fs");
const hooksPath = process.argv[2];
const hooksConfig = JSON.parse(fs.readFileSync(hooksPath, "utf8"));
const hooksMode = fs.statSync(hooksPath).mode;

const isWeaveCursorHook = (hook) => {
  const command = String(hook.command || "");
  return command.includes("/.weave/cursor-plugin/") ||
    command.includes("\\.weave\\cursor-plugin\\");
};

for (const event of Object.keys(hooksConfig.hooks || {})) {
  if (!Array.isArray(hooksConfig.hooks[event])) continue;
  hooksConfig.hooks[event] = hooksConfig.hooks[event].filter(
    hook => !isWeaveCursorHook(hook)
  );
}

const temporaryPath = hooksPath + ".weave-tmp";
fs.writeFileSync(
  temporaryPath,
  JSON.stringify(hooksConfig, null, 2) + "\n",
  { mode: hooksMode }
);
fs.chmodSync(temporaryPath, hooksMode);
fs.renameSync(temporaryPath, hooksPath);
NODE
fi

rm -rf \
  "$HOME/.weave/cursor-plugin" \
  "$HOME/.weave/cursor-plugin.json"

echo "Weave Cursor plugin removed. Restart Cursor."
```

**Windows (PowerShell)** (`cursor-plugin-uninstall.ps1`):

```powershell theme={null}
$ErrorActionPreference = "Stop"

$hooksPath = Join-Path $env:USERPROFILE ".cursor\hooks.json"
if (Test-Path -LiteralPath $hooksPath) {
    $backupPath = "$hooksPath.weave-backup-$(Get-Date -Format yyyyMMddHHmmss)-$([guid]::NewGuid().ToString('N'))"
    Copy-Item -LiteralPath $hooksPath $backupPath

    $cleanupScript = @'
const fs = require("fs");
const hooksPath = process.argv[2];
const hooksConfig = JSON.parse(fs.readFileSync(hooksPath, "utf8"));
const hooksMode = fs.statSync(hooksPath).mode;

const isWeaveCursorHook = (hook) => {
  const command = String(hook.command || "");
  return command.includes("/.weave/cursor-plugin/") ||
    command.includes("\\.weave\\cursor-plugin\\");
};

for (const event of Object.keys(hooksConfig.hooks || {})) {
  if (!Array.isArray(hooksConfig.hooks[event])) continue;
  hooksConfig.hooks[event] = hooksConfig.hooks[event].filter(
    hook => !isWeaveCursorHook(hook)
  );
}

const temporaryPath = hooksPath + ".weave-tmp";
fs.writeFileSync(
  temporaryPath,
  JSON.stringify(hooksConfig, null, 2) + "\n",
  { mode: hooksMode }
);
fs.chmodSync(temporaryPath, hooksMode);
fs.renameSync(temporaryPath, hooksPath);
'@
    $cleanupScript | & node - $hooksPath
    if ($LASTEXITCODE -ne 0) {
        throw "Failed to remove Weave hooks."
    }
}

foreach ($pluginPath in @(
    (Join-Path $env:USERPROFILE ".weave\cursor-plugin"),
    (Join-Path $env:USERPROFILE ".weave\cursor-plugin.json")
)) {
    if (Test-Path -LiteralPath $pluginPath) {
        Remove-Item -LiteralPath $pluginPath -Recurse -Force
    }
}

Write-Host "Weave Cursor plugin removed. Restart Cursor."
```

Uninstall does not revoke the plugin API key. Delete it on the **Cursor plugin API keys** card where you created it if you want every install using it to stop.

## Metrics enabled

Once reporting, the plugin feeds:

* **[AI code LOC](/metrics/ai-code-loc)** — lines generated by Cursor
* **[AI output percentage](/metrics/ai-output-percentage)** — portion of output from Cursor
* **[AI efficiency index](/metrics/ai-efficiency-index)** — impact on productivity
* **[Conversation prompt quality](/metrics/conversation-prompt-quality)** — prompt-level signals from captured sessions

## Cost tracking

The plugin captures prompt-, edit-, and tool-level activity, not billing data, so it does **not** report Cursor spend. Per-user Cursor cost comes from the [Cursor Admin API integration](/ai-tools/cursor#cost-tracking) (Team/Enterprise plans). Run the plugin and the Admin API integration together — the plugin adds per-developer detail, the Admin API adds actual spend.

## Sync frequency

Telemetry is sent in real time as each hook event fires during a session.

## Troubleshooting

<AccordionGroup>
  <Accordion icon="terminal" title="Installer can't find Node">
    The plugin requires Node.js 18+. Install it (`brew install node`, `nvm`, or your platform's package manager) and re-run the install command. The installer bakes the absolute path to `node` into the hook, so GUI-launched apps work too.
  </Accordion>

  <Accordion icon="key" title="Installer can't verify the Weave connection">
    The installer preflights the token before touching any hooks. If it stops with `Error: Could not verify Weave connection.`, the key is wrong or was deleted, or the machine can't reach Weave. Create a new plugin API key in Weave and re-run the command.
  </Accordion>

  <Accordion icon="chart-line" title="No activity after install">
    1. Confirm the install reported `✓ Verified telemetry pipe`
    2. Check that `~/.cursor/hooks.json` contains hooks referencing `weave-telemetry.js` (`weave-telemetry.cmd` on Windows)
    3. Fully quit and reopen Cursor (hooks load on startup)
    4. Verify the machine can reach the ingest endpoint (check network/firewall)
  </Accordion>

  <Accordion icon="user-lock" title="MDM install fails with 'HOME: unbound variable'">
    The script ran as `root` from your MDM, where `$HOME` isn't set. Install in the logged-in user's context instead — use your MDM's "run as current user" option, or the wrapper in [Fleet / MDM rollout](#fleet--mdm-rollout) that re-runs the installer as the console user. Make sure Node.js 18 or later is installed for that user.
  </Accordion>
</AccordionGroup>

## Data privacy

The plugin sends session metadata, file-edit counts, shell exit codes, tool usage, agent output, and — unless privacy mode is on — prompt text. It does **not** read source files or repository contents beyond what Cursor passes through the hook events.

## Related integrations

* [Cursor](/ai-tools/cursor) — Admin API integration (usage, costs, acceptance rates)
* [Claude Code plugin](/ai-tools/claude-code-plugin) — the equivalent per-machine plugin for Claude Code
* [Codex plugin](/ai-tools/codex-plugin) — the equivalent per-machine plugin for Codex
* [Copilot plugin](/ai-tools/copilot-plugin) — Copilot Chat OTEL export to Weave
* [OTel collector](/ai-tools/otel-collector) — route telemetry through your own collector


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.