Cursor CLI calling `composer2-fast` despite always calling with `composer2

Where does the bug appear (feature/product)?

Cursor CLI

Describe the Bug

I’m calling cursor cli from a local app and am regularly seeing calls to composer2-fast despite ensuring that every call is passing in a model call to composer2. There’s a substantial increase in cost and I’m really trying to avoid hitting composer2-fast at all.

It also appears to be for pretty large calls (800k-1.2m+ tokens).

Date
Type
Model
Tokens
Cost
May 11, 09:46 PM
Included
composer-2-fast
0
Included
May 11, 09:44 PM
Included
composer-2-fast
1.1M
Included
May 11, 09:33 PM
Included
composer-2
1.1M
Included
May 11, 09:27 PM
Included
composer-2-fast
804.6K
Included

Steps to Reproduce

Call cursor cli w/ a reasonable sized prompt and pass in composer2 as a model.

Expected Behavior

composer2 is always selected as a model.

Operating System

MacOS

Version Information

CLI: 026.05.09-0afadcc

For AI issues: which model did you use?

composer2

Does this stop you from using Cursor

No - Cursor works, but with this issue

Hey, thanks for the report. Let’s dig in.

A few questions to narrow this down:

  1. What exact model string are you passing, composer2 or composer-2 with the dash? The CLI expects composer-2, and if it doesn’t match, it may fall back to the default composer-2-fast.
  2. How are you authenticating in the CLI, OAuth or a user API key crsr_*? And are you running it interactively or headless with agent -p?
  3. Can you share 2 to 3 Request IDs from the sessions that showed up in the dashboard as composer-2-fast, for example the 1.1M token one at 09:44 PM? You can find them in the CLI output or in the dashboard. With those we can check which backend path was used.

In parallel, two things that might matter here:

  • Built-in subagents the agent spawns on its own, like explore and generalPurpose, currently default to composer-2-fast regardless of the parent --model. This is a known limitation, tracked internally, with no ETA. That said, 800k to 1.2M tokens for a subagent is unusually large, so this is probably not it in your case.
  • There was a similar report in this thread Cursor CLI unable to use composer 2 classic where --model composer-2 is accepted, system/init shows “Composer 2”, but billing still goes under composer-2-fast. If you’re using headless mode with an API key, that matches.

Once you send the info above, we can look at the specific requests.

Thanks for the quick response!

  1. I’m passing composer-2 as the model (as i understand the default / fallback is composer2-fast).
  2. I’m authenticating in the cli and then starting a new session. I’m running it headless with -p.
  3. Request ID’s:

I also just installed the Cursor SDK in case that behaved differently and i’m seeing the same behavior. My first call (a decent sized prompt) kicked off a 2.1M composer2-fastrequest despite passing in the model explicitly (I’ll pass in my parameters below).

A few request ID’s:
“2026-05-11T15:05:59.512Z”,“”,“”,“Included”,“composer-2-fast”,“No”,“0”,“59353”,“3915200”,“35143”,“4009696”,“Included”
^^^ called via Cursor SDK with composer-2

[0] [agent-spawn-provenance] {“type”:“agent_spawn_provenance”,“ts”:“2026-05-11T15:05:48.562Z”,“threadId”:“2825086e-fbb2-45ce-ba56-0a99d01321f2”,“cwd”:“/Users/iolo/code/stormsword”,“callsite”:“cursorRunner.spawnCursor.runAttempt”,“spawnKind”:“user”,“usedResume”:false,“rawModelInput”:“composer-2”,“resolvedModel”:“composer-2”,“coalescedFromEmptyRequest”:false,“usedRufusDefaultCoalesce”:false,“fallbackToCliBinaryDefault”:false,“argsModelFlag”:“–model=composer-2”}

“2026-05-11T13:47:30.240Z”,“”,“”,“Included”,“composer-2-fast”,“No”,“0”,“732”,“212128”,“822”,“213682”,“Included”
“2026-05-11T13:46:58.646Z”,“”,“”,“Included”,“composer-2-fast”,“No”,“0”,“168229”,“859872”,“16167”,“1044268”,“Included”
“2026-05-11T13:44:55.850Z”,“”,“”,“Included”,“composer-2-fast”,“No”,“0”,“52866”,“1362752”,“22400”,“1438018”,“Included”

One of these was cancelled i believe but these 3 were run via cursor-cli with -p

Let me know if there’s more i can do to help diagnose/debug!

Hello just following up to see if there’s any movement here. I’ve been trying to exclusively use cursor cli or sdk for all my usage and had to stop using these itnegrations entirely and rely on the IDE for the past few days. I’d love to keep using these tools because they are PERFECT for my workflow !

hey @iolo I may have the solution you are looking for, Fast is the default model for composer 2, to force the use of the non fast variant, you need to send the model such as the following :

model: {
id: “composer-2”,
params: [{ id: “fast”, value:
“false” }],
},

.. Or also, if you are using the sdk, by calling Cursor.models.list() it will show you all the available models! Hope this help

Thanks Tom! I was looking at the CLI documentation and don’t see a way to pass in structured data like this.

Running through this made me realize my sdk test earlier probably didn’t work (I didn’t pass in an API key). So.. I worked through the integration again today and got to a point where i can make a request but I’m getting a 401/auth error when trying to create a local agent via SDK/API using composer (not fast).

model: {
id: “composer-2”,
params: [
{ id: “fast”, value: “false” }
]
},
local: {
cwd: “/Users/iolo/code/stormsword”
},
apiKey: process.env.CURSOR_API_KEY

SDK runtime logs:

{
“action”:“agent.create”,
“requestedModel”:“composer-2”,
“requestedParams”:{“fast”:false}
}

SDK error returned:

AuthenticationError: Error

status: 401
endpoint: GET /v1/models
operation: Agent.create
isRetryable: false

Stack trace:

AuthenticationError: Error
    at c.throwApiError (/node_modules/@cursor/sdk/dist/esm/index.js:8:1069576)
    at c.<anonymous> (/node_modules/@cursor/sdk/dist/esm/index.js:8:1068523)
    at Generator.next (<anonymous>)
    at i (/node_modules/@cursor/sdk/dist/esm/index.js:8:1066607)
    at process.processTicksAndRejections (node:internal/process/task_queues:104:5

Thanks for trying this and sharing the logs. A few important notes:

Main point about composer-2 non-fast. I looked into a similar case in this thread Cursor CLI unable to use composer 2 classic - #14 by deanrie. Composer-2 non-fast was recently removed from the cursor-agent CLI route. The --model composer-2 flag is accepted, but the request actually goes to composer-2-fast, so you see fast in the dashboard. That explains your original billing symptom. Whether this also applies to the SDK local runtime needs confirmation from the team, I can’t say for sure.

About the 401 on GET /v1/models. That’s a separate issue, let’s dig in. A few questions:

  • What version of @cursor/sdk are you on (npm list @cursor/sdk)?
  • How exactly are you initializing the client? The standard pattern is to set CURSOR_API_KEY in env instead of passing apiKey inside the Agent.create options. Can you try:
    export CURSOR_API_KEY=...
    
    And in code, don’t pass apiKey in options at all.
  • What does await Cursor.models.list() return with that key? If it fails with 401, it’s an auth issue (key, scope, or endpoint). If it works, the issue is likely in the Agent.create payload.
  • The Request ID for the 401 response, if it’s in the SDK logs.

Also, try the most minimal setup first with no params, just model: "composer-2" as a string. In this thread @cursor/sdk 1.0.12 local runs: Opus / GPT-5.4–5.5 / Sonnet 4.5–4.6 / Grok / Codex 5.3 error with empty RunResult it worked for that user. If 401 doesn’t reproduce without params, then it’s likely the params shape, not auth. Keep the composer-2 routing note above in mind, even if the request succeeds, billing may still show fast.

Send me your answers and I’ll try to reproduce on my side too.

Thanks Dean, I just wrote a quick reference implementation and was able to diagnose my issue (the apiKey was not being passed in properly).

I’m now able to successfully call the SDK and pass the parameters mentioned to get composer-2 (not fast) responses from the SDK (at least according to the dashboard)!

I’ll do some tests today because I ran the same prompt (‘say hello’) against composer-2 and composer-2-fast via the SDK and both used about 8k tokens. I would expect composer-2 to be lower but it could be the same because it’s such a simple request.

Thanks again! Will report back if i run into any issues.

Great news that you figured it out. Setting fast: false for composer-2 via the SDK is the correct way to get the non-fast version, and the dashboard is accurate in this case.

A couple notes:

  • For “say hello”, seeing the same ~8k tokens between composer-2 and composer-2-fast is normal. The difference in cost and behavior is more noticeable with larger contexts and harder tasks where the models actually diverge.
  • For the CLI, the situation is still the same: --model composer-2 is accepted, but it actually gets routed to fast. So if you want guaranteed composer-2 non-fast right now, it only works via the SDK with those params. When the CLI routing gets fixed, I’ll let you know.

Run some tests and ping me if anything else comes up. If you ever see composer-2-fast in the dashboard when you explicitly set fast: false via the SDK, I’d love to take a look, especially if you can share the Request ID.

thanks @deanrie !