Continue takes an OpenAI-compatible API as a model entry in config.yaml: provider: openai, a base URL, a key and the roles the entry serves. One block, and an uncensored build answers in Chat, edits inline and runs Agent mode in VS Code, JetBrains and the cn CLI. The same ids work in Cursor, OpenCode and, through a router, in Claude Code.
Where the settings are
Continue has no separate OpenAI-compatible provider. Per its docs, a server that answers the OpenAI format is set up as provider: openai with an apiBase, and that is what this API is. The settings live in ~/.continue/config.yaml on macOS and Linux and %USERPROFILE%\.continue\config.yaml on Windows; Continue creates the file the first time it runs.
To open it from the IDE: open the Continue sidebar (Cmd/Ctrl + L in VS Code, Cmd/Ctrl + J in JetBrains), click the agent selector above the chat input, hover the agent and click the gear icon. The configs dropdown at the top right of the chat input has the same file behind the cog beside Local Config. The cn CLI reads the same file by default, so one edit covers the extension and the terminal.
config.json in the same folder is the older format and is deprecated in the docs; the YAML below is the current one, with the JSON shape shown once for a file that is still on it.
Steps
- Create a key in the console and put it in
~/.continue/.env, one line, no quotes:
UNCENSOREDLLM_API_KEY=sk-ullm-live-…Continue resolves ${{ secrets.UNCENSOREDLLM_API_KEY }} from that file. A project-only key goes in .env at the workspace root or in .continue/.env under it; the docs check those two first, then the global file, then the process environment. The last one is for the CLI only: the VS Code and JetBrains extensions cannot read shell variables.
- Add these entries under
models:inconfig.yaml, keeping the file’sname,versionandschemalines as they are. The three ids are the ones Continue users call most here; any id on the models page goes in the same way, with its display name from the catalog and its context length where the catalog publishes one:
models: - name: GLM-5.3 Uncensored provider: openai model: glm-5.3-uncensored apiBase: https://api.uncensoredllm.ai/v1 apiKey: ${{ secrets.UNCENSOREDLLM_API_KEY }} roles: [chat, edit, apply] capabilities: [tool_use] - name: GLM-5.3 Flash Uncensored provider: openai model: glm-5.3-flash-uncensored apiBase: https://api.uncensoredllm.ai/v1 apiKey: ${{ secrets.UNCENSOREDLLM_API_KEY }} roles: [chat, edit, apply] capabilities: [tool_use] - name: DeepSeek V4.1 Flash Abliterated provider: openai model: deepseek-v4.1-flash-abliterated apiBase: https://api.uncensoredllm.ai/v1 apiKey: ${{ secrets.UNCENSOREDLLM_API_KEY }} roles: [chat, edit, apply] capabilities: [tool_use]- Save. The three names appear in the model selector of the chat input; pick one, then choose Chat, Plan or Agent in the mode selector below the input (
Cmd/Ctrl + .cycles). Edit and Apply use the same entries through their roles.
To paste the key instead of using a secret, put the whole sk-ullm- key on the apiKey line; the docs show both forms. The same entry in the deprecated config.json, for one model, looks like this (title instead of name, no roles):
{ "models": [ { "title": "GLM-5.3 Uncensored", "provider": "openai", "model": "glm-5.3-uncensored", "apiBase": "https://api.uncensoredllm.ai/v1", "apiKey": "sk-ullm-live-…" } ]}In the terminal, cn starts with the same config.yaml; cn --config points it at another YAML file for one session and /config inside the TUI switches between the local configs it knows:
cn --config ~/.continue/config.yamlWhat each setting does
- name
- the display namethe label Continue shows for the entry; it has to be unique in the file
- provider
- openaithe request format; Continue speaks OpenAI chat completions to any apiBase under it
- model
- glm-5.3-uncensoredthe id sent in each request, exactly as the models page spells it
- apiBase
- https://api.uncensoredllm.ai/v1where the requests go instead of OpenAI; ends in /v1, never in /chat/completions
- apiKey
- ${{ secrets.UNCENSOREDLLM_API_KEY }}the whole sk-ullm- key, by secret name or pasted; sent as the bearer token
- roles
- [chat, edit, apply]where the entry can be picked: chat and Agent, inline edits, applying a diff; autocomplete, embed and rerank are the other roles
- capabilities
- [tool_use]tells Continue the model takes tool calls, which Plan and Agent need; it only adds to what Continue detects on its own
- defaultCompletionOptions
- contextLengththe window Continue budgets prompts against; maxTokens, temperature and stop go in the same map
- requestOptions
- timeout, caBundlePath, headersper-model HTTP settings; the fix for a custom certificate authority lives here
Picking a model
Continue sends OpenAI-format requests under provider: openai, and every build on the models page answers in that format. An Agent turn carries the conversation, the files Continue read and every tool result so far, so input tokens are most of the bill and a build with a low input price costs the least per turn. The last column says whether the build takes native tool calls. Continue’s docs say it falls back to system-message tools for a model without them, so capabilities: [tool_use] stays on every entry either way.
| Model | One Agent turn | Tool calls |
|---|---|---|
| GLM-5.3 Uncensored | $0.01 | model page |
| GLM-5.3 Flash Uncensored | $0.0047 | model page |
| DeepSeek V4.1 Flash Abliterated | $0.04 | model page |
| DeepSeek V4 Pro Uncensored | $0.04 | model page |
| GLM-5.3 Abliterated | $0.09 | model page |
| GLM-5.3 Flash Code Uncensored | $0.25 | model page |
| GLM-5.3 Uncensored | Uncensored | $0.282 | $0.846 |
| GLM-5.3 Flash Uncensored | Uncensored | $0.1053 | $0.3685 |
| DeepSeek V4.1 Flash Abliterated | Abliterated | $0.8488 | $1.6975 |
| DeepSeek V4 Pro Uncensored | Uncensored | $0.97 | $1.94 |
| GLM-5.3 Abliterated | Abliterated | $2.1825 | $4.365 |
| GLM-5.3 Flash Code Uncensored | Uncensored | $6.00 | $6.00 |
The block gives each entry the chat, edit and apply roles, which cover Chat, Plan and Agent, the inline edit and the step that writes a proposed diff into the file. autocomplete is a separate role with its own prompt template and its own request shape; the docs’ own example pairs a chat model with a dedicated autocomplete model, and that split holds here. Leave these entries off autocomplete and keep whatever fills that role today. embed and rerank are indexing roles and stay where they are as well.
For coding specifically, the uncensored coding AI guide compares the code builds and costs a full coding day on each. The same ids work in Cursor and OpenCode with their own settings.
Check it
List the models your key can call; every id you put under models: should be in the answer:
curl https://api.uncensoredllm.ai/v1/models -H "Authorization: Bearer sk-ullm-live-…"Then send one request the way Continue does. -i prints the headers: x-uplink-request-id names the request, and on a non-streamed answer x-uplink-charge is what it cost in USD.
curl -i https://api.uncensoredllm.ai/v1/chat/completions \ -H "Authorization: Bearer sk-ullm-live-…" \ -H "Content-Type: application/json" \ -d '{"model": "glm-5.3-uncensored", "messages": [{"role": "user", "content": "Reply with the single word ok."}]}'In Continue, send a message in Chat with one of your entries selected, then switch to Agent and ask for a small edit. Agent asks before it runs a tool by default; the docs’ tool policies make a tool automatic or exclude it. Plan does the same with read-only tools, so it is the safe place to watch a new build read the repository before it changes anything. The requests show on the console’s usage page with their tokens and their charge.
Errors and fixes
401 invalid_api_key: the key is wrong or revoked, or the secret did not resolve. A key exported in the shell is invisible to the extensions; put it in~/.continue/.envunder the name used in${{ secrets.UNCENSOREDLLM_API_KEY }}, or copy it again from the console.404 model_not_found: themodelline is not an id on the models page. Check the spelling against the page; the id goes inmodel, not inname.404with no model in the message:apiBaseis missing its/v1, or has/chat/completionsappended. Continue adds the route itself;apiBaseends at/v1.402 insufficient_balance: the balance does not cover the request. Top up in the console.402 monthly_limit_reachedmeans the key hit the monthly spend limit you set on it.403 scope_denied: the key is limited to certain models and this is not one of them.429 rate_limited: the key hit its rate limit. The response carriesretry-after.- Plan or Agent greyed out with Not Supported: Continue did not detect tool support on the entry. The docs’ fix is
capabilities: [tool_use]on the model, which the block above already has; a build whose model page says it takes no tool calls runs on Continue’s system-message tools instead. - The entries are missing from the model selector: the configs dropdown is on another config. Switch it to Local Config, the one backed by
~/.continue/config.yaml. fetch failedon a network with its own certificate authority: setrequestOptions.caBundlePathon each entry to the exported CA file, per the FAQ in Continue’s docs.- Requests arriving at
/completionsinstead of/chat/completions: the entry carriesuseLegacyCompletionsEndpoint: true. Remove it; the API serves chat completions.
Questions
provider: openai, with apiBase set to the API’s /v1 URL. Continue has no separate OpenAI-compatible entry; its docs route every server that answers the OpenAI chat format through the openai provider and an apiBase override, and this API is one of them.
On the apiKey line of the model entry, either pasted in full or as ${{ secrets.NAME }} with NAME defined in ~/.continue/.env, a workspace .env or .continue/.env. Shell variables reach the cn CLI only; the VS Code and JetBrains extensions read the .env files.
No. The API already speaks the OpenAI format with its own key, so Continue connects to it directly with the entry above. A LiteLLM proxy only adds something when you route several providers behind one local URL. See the LiteLLM guide.
Yes. Agent and Plan need tool calls, so each entry carries capabilities: [tool_use]; the builds whose model page lists native tool support handle them directly, and Continue’s docs say the rest run on its system-message tools. The table above costs one Agent turn on each at the live price. See the models page.
Every model above is on the uncensored model list with its live price per million tokens. Per-token pricing sets the whole catalog side by side, and the family directory groups the builds by base model.