Skip to main content
Glama
smith

cursor-otel

by smith
README.md
# cursor-otel

An [MCP](https://modelcontextprotocol.io/) server that instruments [Cursor](https://cursor.com/) AI agent interactions with [OpenTelemetry](https://opentelemetry.io/) traces and logs.

Each agent turn becomes an OTel span following the [GenAI semantic conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/), with the user query and assistant response captured as span attributes. Logs emitted during a turn are correlated to the trace via context propagation.

## Disclaimer

This is an experimental personal project. It is not affiliated with, endorsed by, or supported by Elastic, Cursor, or the OpenTelemetry project. Use at your own risk.

## Tools

| Tool | Description |
|------|-------------|
| `start_turn` | Begin a traced span for an agent turn. Returns a `turn_id` and `conversation_id`. |
| `end_turn` | End the span for a turn. Accepts a response summary, tool count, and optional error. |
| `agent_log` | Emit an OTel log record, optionally correlated to an active turn's trace. |

## Setup

### Prerequisites

An OpenTelemetry collector (or compatible backend) accepting OTLP/HTTP on `http://localhost:4318`. Override with the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable.

### Install

```sh
git clone https://github.com/smith/cursor-otel.git
cd cursor-otel
npm install
```

### Configure Cursor

Add to your `.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "cursor-otel": {
      "command": "node",
      "args": ["/absolute/path/to/cursor-otel/index.mjs"]
    }
  }
}
```

### Agent rules

Add a Cursor rule (e.g. `.cursor/rules/cursor-otel.mdc`) to instruct the agent to call the tools on every turn:

```
## Agent OTel instrumentation

Every user interaction MUST be traced. Use the `cursor-otel` MCP tools.

### On each user query

1. Call `start_turn` with:
   - `conversation_id`: reuse the value from the previous `start_turn` response
     in this conversation. Omit on the first call (the server generates one).
   - `user_message`: the user's query (first 500 chars).
   - `model`: the model name if you know it.
2. Save the returned `turn_id` and `conversation_id`.

### After completing your response

Call `end_turn` with:
- `turn_id`: from `start_turn`.
- `response`: 1-2 sentence summary of what you did.
- `tool_count`: total number of tool calls you made this turn.
- `error`: set only if the turn failed.

### Logs

Use `agent_log` (with the `turn_id`) for notable events: errors, key decisions,
warnings. Don't log routine steps.

### Rules

- `start_turn` and `end_turn` are **mandatory** on every turn. No exceptions.
- Keep `start_turn` as the **first** tool call and `end_turn` as the **last**.
- These calls are fast and non-blocking — don't skip them to save time.
```

## License

[MIT](LICENSE)