Running Kimi Code on Claude Code
DEV Community

Running Kimi Code on Claude Code

I pay for Claude and I pay for Kimi Code, and I want both available from the same terminal without choosing one in the morning. Kimi publishes a guide for pointing Claude Code at their endpoint. It tells you to export a handful of environment variables in your shell profile, which works, and which also routes every Claude Code session on the machine to Kimi from then on. Your Anthropic subscription sits there unused while you wonder why Opus got worse. The fix is boring: a second settings file and a shell function that loads it. Ten minutes. The part worth writing down is that the headline model ID in Kimi's guide is rejected by Kimi's own endpoint, and it's rejected with a 401 that says your credentials are bad. I lost time auditing a key that was never the problem. Then I found a second version of the same lie living in ~/.claude.json , and that one is better disguised. TL;DR. Put the Kimi config in ~/.claude/kimi-settings.json rather than~/.claude/settings.json , then add aclaude-kimi() function that runsclaude --settings "$HOME/.claude/kimi-settings.json" "$@" . Base URL ishttps://api.kimi.com/coding/ with the key inANTHROPIC_API_KEY . The model isk3 , notk3[1m] , whatever the docs say. SetCLAUDE_CODE_MAX_CONTEXT_TOKENS to1048576 because a barek3 gives Claude Code no window to infer. If interactive mode 401s whilecurl andclaude -p both work, your key is in the rejected list in~/.claude.json and no amount of key rotation will fix it. Kimi has two API surfaces and only one of them is yours This is the distinction that decides whether anything else in this post works, so get it straight first. A Kimi Code subscription authenticates against https://api.kimi.com/coding/ , using ANTHROPIC_API_KEY , which is sent as an x-api-key header. Model IDs are short: k3 , k3-256k , kimi-for-coding . The Moonshot platform is a different thing. It lives at https://api.moonshot.ai/anthropic , uses ANTHROPIC_AUTH_TOKEN as a bearer token, and wants model IDs with a kimi- prefix. That is the surface you pay for by the token. It's also what most of the search results describe. They are different products. Your subscription key will not authenticate against the platform host, and the failure is a flat 401 that tells you nothing about why. If you follow the popular guide with a subscription key, this is where you stop. 1. Get a key Go to kimi.com/code/console and create one. Two things worth knowing before you click. You get at most five keys, and each is shown exactly once, at creation. There is no reveal button later, only delete and make a new one. Copy it somewhere before you close the dialog. 2. Write the settings file Create it empty and lock it down before the key goes anywhere near it, so it's never briefly readable by anything else on the machine: touch ~/.claude/kimi-settings.json chmod 600 ~/.claude/kimi-settings.json Then paste this in, replacing the placeholder: { "env": { "ANTHROPIC_BASE_URL": "https://api.kimi.com/coding/", "ANTHROPIC_API_KEY": "PASTE_YOUR_KIMI_CODE_KEY_HERE", "ANTHROPIC_MODEL": "k3", "ANTHROPIC_DEFAULT_OPUS_MODEL": "k3", "ANTHROPIC_DEFAULT_SONNET_MODEL": "k3", "ANTHROPIC_DEFAULT_FABLE_MODEL": "k3", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "kimi-for-coding", "CLAUDE_CODE_SUBAGENT_MODEL": "k3", "ANTHROPIC_DEFAULT_OPUS_MODEL_NAME": "Kimi K3", "ANTHROPIC_DEFAULT_OPUS_MODEL_DESCRIPTION": "Kimi Code K3 (1M context)", "ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME": "Kimi K2.7 Code", "CLAUDE_CODE_MAX_CONTEXT_TOKENS": "1048576", "CLAUDE_CODE_AUTO_COMPACT_WINDOW": "950000", "CLAUDE_CODE_EFFORT_LEVEL": "high" } } Check the permissions again after you save. Some editors write a temp file and rename it into place, which lands at your umask and quietly undoes the chmod you just ran: ls -l ~/.claude/kimi-settings.json # want -rw------- There are six model slots, not one, and that's deliberate. Claude Code uses the haiku slot for background chores like naming your conversation, and pointing those at K3 spends your quota on titles. kimi-for-coding is ungated on every tier, so it's the safe floor for throwaway work. The two window numbers are the part people get wrong. CLAUDE_CODE_AUTO_COMPACT_WINDOW is a trigger threshold, not a statement of how much context you have, so it needs headroom underneath the real window. Kimi's guide sets it to 1048576 , which is out of range anyway: Claude Code accepts 100000 to 1000000 . It also has to be a plain integer. Write 500k and it parses as 500 and clamps to the floor, and you'll be wondering why compaction fires roughly immediately. 3. The model ID in the official guide does not work Kimi's own Claude Code guide tells you to set ANTHROPIC_MODEL to k3[1m] . Their endpoint rejects it. I sent each ID at api.kimi.com/coding/ with curl, and here's what came back: | Model ID | HTTP | What comes back | |---|---|---| k3 | 200 | Works. Main conversation model | k3-256k | 200 | Works. Smaller window variant | kimi-for-coding | 200 | Works. Ungated on all tiers | k3[1m] | 401 | Your model id does not exist, recognized as other:k3[1m]. Please set model id as k3. | Read that 401 again. It's an authentication_error , and the message body is about a model ID. Nothing in the status code suggests you should go looking at your model configuration, so you go and audit your key instead, and your key is fine. It cost me more time than anything else in this setup. Use the bare k3 . It is natively a 1M context model and the suffix was never what unlocked that. There is a consequence though, and it's why CLAUDE_CODE_MAX_CONTEXT_TOKENS is in the config above rather than being decorative. With a [1m] style ID, Claude Code can read the window size out of the name. A bare k3 tells it nothing, so it falls back to a conservative guess and starts compacting your session far earlier than it needs to. Declaring the real number fixes that. If you're on k3-256k instead, change ANTHROPIC_MODEL , ANTHROPIC_DEFAULT_OPUS_MODEL , ANTHROPIC_DEFAULT_SONNET_MODEL , ANTHROPIC_DEFAULT_FABLE_MODEL and CLAUDE_CODE_SUBAGENT_MODEL to k3-256k , leave the haiku slot alone, and set CLAUDE_CODE_MAX_CONTEXT_TOKENS to 262144 with the compact window at 240000 . I'm listing all five by name on purpose. Forget CLAUDE_CODE_SUBAGENT_MODEL and your subagents keep running on the 1M model while you believe you moved everything down. 4. Add the launcher cat >> ~/.zshrc <<'EOF' # Claude Code against the Kimi Code subscription. # Plain claude is unaffected and keeps the claude.ai subscription. claude-kimi() { command claude --settings "$HOME/.claude/kimi-settings.json" "$@" } EOF exec zsh Use $HOME rather than ~ so the path resolves however the function gets called. The --settings flag layers that file on top of your normal user config, and because ~/.claude/settings.json has no env block on my machine, there's nothing for it to collide with. Check yours before you assume the same: python3 -c "import json,os;print('env' in json.load(open(os.path.expanduser('~/.claude/settings.json'))))" If that prints True , whatever is in there will fight with the Kimi config, and you should move it out first. 5. Test the endpoint before you test Claude Code Confirm the key, host and model at the HTTP layer while there's only one thing that can be wrong. Then any failure in the next step is a Claude Code problem, and you already know it isn't credentials. read -rs "KEY?Kimi Code key: "; echo curl -sS https://api.kimi.com/coding/v1/messages \ -H "x-api-key: $KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{"model":"k3","max_tokens":16, "messages":[{"role":"user","content":"Say OK."}]}' You want JSON with a content array in it. read -rs keeps the key out of your shell history, and note the header is x-api-key rather than a bearer token, which is the practical tell that you're on the subscription surface and not the platform one. Run unset KEY when you're finished with it. Two notes on this. If you get a 404 on everything, your base URL includes the full path and Claude Code is appending v1/messages to something that already ends in it. Set the base, keep the trailing slash, nothing more. And k3 needs the Moderato tier or above. If it comes back with a 401 naming the model and linking an upgrade page, that's tier gating rather than a bad ID, and you want every slot on kimi-for-coding instead. Both failures arrive as authentication_error , so the status code can't tell them apart and the message body is the only thing that can. A curl probe here is fine, by the way. Kimi's terms require tools to identify themselves honestly, and curl does. Forging a User-Agent to make one client look like another is the thing they take issue with. 6. Confirm both lanes In one tab: claude-kimi # then, inside the session: /status /status should show https://api.kimi.com/coding/ and a Kimi model. Send it a real message so you've exercised the round trip rather than just the startup path. Then open a separate tab and run plain claude , and check /status there too. This is the whole point of the exercise, so actually do it. Verifying that the isolation held is more important after a Claude Code upgrade than it is today: model variable precedence changed in v2.1.195, and the next release that touches settings layering is not going to send you a note. Expect one prompt on the first interactive claude-kimi , asking whether to use the detected API key. Say yes. The rejected key list, which is the worst one Answer no to that prompt, deliberately or with a stray keypress on a dialog you weren't expecting, and Claude Code writes the key's last 20 characters into a rejected list in ~/.claude.json . From then on, interactive sessions refuse it and tell you this: Please run /login ยท API Error: 401 Here is why this one is genuinely nasty. None of the obvious diagnostics consult that list, so every one of them clears the key. I had curl returning 200, claude -p "hello" returning 200, a config file that was correct, an endpoint that was up, and a key that was valid. Only

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.