# Cursor Protocol Debugger

[中文](README.md) | [English](README.en.md)

This standalone local Cursor API debugging service forwards every HTTP request outside the `__debuger__` debugging namespace to the fixed upstream `https://api2.cursor.sh`, preserving the method, path, query, headers, and body. It continues to capture `BidiAppend`, `RunSSE`, Fork Chat, and model-discovery traffic.

It is not a general-purpose HTTP proxy, does not handle `CONNECT`, requires no CA certificate, and does not modify the system proxy.

## Start

Generate the sibling `cursor-proto` module's Go code before the first build:

```bash
(cd ../cursor-proto && ./scripts/generate.sh)
go run .
```

The service listens on a single port:

- Cursor API service: `http://127.0.0.1:9090`
- Debugging UI: `http://127.0.0.1:9090/__debuger__/`
- Debugging API: `http://127.0.0.1:9090/__debuger__/api/*`
- Fixed upstream: `https://api2.cursor.sh`

The debugging UI opens automatically after startup.

## Configure Cursor

Quit Cursor completely, then launch it from a terminal with the local API address:

```bash
CURSOR_API_ENDPOINT=http://127.0.0.1:9090 \
CURSOR_API_BASE_URL=http://127.0.0.1:9090 \
/Applications/Cursor.app/Contents/MacOS/Cursor
```

`CURSOR_API_ENDPOINT` overrides the Agent API endpoint. `CURSOR_API_BASE_URL` also routes requests such as authentication that use the base API address through this service. Cursor proxy and Network settings do not need to be changed.

## Build

```bash
(cd ../cursor-proto && ./scripts/generate.sh)
go build -o ./bin/cursor-proxy-debugger .
```

## Dependency Layout

The debugger is an independent Go module. Cursor protobuf message packages are generated by the sibling `cursor-proto` module. The generated `gen/` directory is not committed, so run its `scripts/generate.sh` before the first build. This project does not depend on the outer `cursor-byok` Go module.

## Options

```text
-addr             Cursor API service listen address; default: 127.0.0.1:9090
-max-exchanges    Maximum exchanges retained in memory; default: 200
-db               SQLite database path; defaults to the user configuration directory
-open             Open the browser after startup; default: true
```

## Data Handling

- Every request received by the service is forwarded to `https://api2.cursor.sh`; clients cannot select another upstream.
- The `__debuger__` namespace is reserved for the local debugging page and API and is never forwarded upstream.
- `RunSSE` is decoded incrementally using the 5-byte Connect frame header and supports per-frame gzip decompression.
- `BidiAppendRequest.data` is further decoded as `agent.v1.AgentClientMessage`.
- Fork Chat's `ForkBackgroundComposer`, `NotifyConversationClone`, and `UploadConversationBlobs` traffic is decoded bidirectionally as protobuf JSON.
- `CppService/AvailableModels`, `AiService/AvailableModels`, `GetDefaultModel`, and `GetDefaultModelNudgeData` are decoded bidirectionally.
- Requests can be filtered by time and protocol `request_id`; the UI can query by `conversation_id` and group requests by conversation.
- Complete captures are stored in SQLite and remain queryable after restart; `max-exchanges` only limits hot in-memory data.
- Sensitive headers such as `Authorization`, `Cookie`, and `Set-Cookie` are hidden in the UI by default.
- Raw bodies are retained up to 2 MiB per side by default; capture limits never truncate forwarded traffic.
