[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81244":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":13,"stars30d":13,"stars90d":15,"forks30d":15,"starsTrendScore":17,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":27,"readmeContent":28,"aiSummary":29,"trendingCount":15,"starSnapshotCount":15,"syncStatus":13,"lastSyncTime":30,"discoverSource":31},81244,"cursor-sdk-gateway","divyaran7an\u002Fcursor-sdk-gateway","divyaran7an","Use any LLM with the Cursor Agent SDK","",null,"JavaScript",24,2,22,0,1,3,44.63,"MIT License",false,"main",true,[24,25,26],"ai-agents","cursor-ai","cursor-sdk","2026-06-12 04:01:32","\u003Cp align=\"center\">\n  \u003Cimg src=\"https:\u002F\u002Fraw.githubusercontent.com\u002Fdivyaran7an\u002Fcursor-sdk-gateway\u002Fmain\u002Fassets\u002Fhero.png\" alt=\"Cursor SDK Gateway — use any LLM with the Cursor Agent SDK\" width=\"800\">\n\u003C\u002Fp>\n\n# Cursor SDK Gateway\n\n[![npm version](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fv\u002Fcursor-sdk-gateway.svg)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fcursor-sdk-gateway)\n[![Downloads](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fdm\u002Fcursor-sdk-gateway.svg)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fcursor-sdk-gateway)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-yellow.svg)](#license)\n\nThe Cursor Agent SDK is great, but every request routes through Cursor's backend and needs a Cursor API key. This is a small library that lets you point it at any OpenAI-compatible provider through the Vercel AI SDK instead.\n\nYour code keeps using `@cursor\u002Fsdk`, the local executor still runs all the tools the same way, and only the model call goes somewhere else.\n\n```ts\nimport { configureCursorGateway } from \"cursor-sdk-gateway\"\n\nawait configureCursorGateway({\n  provider: \"ai-gateway\",\n  apiKey: process.env.AI_GATEWAY_API_KEY!,\n})\n\nconst { Agent } = await import(\"@cursor\u002Fsdk\")\n\nconst agent = await Agent.create({\n  model: { id: \"deepseek\u002Fdeepseek-v4-flash\" },\n  local: { cwd: process.cwd() },\n})\n\nconst run = await agent.send(\"Summarize this repository\")\n\nfor await (const event of run.stream()) {\n  console.log(event)\n}\n```\n\n## Install\n\n```bash\nnpm install cursor-sdk-gateway @cursor\u002Fsdk\n```\n\n## Quick start\n\n### 1. Configure once before `@cursor\u002Fsdk` is loaded\n\n```ts\nimport { configureCursorGateway } from \"cursor-sdk-gateway\"\n\nawait configureCursorGateway({\n  provider: \"ai-gateway\",\n  apiKey: process.env.AI_GATEWAY_API_KEY!,\n})\n\nconst { Agent } = await import(\"@cursor\u002Fsdk\")\n```\n\n### 2. Use Cursor SDK normally\n\n```ts\nconst agent = await Agent.create({\n  model: { id: \"deepseek\u002Fdeepseek-v4-flash\" },\n  local: { cwd: process.cwd() },\n})\n\nconst run = await agent.send(\"Create a README section for local setup\")\nawait run.wait()\n```\n\n### 3. Remove it cleanly\n\nDelete the `configureCursorGateway()` call and switch back to a Cursor model id. That's it.\n\nIf a file in your project already imports `@cursor\u002Fsdk`, put the gateway setup in your entrypoint before that import. The setup has to run first.\n\n## If something doesn't work\n\n- **It still routes through Cursor's models.** Make sure `configureCursorGateway()` runs *before* anything imports `@cursor\u002Fsdk`. The dynamic-import pattern in step 1 handles this.\n- **`@cursor\u002Fsdk` not found.** It's a peer dependency, install it explicitly: `npm install @cursor\u002Fsdk`.\n- **The provider rejects the request.** The endpoint must support OpenAI-compatible streaming with tool and function calls. Plain chat-only models won't drive the agent loop.\n\n## Vercel AI Gateway\n\n```bash\nexport AI_GATEWAY_API_KEY=\"vck_...\"\n```\n\n```ts\nawait configureCursorGateway({\n  provider: \"ai-gateway\",\n  apiKey: process.env.AI_GATEWAY_API_KEY!,\n})\n```\n\nUse any provider model id your gateway supports. The examples default to `deepseek\u002Fdeepseek-v4-flash` because it's cheap.\n\n## OpenAI-compatible endpoints\n\nFor OpenRouter, LiteLLM, vLLM, LocalAI, or your own gateway. The endpoint needs to support OpenAI-compatible chat completions with streaming and tool\u002Ffunction calls, since plain chat-only endpoints won't work for Cursor's agent loop.\n\n```ts\nawait configureCursorGateway({\n  provider: \"openai-compatible\",\n  baseURL: \"https:\u002F\u002Fopenrouter.ai\u002Fapi\u002Fv1\",\n  apiKey: process.env.OPENROUTER_API_KEY!,\n})\n```\n\nLocal endpoint:\n\n```ts\nawait configureCursorGateway({\n  provider: \"openai-compatible\",\n  baseURL: \"http:\u002F\u002Flocalhost:4000\u002Fv1\",\n  apiKey: \"local-key\",\n})\n```\n\nA few extra provider options pass through too:\n\n- AI Gateway: `baseURL`, `headers`, `metadataCacheRefreshMillis`, `imageModel`, `image`\n- OpenAI-compatible: `headers`, `queryParams`, `includeUsage`, `imageModel`, `image`\n\nFor image generation:\n\n```ts\nawait configureCursorGateway({\n  provider: \"ai-gateway\",\n  apiKey: process.env.AI_GATEWAY_API_KEY!,\n  image: { model: \"openai\u002Fgpt-image-1\", size: \"1024x1024\" },\n})\n```\n\nWithout an image model, `generateImage` calls return a Cursor-shaped error result. The lifecycle event still fires correctly.\n\n## Migrating an existing Cursor SDK app\n\nBefore:\n\n```ts\nimport { Agent } from \"@cursor\u002Fsdk\"\n\nconst agent = await Agent.create({\n  apiKey: process.env.CURSOR_API_KEY!,\n  model: { id: \"composer-2\" },\n  local: { cwd: process.cwd() },\n})\n```\n\nAfter:\n\n```ts\nimport { configureCursorGateway } from \"cursor-sdk-gateway\"\n\nawait configureCursorGateway({\n  provider: \"openai-compatible\",\n  baseURL: process.env.OPENAI_COMPATIBLE_BASE_URL!,\n  apiKey: process.env.OPENAI_COMPATIBLE_API_KEY!,\n})\n\nconst { Agent } = await import(\"@cursor\u002Fsdk\")\n\nconst agent = await Agent.create({\n  model: { id: \"deepseek\u002Fdeepseek-v4-flash\" },\n  local: { cwd: process.cwd() },\n})\n```\n\nExisting code that passes `apiKey: process.env.CURSOR_API_KEY` keeps working. For local gateway runs the gateway supplies the placeholder Cursor key the SDK expects.\n\n## Features\n\n- Use any provider you already have a key for, through Vercel AI Gateway or any OpenAI-compatible endpoint.\n- Drop into any existing `@cursor\u002Fsdk` app with one config call before the SDK import.\n- All Cursor local file and shell tools keep working: `write`, `edit`, `read`, `ls`, `grep`, `glob`, `delete`, `shell`.\n- MCP servers, project hooks, subagents, and background shell with `write_shell_stdin` all run as normal.\n- Optional image generation by passing an image model in the config.\n- `npm test` runs an offline parity check against every public Cursor tool, no API key needed.\n\n## Scope\n\nLocal agents only.\n\nThis doesn't replace Cursor's cloud features like VMs, hosted artifacts, the web Agents Window, or PR automation. For those, use Cursor's own runtime. `agent.listArtifacts()` returns an empty list in local mode, matching Cursor's own local SDK.\n\n## Examples\n\nRunnable examples live in [`examples\u002F`](.\u002Fexamples). Each one is a normal `@cursor\u002Fsdk` local agent script:\n\n```bash\nnode examples\u002Fbasic\u002Frun.mjs\nnode examples\u002Flocal-tools\u002Frun.mjs\nnode examples\u002Fmcp\u002Frun.mjs\nnode examples\u002Fhooks\u002Frun.mjs\nnode examples\u002Fsubagents\u002Frun.mjs\nnode examples\u002Fbackground-shell\u002Frun.mjs\nnode examples\u002Fresume-generator\u002Frun.mjs \"Person Name\"\nnode examples\u002Fcursor-cookbook\u002Fquickstart\u002Frun.mjs\n```\n\n`resume-generator` is adapted from Anthropic's [Claude Agent SDK demos](https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fclaude-agent-sdk-demos\u002Ftree\u002Fmain\u002Fresume-generator), with the same workflow swapped to `@cursor\u002Fsdk` and `cursor-sdk-gateway`. The `cursor-cookbook\u002F` folder ports a few of [Cursor's own cookbook examples](https:\u002F\u002Fgithub.com\u002Fcursor\u002Fcookbook\u002Ftree\u002Fmain\u002Fsdk) the same way.\n\nSee [`examples\u002FREADME.md`](.\u002Fexamples\u002FREADME.md) for setup and a one-line summary of each.\n\n## How it works\n\n`configureCursorGateway()` starts a local endpoint that speaks Cursor SDK's protocol, points `@cursor\u002Fsdk` at it via `CURSOR_BACKEND_URL`, and lets Cursor's own local executor keep handling files, shell, MCP, subagents, and hooks. Only the model call is rerouted.\n\n```txt\n@cursor\u002Fsdk local agent\n  -> cursor-sdk-gateway local endpoint\n  -> Cursor local executor (files, shell, MCP, subagents)\n  -> gateway hook runner (.cursor\u002Fhooks.json)\n  -> Vercel AI SDK streamText\n  -> Vercel AI Gateway or @ai-sdk\u002Fopenai-compatible\n```\n\nStack:\n\n- `@cursor\u002Fsdk` for the public API your app imports\n- `ai` for streaming via `streamText` and Vercel AI Gateway\n- `@ai-sdk\u002Fopenai-compatible` for OpenAI-compatible endpoints\n- `zod` for model-facing tool schemas\n\n## References\n\n- Cursor's SDK announcement: https:\u002F\u002Fcursor.com\u002Fblog\u002Ftypescript-sdk\n- Cursor SDK docs: https:\u002F\u002Fcursor.com\u002Fdocs\u002Fsdk\u002Ftypescript\n- `@cursor\u002Fsdk` on npm: https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@cursor\u002Fsdk\n- Cursor's official cookbook: https:\u002F\u002Fgithub.com\u002Fcursor\u002Fcookbook\n\n## Disclaimer\n\nThis isn't an official Cursor or Anysphere project, just something I built on top of their SDK.\n\n## License\n\nMIT\n\nBuilt with [pattrns.ai](https:\u002F\u002Fpattrns.ai) by [@divyaranjan_](https:\u002F\u002Fx.com\u002Fdivyaranjan_).\n","Cursor SDK Gateway 项目允许开发者使用任何与OpenAI兼容的LLM服务来替代Cursor Agent SDK默认的后端调用。其核心功能是通过简单的配置即可将模型请求重定向至自定义的AI服务提供商，同时保持原有代码逻辑不变，仅需更改少量设置即可实现切换。该项目基于JavaScript开发，支持动态导入和环境变量配置，具有良好的灵活性和易用性。适用于需要在不改动现有基于Cursor SDK构建的应用程序情况下，快速替换底层AI模型服务的各种场景，比如当希望降低成本、提高性能或是测试不同模型效果时。","2026-06-11 04:04:01","CREATED_QUERY"]