Cursor LLM gateway config is a no-op: writes settings Cursor never reads
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 2.2k
- Forks
- 300
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 184
Description
Summary
thv llm setup --client cursor reports success and patches ~/Library/Application Support/Cursor/User/settings.json with:
"cursor.general.openAIBaseURL": "http://localhost:14000/v1",
"cursor.general.openAIAPIKey": "thv-proxy"
(pkg/client/config.go:517-519, via ConfigureLLMGateway in pkg/client/llm_gateway.go). The gateway proxy (thv llm proxy start) starts and responds correctly. But nothing changes in Cursor: Settings → Models → "Override OpenAI Base URL" stays off, and manually switching it on shows the stock default (https://api.openai.com/v1), not the value from settings.json.
Root cause
Checked directly against the installed Cursor client (workbench.desktop.main.js, Cursor 3.15.19). The keys ToolHive writes — openAIBaseURL / openAIAPIKey (with that exact casing, under cursor.general.*) — do not appear anywhere in the bundle. The feature Cursor actually has is openAIBaseUrl (lowercase Url) plus a separate useOpenAIKey boolean, and both are read and written exclusively through Cursor's own internal state store, not the standard VS Code configuration service:
this.reactiveStorageService.applicationUserPersistentStorage.openAIBaseUrl ?? "https://api.openai.com/v1"
...
i.setApplicationUserPersistentStorage("openAIBaseUrl", v)
i.setApplicationUserPersistentStorage("useOpenAIKey", !0)
There is no code path in the bundle that reads cursor.general.openAIBaseURL (or any cursor.general.* key) from settings.json for this feature. So ConfigureLLMGateway for Cursor patches a file/key that the current app never consults — thv llm setup succeeds and reports nothing wrong, but the integration silently does nothing.
I have not yet located where applicationUserPersistentStorage actually persists to disk — a search of ~/Library/Application Support/Cursor/User/globalStorage/state.vscdb's ItemTable for openai/baseurl/apikey-like keys came up empty, so it's under a different key format, a different table, or a different storage file entirely.
Why this needs care, not just a key-name fix
applicationUserPersistentStorage is Cursor's own internal, undocumented storage mechanism — not a stable public API surface the way settings.json is. Even once the correct persistence location is found, writing into it directly is inherently more fragile than the settings.json approach ToolHive uses for every other client, and could silently break again on a future Cursor release. Worth deciding whether:
- It's worth reverse-engineering and writing to Cursor's private storage anyway (accepting the fragility), or
- Cursor should be marked as unsupported for the LLM gateway proxy-mode integration until/unless Cursor exposes a supported configuration surface for this, or
- Some other integration point exists (e.g. a documented settings key for a different mechanism, or an extension-based approach) that hasn't been checked yet.
Impact
Every thv llm setup --client cursor run to date has silently failed to configure Cursor, while reporting success. Given IsClientInstalled/DetectedLLMGatewayClients both consider Cursor supported and configured, this has presumably shipped since Cursor support was added and gone unnoticed.
References
pkg/client/config.go:485-521(Cursor'sclientAppConfig, including theLLMGatewayKeysspecs)pkg/client/llm_gateway.go:39-89(ConfigureLLMGateway, the JSON-Pointer patch path used for Cursor)- Related: #6292 (Cursor/VSCode detection false negatives) — that issue is about detection; this one is about the actual configuration being applied being ineffective even when detection succeeds.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in pkg/client/config.go:485-521 and pkg/client/llm_gateway.go:39-89, then trace the Cursor path used by thv llm setup --client cursor. Determine whether Cursor has a reliable supported configuration surface or whether the client should be marked unsupported; done means the chosen behavior is implemented and setup no longer silently claims success for an ineffective integration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100