# Cursor HTTP/1.1 transport reproduction

These are real T3 server/CLI runs, not unit tests or replay-agent responses. Each side used its own fresh data directory and synthetic workspace. Both used the same installed Cursor SDK, credentials, prompt, custom model setting and proxy. No application source was changed.

Set EVIDENCE_CURSOR_MODEL to a valid model supported by the account. The driver adds it as a custom model on both sides so that asynchronous provider model discovery does not prevent the base turn from starting. Set CURSOR_API_KEY through the environment; do not put credentials in files intended for publication.

Install mitmproxy in a virtual environment. Start this trusted TLS reverse proxy, substituting paths to a new disposable evidence directory:

```sh
mitmdump --mode reverse:https://api2.cursor.sh --listen-host 127.0.0.1 --listen-port 18443 --set http2=false --set confdir=<evidence>/mitm --set flow_detail=0 -s route.py
```

The routing addon sends /v1/ API requests to api.cursor.com and agent requests to api2.cursor.sh. This keeps model discovery and authentication real while providing one HTTP/1.1-only TLS origin. Streaming responses pass through without buffering. The driver sets CURSOR_BACKEND_URL=https://localhost:18443 and trusts the generated CA through NODE_EXTRA_CA_CERTS. It writes network.useHttp1ForAgent=true in a fresh CURSOR_CONFIG_DIR, starts the real server, adds a synthetic project through the real CLI and requests "Reply with OK only. Do not use tools."

Run driver.py once for each checkout, with different output directories and ports:

```sh
python3 driver.py <base-checkout> <evidence>/before --side Before --port 18445 --ca <evidence>/mitm/mitmproxy-ca-cert.pem
python3 driver.py <head-checkout> <evidence>/after --side After --port 18444 --ca <evidence>/mitm/mitmproxy-ca-cert.pem
```

The driver stops each server after the turn. Stop mitmdump afterward.

The transcripts and asciicast files contain captured CLI output, with generated thread/run IDs removed and workspace paths replaced. Model identifiers are omitted from displayed commands. The PNGs and MP4s are terminal renderings/playback of those timed output events, not browser screenshots. Both use a 1320x740 dark terminal canvas. The final base run failed with the ALPN error and exit 1; the final head run completed with reply OK and exit 0. The proxy observed HTTP/1.1 RunSSE responses with status 200.

AI-assisted; verified with the tests and tools listed above.
