@usemesmer/mesmer-cursor-otel
v0.1.1
Published
Mesmer OpenTelemetry hooks for Cursor IDE and Cursor Cloud Agents
Readme
Mesmer Cursor OpenTelemetry
mesmer-cursor-otel adds Mesmer telemetry to Cursor installations that do not use Cursor Enterprise's native OpenTelemetry export.
The package uses the same project configuration for Cursor IDE and Cursor Cloud Agents: install the package, run mesmer-cursor-otel setup in the project, and commit the resulting .cursor/hooks.json. It does not split the integration into a desktop plugin and a separate Cloud script.
The package is distributed on NPM as @usemesmer/mesmer-cursor-otel and exposes the mesmer-cursor-otel executable.
Setup
Install the package, then run the same setup command from the repository in Cursor IDE and in the Cursor Cloud Agent environment:
npm install -g @usemesmer/[email protected]
mesmer-cursor-otel setupbun installs the same package:
bun add -g @usemesmer/[email protected]
mesmer-cursor-otel setupEither way the mesmer-cursor-otel executable runs on Node.js 20 or newer, which remains a requirement. If you were given a tarball instead, install it by path: npm install -g ./usemesmer-mesmer-cursor-otel-0.1.1.tgz, or with bun using an absolute path.
setup installs the pinned runtime outside the repository and safely merges Mesmer-owned commands into the project's .cursor/hooks.json. Commit that hooks file so Cursor IDE and Cursor Cloud Agents load the same configuration. Unrelated project hooks are preserved.
Set MESMER_OTLP_TOKEN in the environment that launches Cursor. For Cloud Agents, configure it as a Runtime Secret, never as a build secret. The token is read only when a hook runs and is never stored in the project or runtime files.
At hook runtime, Cursor's CURSOR_USER_EMAIL value is added to the exported OpenTelemetry resource as user.email when available. The wrapper also adds the lowercase SHA-256 fingerprint of the exact Bearer token as mesmer.otlp.token_fingerprint. The plaintext token remains only in the OTLP authorization header and is never copied into telemetry attributes.
Telemetry is sent over OTLP HTTP/protobuf to https://telemetry.mesmer.co.
Check or remove the current project's installation with:
mesmer-cursor-otel doctor
mesmer-cursor-otel uninstalldoctor checks the package, pinned runtime, project hooks, credential presence, and endpoint and prints remediation for every problem. uninstall removes only the current project's Mesmer-owned hook entries and runtime; unrelated Cursor hooks and configuration are preserved. Both commands are safe to run repeatedly. Removing the setup does not uninstall the global NPM package.
What is captured
This version enables every content-capture control exposed by upstream 0.14.0. Prompts, model responses, shell commands, tool calls and definitions, file edits, and MCP payloads are exported without masking, so secrets that appear in agent input or output reach Mesmer. Cursor lifecycle events that upstream does not yet model are still forwarded, but may emit only generic event metadata.
Events are attributed to the developer's Cursor account email, so telemetry is per-engineer rather than aggregate.
Capture is scoped to each repository where setup has been run, and only occurs where MESMER_OTLP_TOKEN is present in the environment. Review this against your data policy before enabling it on sensitive repositories.
Delivery
Every Cursor hook event is exported to OTLP as it happens. The wrapper forces
IDE_OTEL_BATCH_ON_STOP=false and IDE_OTEL_LOCAL_SPANS=false, which keeps the upstream runner on
its streaming path: one span per event, flushed before the hook returns, and no span copies written
to the runtime directory.
This matters most for Cursor Cloud Agents. Upstream's own default configuration buffers every event
that is not a session boundary into files under the project runtime, and drains them only on stop
(the current generation) or sessionEnd (everything). Cloud Agents do not reliably emit
sessionEnd, so buffered events from any earlier generation expired unsent.
sessionStart and sessionEnd are registered for the same reason. Upstream's streaming path reads
the session context to correlate events into one trace but, unlike its batching path, never creates
that context lazily — without a sessionStart hook every exported span would land in its own trace.
The wrapper also forces OTEL_EXPORTER_OTLP_TIMEOUT=3. Hooks block the agent, and the pinned
OpenTelemetry SDK ignores the runner's own flush timeout, so the exporter's 10-second default would
otherwise be the only bound on a hook waiting for an unreachable collector.
These settings, along with the content-capture controls above, are set by the wrapper and cannot be
overridden from the environment. Every other OTEL_* and IDE_OTEL_* variable is passed through to
the runner unchanged.
Runtime
The wrapper uses o11y-dev/opentelemetry-hooks as its event runner. The initial package pins upstream version 0.14.0 exactly; it never follows a floating version or branch. Customers invoke only mesmer-cursor-otel, never the upstream runner directly.
The initial supported platforms are x64 and arm64 macOS and Linux with Node.js 20 or newer. Credentials are runtime configuration and must never be committed to this repository or to a customer's project.
Packaging
Maintainers build the distributable tarball from a checkout. With bun:
bun pm packThis writes usemesmer-mesmer-cursor-otel-0.1.1.tgz into the current directory; *.tgz is gitignored, so packing does not dirty the tree. Use --destination <dir> to write elsewhere — bun creates the directory if it does not exist. Pass --gzip-level 6; bun's default level of 9 produces a slightly larger tarball for this package.
bun pm pack --destination dist --gzip-level 6The npm equivalent is npm pack, which is what CI and the release scripts use. Both tools produce the same 18 files with the same contents, permissions, and package/ prefix, and either tarball installs with either package manager.
A specific commit can be installed for validation without publishing:
npm install -g github:usemesmer/mesmer-cursor-otel#<sha>. There is no build or prepare step,
so the git install resolves the same files list as the tarball.
[!NOTE]
npm run check:packageandnpm run smoke:releaserequire npm.scripts/verify-package.mjsreadsnpm pack --dry-run --json, andbun pm packhas no JSON output, so a bun-produced tarball cannot be validated by the packaged-contents contract test.
