Where does the bug appear (feature/product)?
Somewhere else…
Describe the Bug
When creating a local Cursor SDK agent with an API key and an explicit model, the SDK calls the cloud model-list endpoint (GET /v1/models) before creating the local agent. For a free user, that endpoint returns:
[plan_required] Cloud Agent is not available for free users. Please upgrade to Pro.
This blocks Agent.create({ local: ... }) even though the requested runtime is local and no cloud agent is requested.
Steps to Reproduce
import {
Agent,
Cursor,
CursorAgentError,
AuthenticationError,
ConfigurationError,
NetworkError,
RateLimitError,
} from "@cursor/sdk";
const apiKey = process.env.CURSOR_API_KEY;
if (!apiKey) throw new Error("CURSOR_API_KEY missing");
async function probe(name, fn) {
try {
await fn();
console.log(`${name}: ok`);
} catch (err) {
console.log(`${name}: failed`);
console.log({
name: err?.name,
message: err?.message,
code: err?.code,
status: err?.status,
endpoint: err?.endpoint,
operation: err?.operation,
isRetryable: err?.isRetryable,
cursorAgentError: err instanceof CursorAgentError,
authenticationError: err instanceof AuthenticationError,
configurationError: err instanceof ConfigurationError,
networkError: err instanceof NetworkError,
rateLimitError: err instanceof RateLimitError,
});
}
}
await probe("Cursor.models.list", () => Cursor.models.list({ apiKey }));
await probe("Agent.create local auto with apiKey", async () => {
const agent = await Agent.create({
apiKey,
model: { id: "auto" },
local: { cwd: process.cwd(), settingSources: [] },
});
try {
const run = await agent.send("Hello");
const result = await run.wait();
console.log(result);
} finally {
await agent[Symbol.asyncDispose]?.();
}
});
Run:
export CURSOR_API_KEY="cursor_..."
node repro.mjs
Observed Output
Cursor.models.list: failed
{
name: 'UnknownAgentError',
message: '[plan_required] Cloud Agent is not available for free users. Please upgrade to Pro.',
code: 'plan_required',
status: 403,
endpoint: 'GET /v1/models',
operation: 'Cursor.models.list',
isRetryable: false,
cursorAgentError: true,
authenticationError: false,
configurationError: false,
networkError: false,
rateLimitError: false
}
Agent.create local auto with apiKey: failed
{
name: 'UnknownAgentError',
message: '[plan_required] Cloud Agent is not available for free users. Please upgrade to Pro.',
code: 'plan_required',
status: 403,
endpoint: 'GET /v1/models',
operation: 'Agent.create',
isRetryable: false,
cursorAgentError: true,
authenticationError: false,
configurationError: false,
networkError: false,
rateLimitError: false
}
Investigation Notes
From inspecting the bundled SDK output in @cursor/[email protected], local Agent.create appears to follow this path:
Agent.create({ apiKey, model, local })
-> createDefaultAgent(...)
-> CursorAgentPlatform.createAgent(...)
-> resolveLocalModelSelection(model, apiKey)
-> listModelsForLocalValidation(apiKey)
-> CloudApiClient.listModels()
-> GET /v1/models
Because the backend returns 403 plan_required, the SDK wraps it as UnknownAgentError, not AuthenticationError, ConfigurationError, NetworkError, or RateLimitError.
Why This Seems Like A Bug
The request explicitly uses local runtime:
await Agent.create({
apiKey,
model: { id: "auto" },
local: { cwd: process.cwd(), settingSources: [] },
});
No cloud option is passed. A free user should be able to use local runtime without Cloud Agent plan access, or the SDK should clearly document that any authenticated local run requires Cloud Agent plan access.
Question For Maintainers
Is GET /v1/models intended to be required for local SDK agents when apiKey is provided?
If not, could local model validation skip this cloud endpoint, or treat plan_required as a non-fatal validation failure for local agents?
Expected Behavior
I’m expecting that no error found and sdk should work with my free account
Screenshots / Screen Recordings
Operating System
Windows 10/11
Version Information
Environment
- Package:
@cursor/sdk - Version:
1.0.13 - Runtime: Node.js
v24.11.1 - OS: Windows 11
- Account plan: Free user
- SDK mode being used: local runtime
Does this stop you from using Cursor
No - Cursor works, but with this issue
