Kimi K3 & GLM Coding Plans in Claude Code (Flat-Rate, No Per-Token Billing)
Use Moonshot's Kimi K3 and Z.AI's GLM coding plan subscriptions in Claude Code without per-token API billing, through the open-source Ferrox LLM gateway. Full setup guide.

On this page ▾
A single Claude Code session can burn millions of tokens. At per-token API prices, heavy agentic use gets expensive fast. Moonshot AI (Kimi) and Z.AI (GLM) both sell flat-rate coding plan subscriptions that are far cheaper than pay-as-you-go billing. The catch: Claude Code speaks Anthropic’s API protocol, and Kimi’s coding plan is OpenAI-compatible only.
This guide shows how to use both the Kimi K3 and GLM coding plans in Claude Code with zero per-token charges, using Ferrox, a free, open-source LLM gateway written in Rust that translates between API dialects.
The protocol problem
Claude Code can talk to any Anthropic-compatible endpoint via ANTHROPIC_BASE_URL. Here’s how the two coding plans line up:
| Provider | Coding plan endpoint | Protocol | Works with Claude Code directly? |
|---|---|---|---|
| Z.AI (GLM) | https://api.z.ai/api/anthropic | Anthropic | Yes |
| Moonshot (Kimi) | https://api.kimi.com/coding/v1 | OpenAI only | No |
Moonshot does run an Anthropic-compatible endpoint at https://api.moonshot.ai/anthropic, but coding-plan keys are rejected there; that route bills the standard pay-as-you-go account. So for Kimi you need something in the middle that speaks Anthropic on one side and OpenAI on the other.
Enter Ferrox
Ferrox is a stateless, MIT-licensed LLM API gateway written in Rust. It normalises every provider into one internal format and re-exposes it in both the OpenAI and Anthropic dialects:
flowchart LR
CC[Claude Code] -->|Anthropic protocol| F[Ferrox]
F -->|OpenAI protocol| K[Kimi K3 coding plan]
F -->|Anthropic protocol| G[Z.AI GLM coding plan]One gateway, one local endpoint, one auth token in your Claude Code config. Beyond protocol translation you get multi-provider routing (failover, round-robin, weighted) across Anthropic, OpenAI, Gemini, and AWS Bedrock, virtual keys with per-model access control, rate limiting, circuit breakers, and Prometheus metrics.
Step 1: Configure Ferrox
Create config/local.yaml. Never commit API keys; reference environment variables:
providers:
# Z.AI coding plan is served over the Anthropic-native endpoint.
# Do NOT use https://api.z.ai/api/paas/v4; that route bills
# the pay-as-you-go balance instead of your coding plan.
- name: zai
type: anthropic
api_key: "${Z_AI_API_KEY}"
base_url: "https://api.z.ai/api/anthropic"
# Kimi coding plan is OpenAI-compatible only.
# Do NOT use https://api.moonshot.ai/anthropic; coding-plan keys are rejected there.
- name: moonshot
type: openai
api_key: "${MOONSHOT_API_KEY}"
base_url: "https://api.kimi.com/coding/v1"
models:
- alias: glm-5.2
routing:
strategy: failover
targets:
- provider: zai
model_id: "glm-5.2"
- alias: glm-4.5-air # cheap/fast, good for the Haiku slot
routing:
strategy: failover
targets:
- provider: zai
model_id: "glm-4.5-air"
- alias: k3 # Kimi K3, 1,048,576 token context
routing:
strategy: failover
targets:
- provider: moonshot
model_id: "k3"
virtual_keys:
- key: "${PROXY_KEY:-sk-local-dev}"
name: claude-code
allowed_models: ["*"]
rate_limit:
requests_per_minute: 120
burst: 20
Two things to note. Providers point at the coding plan endpoints, not the default API endpoints; getting base_url wrong is the top cause of “insufficient balance” errors. And the virtual key is what Claude Code authenticates with, so your real provider keys never enter any Claude Code settings file.
Step 2: Run Ferrox
Gateway only, no database or Redis needed:
docker run -d --name ferrox --restart unless-stopped \
-p 127.0.0.1:2333:8080 \
-e Z_AI_API_KEY -e MOONSHOT_API_KEY -e PROXY_KEY \
-v "$(pwd)/config/local.yaml:/app/config/local.yaml:ro" \
ghcr.io/shaharia-lab/ferrox:latest --config /app/config/local.yaml
-e VAR without a value inherits the variable from your shell, so keys stay out of shell history and docker inspect output. Verify:
curl http://localhost:2333/healthz # {"status":"ok"}
curl http://localhost:2333/anthropic/v1/models \
-H "Authorization: Bearer sk-local-dev" # lists your aliases
No Docker? Binaries for macOS and Linux are on GitHub Releases, or brew install shaharia-lab/tap/ferrox.
Step 3: Point Claude Code at Ferrox
Claude Code appends /v1/messages to ANTHROPIC_BASE_URL, and Ferrox serves its Anthropic surface under /anthropic. So the base URL is http://localhost:2333/anthropic. Keep one settings file per backend:
~/.claude/settings_kimi.json
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"env": {
"ANTHROPIC_BASE_URL": "http://localhost:2333/anthropic",
"ANTHROPIC_AUTH_TOKEN": "sk-local-dev",
"API_TIMEOUT_MS": "3000000",
"ANTHROPIC_MODEL": "k3",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "k3",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "k3",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "k3",
"CLAUDE_CODE_SUBAGENT_MODEL": "k3",
"CLAUDE_CODE_AUTO_COMPACT_WINDOW": "1048576"
}
}
~/.claude/settings_glm.json
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"env": {
"ANTHROPIC_BASE_URL": "http://localhost:2333/anthropic",
"ANTHROPIC_AUTH_TOKEN": "sk-local-dev",
"API_TIMEOUT_MS": "3000000",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-5.2",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-5.2",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-4.5-air"
}
}
ANTHROPIC_AUTH_TOKEN is the Ferrox virtual key, not a provider key. CLAUDE_CODE_AUTO_COMPACT_WINDOW sets how much context Claude Code uses before auto-compacting; set it to the model’s real window (K3 is 1,048,576 tokens).
Run it:
claude --settings ~/.claude/settings_kimi.json
claude --settings ~/.claude/settings_glm.json
Every request now flows through Ferrox and bills against your flat-rate subscription.
Mixing both plans in one session
Ferrox routes per model alias, so one settings file can spread Claude Code’s model slots across both subscriptions. For example, K3’s huge context for the main loop and cheap GLM 4.5 Air for the background slot:
"ANTHROPIC_DEFAULT_OPUS_MODEL": "k3",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "k3",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-4.5-air"
You can also give an alias multiple targets so one plan falls back to the other:
- alias: primary
routing:
strategy: failover
targets:
- provider: moonshot
model_id: "k3"
- provider: zai
model_id: "glm-5.2"
Clients only ever see your aliases, so you can repoint primary at a different vendor without touching any Claude Code settings file.
Troubleshooting
Insufficient balance or no resource package (Z.AI, HTTP 429, code 1113): you’re on the pay-as-you-go route, not the coding plan. base_url must be https://api.z.ai/api/anthropic with type: anthropic, not /api/paas/v4.
Invalid Authentication from Moonshot: coding-plan keys only work against https://api.kimi.com/coding/v1. They are rejected by api.moonshot.ai and api.moonshot.cn on both routes.
There's an issue with the selected model (…) in Claude Code: the model name was rejected locally before reaching Ferrox. Use plain alias names; Claude Code strips its [1m] suffix before sending, so set the window with CLAUDE_CODE_AUTO_COMPACT_WINDOW instead.
Model alias '…' is not configured (HTTP 404): Ferrox matches aliases exactly. Check GET /anthropic/v1/models for what it actually serves.
Empty responses with finish_reason: "length": K3 is a reasoning-heavy model; a small max_tokens can be consumed entirely by reasoning. Allow a few hundred tokens.
When in doubt, docker logs ferrox shows every routed request with the resolved alias, provider, upstream model ID, and status.
Ferrox for teams and organizations
The same setup scales to a whole team:
- Centralized credentials. Provider keys live in one deployment, not fifty settings files. Rotate in one place.
- Scoped access. Each developer or CI job gets a virtual key with per-model access and its own rate limit. Revoke one key without touching anyone else.
- Provider independence. Clients only see aliases, so you can swap or add providers (Gemini, Bedrock, a self-hosted model) behind the same endpoint with zero client changes.
- Production-grade ops. Stateless and horizontally scalable, with Prometheus metrics, structured logs, and OpenTelemetry tracing built in.
Ferrox is MIT-licensed, single-binary Rust, and runs anywhere Docker does. If it’s useful to you, a star on GitHub goes a long way.
FAQ
Can I use the Kimi K3 coding plan in Claude Code? Not directly. Kimi’s coding plan is OpenAI-compatible only, and Claude Code speaks the Anthropic protocol. Ferrox bridges the two.
Can I use the Z.AI GLM coding plan in Claude Code?
Yes, directly via https://api.z.ai/api/anthropic. Running it through Ferrox adds virtual keys, rate limiting, failover, and unified metrics.
Does Claude Code usage tracking still work through Ferrox?
Yes. Claude Code receives normal Anthropic-style responses with token counts, so /cost and /usage work. Ferrox adds server-side Prometheus metrics across all keys and models.
Is Ferrox free? Yes, open source under the MIT license, with binaries, a Homebrew tap, and a Docker image.
Wrapping up
Flat-rate coding plans are the pricing model agentic coding needed. With Ferrox in the middle, Claude Code isn’t locked out of them just because a provider chose a different API dialect. One YAML file, one Docker container, one settings file per plan, and Kimi K3’s million-token context and GLM 5.2 become everyday model slots in Claude Code. The full configuration reference is in the Ferrox docs.