Claude Code only speaks the Anthropic Messages API, and Token Factory serves its open coding models through an OpenAI-compatible API. Claude Code reads its endpoint from the environment, so a local translation proxy is enough to run Kimi, Qwen, MiniMax, or DeepSeek behind the CLI you already use, with no change to the agent itself.
This cookbook does that two ways: with nebiusrelay, the proxy Nebius links for Claude Code, and, through the one-shot prompt, with a relay you build yourself.
What you will build
A working Claude Code session whose every token is served by an open model on Token Factory:
moonshotai/Kimi-K2.7-Codeas the coding model: 262K context, text-only, built for agentic coding.nebiusrelayas the local Anthropic-to-Token-Factory translator, injected for one run at a time.- Claude Code itself, unmodified. Your login, subscription, settings, and
CLAUDE.mdfiles stay exactly as they are.
A measured headless task that wrote one file took 22 seconds and cost $0.032 for 30,873 input and 609 output tokens.
Why Claude Code needs a proxy at all
Cursor, Cline, and OpenCode can point straight at Token Factory because they speak the OpenAI chat-completions format Token Factory serves. Claude Code speaks Anthropic Messages: a different request shape, a different response shape, and a different server-sent-event vocabulary for streaming. The relay accepts Anthropic Messages on localhost, rewrites each request into chat-completions, and rewrites the reply, including tool calls, back into Anthropic blocks. The one-shot prompt reproduces that translation in about 280 lines of standard-library Python.
Prerequisites
- macOS or Linux, and
curl - Claude Code already installed. The relay routes it but does not install it.
- A Nebius Token Factory account and API key
- The key in an environment variable, never pasted into a tracked file
nebiusrelay runs on Bun and installs it for you if it is missing.
Run the cookbook
-
Install the relay. It writes to
~/.nebiusrelay/, links the wrappers into a writable directory already on yourPATH, and adds aPATHline to your shell profile:curl -fsSL https://nebius-tf-relay.vercel.app/install.sh | shRead the script before piping it to a shell if you have not seen it before. Then restart your shell, or run the
export PATH=...line it prints, and confirm the install:nebiusrelay --version -
Give it your Token Factory key. Either store it once, interactively:
nebiusrelay configureor export it and skip the prompts, which is the form to use in CI or from another agent:
export NEBIUS_API_KEY="your-token-factory-key" -
Launch Claude Code on an open model. Put
--mainbefore theclaudesubcommand. The troubleshooting section explains why the order matters:nebiusrelay --main moonshotai/Kimi-K2.7-Code claudeThe banner confirms where your tokens are going before the session starts:
Nebius TF Relay ▸ Routing Claude Code → Nebius Token Factory (Kimi K2.7 Code). Not Anthropic.Omit
--mainand you get the relay’s built-in default, which is Kimi K2.7 Code in v0.14.3. The short aliasnclaudeis the same thing with no model flag. -
Run one headless task so that success is a file on disk. Close stdin with
< /dev/null; without it a non-interactive run blocks waiting for input:nebiusrelay --main moonshotai/Kimi-K2.7-Code claude \ -p "Use the Write tool to create hello.py whose only line is: print('relay ok')" \ --dangerously-skip-permissions --output-format json < /dev/null--dangerously-skip-permissionsstops a headless run from stalling on a permission prompt. Use it only in a throwaway directory.
Verify the result
The file exists, with the right contents. This shows that tool calls survived the translation in both directions:
cat hello.py
The tokens came from Token Factory. The relay prints a cost line when the session ends, priced against the model’s real per-token rates:
[nebiusrelay cost] session total: $0.0318 (30,873 in, 609 out)
For history across sessions, all of it stored locally under ~/.nebiusrelay and never uploaded:
nebiusrelay usage --last 7d
Switching models works. Run the same task again against a different one and watch the banner change:
nebiusrelay --main moonshotai/Kimi-K2.6 claude -p "reply with OK only" \
--dangerously-skip-permissions < /dev/null
Every model your account can see is available here, including moonshotai/Kimi-K3, Qwen/Qwen3.5-397B-A17B, MiniMaxAI/MiniMax-M3, deepseek-ai/DeepSeek-V4-Pro, and zai-org/GLM-5.2, because the relay pulls the catalog from Token Factory at startup.
Troubleshooting
-
--mainseems to be ignored.nclaude --main Xandnebiusrelay claude --main Xboth put the flag after the harness name, where it is passed through to Claude Code and dropped, so the run silently uses the default model. The banner names the model actually in use. Always writenebiusrelay --main <model> claude .... -
The agent says it did the work, but nothing changed on disk. Open coding models will sometimes narrate a file write without emitting the tool call. Naming the tool fixes it: “Use the Write tool to create
hello.py…” succeeded where “Create a filehello.py…” only repliedDONE. Verify withgit status, not with the transcript. -
A headless run hangs and produces nothing. Add
< /dev/null. Note that the lineReading additional input from stdin...also prints on healthy runs; a real hang shows as output that stops growing. -
No Nebius API key found. Runnebiusrelay configure, or exportNEBIUS_API_KEYin the same shell. -
claude: command not found. The relay does not install agent CLIs. Install Claude Code, then retry. -
Web search fails inside the session. Search is emulated through a separate provider key that
nebiusrelay configurecollects; without it, searches return an explicit “not set” error rather than failing quietly. In v0.14.3 the docs name this key inconsistently, so set it viaconfigurerather than guessing an environment variable. -
A model is missing from the catalog. Nebius adds and removes models;
zai-org/GLM-5.2andzai-org/GLM-5.1have traded places before. Check what your account can see:curl -s https://api.tokenfactory.nebius.com/v1/models \ -H "Authorization: Bearer $NEBIUS_API_KEY" | grep '"id"'
Build the relay yourself
prompt.md is a one-shot prompt for the underlying exercise: build the Anthropic-Messages-to-Token-Factory relay from scratch, in standard-library Python, with tests. Translating the streaming protocol by hand makes the failure modes above easier to understand, and the result is usable: real Claude Code will drive a Token Factory model through it, tool calls included.
Two details are easy to miss. Claude Code posts to /v1/messages?beta=true, so a route match on the raw path rejects every request before it reaches your translator; match on the path with the query string stripped. Streamed tool calls arrive as OpenAI tool_calls argument fragments and have to be re-emitted as Anthropic input_json_delta events inside a tool_use content block; if that is wrong, the agent can talk but cannot act.
Clean up
Nothing was written to your Claude Code configuration, so there is nothing to restore. Stop using the wrappers and your setup is unchanged. To stop the shared background proxy:
nebiusrelay daemon stop
To remove the relay completely, delete its directory and the PATH line the installer added to your shell profile:
rm -rf ~/.nebiusrelay
unset NEBIUS_API_KEY
If you pasted your Token Factory key into a shell history file, a notebook, or a commit, rotate it in the Token Factory console rather than deleting the file and assuming it is gone.