Zed with an uncensored model

One openai_compatible block in Zed’s settings.json: the API URL, uncensored ids with their context windows and capabilities, the key in the keychain or an env var. The cost per agent turn and the errors.

Steps checked November 2, 2026 · prices as of November 9, 2026

Zed’s Agent Panel takes an OpenAI-compatible provider in settings.json: an API URL, the model ids with their context windows, and a key in the keychain or an environment variable. One block, and an uncensored build answers in the panel with tool calls for edits and terminal commands. The block below carries the UncensoredLLM URL and the ids Zed users run here.

Where the settings are

Zed keeps the provider in its user settings file: ~/.config/zed/settings.json on macOS and Linux, %APPDATA%\Zed\settings.json on Windows. Open it with zed: open settings file from the command palette. The project file .zed/settings.json takes editor and language options only, so the provider goes in the user file.

The same provider can be added from the settings UI: agent: open settings (also in the Agent Panel’s top-right menu) opens Settings → AI → LLM Providers, where Add Provider asks for a provider name, an API URL, a model ID and a context window. The key is entered on that page too, or read from an environment variable. It never goes in settings.json.

Steps

  1. Add the provider to settings.json. Zed needs max_tokens for every entry, so the three ids under available_models are the first of the builds below whose context window the catalog publishes; any id on the models page goes in the same way, with the window its page states. The agent.default_model block selects the first one for new threads:
settings.json
1{
2 "language_models": {
3 "openai_compatible": {
4 "uncensoredllm": {
5 "api_url": "https://api.uncensoredllm.ai/v1",
6 "available_models": [
7 {
8 "name": "deepseek-v4.1-flash-1017-uncensored",
9 "display_name": "DeepSeek V4.1 Flash 1017 Uncensored",
10 "max_tokens": 1048576,
11 "capabilities": { "tools": true, "images": false, "parallel_tool_calls": false, "prompt_cache_key": false }
12 },
13 {
14 "name": "glm-5.3-flash-apex-abliterated",
15 "display_name": "GLM-5.3 Flash Apex Abliterated",
16 "max_tokens": 1048576,
17 "capabilities": { "tools": true, "images": false, "parallel_tool_calls": false, "prompt_cache_key": false }
18 },
19 {
20 "name": "kimi-k3-uncensored",
21 "display_name": "Kimi K3 Uncensored",
22 "max_tokens": 262144,
23 "max_output_tokens": 65536,
24 "capabilities": { "tools": true, "images": true, "parallel_tool_calls": false, "prompt_cache_key": false }
25 }
26 ]
27 }
28 }
29 },
30 "agent": {
31 "default_model": {
32 "provider": "uncensoredllm",
33 "model": "deepseek-v4.1-flash-1017-uncensored"
34 }
35 }
36}
  1. Create a key in the console and give it to Zed one of two ways. In the UI: agent: open settings, find uncensoredllm under LLM Providers and paste the key; Zed stores it in the system keychain. Or export it in the environment Zed starts from, under the name Zed derives from the provider id:
shell
1export UNCENSOREDLLM_API_KEY="sk-ullm-live-…"
  1. Open the Agent Panel (agent: new thread, or the sparkle icon in the status bar) and send a message. The model selector on the message editor (cmd-alt-/ on macOS, ctrl-alt-/ on Linux and Windows) switches to another id under uncensoredllm; the choice is saved back to agent.default_model.

A non-empty environment variable wins over a keychain entry. To stop using a key that came from the variable, unset it and restart Zed.

What each setting does

openai_compatible.uncensoredllm
the provider id
the name in the model selector, the provider value in agent.default_model and the stem of the env var name
api_url
https://api.uncensoredllm.ai/v1
where the requests go; the /v1 at the end matters, and nothing after it
available_models[].name
deepseek-v4.1-flash-1017-uncensored
the model id sent in each request, exactly as the models page shows it; Zed lists only the ids written here
available_models[].display_name
the name in the picker
optional; the id shows when it is missing
available_models[].max_tokens
the context window
required; Zed compacts a thread at 90% of it by default, so the catalog’s number keeps compaction honest
available_models[].max_output_tokens
the output limit
optional; sent as max_completion_tokens on each request
available_models[].capabilities
{ tools, images, parallel_tool_calls, prompt_cache_key }
tools defaults to true and is what the agent needs for edits and shell commands; images follows the catalog; the other two stay false here
agent.default_model
{ provider: uncensoredllm, model: deepseek-v4.1-flash-1017-uncensored }
the model new threads start on; inline_assistant_model, commit_message_model, thread_summary_model and compaction_model take the same shape
UNCENSOREDLLM_API_KEY
the whole sk-ullm- key
the env var Zed reads for this provider id; the keychain entry from the settings UI is the alternative

Picking a model

Zed sends OpenAI-format chat completions to the api_url, and every build on the models page answers in that format. An agent turn carries the thread, the files Zed 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 tool calls; a model without them gets a No tools label in the selector, and the agent cannot edit files or run commands with it.

The context window matters twice. Zed compacts a thread when it reaches 90% of the entry’s max_tokens (the agent.auto_compact threshold), so a build with a long window goes longer between compactions and keeps more of the thread verbatim. A window under 80,000 tokens cannot auto-compact at all; Zed shows a banner near the limit and offers a new thread seeded with a summary instead. Compaction itself is a request to the thread’s model, billed like any other, unless agent.compaction_model points it at a smaller build.

ModelOne agent turnTool calls
GLM-5.3 Uncensored$0.01model page
GLM-5.3 Flash Uncensored$0.0047model page
DeepSeek V4.1 Flash Abliterated$0.04model page
DeepSeek V4 Pro Uncensored$0.04model page
GLM-5.3 Abliterated$0.09model page
GLM-5.3 Flash Code Uncensored$0.25model page
DeepSeek V4.1 Flash 1017 Uncensored$0.04model page
GLM-5.3 Flash Apex Abliterated$0.04model page
Kimi K3 Uncensored$0.26model page

40,000 input and 1,200 output tokens at the catalog prices on 2026-11-09. Tool calls as the catalog publishes them; where it does not, the model page says.

Uncensored models and their prices per million tokens
GLM-5.3 Uncensoredglm-5.3-uncensoredUncensored$0.282$0.846
GLM-5.3 Flash Uncensoredglm-5.3-flash-uncensoredUncensored$0.1053$0.3685
DeepSeek V4.1 Flash Abliterateddeepseek-v4.1-flash-abliteratedAbliterated$0.8488$1.6975
DeepSeek V4 Pro Uncensoreddeepseek-v4-pro-uncensoredUncensored$0.97$1.94
GLM-5.3 Abliteratedglm-5.3-abliteratedAbliterated$2.1825$4.365
GLM-5.3 Flash Code Uncensoredglm-5.3-flash-code-uncensoredUncensored$6.00$6.00
DeepSeek V4.1 Flash 1017 Uncensoreddeepseek-v4.1-flash-1017-uncensoredUncensored$0.825$3.30
GLM-5.3 Flash Apex Abliteratedglm-5.3-flash-apex-abliteratedAbliterated$0.80$3.20
Kimi K3 Uncensoredkimi-k3-uncensoredUncensored$5.745$28.68

Prices per million tokens, read from the live catalog on 2026-11-09.

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, OpenCode and, through a router, Claude Code.

Check it

List the models your key can call; every id you put under available_models should be in the answer:

shell
1curl https://api.uncensoredllm.ai/v1/models -H "Authorization: Bearer sk-ullm-live-…"

Then send one request the way Zed 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.

shell
1curl -i https://api.uncensoredllm.ai/v1/chat/completions \
2 -H "Authorization: Bearer sk-ullm-live-…" \
3 -H "Content-Type: application/json" \
4 -d '{"model": "deepseek-v4.1-flash-1017-uncensored", "messages": [{"role": "user", "content": "Reply with the single word ok."}]}'

In Zed, send a message in a new thread with one of your ids selected. The request shows on the console’s usage page with its tokens and its charge. The thread’s token count shows near the profile selector in the panel’s message editor and climbs against the max_tokens you set.

Errors and fixes

  • 401 invalid_api_key: the key is wrong or revoked, or an old value of UNCENSOREDLLM_API_KEY is still set in Zed’s environment and is overriding the keychain entry. Copy the key again from the console, or unset the variable and restart Zed.
  • 404 model_not_found: a name under available_models is not on the models page. Check the spelling against the page; the id is name, not display_name.
  • 402 insufficient_balance: the balance does not cover the request. Top up in the console. 402 monthly_limit_reached means 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 carries retry-after.
  • LLM provider is not configured or does not support the configured model: the provider in agent.default_model (or inline_assistant_model) is not the key under openai_compatible, the model is not a name in that provider’s available_models, or the provider has no key yet. Make the three match and enter the key. Zed issue #63878 (open, September 2026) reports the message from the inline assistant while the same provider and model work in the Agent Panel.
  • No tools next to the model: capabilities.tools is false for that entry. Set it to true for a build the model page lists with tool calls.
  • The provider’s settings cannot be edited from the UI: as of Zed issue #35461 (open), the LLM Providers page changes a custom provider’s key only. Change the URL, the ids or the context windows in settings.json.
  • Compaction or thread summaries fail with an error about reasoning_effort: Zed sends "reasoning_effort": "none" on those requests when a model entry declares a reasoning_effort (Zed issue #60411, open, November 2026). Leave the field out of these entries.
  • Two providers on the same api_url share one key: Zed stores the key per URL, so a second block pointing at https://api.uncensoredllm.ai/v1 with a different key keeps asking for it (issue #41585). One provider block with all the ids is enough; a key limited to certain models is a scope on the key, not a second provider.

Questions

Either in the LLM Providers page of Agent Settings, which stores it in the system keychain, or in an environment variable named after the provider id in upper snake case plus _API_KEY, so UNCENSOREDLLM_API_KEY for the block above. Zed does not read keys from settings.json, and a set environment variable wins over the keychain.

Zed could not match the provider and model in agent.default_model (or inline_assistant_model) to a configured provider with a key. The provider value must be the key under openai_compatible, the model must be one of that provider’s available_models names, and the provider must have a key in the keychain or the environment.

Yes. agent.commit_message_model, agent.inline_assistant_model, agent.thread_summary_model and agent.compaction_model each take the same { provider, model } shape as agent.default_model and fall back to it when unset. A fast build for commit messages and summaries and a strong one for the agent thread is the usual split; the table above costs one agent turn on each. See the models page.

No. Zed offers only the ids written under available_models, each with its max_tokens, so a new model on the models page reaches the selector when its id and context window are added to the block. The curl in Check it lists every id the key can call.

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.

Get a keyPrepaid from $10, no subscription.

New models and price changes, once a month.

New uncensored builds with their prices, price moves, and what the daily model check found.

Join on Telegram