# Install Mesmer for Cursor: one engineer, a fleet, or a Build

_Published September 24, 2026_

**By [Jean Ribeiro Lustosa](https://mesmer.co/resources/author/jean)**

**Section:** Playbook

> **TL;DR.** Mesmer's Cursor integration installs with one shell command: once per machine for an individual engineer, as a recurring Rippling script policy plus a configuration profile for a fleet, or inside a Cloud Agent Build via environment.json. Capture every repository, no per-project opt-in, no per-engineer opt-out.

---

Mesmer's Cursor integration exports what your agents actually did — prompts,
file edits, shell commands, tool calls — over OpenTelemetry, and lands it
next to delivered effort in the same [AI Usage tab](/resources/agent-analytics)
that already reports Claude Code spend. It installs once per machine with
a single shell command.

That shapes how three different people roll it out — an individual
engineer running one command, an IT team pushing it to a fleet through
Rippling, and a platform engineer wiring it into a Cursor Cloud Agent
Build. Each gets its own section below, followed by the part worth
reading before any of them: exactly what this captures, and what it
deliberately doesn't.

### An individual engineer: one command, once

Put the organisation token in the environment that runs the installer, then
run the one-liner:

```sh
export MESMER_OTLP_TOKEN='<org token>'
curl -fsSL https://mesmer.co/cursor-otel/install.sh | sh
```

Restart Cursor — it reads `hooks.json` at startup — and check that it
worked:

```sh
~/.local/share/mesmer-cursor-otel/bin/mesmer-cursor-doctor
```

`doctor` checks the runtime, the launcher, the hook registration, the
stored credential and the endpoint, and then does the check that actually
matters: whether spans have been delivered to the collector recently. It
prints remediation for whatever's wrong, and it's safe to run as often as
you like.

Requirements, current as of 2026, are deliberately thin: macOS or Linux, `x64` or `arm64`,
`/bin/sh`, `curl` and `tar`. Nothing else — the release ships a vendored,
relocatable CPython, so there's nothing to install from a package manager
on the target machine. The whole runtime occupies about 51 MB on disk
after a roughly 17 MB download.

Re-running the install command later is safe: it's idempotent, upgrades
in place, and keeps whatever token is already stored if you don't supply
a new one.

From then on it keeps itself current: on every session start it spawns a
detached background check that upgrades in place.

### A fleet, through Rippling

We support Rippling MDM. This section describes what to deploy rather
than where to click — check Rippling's current documentation for the
exact screen; the shape of the deployment itself doesn't change.

It's two pieces, deployed together.

**A recurring script policy** runs the identical one-liner, with one flag
added:

```sh
curl -fsSL https://mesmer.co/cursor-otel/install.sh | sh -s -- --scope user
```

That's the whole policy, and it works unchanged whether Rippling happens
to run it as root or as the signed-in user. If nobody is signed in, which
is normal right after a machine boots, it exits cleanly without
installing anything. That's exactly why
the policy has to be **recurring** rather than one-time: a recurring
policy installs the first time it runs after someone actually logs in, and
on a shared or multi-account Mac, whoever is signed in when it fires gets
their own install.

**A configuration profile** carries the organisation token, so it never
has to appear in the script, in argv, or in an MDM run-script log.
Download [`mesmer-cursor-otel.mobileconfig`](/downloads/mesmer-cursor-otel.mobileconfig)
and edit it — fill in the token and two distinct UUIDs (one for the
profile, one for the settings payload inside it; macOS rejects a profile
that reuses one) and assign it at the device level, not the user level,
since a user-scoped assignment lands somewhere the hook never reads.

| Key | Required | Meaning |
| --- | --- | --- |
| `MESMER_OTLP_TOKEN` | yes | The organisation token — same name as the environment variable a single-machine install uses. Ask the Mesmer team for it. |

Order doesn't matter between the two pieces: if the script runs before
the profile lands, the hook is registered and simply exports nothing
until it does — nothing breaks and no one is blocked in the meantime.

### Cursor Cloud Agents: install during the Build

The hook installs from the repository's own `.cursor/environment.json`,
during the environment's Build, with a scope flag that changes how the
file is written:

```json
{
  "install": "curl -fsSL https://mesmer.co/cursor-otel/install.sh | sh -s -- --scope cloud-agent"
}
```

Add that after your own install steps if you have any.

The token has to be a **team secret** or an **environment secret**, never
a user secret. User secrets are only added when an agent starts, and
aren't available during Builds — which is exactly when the installer
looks for one. Get the scope wrong and the install still "succeeds": it
fails open, logs a warning, and quietly exports nothing from every agent
that boots off that snapshot. The Build log is honest about it either
way — a healthy install prints the version, the hooks path and the
endpoint; a missing token prints `warning: no MESMER_OTLP_TOKEN in the
environment` instead.

Because the Build sequence is strictly ordered — the environment clones
the repository and runs `install` to completion before it ever snapshots
the disk — there's no window where an agent could load a hook
configuration out from under it.


| | Individual / Rippling fleet | Cursor Cloud Agent |
| --- | --- | --- |
| Hooks file | `~/.cursor/hooks.json` (user level) | `<repo>/.cursor/hooks.json` (project level) |
| Written by | `install.sh` (`--scope user`, the default) | `install.sh --scope cloud-agent`, during the Build |
| Written how | Merged into whatever is already there | Merged into whatever is already there |
| Lifetime | Until you uninstall | Until the next Build |


These two paths are kept deliberately disjoint. Don't commit the
`.cursor/hooks.json` a Build writes — it's regenerated every time, its
paths are only valid inside that VM, and committing it would make every
teammate's laptop fire the hook a second time.

> **INFO.** Capture applies to every repository on the machine, with no per-repository or per-engineer opt-out short of a full uninstall. See what that includes below.

### What actually reaches Mesmer

Once installed, every repository you open in Cursor is instrumented —
work repositories, personal projects, a throwaway clone, all of them —
because the hooks are registered once at the user level and fire for
every session on the machine regardless of path. The unit of consent
here is the machine, not the project.

Every content-capture control upstream exposes is on. Prompts, model
responses, model thoughts, shell commands, tool
calls, tool definitions, file reads and file edits are all exported as
text — as are MCP calls, including the server and tool name, the request
and the result. An MCP call is the one place an agent reaches outside the
repository, so whatever it sends and receives goes too. That's across
every hook event this integration registers — from `sessionStart` through
shell execution, file edits, tool calls and MCP calls, to `stop`.

### Troubleshooting

**Telemetry stopped arriving.** Open Cursor's **Hooks** output channel and
look for `Invalid user config` or `Failed to parse user hooks
configuration`. Cursor silently discards an entire `hooks.json` if it
contains even one unrecognised event key — from any tool, not just this
one — and reports the failure nowhere else. A single bad entry added by
something unrelated disables every hook in the file, ours included.
Remove the offending entry and restart Cursor.

**Nothing arrives right after installing.** `hooks.json` is only read at
Cursor startup, so restart it, then run `mesmer-cursor-doctor`.

**A token in your shell can win over what's stored.** Credentials resolve
in this order: a managed configuration profile, then `MESMER_OTLP_TOKEN`
in the environment that launched Cursor, then the stored `mesmer.json`.
On an unmanaged machine, a `MESMER_OTLP_TOKEN` left exported in a shell
profile for any other reason will keep authenticating every span with
that value instead of the one you installed with. `doctor` reports which
source is actually in use.

`doctor` is the right tool for checking whether telemetry is actually
being delivered — trust its output over anything you inspect by hand.
If it doesn't resolve the issue, reach out to the Mesmer team.

**Uninstalling.**

```sh
~/.local/share/mesmer-cursor-otel/bin/mesmer-cursor-uninstall
```

It strips Mesmer's entries from `hooks.json` first, then removes the
install — that order matters, since the hook entries are absolute paths
into the install directory. Unrelated Cursor hooks are preserved.

---

Canonical: https://mesmer.co/resources/install-mesmer-for-cursor
