{"slug": "why-localhost-doesn-t-work-as-openai-base-url-in-cursor-and-how-to-fix-it", "title": "Why localhost doesn't work as OpenAI Base URL in Cursor — and how to fix it", "summary": "Cursor's cloud backend routes all LLM API calls through its servers at api2.cursor.sh, making localhost base URLs unreachable and causing chat requests to hang. A developer found that exposing a local proxy via a Cloudflare tunnel resolves the issue, which is what the Ungate extension automates.", "body_md": "**TL;DR:** Cursor doesn't call your OpenAI Base URL from your local machine. It routes every request through its backend servers on `api2.cursor.sh`\n\n, so `http://localhost:8082`\n\nis unreachable — the chat hangs and your proxy logs stay empty. To connect Ollama, LM Studio, LiteLLM, or a custom subscription proxy, you must expose your local port through a public URL — a Cloudflare tunnel is the simplest way, and it is what the Ungate extension automates.\n\nWhen I first wrote a local Fastify proxy to connect my Claude subscription to Cursor, the setup felt trivial: start the server on port 8082, open `Cursor Settings → Models → Override OpenAI Base URL`\n\n, paste `http://localhost:8082/v1`\n\n, and hit save. I typed a prompt into chat, hit Enter, and watched the status indicator spin forever.\n\nI opened terminal logs expecting to see incoming HTTP requests. Nothing. I ran `tcpdump`\n\non my loopback interface — zero packets from Cursor.\n\nI spent an hour double-checking port bindings and firewall rules before realizing the issue wasn't in my code. It is in how Cursor is built.\n\nUnlike VS Code extensions, Aider, or Continue.dev — which send LLM API calls directly from your local Node process — Cursor processes chat and agent context on its own remote servers (`api2.cursor.sh`\n\n).\n\nWhen you select a model and send a message, the request path is:\n\n```\nCursor UI\n   ↓\nCursor's cloud backend\n   ↓\nOverride OpenAI Base URL\n   ↓\nLLM Provider\n```\n\nBecause the third step originates from Cursor's cloud backend over the public internet, `http://localhost:8082/v1`\n\nresolves to the backend server's own loopback interface — not your laptop.\n\nThis breaks every local setup out of the box. Whether you are trying to route Cursor through Ollama (`http://localhost:11434`\n\n), LiteLLM (`http://localhost:4000`\n\n), vLLM, or a custom proxy, Cursor's backend simply cannot reach your machine's `localhost`\n\n. The safe version of the same idea, `cursor localhost base url not working`\n\n, is exactly the symptom this post explains.\n\nWhen `http://localhost:8082/v1`\n\nis configured in Cursor Settings:\n\n`api2.cursor.sh`\n\n.`http://localhost:8082/v1/chat/completions`\n\nfrom its cloud servers.This makes debugging infuriating. The empty logs suggest your proxy isn't listening, when in reality the request died thousands of miles away before reaching your network.\n\nYou can confirm this exact behavior right now without changing your proxy code.\n\nFirst, check that your local server works:\n\n```\ncurl http://localhost:8082/health\n# → 200 OK\n```\n\nSecond, start an ad-hoc Cloudflare tunnel to expose that port publicly:\n\n```\ncloudflared tunnel \\\n  --config /dev/null \\\n  --url http://localhost:8082\n```\n\nGrab the generated `https://<random>.trycloudflare.com`\n\nURL from terminal output and test it from outside your local network (for example, from your phone over LTE):\n\n```\ncurl https://<random>.trycloudflare.com/health\n# → 200 OK\n```\n\nPaste that `https://...`\n\naddress into `Cursor Settings → Models → Override OpenAI Base URL`\n\n. Send a prompt in Cursor chat. Your local proxy logs will instantly light up with incoming requests.\n\nSwitch the setting back to `http://localhost:8082/v1`\n\n, and it immediately hangs again. Same machine, same code, different origin.\n\nTo let Cursor's cloud backend talk to a local process on your laptop, you need a public endpoint that routes back to your machine.\n\nA Cloudflare tunnel creates an outbound-only WebSocket connection from your machine to Cloudflare's edge network:\n\n```\nCursor backend\n   ↓\nhttps://<tunnel>.trycloudflare.com\n   ↓\nCloudflare Edge\n   ↓\nLocal machine (port 8082)\n   ↑\noutbound-only connection\n```\n\nBecause your machine initiates the connection outward, you don't need port forwarding, static IPs, or open inbound firewall ports.\n\nOnce people switch to a tunnel URL, they sometimes hit a new set of errors that look identical to the localhost issue:\n\n`cloudflared`\n\ninstalled locally, it may silently read `~/.cloudflared/config.yml`\n\n. If that config contains ingress rules with a catch-all `http_status:404`\n\nfrom a previous named tunnel, your quick tunnel will return Cloudflare's 404 page. Prevent this by passing `--config /dev/null`\n\n(see the command below).`trycloudflare.com`\n\nquick tunnels share rate limits per IP. For permanent setups, use a named tunnel tied to a free Cloudflare account.`8082`\n\n, but `cloudflared`\n\nwas started pointing at `8080`\n\n.`curl https://<tunnel>/health`\n\nreturns `404`\n\nwith a `server: cloudflare`\n\nheader, the tunnel isn't reaching your port. If it returns a JSON error, the request reached your proxy.To force a quick tunnel to ignore `~/.cloudflared/config.yml`\n\nentirely:\n\n```\ncloudflared tunnel \\\n  --config /dev/null \\\n  --url http://localhost:8082 \\\n  --edge-ip-version 4\n```\n\nIf requests in Cursor chat hang or fail when using a custom Base URL:\n\n`Override OpenAI Base URL`\n\nset to `https://`\n\n? Plain `http://localhost`\n\nwill never work.`curl https://<your-tunnel-url>/health`\n\nfrom a non-local network (e.g., mobile hot spot).`server: cloudflare`\n\nis present, fix the tunnel flags (`--config /dev/null`\n\n).There is one more unrelated Cursor quirk: it silently unchecks the `Override OpenAI Base URL`\n\nsetting every few hours, which silently sends requests through your API tokens instead. If your proxy suddenly stops receiving requests, check that checkbox first — I explain this bug in my [post about using Claude and ChatGPT subscriptions in Cursor](https://dev.to/orchidfiles/how-to-use-a-claude-subscription-in-cursor-without-paying-for-api-tokens-1bfa).\n\nSetting up `cloudflared`\n\nmanually every time you launch Cursor gets tedious. That's why I built Ungate — an open-source Cursor extension that connects Claude and ChatGPT subscriptions directly to native Cursor chat.\n\nUngate handles the entire proxy lifecycle automatically:\n\n`cloudflared`\n\nbinary with `--config /dev/null`\n\nto bypass local config conflicts.You can install Ungate by searching for `@id:orchidfiles.ungate`\n\nin Cursor Extensions, or read the full setup guide here: [How to use Claude and ChatGPT subscriptions in Cursor](https://dev.to/orchidfiles/how-to-use-a-claude-subscription-in-cursor-without-paying-for-api-tokens-1bfa).\n\nGitHub repository: [https://github.com/orchidfiles/ungate](https://github.com/orchidfiles/ungate)\n\nMy Blog: [orchidfiles.com](https://orchidfiles.com/)\n\nTelegram Channel: [@orchidfiles](https://t.me/orchidfiles)", "url": "https://wpnews.pro/news/why-localhost-doesn-t-work-as-openai-base-url-in-cursor-and-how-to-fix-it", "canonical_source": "https://dev.to/orchidfiles/why-localhost-doesnt-work-as-openai-base-url-in-cursor-and-how-to-fix-it-589e", "published_at": "2026-08-11 09:20:44+00:00", "updated_at": "2026-08-11 09:46:41.259254+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "ai-infrastructure"], "entities": ["Cursor", "OpenAI", "Cloudflare", "Ollama", "LM Studio", "LiteLLM", "Ungate", "Fastify"], "alternates": {"html": "https://wpnews.pro/news/why-localhost-doesn-t-work-as-openai-base-url-in-cursor-and-how-to-fix-it", "markdown": "https://wpnews.pro/news/why-localhost-doesn-t-work-as-openai-base-url-in-cursor-and-how-to-fix-it.md", "text": "https://wpnews.pro/news/why-localhost-doesn-t-work-as-openai-base-url-in-cursor-and-how-to-fix-it.txt", "jsonld": "https://wpnews.pro/news/why-localhost-doesn-t-work-as-openai-base-url-in-cursor-and-how-to-fix-it.jsonld"}}