@magpie-community/opencode-cursor-auth 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +70 -0
  2. package/index.mjs +1417 -0
  3. package/package.json +11 -0
package/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # @magpie-community/opencode-cursor-auth
2
+
3
+ Signs in to a [Cursor](https://cursor.com) subscription (Pro, Pro+, Ultra,
4
+ Teams) and makes its requests on the API `cursor-agent` talks to, in
5
+ OpenCode and in magpie. Provider id: `cursor`.
6
+
7
+ ## Signing in
8
+
9
+ An account is a Cursor access token. There are three ways to get one:
10
+
11
+ - **Cursor (browser)**: the sign-in `cursor-agent login` does. The page
12
+ `cursor.com/loginDeepControl` is opened with a PKCE challenge, and the
13
+ plugin polls `api2.cursor.sh/auth/poll` until the browser has signed in.
14
+ The account is named by its email (`DashboardService/GetMe`).
15
+ - **cursor-agent's sign-in**: takes the account `cursor-agent login`
16
+ signed in to. Its token is read on every request from where the CLI
17
+ keeps it: the macOS keychain (`cursor-access-token`), else its
18
+ `auth.json` (`~/.cursor/`, `$XDG_CONFIG_HOME/cursor/` or
19
+ `%APPDATA%\Cursor\`). The plugin never writes it; when it has less than
20
+ 5 minutes left, `cursor-agent status` is run, which renews it.
21
+ - **Cursor API key**: a key from cursor.com/dashboard → Integrations. It is
22
+ exchanged for a token at `/auth/exchange_user_api_key`, as the CLI does
23
+ with `CURSOR_API_KEY`, and exchanged again when the token runs out.
24
+
25
+ Sign-ins are kept where OpenCode keeps them (`auth.json`; in magpie,
26
+ `plugin-auth.json`). A browser sign-in's token lasts about two months.
27
+ Cursor gives the CLI no way to renew it, so after that you sign in again.
28
+
29
+ ## Requests
30
+
31
+ OpenCode speaks chat completions (`@ai-sdk/openai-compatible`); the
32
+ plugin's `fetch` answers them on Cursor's agent API:
33
+
34
+ - The agent API is the one `ServerConfigService/GetServerConfig` names for
35
+ the account (a team may be served in one region only), else
36
+ `agentn.global.api5.cursor.sh`. A refusal that names a region is tried
37
+ once more with the config asked again.
38
+ - Each request is one `agent.v1.AgentService/Run`, a Connect stream both
39
+ ways over HTTP/2, with the CLI's headers (`x-cursor-client-type: cli`,
40
+ its version, privacy mode on).
41
+ - The whole conversation goes each time, as AI SDK messages kept as blobs
42
+ the server asks for. The caller's tools are MCP tools, listed in the
43
+ system prompt; the model calls them through Cursor's `CallDynamicTool`,
44
+ and the calls come back as chat completion tool calls. Cursor's own tools
45
+ (shell, file reads, edits) are never run.
46
+ - Text, thinking (`reasoning_content`) and token usage come back streamed
47
+ or not. Failures keep their statuses: 401 to sign in again, 429 at the
48
+ usage limit, 400 for a prompt too long, 403 for a region refusal.
49
+
50
+ ## Models
51
+
52
+ The `config` hook declares `auto` (Cursor's pick). Once signed in, the
53
+ `provider.models` hook lists the account's models
54
+ (`AgentService/GetUsableModels`, cached 10 minutes), by the ids
55
+ `cursor-agent models` shows:
56
+
57
+ - Cursor lists a model once per effort (`gpt-5.6-low`, `gpt-5.6-high`, …).
58
+ Each family is one model here, with the efforts as variants; the
59
+ request's `reasoning_effort` picks the id, fitted to the nearest one there
60
+ is. `-fast` and `-thinking` models stay models of their own; a
61
+ `service_tier` of `priority` picks the fast one.
62
+ - The context window is 1M for a model whose name says 1M, else 200K.
63
+
64
+ ## Not included
65
+
66
+ - Usage and plan limits.
67
+ - Web search: Cursor's own web search is refused like its other tools.
68
+ - Switching between several accounts. OpenCode keeps one sign-in per
69
+ provider.
70
+ - The Responses and Messages APIs: only chat completions are answered.