Skip to content

Repository files navigation

claude-cursor-proxy

中文 | English

CI Release GitHub Release License: MIT Platforms

Adapted from raine/claude-code-proxy. This project is a Cursor-first local proxy for Claude Code and Grok Build (grok / grok-build).

Run Cursor models (Fable 5) from Claude Code or grok-build — stably.

Claude Code ──Anthropic /v1/messages──► claude-cursor-proxy (:18765)
grok-build  ──Responses / Messages ──►        │
                                              ├── Cursor (Fable 5)   ← primary
                                              ├── Codex             ← additional
                                              ├── Kimi
                                              └── Grok

Quick start · Models · Sand mode · Features · Config · MCP troubleshooting · Limitations


What it does

Claude Code speaks Anthropic (/v1/messages). grok-build speaks OpenAI Responses (/v1/responses). Cursor uses its own Agent protocol. They do not talk to each other directly.

This tool runs a local one-way proxy (default 127.0.0.1:18765):

  1. Claude Code or grok-build send their usual requests to the proxy
  2. The proxy translates them for Cursor and forwards upstream
  3. It streams the matching SSE back — Anthropic ping keep-alive for Claude Code, Responses events for grok-build

Primary upstream: Cursor (Fable 5). Additional backends in the same process: Codex, Kimi, Grok.

Not affiliated with Anthropic, Cursor, OpenAI, Moonshot, or xAI.


Why

Stable sessions HTTP/2 BiDi upstream + Anthropic ping SSE keep-alive downstream
Fable 5 Set ANTHROPIC_MODEL=claude-fable-5[1m] (and the same for ANTHROPIC_SMALL_FAST_MODEL)
Usage / ctx Cursor turn usage mapped onto Anthropic usage for status lines and compaction
Tools Cursor exec / native tools remapped into Claude Code and grok-build tool loops (best-effort)
Simple install Checksummed binaries; macOS ad-hoc codesign; config under ~/.config/claude-cursor-proxy

Honest scope: best-effort compatibility — not a full Cursor IDE mirror. See Limitations.


Quick start

Install

curl -fsSL https://raw.githubusercontent.com/YeautyYE/claude-cursor-proxy/main/install.sh | bash

macOS / Linux. Windows: download the .zip from Releases (or use WSL).

Other install options
Method Command
Pin version CLAUDE_CURSOR_PROXY_VERSION=v0.1.115 curl -fsSL …/install.sh | bash
Custom dir CLAUDE_CURSOR_PROXY_INSTALL_DIR=/opt/bin bash install.sh
From source cargo install --git https://github.com/YeautyYE/claude-cursor-proxy --locked
Fork / mirror GITHUB_REPO=owner/repo curl -fsSL https://raw.githubusercontent.com/owner/repo/main/install.sh | bash

Log in + serve

claude-cursor-proxy cursor auth login
claude-cursor-proxy serve                 # 127.0.0.1:18765 + monitor TUI
claude-cursor-proxy serve --no-monitor    # logs only
claude-cursor-proxy serve --port 11435    # custom port

Hot account switch (no restart)

Run claude-cursor-proxy cursor auth login in another terminal while serve is running. Credentials are re-read from the store on every request, so:

  • new requests use the new account immediately;
  • in-flight runs keep the token they captured at start and finish on the previous login — nothing is interrupted;
  • existing sessions start a fresh Cursor conversation on their next turn (the client resends its history automatically).

cursor auth status shows the active account. Note: if CCP_CURSOR_AUTH_TOKEN/CURSOR_AUTH_TOKEN is set in the serve process's environment, the env token shadows the store and a login hot swap will not take effect until you unset it.

Multiple Cursor accounts

Use login when you want the newly authenticated account to become active. Use add when you want to keep the current account active and append another login to the local account pool:

claude-cursor-proxy cursor auth add --label work
claude-cursor-proxy cursor auth list
claude-cursor-proxy cursor auth use ACCOUNT_ID
claude-cursor-proxy cursor auth usage                 # every saved account
claude-cursor-proxy cursor auth usage ACCOUNT_ID      # one account
claude-cursor-proxy cursor auth usage --json          # machine-readable

ACCOUNT_ID may be the id printed by list, an unambiguous email, or a label. The pool is stored in cursor/accounts.json; the selected credential remains mirrored to the existing cursor/auth.json so older installations continue to work. In the monitor TUI, press a to open the account panel, Enter to switch, u to fetch the selected account, and U to fetch every account in parallel. Each account has its own refresh worker, so moving to another row does not cancel the account that was just refreshed. Successful snapshots are cached under the state directory and shown again on the next TUI open; the Updated column (or the selected-row detail on narrow terminals) shows the last dashboard fetch time. Press r to refresh the account list and all usage. Press d on a selected account, then y/Enter to confirm deletion (n/Esc cancels). Removing the active account immediately activates the next available account. Adding, switching, or removing accounts does not require restarting serve.

To reserve a saved account for particular models, press m from the main TUI or the account panel. Use j/k to select a model and Enter/Space to choose a saved account or automatic; press x to clear an assignment or a to enter a catalog id that is not listed yet. Changes apply to new requests immediately without changing the active account. Model-bound live runs, conversation checkpoints, KV state, and tool continuations are partitioned by account, so two models can use different accounts concurrently in one serve process. The TUI stores the stable account id; labels and emails remain useful selectors for headless configuration.

Point Claude Code at the proxy (Fable 5)

export ANTHROPIC_BASE_URL=http://127.0.0.1:18765
export ANTHROPIC_AUTH_TOKEN=unused
export ANTHROPIC_MODEL=claude-fable-5[1m]
export ANTHROPIC_SMALL_FAST_MODEL=claude-fable-5[1m]
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
export CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK=1
claude

Same keys work under "env" in ~/.claude/settings.json.

Always set ANTHROPIC_SMALL_FAST_MODEL to a full model id (same as ANTHROPIC_MODEL is fine). Otherwise Claude Code’s background small-model calls return HTTP 400.

Codex / Kimi / Grok
claude-cursor-proxy codex auth login
ANTHROPIC_BASE_URL=http://127.0.0.1:18765 ANTHROPIC_AUTH_TOKEN=unused \
  ANTHROPIC_MODEL=gpt-5.6-sol[1m] ANTHROPIC_SMALL_FAST_MODEL=gpt-5.6-luna[1m] \
  CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK=1 \
  claude

claude-cursor-proxy kimi auth login   # or: grok auth login

Point grok-build at the proxy

grok-build 1.0.13 has two endpoint layers. Startup account settings and the model catalog use the global GROK_CLI_CHAT_PROXY_BASE_URL setting (or [endpoints].cli_chat_proxy_base_url); a [model.*].base_url only controls inference after startup. Point the global endpoint at this proxy as well as each model block below. The environment variable is convenient for a one-shot run; the TOML setting is persistent.

1. Log in (once) and start the proxy

claude-cursor-proxy grok auth login      # required for grok-4.5 / grok-4.6 chat
claude-cursor-proxy cursor auth login    # only if you also route Fable / Composer
claude-cursor-proxy serve                # 127.0.0.1:18765

2. Edit ~/.grok/config.toml — set the global startup endpoint and override the official ids so Fast + effort menus stay enabled. Fast is reasoning.effort = "low".

# ~/.grok/config.toml

[endpoints]
# Grok startup settings/model-catalog requests (required for local proxy):
cli_chat_proxy_base_url = "http://127.0.0.1:18765/v1"
# Optional image/video tools (also a global endpoint):
xai_api_base_url = "http://127.0.0.1:18765/v1"

[auth]
# Do not let an expired grok.com OIDC token block local-proxy startup.
# The proxy uses its own saved upstream credential for these requests.
preferred_method = "api_key"

[model.grok-4.6]
base_url = "http://127.0.0.1:18765/v1"
api_key = "unused"

[model.grok-4.5]
base_url = "http://127.0.0.1:18765/v1"
api_key = "unused"

# Cursor catalog via grok-build (official OpenAI Responses, not Claude Messages)
[model.cursor-grok]
model = "cursor-grok-4.6-xhigh-fast"
base_url = "http://127.0.0.1:18765/v1"
api_backend = "responses"
api_key = "unused"

# Optional: Claude Code-style Anthropic Messages (not the grok-build default)
[model.via-ccp]
model = "claude-fable-5[1m]"
base_url = "http://127.0.0.1:18765/v1"
api_backend = "messages"
context_window = 1000000
api_key = "unused"
supports_reasoning_effort = true
reasoning_effort = "high"

3. Run grok-build

grok --model grok-4.6
# or: grok --model grok-4.5
# or: grok --model cursor-grok
# or: grok --model via-ccp

For a temporary shell/session, the equivalent global override is:

GROK_CLI_CHAT_PROXY_BASE_URL=http://127.0.0.1:18765/v1 \
  grok --model grok-4.6

Inbound api_key is accepted (Authorization: Bearer … or x-api-key; unused, other placeholders, and JWT-looking session tokens are treated as empty) and is not used as a user/tenant id. Grok /v1/responses passthrough forwards conversation, compaction (x-compaction-at, x-compactions-remaining), doom-loop, and a charset-limited x-grok-model-override — never Authorization, Cookie, or x-grok-user-id.

GET /v1/models advertises model, context_window, api_backend=responses (grok-build's official OpenAI Responses backend), supports_reasoning_effort, and reasoning_efforts (grok-4.6 includes xhigh / high / medium / low). A custom [model.*] block that omits api_backend defaults to Chat Completions in grok-build; set api_backend = "responses". This proxy does not implement /v1/chat/completions. /v1/messages remains for Claude Code.

Media routes (/v1/images/*, /v1/videos/*) proxy to https://api.x.ai/v1 (override with CCP_GROK_MEDIA_BASE_URL). A real client key is forwarded; placeholders and grok-build session JWTs fall back to the stored Grok OAuth token.


Models

Set ANTHROPIC_MODEL and ANTHROPIC_SMALL_FAST_MODEL to full model ids. Recommended Cursor default: claude-fable-5[1m].

Other backends use their own full ids (for example gpt-5.6-sol[1m], kimi-for-coding, grok-composer-2.5-fast). Unknown ids return 400.

How to list supported models

# Built-in registry
claude-cursor-proxy models
claude-cursor-proxy models --full

# While serve is running — Anthropic-compatible list
# (merges Cursor GetUsableModels when logged in + registry)
curl -s http://127.0.0.1:18765/v1/models | jq '.data[].id'

Sand mode

Sand is a separate Cursor request surface selected per model. For a model that matches the Sand policy, the proxy sends Cursor's x-cursor-client-type: sand; other Cursor models keep the normal cli (or your configured CCP_CURSOR_CLIENT_TYPE) identity. Mixed routing happens in the same claude-cursor-proxy serve process; a second Sand binary is not needed.

grok-bot is the name of Cursor's server-side Bot/Sand product and entitlement; it is not a local process that must be started before the proxy. On a first-use account, complete Cursor's one-time Bot onboarding in a browser: https://cursor.com/bot/onboarding?product=grok-bot. After the account has the entitlement, keep only claude-cursor-proxy serve running. If the account was just onboarded, run cursor auth login/cursor auth usage once to refresh the stored session and quota snapshot. A response such as Sand traffic is not supported on this endpoint means the selected route rejects Sand traffic. The current proxy keeps plain text and Fable's text-tool/history bridge on InferenceService/Stream; native Sand tool catalogs prefer the strict InferenceService/RunInference handshake and fall back to Stream on that exact route rejection (direct-stream: ready in cursor sand-status confirms the base Sand route). The policy applies only to requests resolved to the Cursor provider; Codex, Kimi, and native Grok routes keep their normal providers by default. There is one intentional Grok exception: an explicit cursor.modelAccounts rule for a grok-* name opts that name into Cursor's account-backed Grok catalog. This lets the same public id be used either for the native Grok provider or for a Cursor account, but the two paths have different logins and quota meters.

Sand selection and account selection are independent. For example, gemini-3.1-pro can be marked [sand] with s and assigned to a specific Cursor account with m; both settings are applied to the same request.

Cursor quota lanes (important for Grok 429s)

Cursor exposes two independent allowance lanes. The account selected by modelAccounts only chooses which account is used; it does not switch a request between these lanes:

TUI marker Cursor surface Dashboard meter Meaning
[cli] AgentService / x-cursor-client-type: cli CLI/API (apiPercentUsed, plus Auto/Total) Normal Cursor CLI requests
[sand] Desktop InferenceService / x-cursor-client-type: sand Sand/Grok Bot (usagePercent) Sand requests, including Cursor Grok

The percentages are used percentages: 100% means that lane is exhausted. A low Sand/Bot value does not replenish an exhausted CLI/API lane, and a full CLI/API meter does not mean Sand is unavailable. The account panel and the m model-account editor show both meters; the selected model's lane is shown first. Use u for one account or U for all accounts to refresh a stale snapshot, then check the Updated timestamp.

The proxy never silently changes the quota lane. For an account-scoped Sand policy/allowance error, it tries the other saved, non-cooled accounts in the same lane, with a per-request hard ceiling of 16 swaps; an explicit model-account binding keeps failover within that binding. Change the model's [cli]/[sand] selection or its account binding in the TUI when you need a different lane or a deterministic account.

Grok 4.6: native route versus Cursor Sand

grok-4.6 is a name shared by two providers:

  • With no Cursor model-account rule, grok-4.6 uses the native Grok provider and the grok auth login credential. Cursor CLI/Sand quotas do not apply.
  • A cursor.modelAccounts rule for grok-4.6 (or an explicit cursor-grok-4.6-* catalog id) selects the Cursor provider and the mapped Cursor account. cursor auth login / cursor auth add manage that account.
  • To spend the Sand/Grok Bot meter, mark the exact Cursor model as [sand] in the TUI. high and xhigh catalog ids are separate rows and can be mapped to different accounts; do not rely on a broad rule when the tiers have different balances.

Recommended TUI flow for a Cursor Grok 4.6 request:

  1. Press s, press a if needed, and add/select cursor-grok-4.6-xhigh-fast; toggle it to [sand].

  2. Press m, select the same model row, choose the account with the desired Sand/Bot balance, and press Enter.

  3. Point grok-build (or Claude Code) at that exact id. For grok-build:

    [model.cursor-grok-sand]
    model = "cursor-grok-4.6-xhigh-fast"
    base_url = "http://127.0.0.1:18765/v1"
    api_backend = "responses"
    api_key = "unused"
    grok --model cursor-grok-sand

If the Events/Requests pane shows cursor-grok-4.6-xhigh-fast [cli], the request is spending CLI/API quota even when the mapped account still has Sand/Bot capacity; toggle that exact row to [sand]. If it shows [sand] and the Sand meter is available, inspect the selected account name/email and the Updated time before retrying. A native grok --model grok-4.6 profile remains on the native Grok provider unless it is explicitly account-bound to Cursor.

For a definitive mapping check, inspect the structured proxy log while sending one request. For a future diagnostic launch, enable the flags before serve and use a spare port; leave an existing serve process untouched:

CCP_LOG_STDERR=1 CCP_LOG_VERBOSE=1 claude-cursor-proxy serve --no-monitor --port 18766

Point the diagnostic client at http://127.0.0.1:18766; otherwise keep using the existing port and inspect its proxy.log.

The cursor_account_selected record includes accountBinding; both it and policy_rate_limit_breaker_open include the truncated accountId, resolved model, clientType, quotaLane, and cached apiPercent/botPercent values. No bearer token is included. Compare those fields with the model badge and the account row's Updated time. A mismatch identifies a routing/configuration issue; matching fields confirm which account and lane were attempted, while Cursor may still reject that lane for a policy or capacity decision.

SandClientMode and SandStreamToolkit are version-locked Cursor Desktop bundle patchers. This proxy does not install, modify, or require a patched Cursor.app: it routes each selected request through its own Sand H2 path. The optional Desktop-bundle section in sand-status is informational only.

Recommended: configure Sand from the monitor TUI. Keep one serve process running and use the shortcuts below; this avoids hand-editing configuration files and makes the active request type visible immediately.

On the first interactive start, the TUI opens a Default Transport chooser. Select CLI / API or Bot / Sand with the arrows or j/k, then press Enter to save. This is the fallback for Cursor models without an explicit [sand] selection; per-model Sand selections still take priority. The saved choice is reused on later starts. Press t at any time to reopen the chooser and switch the default. If CCP_CURSOR_CLIENT_TYPE is set, it remains the authoritative environment override and the TUI leaves it unchanged.

Key Action
s Open Sand Models and select the model list
j / k Move through models
Space / Enter Toggle the selected model between [sand] and [cli]
a Add a model id manually (for example claude-fable-5)
u Open the account-usage view
a (main view) Open the Cursor account panel
m (main view) Assign Cursor models to saved accounts
t Choose the default CLI / API or Bot / Sand lane
Esc / s Close the Sand editor

Fast setup

claude-cursor-proxy cursor auth login
claude-cursor-proxy serve              # keep the monitor TUI open

In the monitor TUI, press s to open Sand Models. Use j/k to select a model, Space or Enter to toggle it, and a to enter an exact Cursor catalog id such as claude-fable-5. From the model list, press u to inspect account usage. The list is marked [sand] or [cli]; changes apply to new requests and are written atomically to config.json. The TUI requires a terminal; serve --no-monitor keeps the proxy running without it.

Fable has no built-in Sand exception. It follows the same explicit model policy as every other Cursor model: select claude-fable-5 (or a catalog variant) in Sand Models to mark it [sand], or leave it unselected to use the configured default identity. An empty policy is valid and no model is added implicitly.

For a read-only terminal diagnostic, run:

claude-cursor-proxy cursor sand-status
claude-cursor-proxy cursor sand-status --json

This reports the effective model policy, Sand client version, H2 transport, proxy route markers, account names, and usage-cache timestamps. Its Desktop bundle inspection is explicitly marked optional and requiredForProxy: false; the command does not open a Cursor request or consume model quota. JSON output contains no access or refresh tokens.

Cursor model cells in the Sessions, Active requests, Recent requests, and Events panes carry the same [sand]/[cli] badge, so the selected request surface is visible without opening the editor. Fable aliases are resolved before matching: a rule for claude-fable-5-thinking-max also covers the usual claude-fable-5[1m], fable[1m], and cursor: forms.

This TUI flow is the recommended way to manage Sand routing. You do not need to edit a file or launch another binary; the running serve process picks up the saved policy for the next request. Environment variables and config.json are fallback interfaces for automation, not the normal setup path.

Use the selected model

After enabling a model with s, point Claude Code at that model:

export ANTHROPIC_BASE_URL=http://127.0.0.1:18765
export ANTHROPIC_AUTH_TOKEN=unused
export ANTHROPIC_MODEL="claude-fable-5"
export ANTHROPIC_SMALL_FAST_MODEL="claude-fable-5"
claude

For a temporary shell/session or automation, CCP_CURSOR_SAND_MODELS can override the TUI policy:

export CCP_CURSOR_SAND_MODELS="claude-fable-5"

To add an exact Cursor catalog id that is not in the current list, press a inside Sand Models and enter it directly; for example, claude-fable-5.

CCP_CURSOR_SAND_MODELS is a comma-separated list and supports * and ?. Model matching is case-insensitive and normalizes [1m] plus cursor:/cursor-agent:/cursor-plan:/cursor-ask: prefixes, so a rule for claude-fable-5 also covers cursor:claude-fable-5[1m]. An environment value always overrides cursor.sandModels in config.json; unset it to edit the file from the TUI. Leave CCP_CURSOR_CLIENT_TYPE at its default cli when you want mixed routing; setting it to sand makes unmatched models use Sand too. Model-specific rules are authoritative and have no hidden Fable exception; account selection and quota failover remain independent.

Model discovery

The built-in Cursor catalog is only an offline/startup fallback. With a Cursor login, the proxy fetches GetUsableModels at startup and refreshes it when GET /v1/models is requested. It also probes Cursor's aiserver.v1.AiService/AvailableModels catalog when available; that response contains canonical family ids, aliases, and effort variants needed to map a CLI slug such as gemini-3.6-flash-high to the Sand family id gemini-3.6-flash. Catalog snapshots are scoped by account and request identity (cli versus sand) and expire after a short TTL, so one account or lane cannot leak model entitlements into another. The returned account catalog is merged into the TUI and model list. You can still add an exact id with a or set it in the environment, but the signed-in Cursor account must expose that model upstream. The active view changes immediately on an account switch, and an in-flight response from the previous account is discarded. Fresh snapshots for other saved accounts remain separately keyed for fast model/account switching; logout clears the active live snapshot.

The live catalog cache is process-local (it never stores credentials) and its TTL is 5 minutes. Within that window repeated /v1/models calls and concurrent warm-up requests reuse one snapshot (one request per account and cli/sand identity); a refreshed access JWT keeps the same account key. A proxy restart starts with the built-in fallback and refreshes the live catalog in the background; it does not load a catalog file from disk. This keeps model entitlements scoped to the account/session that supplied them.

Account usage

The monitor polls Cursor's read-only dashboard endpoints and shows the signed-in account, plan, Auto/API percentages, on-demand dollars, dashboard cost/event totals, and the Sand/Grok Bot period meter when the account provides it. Press u for the multi-line usage view, including the Sand period and recent usage events. cursor auth status shows the active login. On macOS, the monitor can fall back to Cursor Desktop's read-only state.vscdb; missing dashboard fields are omitted rather than invented. In headless serve --no-monitor, a lightweight poller requests only the Sand meter once per minute so an exhausted Sand turn can still be reported as HTTP 429; usage display remains a TUI feature. The full dashboard poll interval is 60 seconds; the in-memory Sand/API evidence used for classifying payload-less turns expires after 180 seconds when dashboard requests temporarily fail. Successful per-account dashboard snapshots are cached at ~/.local/state/claude-cursor-proxy/cursor/account-usage.json on macOS/Linux (or the platform state directory). The cache contains usage data and fetch timestamps only, never access or refresh tokens, and is rebuilt automatically when it is missing or corrupt; an older snapshot remains visible until a successful refresh replaces it. If a worker panics or exceeds its watchdog, the last successful snapshot stays visible and the row leaves its stuck refreshing state. Once the detached request exits, u can retry it; a late network result is accepted only for the account credentials that produced it.

claude-cursor-proxy cursor auth status

Features

  • Anthropic surface: POST /v1/messages, count_tokens, /healthz, /v1/models
  • grok-build surface: POST /v1/responses, POST /v1/images/generations, POST /v1/images/edits, POST /v1/videos/generations, GET /v1/videos/{id}
  • Cursor Agent Connect (BiDi Run); optional HTTP/1 via CCP_CURSOR_HTTP1=1
  • SSE keep-alive (ping) so quiet thinking does not look stalled
  • Model routing by ANTHROPIC_MODEL
  • Auth stored by the proxy; Cursor can fall back to Cursor Agent Keychain / auth.json
  • Monitor TUI when stdout is a TTY (demo for a simulated UI)

Configuration

For interactive routing and usage inspection, prefer the monitor TUI: s selects Sand models, m assigns models to Cursor accounts, a opens account management, and u opens account usage. The file and environment settings below are primarily for headless or automated deployments.

Precedence: env > config.json > defaults.

Platform Path
macOS / Linux ~/.config/claude-cursor-proxy/config.json
Windows %APPDATA%\claude-cursor-proxy\config.json

Override with CCP_CONFIG_DIR. Env prefix stays CCP_* (unchanged from earlier builds). Provider auth files under previous paths (~/.config/claude-cursor-bridge/, ~/.config/claude-code-proxy/) are still read as a migration fallback.

Variable Default Purpose
PORT 18765 Listen port
CCP_BIND_ADDRESS 127.0.0.1 Bind address
CCP_ADVERTISED_MODELS unset Optional comma-separated allowlist for GET /v1/models (useful for managed desktop model pickers)
CCP_CURSOR_AUTH_TOKEN unset Cursor bearer override
CCP_CURSOR_BASE_URL https://api2.cursor.sh Cursor API base
CCP_CURSOR_SAND_BASE_URL value of CCP_CURSOR_BASE_URL Optional base URL for Sand InferenceService/Stream / RunInference
CCP_CURSOR_SAND_CLIENT_VERSION 0.30.0 Sand/Grok Bot API identity version; override only for a gateway that requires it
CCP_CURSOR_SAND_STRICT_H2 0 Force strict H2 prior-knowledge for Sand; normal TLS ALPN is recommended for HTTPS proxies
CCP_CURSOR_CLIENT_TYPE cli Default x-cursor-client-type value; the TUI t chooser persists the same setting in cursor.clientType
CCP_CURSOR_SAND_MODELS unset Comma-separated model selectors routed with x-cursor-client-type: sand; supports * and ?
CCP_CURSOR_SAND_OPEN_CONCURRENCY 512 Maximum simultaneous Sand InferenceService cold opens (1–512); the logical request queue remains 512
CCP_CURSOR_SAND_ACCOUNT_OPEN_CONCURRENCY 512 Maximum simultaneous Sand cold opens per account/model lane (1–512); this is a handshake limit, not a hidden low concurrency default
CCP_CURSOR_SAND_OPEN_INITIAL_INFLIGHT 32 Initial global cold-open in-flight window (1–512); successful opens ramp toward the 512 hard ceiling
CCP_CURSOR_SAND_OPEN_INITIAL_RATE 32 Initial cold-open launch rate per second (1–512); this is a handshake ramp, not the logical request limit
CCP_CURSOR_SAND_ACCOUNT_OPEN_INITIAL_INFLIGHT 32 Initial per-account/model cold-open window (1–512); isolated per route and adaptive after outcomes
CCP_CURSOR_SAND_ACCOUNT_OPEN_INITIAL_RATE 32 Initial per-account/model cold-open launch rate per second (1–512)
CCP_CURSOR_SAND_OPEN_RATE 512 Cold-open launch-rate ceiling; transient failures do not reduce the process-wide window (1–512)
CCP_CURSOR_SAND_OPEN_QUEUE_SECS 3 Sand admission queue slice (1–120s); saturated requests stay queued and retry the slice without issuing unbounded upstream opens
CCP_CURSOR_SAND_OPEN_TIMEOUT_SECS 90 Per-attempt Sand HTTP open timeout (10–180s)
CCP_CURSOR_SAND_OPEN_TOTAL_SECS 180 Total budget for one Sand open/retry episode (20–900s)
CCP_CURSOR_SAND_OPEN_RETRIES unset (TOTAL_ATTEMPTS - 1) Maximum retries inside one Sand open episode (0–8); an explicit value can lower the hard attempt cap
CCP_CURSOR_SAND_TOTAL_ATTEMPTS 3 Hard transport-attempt budget for one open episode (1–8); the whole logical turn is additionally bounded by CCP_CURSOR_SAND_LOGICAL_ATTEMPTS
CCP_CURSOR_SAND_LOGICAL_ATTEMPTS 8 Total Sand transport opens allowed across the initial open and all pre-output replays for one logical turn (1–32)
CCP_CURSOR_SAND_ACCOUNT_FAILOVER_ATTEMPTS 16 Maximum fresh account handoffs for one logical Sand turn (1–16); independent from transport retries
CCP_CURSOR_SAND_OPERATION_ENTRIES 2048 Maximum in-process logical Sand operation records; excess requests receive bounded backpressure
CCP_CURSOR_SAND_OPERATION_SUBSCRIBERS 512 Maximum attached HTTP retries for one logical operation; matches the documented fan-out
CCP_CURSOR_SAND_OPERATION_REPLAY_EVENTS / CCP_CURSOR_SAND_OPERATION_REPLAY_BYTES 16384 / 16MiB Bounded replay history used by duplicate requests; oversized histories stay single-owner
CCP_CURSOR_SAND_RETRY_BUDGET_SECS 600 Shared logical budget across the initial Sand open and pre-output stream replays (60–3600s); queue time is included here, while each admitted open gets its own transport budget
CCP_CURSOR_SAND_BREAKER_THRESHOLD 3 Consecutive transient Sand open failures before the account/model circuit cools down (1–16)
CCP_CURSOR_SAND_BREAKER_COOLDOWN_SECS 15 Sand account/model circuit cooldown (1–300s)
CCP_CURSOR_MODEL_ACCOUNTS unset JSON object or model=account list assigning Cursor model selectors to account ids, unique labels, or emails; supports * and ?
CCP_CURSOR_STATE_DB Cursor Desktop state path on macOS Optional read-only state.vscdb path used by the TUI usage fallback
CCP_CURSOR_HAIKU_MODEL claude-haiku-4-5 Cursor catalog id used for Anthropic haiku aliases and desktop small-model probes
CCP_CURSOR_CATALOG_REQUEST_TIMEOUT_SECS 4 Timeout for the optional AvailableModels metadata probe (capped at 30 seconds)
CCP_CURSOR_CLI_KEYCHAIN_FALLBACK on Disable with 0 / false
CCP_CURSOR_EMBED_SYSTEM off Forward Anthropic system into Cursor user text (can trigger Fable injection loops)
CCP_CURSOR_FORCE_TOOLS_IN_PROMPT off Dump all tool schemas (large); BiDi already keeps Claude-local tools (Workflow/Skill/…)
CCP_CURSOR_LIVE_CONCURRENCY 1024 Fair cap for bulk (cursor-grok-*) generation starts (1–8192)
CCP_CURSOR_LIVE_RUNS 4096 Process-wide cap for live requests holding a Run slot (1–16384); generation-start capacity is controlled separately by CCP_CURSOR_LIVE_CONCURRENCY
CCP_CURSOR_LIVE_INTERACTIVE_RESERVE 128 Protected start capacity for non-Grok models (Gemini/Claude/… subagents); interactive starts may also borrow idle bulk slots, but bulk never borrows the reserve (0–1024)
CCP_CURSOR_LIVE_QUEUE_SECS 30 Maximum local admission wait before retryable HTTP 503 (1–300s)
CCP_CURSOR_LIVE_ATTACH_WAIT_MS 15000 Same-operation attach handoff wait before local busy is returned (500–60000ms)
CCP_CURSOR_LIVE_RESUME_ATTACH_WAIT_MS 4000 Pre-response same-operation attach wait (500–5000ms); kept below the Claude Code stream watchdog
CCP_CURSOR_LIVE_CONFLICT_WAIT_MS 180000 Wait for a different operation to observe the current session Run advance (500–600000ms)
CCP_CURSOR_LIVE_RESUME_WAIT_MS 5000 Pre-response tool-result handoff wait; kept below the client stream watchdog (500–5000ms)
CCP_CURSOR_LIVE_NESTED_WAIT_MS 1500 Pre-response nested-agent handoff wait (500–5000ms)
CCP_CURSOR_RESOURCE_RETRIES 6 Same-request retries for transient Cursor ERROR_RESOURCE_EXHAUSTED responses (1–12); billing/quota/capacity policy 429s are never hidden-retried
CCP_CURSOR_POLICY_429_COOLDOWN_SECS 30 Local cooldown after an account/model/Sand-or-CLI policy 429; fresh requests on that exact route fail fast with HTTP 429 + Retry-After (5–600s)
CCP_CURSOR_POLICY_429_PROBE_WINDOW_MS 30000 CLI/API cold account/model/route single-flight window: useful output releases the wave immediately; a quiet expiry admits only one additional probe (25–120000ms)
CCP_CURSOR_SAND_POLICY_429_PROBE_WINDOW_MS 5000 Sand/Bot cold account/model single-flight window; later quota evidence still opens the account breaker (25–120000ms)
CCP_CURSOR_STEP_FAILURE_RETRIES 4 Same-request retries for pre-output Cursor Failed to run step, exceeded max retries failures (1–8); post-output failures are forwarded
CCP_CURSOR_LIVE_RESUME_RESERVE 64 Additional capacity reserved for paused Runs that need to submit tool results (0–512)
CCP_CURSOR_OPERATION_LEDGER off Opt-in durable operation ledger (crash-safe replay refusal). Stays off by default until completion is gated on downstream delivery, so dropped responses cannot permanently refuse client retries
CCP_CURSOR_LIVE_TIMEOUT_SECS 1800 Active model-generation budget for each live segment (max 3600s; paused while downstream tools run)
CCP_CURSOR_TOOL_TTL_SECS same as live timeout Maximum wait after a tool batch reaches the downstream client; an admitted result is allowed to finish dispatch
CCP_CURSOR_HEARTBEAT_PROGRESS_SECS 1200 Maximum heartbeat-only thinking period without model progress
CCP_CURSOR_GEMINI_FLASH_PROGRESS_SECS 180 Gemini Flash heartbeat-only progress deadline; a hollow pre-output run is rotated and retried inside the same client request instead of appearing stuck
CCP_CURSOR_H2_SHARDS 16 Stable H2 client pools used to isolate concurrent conversations (1–64)
CCP_CURSOR_LIVE_RECOVERY_OPENS 16 Process-wide cap for simultaneous ResumeAction replacement opens (1–128)
CCP_ANTHROPIC_SSE_PING_SECS 5 SSE heartbeat interval (message_delta + ping; keep below Claude Code's 10s stream watchdog)
CCP_CURSOR_NO_PROXY off Skip HTTP(S)_PROXY for Cursor API (1 / true)
CCP_LOG_STDERR / CCP_LOG_VERBOSE / CCP_TRAFFIC_LOG unset Debug

The two Sand open limits cover the HTTP/2 handshake and request headers; those permits are released as soon as the upstream stream is established. The logical request queue and hard ceiling remain 512. The default cold-open window starts at 32 and grows after successful headers, so a fresh Grok route does not receive a synchronized 512-way handshake burst. Operators can tune the global and per-account/model initial windows and rates when a private gateway needs a different ramp. There is deliberately no second process-wide lifetime semaphore for accepted model streams: long generations and tool pauses must not turn the documented 512-way fan-out into a local 504 queue. A saturated open lane is fairly admitted with a pair-wise gate (a waiter never holds an account permit while waiting for a global one), and the shared sharded H2 client pool avoids a new TCP/TLS client per request. Unbound requests that remain behind a slow account lane can rotate on the same account until the bounded logical retry budget is exhausted; explicit model-account bindings stay pinned, while quota/authentication errors still use the account-pool failover path. These controls shape handshake pressure and observability without changing the client's logical concurrency; accepted streams are released by the normal driver on End, transport error, or downstream cancellation.

Claude Code (client) env / settings

These are Claude Code knobs (not proxy config). Useful when /deep-research or ToolSearch misbehaves through a custom ANTHROPIC_BASE_URL:

Variable / setting Purpose
enableWorkflows: true (settings) Force Workflows on if your plan defaults them off
ENABLE_TOOL_SEARCH=true Re-enable ToolSearch when BASE_URL is not api.anthropic.com
_CLAUDE_CODE_ASSUME_FIRST_PARTY_BASE_URL=1 Treat proxy BASE_URL as first-party for some gates (use only if you know you need it)

Rules / skills: Claude Code injects CLAUDE.md and skill text into /v1/messages locally (often as user <system-reminder>). The proxy forwards those messages; it does not strip them. Top-level Anthropic system stays omitted by default (opt in with CCP_CURSOR_EMBED_SYSTEM=1).

Verify /deep-research: transcript should show a Workflow tool_use (name: deep-research), not only Bash curl/mkdir.

{
  "bindAddress": "127.0.0.1",
  "port": 18765,
  "cursor": {
    "sandModels": ["claude-fable-5"],
    "modelAccounts": {
      "claude-fable-5": "work",
      "gemini-3.1-pro": "ACCOUNT_ID"
    }
  },
  "log": { "stderr": false, "verbose": false }
}

This is the shape written by the TUI; manual editing is mainly useful for automation. Account values may be the id printed by cursor auth list, a unique label, or a unique email. Model selectors are case-insensitive and may contain * and ?; an exact model rule wins over a wildcard rule. For an environment-only deployment, the equivalent account policy is:

export CCP_CURSOR_MODEL_ACCOUNTS='{"claude-fable-5":"work","gemini-*":"ACCOUNT_ID"}'

See Sand mode for the complete routing, TUI, model discovery, and usage guide.


MCP troubleshooting

If Claude Code repeatedly prints MCP server 'plugin:lobster-channel:lobster-channel' not connected, the message is produced by Claude Code's local hook dispatcher when its Lobster client is missing or stale. It happens before an HTTP request reaches this proxy, so proxy stream retries do not repair the local MCP registry.

One confirmed cause is Lobster 1.23.0's local lifecycle: Claude Code can start one plugin process per session while the processes share a bridge binding. When a newer process takes over, the bridge closes the older one with code 4405 (session superseded), and that runtime calls process.exit(1). The older Claude session then keeps a disconnected MCP registry entry and can print the error on every hook. Competing pairing processes can similarly cause 4407 handshake takeovers. This is a local Lobster/session-lifecycle problem, not a Cursor inference-stream retry failure.

Use this order:

  1. Keep the existing serve process. Use the monitor TUI first: press s to inspect or toggle Sand models and u to inspect account usage. A second Sand binary is not needed.

  2. Inspect the selected project:

    claude-cursor-proxy mcp-doctor --cwd "$PWD"
    claude-cursor-proxy mcp-doctor --cwd "$PWD" --json

    The doctor scans installed dist/server.js files for the exit-prone 4405 branch, reports explicit 4405/4407 log events, and warns when multiple Lobster processes can compete for the shared binding. If it reports an exit-prone runtime, update Lobster to a build that keeps a superseded process dormant instead of terminating the stdio MCP child.

  3. If the report lists Lobster under disabledMcpServers, run claude-cursor-proxy mcp-doctor --cwd "$PWD" --repair. The repair makes a timestamped backup and removes only Lobster entries. Start a new Claude Code session after the repair.

  4. For an existing session, try /mcp reconnect plugin:lobster-channel:lobster-channel. If the session still reports not connected after a 4405 exit, start a new session after updating Lobster; reconnecting the registry cannot revive a child process that already exited. This does not require restarting the proxy.

  5. Batch commands such as claude --bare --tools "" -p ... should use a dedicated Claude config directory, so global Lobster hooks are not loaded into a process with no matching MCP client:

    BATCH_CONFIG="$(mktemp -d)"
    CLAUDE_CONFIG_DIR="$BATCH_CONFIG" claude --bare --tools "" -p "$PROMPT"

    Put only the settings needed by the batch in that directory; do not copy the global plugin/hooks tree. The doctor follows Claude Code's path rules: default ~/.claude.json, or $CLAUDE_CONFIG_DIR/.claude.json when the variable is non-empty. A legacy .config.json is used only when the canonical file is absent.


Limitations

  • Not official. Provider ToS and account risk are yours.
  • No client auth on the proxy. Loopback by default; non-loopback only behind a firewall or authenticating reverse proxy.
  • Rate limits follow the upstream account.
  • Parity is best-effort. Text, tools, thinking, and streaming work for supported paths; some edge cases are approximated or omitted.
  • Not a full Cursor IDE. Workspace/tool callbacks beyond Claude Code / grok-build tool loops are incomplete.
  • Linux prebuilts are glibc. Alpine/musl: build from source.
Symptom Fix
macOS Killed: 9 codesign --force -s - "$(command -v claude-cursor-proxy)"
Auth / 401 claude-cursor-proxy cursor auth login
Background 400 Set ANTHROPIC_SMALL_FAST_MODEL to a known full model id
Duplicated tools CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK=1
Claude Code prints Edit unavailable / switches to StrReplace, or an edit call loops Update to ≥0.1.83 and restart serve. Claude Code 2.1.193's text_editor_20250728 / str_replace_based_edit_tool pair is preserved end-to-end; Cursor PiEdit replacements are normalized and returned with the matching native result.
/deep-research uses Bash/curl only Update proxy (≥ Workflow passthrough); confirm Workflow in transcript; set enableWorkflows: true if needed
Hung SSE Check ~/.local/state/claude-cursor-proxy/proxy.log; try CCP_LOG_STDERR=1 CCP_TRAFFIC_LOG=1 serve --no-monitor
Image attachment immediately fails with 502 Image not found [internal] Update to ≥0.1.83 and restart serve. The proxy keeps the original inline bytes, rotates the selected-image id once, and retries on a fresh Cursor conversation; a persistent upstream error is then surfaced instead of opening an unbounded retry loop.
grok-build returns 413 Cursor KV blob store limit exceeded (blobs=4097 / about 64 MiB) Update to ≥0.1.84 and restart serve. The proxy rotates a near-limit Cursor conversation before the next turn; an upstream 413 receives one bounded fresh-conversation retry with the complete Anthropic history and refreshed image ids. No manual /compact or new chat is needed.
Gemini/Fable Sand returns ERROR_PRO_USER_RATE_LIMIT_EXCEEDED while the same model works as CLI Sand and CLI are separate Cursor request identities and quota buckets. In the TUI press s, select the model, and toggle it to [cli]; the proxy keeps Sand 429s visible and does not silently spend the CLI/API allowance.
grok-build/Claude Code gets HTTP 429 You're out of usage for grok-4.6 or cursor-grok-* while the mapped account still has Sand/Bot balance Check the request badge first. [cli] uses the account's CLI/API meter; [sand] uses Sand/Grok Bot. A model→account binding selects a credential but does not change the lane. For Cursor Grok, add the exact cursor-grok-4.6-* id in Sand Models, toggle [sand], then bind that same row with m; refresh with u/U and verify Updated. Bare grok-4.6 remains the native Grok provider unless explicitly account-bound to Cursor.
grok-build Server error (500) - Something went wrong on our side on unpaid invoice or unsupported country/region Update to ≥0.1.47 and restart serve. Cursor billing is HTTP 429 with the invoice text; geo/policy blocks are HTTP 403 with the country/region text.
grok-build Server error (500) after Cursor live open timed out / duplicate Cursor runs Update to ≥0.1.57 and restart serve. Response-less live opens fail closed as HTTP 409; local open-slot saturation is jittered HTTP 503.
Sand bursts show 503 Sand open admission queue timed out Update to the current release and restart serve. Admission applies bounded backpressure: saturated requests wait for a real open slot instead of flooding Cursor with untracked opens. Genuine upstream capacity errors still use bounded retries and Retry-After.
Claude Code unexpected internal error then live open timed out after 10s (often gemini-3.6-flash-high) Update to ≥0.1.58 and restart serve. HTTP/1 ResumeAction uses the first-open budget, not a flat 10s.
grok-build Conflict (409) - error sending request / live open timed out after 20s, or Claude Code Agent type 'gemini-3.6-flash-high' not found Update to ≥0.1.57 and restart serve. Proven pre-connect misses may switch transport; response-less sends are never replayed. Agent/Task model slugs remap to general-purpose.
grok-build dumps raw <tool_use> / <parameter> XML, or Cursor auth failed: /usr/bin/security: Too many open files Update to ≥0.1.51 and restart serve. Named-parameter XML is recovered as tools; XML spawn_subagent waits for turn end; serve raises the macOS 256-file limit.
grok-build ends with Cursor finished this turn without text or tool calls, or reports that workflow was intercepted/renamed Update to the current release and restart serve. Live heartbeats no longer abort valid thinking at 240s, while a heartbeat-only run with no model progress is bounded to 20 minutes by default. A truly empty Cursor turn still retries instead of becoming successful assistant text; malformed control XML is quarantined; exact workflow/skill casing is preserved.
grok-build/Grok 4.6 fan-out shows many failed subagents, repeats completed tools, stalls without tokens, or reports rate_limit_error: Cursor live generation concurrency saturated Update to the current release and restart serve. Current defaults admit 1024 bulk starts, protect another 128 interactive starts and 64 tool-result resumes, queue overflow fairly for up to 30 seconds, spread conversations across 16 H2 pools, and bound replacement opens to 16. Start a fresh Grok session after upgrading.
grok-build Conflict (409) - Cursor live open timed out after 20s then many A Cursor live run is already active, or requests stay streaming at 0 B/s Update to ≥0.1.65 and restart serve. H2 first-open waits 90s; after one timeout the H2 circuit uses HTTP/1 for 30s, then half-opens with one read-only model-catalog probe. A still-connected duplicate is HTTP 503 + Retry-After; an identical retry whose original consumer is gone attaches to the in-flight run and replays the segment, and a retry of an already-completed turn receives the retained original response. Genuinely ambiguous acceptance remains fail-closed as 409. Start a fresh Grok session after upgrading.
Cursor produced an empty turn after tool results without a newer checkpoint, or grok-build Conflict (409) - Cursor resume produced no progress after tool results Update to ≥0.1.82 and restart serve. A newer post-result checkpoint is continued directly. If Cursor omits it and no text/new tool reached the client, the proxy clears the stale Cursor state and internally retries the same downstream request from the complete Anthropic history, which already contains the finished tool_result. Partial result dispatch or client-visible partial output still remains ambiguity-fenced.
grok-build reports Cursor tool result wait expired, or a heartbeat stall first appears as 502 and then 409 Update to ≥0.1.62 and restart serve. Tool time starts when Grok receives the batch and no longer consumes the next model segment's budget; an already-admitted tool result wins the TTL boundary. Unresolved heartbeat completion is reported as 409 immediately because replay could duplicate the Run.
Claude Code Bash widget titles a giant python3 -c script Update to ≥0.1.48 and restart serve. Cursor Shell has no description; the proxy now fills a short one-line title.
45s 502 idle timeout / 0 response bytes Update to ≥0.1.39 and restart serve. Still set CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK=1. Clash/Surge TUN: DIRECT *.cursor.sh. Optional: CCP_CURSOR_HTTP1=1
Stream idle timeout - no chunks received, especially on the first turn or before a background tool result resumes Update to the current release and restart serve. /v1/messages commits the Anthropic SSE lifecycle before Cursor live open, so the client receives bytes immediately and emits a watchdog-safe message_delta + ping heartbeat every 5s by default. Pre-output Cursor open/step failures stay inside the bounded retry loop; /v1/responses intentionally keeps held-HTTP mapping for response.failed.
Gemini/Fable returns ERROR_PRO_USER_RATE_LIMIT_EXCEEDED repeatedly, or Sand says finished this turn without text or tool calls on every resend Update to ≥0.1.82 and restart serve. Explicit policy errors and Sand's 100%-meter empty-END sentinel become HTTP 429 with Retry-After; a short cold-key gate stops the first retry wave before it opens many identical Runs. Cooldowns are isolated by stable account, resolved model, and Sand/CLI route, while native tool-result continuations and accepted attaches keep their resume path.
grok-build context compaction reports idle timeout after 45s with no useful progress / 0 response bytes, or the response parser rejects compaction events Update to ≥0.1.82 and restart serve. xai-compact-* and compact_20260112 requests use a stable isolated Cursor live lane, and summaries are emitted as standard Responses assistant/output-text events accepted by Grok Build.
Claude Code shows Cursor live run cancelled, or Grok 4.6 repeatedly reports A Cursor live run is already active after /compact Update to ≥0.1.77 and restart serve. Replacement reservations keep both the old operation fingerprint and its durable Run owner through cancellation teardown; a dropped handoff now seals the existing ledger marker as a scoped ambiguous operation instead of leaving Dispatched state that blocks every later turn. Completed runs are replayed after an attach race and resolved pre-output cancellation is retried inside the same SSE request.
502 Image not found [internal] on a text-only turn Update to ≥0.1.40 and restart serve, then retry the same message once (the poisoned conversation checkpoint is cleared on that error). A new Claude Code session also works.
502 Conversation data missing / missing blobs and the session cannot recover Update to ≥0.1.45 and restart serve, then retry the same message. The failed turn now resets the unrecoverable Cursor conversation binding; the first retry replays full history in a fresh Cursor conversation without requiring a new Claude Code chat.
400 Missing tool_result blocks for pending tools after an interrupted turn / with background shells Update to ≥0.1.45 and restart serve. A new request without current-turn tool results now supersedes the abandoned live turn; partial tool-result batches are still rejected.
25s 502 broken pipe (reconnect skipped: no checkpoint) on the first message Update to ≥0.1.44 and restart serve. First-turn ResumeAction uses conversation_id even before a checkpoint, and broken-pipe H2 flips to HTTP/1. Clash/Surge TUN: DIRECT *.cursor.sh. Optional: CCP_CURSOR_HTTP1=1
46s 502 Cursor stream produced no useful progress on Fable high Update to ≥0.1.43 and restart serve. Heartbeat-only thinking waits 240s; a fully silent stream still fails at 45s. Clash/Surge TUN: DIRECT *.cursor.sh. Optional: CCP_CURSOR_HTTP1=1
502 Cursor live open timed out after 20s / follow-on 90s buffered 502 Update to ≥0.1.42 and restart serve. H2 first-open is 20s; HTTP/1 is 90s and only after 464/421. Clash/Surge TUN: DIRECT *.cursor.sh. Optional: CCP_CURSOR_HTTP1=1
~8 min 502 error decoding response body Update to ≥0.1.41 and restart serve. Reconnect is bounded to 45s. Clash/Surge TUN: DIRECT *.cursor.sh. HTTP proxy mode: CCP_CURSOR_NO_PROXY=1. Optional: CCP_CURSOR_HTTP1=1

Contributing

See CONTRIBUTING.md. Before a PR: cargo fmt, cargo clippy -- -D warnings, cargo test --all.

Security: SECURITY.md.

License

MIT — includes copyright from the upstream project and this fork’s maintainers.

About

Local proxy so Claude Code and grok-build (Grok CLI) can use Cursor models (Fable), plus Codex, Kimi, and Grok

Topics

Resources

Contributing

Security policy

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages