@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.
- package/README.md +70 -0
- package/index.mjs +1417 -0
- 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.
|