{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreiazvyqjaribz3s2wvciikmx4thmoamwoehuzhbvqm3wh7isou5b7y",
    "uri": "at://did:plc:n33jch3tw52k4payg4mahijb/app.bsky.feed.post/3mmlpkwh6uim2"
  },
  "path": "/blog/cursor-openai-proxy",
  "publishedAt": "2026-05-23T05:00:00.000Z",
  "site": "http://randomblock1.com",
  "tags": [
    "cursor-openai-api",
    "Cursor SDK",
    "Cursor just announced Composer via the SDK is 90% off this weekend.",
    "Hono",
    "@ai-sdk/openai-compatible",
    "per Cursor"
  ],
  "textContent": "## TL;DR\n\nI built cursor-openai-api, a small HTTP server that speaks OpenAI’s API but routes every request through the Cursor SDK. Point any OpenAI client (like OpenCode, OpenClaw, your own scripts, whatever) at it, and you get Composer 2.5 (and every other model Cursor exposes) with your Cursor plan’s usage.\n\nAnd the timing is good: Cursor just announced Composer via the SDK is 90% off this weekend. Composer is already one of the best agentic coding models out there for the price, and at a 90% discount it feels almost free. It’s a great excuse to actually try it in your own tools, and to use the more expensive Fast Mode.\n\n## Why this exists\n\nCursor’s editor is great, but Composer is locked behind it. If you wanted to use it in a script, in OpenCode, in a custom agent, or just hit it from `curl`, you couldn’t. The Cursor SDK opened the door, but almost everything expects OpenAI’s `/v1/chat/completions` shape, not a vendor-specific SDK. The Cursor SDK also has a different way of handling tool calls and thinking, which OpenAI clients don’t know how to parse.\n\nSo I wrote an adapter. The proxy is a Hono server that translates OpenAI requests into Cursor SDK calls, streams that back as SSE chunks, and maps thinking, tool calls, and usage into the fields OpenAI clients already know how to parse.\n\nThe result is that anything that takes a `base_url` and an `api_key` Just Works:\n\n\n    from openai import OpenAI client = OpenAI( base_url=\"http://localhost:8080/v1\", api_key=\"onlyNeededIfYouSetIt\", ) response = client.chat.completions.create( model=\"composer-2.5\", messages=[{\"role\": \"user\", \"content\": \"Refactor this function.\"}], ) print(response.choices[0].message.content)\n\nThat’s it. Same code, different LLM.\n\nA few nice details I added to make using it easier:\n\n  * **Speed aliases.** Composer defaults to Fast Mode in Cursor’s catalog. To use the less expensive standard tier you’d normally pass `cursor_model_params: [{ \"id\": \"fast\", \"value\": \"false\" }]`, which is annoying, and may require code changes. The proxy auto-generates `<model>-slow` and `<model>-fast` aliases for every model that supports both, so you can just ask for `composer-2.5-slow`. This also works for other models, like `gpt-5.5` that has the `fast` parameter.\n  * **Thinking interleave for OpenCode.** @ai-sdk/openai-compatible collapses all `content` into a single text block per stream, which mangles ordering when the model interleaves thinking and text. There’s a special `preamble-as-reasoning` mode that re-routes buffered text into `reasoning_content` when the model crosses a thinking or tool boundary, so OpenCode renders **Thought → Response** in the right order.\n\nIn other words, it has a compatibility mode for OpenCode’s way of rendering thinking, so it doesn’t break because Cursor works a little differently.\n\n  * **Client tool loops.** If the request includes a `tools` array, the proxy enters client-tool-loop mode: it instructs the model to emit Composer tool-call markers for your tool names, parses them out of the text stream, and returns OpenAI `tool_calls` with `finish_reason: \"tool_calls\"`. Your client executes them locally and the conversation continues. This is what makes things like OpenCode’s tool-using agents work with Composer as the backend.\n  * **Abort support.** Drop the HTTP connection and the in-flight `run.cancel()` fires. No need to waste tokens on a response that won’t be read.\n\n\n\n## Why it’s useful\n\nA few things I’ve actually used it for:\n\n  * **OpenCode with Composer 2.5.** OpenCode is a terminal coding agent that talks to any OpenAI-compatible endpoint. Pointing it at the proxy gets you Composer with the full tool loop (file edits, shell, search) in a TUI instead of Cursor’s editor.\n  * **One-off scripts.** Need to generate something from a CLI, a `Makefile`, a cron job? `curl http://localhost:8080/v1/chat/completions` with the model id and you’re done. No editor required.\n  * **Existing agents.** If you’re building anything on top of the OpenAI SDK, like eval harnesses, code review bots, batch refactors, you can swap the model to Composer by changing the base URL. Your retry logic, token counting, tracing, etc. all still work.\n  * **Comparison/benchmark.** Run the same prompt against `composer-2.5`, `claude-opus-4-7`, and `gpt-5.5` from the same script and compare the output. Cursor’s catalog has a lot of models behind one key; this exposes all of them through one endpoint.\n\n\n\n## Try it this weekend\n\nSetup is three commands:\n\n\n    git clone https://github.com/Randomblock1/cursor-openai-api cd cursor-openai-api bun install # or npm install export CURSOR_API_KEY=\"crsr_...\" # from cursor.com/dashboard/integrations bun run start # or npm run start:node\n\nThen point your favorite OpenAI client at `http://localhost:8080/v1` with `composer-2.5` as the model. While Composer is 90% off for the weekend (per Cursor) it’s basically free to put through its paces.\n\nEnjoy!",
  "title": "Use Cursor Composer 2.5 Anywhere With an OpenAI-Compatible API",
  "updatedAt": "2026-05-23T05:00:00.000Z"
}