caft/docs
Dashboard

Coding agents

Point your coding agent at caft. Claude Code and Codex go through a local router.

SettingValue
API formatOpenAI Chat Completions
Base URLhttps://api.caft.dev/v1
API keyYour caft API key
Model IDglm-5.3-flash

Use the base URL, not the full /chat/completions URL, unless a section says otherwise. Each example reads the key from CAFT_API_KEY. Setting names can differ between client versions.

OpenCode

Merge this into ~/.config/opencode/opencode.json, run opencode models caft to check that caft/glm-5.3-flash is listed, then start OpenCode.

JSON
{
  "$schema": "https://opencode.ai/config.json",
  "model": "caft/glm-5.3-flash",
  "small_model": "caft/glm-5.3-flash",
  "provider": {
    "caft": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "caft",
      "options": {
        "baseURL": "https://api.caft.dev/v1",
        "apiKey": "{env:CAFT_API_KEY}"
      },
      "models": {
        "glm-5.3-flash": {
          "name": "GLM 5.3 Flash"
        }
      }
    }
  }
}

The caft/ prefix picks the provider inside OpenCode; caft receives glm-5.3-flash.

OMP

OMP (Oh My Pi) is separate from pi. Merge this into ~/.omp/agent/models.yml, then run omp --model caft/glm-5.3-flash.

YAML
providers:
  caft:
    baseUrl: https://api.caft.dev/v1
    api: openai-completions
    apiKey: CAFT_API_KEY
    authHeader: true
    models:
      - id: glm-5.3-flash
        name: GLM 5.3 Flash (caft)

apiKey names the environment variable; authHeader: true sends it as a bearer token.

Kilo

  1. Open Settings → Providers → Custom provider.
  2. Provider ID caft, display name caft, Provider API OpenAI Compatible (not OpenAI Responses).
  3. Enter the base URL and your key, add the model, save, and select it.
Set the model's context and output limits from the Models page. If they stay at 0, Kilo turns off automatic context compaction.

Cline

In Cline's settings choose OpenAI Compatible, enter the base URL, your key, and model glm-5.3-flash, then save.

pi

Add this provider to ~/.pi/agent/models.json, start pi, and pick GLM 5.3 Flash (caft) in /model. The $ tells pi to read the environment variable.

JSON
{
  "providers": {
    "caft": {
      "baseUrl": "https://api.caft.dev/v1",
      "api": "openai-completions",
      "apiKey": "$CAFT_API_KEY",
      "models": [
        {
          "id": "glm-5.3-flash",
          "name": "GLM 5.3 Flash (caft)"
        }
      ]
    }
  }
}

Hermes

  1. Outside a chat, run hermes model. (/model inside a chat only switches between providers you already added.)
  2. Choose Custom endpoint (self-hosted / VLLM / etc.).
  3. Enter the base URL, your key, and model glm-5.3-flash. API compatibility: Chat Completions or Auto-detect.
  4. If asked for a context length, use the value on the Models page. Start a new session.

OpenClaw

Merge this into ~/.openclaw/openclaw.json and start a new session. If OpenClaw runs as a background service, give that service CAFT_API_KEY too.

JSON
{
  "agents": {
    "defaults": {
      "model": {
        "primary": "caft/glm-5.3-flash"
      }
    }
  },
  "models": {
    "mode": "merge",
    "providers": {
      "caft": {
        "baseUrl": "https://api.caft.dev/v1",
        "apiKey": "${CAFT_API_KEY}",
        "api": "openai-completions",
        "models": [
          {
            "id": "glm-5.3-flash",
            "name": "GLM 5.3 Flash (caft)"
          }
        ]
      }
    }
  }
}

Aider

Shell
export OPENAI_API_BASE=https://api.caft.dev/v1
export OPENAI_API_KEY="$CAFT_API_KEY"
aider --model openai/glm-5.3-flash --no-show-model-warnings

Keep the openai/ prefix; it selects Aider's OpenAI-compatible client. Ignore the model names Aider suggests.

Goose

Save this as ~/.config/goose/custom_providers/caft.json. Goose needs the full /chat/completions URL.

JSON
{
  "name": "caft",
  "engine": "openai",
  "display_name": "caft",
  "api_key_env": "CAFT_API_KEY",
  "base_url": "https://api.caft.dev/v1/chat/completions",
  "models": [
    {
      "name": "glm-5.3-flash"
    }
  ],
  "requires_auth": true,
  "supports_streaming": true
}
Shell
export GOOSE_PROVIDER=caft
export GOOSE_MODEL=glm-5.3-flash
goose run --with-builtin developer -t "Say hello."

The developer extension gives Goose its file and shell tools.

Crush

Add this to ~/.config/crush/crushrc, then select caft/glm-5.3-flash. Use --type openai-compat; openai is reserved for OpenAI itself.

Shell
provider add caft --type openai-compat \
  --name "caft" \
  --base-url "https://api.caft.dev/v1" \
  --api-key "$CAFT_API_KEY"

model add caft/glm-5.3-flash --name "GLM 5.3 Flash"

Qwen Code

Shell
export OPENAI_API_KEY="$CAFT_API_KEY"
export OPENAI_BASE_URL=https://api.caft.dev/v1
export OPENAI_MODEL=glm-5.3-flash
qwen --auth-type openai

Use --auth-type openai (Chat Completions), not openai-responses.

Continue

Works in the editor extension and the cn CLI. Put the key in ~/.continue/.env (the extension does not read shell variables), then merge the model into ~/.continue/config.yaml.

Shell
CAFT_API_KEY=YOUR_CAFT_API_KEY
YAML
name: caft
version: 1.0.0
schema: v1
models:
  - name: GLM 5.3 Flash (caft)
    provider: openai
    model: glm-5.3-flash
    apiBase: https://api.caft.dev/v1
    apiKey: ${{ secrets.CAFT_API_KEY }}
    roles:
      - chat
      - edit
      - apply
    capabilities:
      - tool_use

ZCode

Add caft as a custom provider; the built-in Z.ai provider connects to Z.ai.

  1. Settings → Model settings → Add provider → Create custom provider.
  2. Base URL as above, API format Chat completions, your key.
  3. Add model glm-5.3-flash with Smart configuration on.
  4. In Advanced settings, clear Image, Video and PDF, and replace the Reasoning parameter mapping with:
Mapping
{
  "reasoning_effort": reasoningLevel == "disabled" ? "none" : reasoningLevel == "enabled" ? "high" : reasoningLevel
}

The default mapping adds thinking, enable_thinking and reasoning fields that can be rejected with HTTP 400. This one sends only reasoning_effort.

Claude Code

Claude Code speaks Anthropic Messages. Claude Code Router (CCR) translates it to Chat Completions on your machine.

On first start CCR rewrites ~/.claude/settings.json and ~/.codex/config.toml. Back them up first and restore them after you stop CCR.
  1. npm install -g @musistudio/claude-code-router (Node.js 22+).
  2. Save this as ~/.claude-code-router/config.json. CCR reads it only on first start.
JSON
{
  "HOST": "127.0.0.1",
  "PORT": 3456,
  "APIKEY": "your-local-ccr-key",
  "Providers": [
    {
      "name": "caft",
      "api_base_url": "https://api.caft.dev/v1/chat/completions",
      "api_key": "$CAFT_API_KEY",
      "models": [
        "glm-5.3-flash"
      ]
    }
  ]
}
Shell
ccr start

export ANTHROPIC_BASE_URL=http://127.0.0.1:3456
export ANTHROPIC_AUTH_TOKEN=your-local-ccr-key
export ANTHROPIC_MODEL=caft/glm-5.3-flash
export ANTHROPIC_DEFAULT_HAIKU_MODEL=caft/glm-5.3-flash
export ANTHROPIC_DEFAULT_SONNET_MODEL=caft/glm-5.3-flash
export ANTHROPIC_DEFAULT_OPUS_MODEL=caft/glm-5.3-flash
claude

APIKEY is a local secret between Claude Code and CCR, not your caft key. Without the model variables, Claude Code asks for Claude model names and CCR returns 400.

Codex

Codex speaks the Responses API. A local LiteLLM proxy translates it to Chat Completions.

  1. Set CAFT_API_KEY, and LITELLM_MASTER_KEY to a separate secret starting with sk-.
  2. Save as config.yaml and run litellm --config config.yaml --host 127.0.0.1 --port 4000.
YAML
model_list:
  - model_name: caft-flash
    litellm_params:
      model: openai/glm-5.3-flash
      api_base: https://api.caft.dev/v1
      api_key: os.environ/CAFT_API_KEY
      use_chat_completions_api: true
      additional_drop_params: ["web_search_options"]

general_settings:
  master_key: os.environ/LITELLM_MASTER_KEY
  1. Merge into ~/.codex/config.toml, set LITELLM_API_KEY to the master key, and start Codex.
TOML
model = "caft-flash"
model_provider = "caft-litellm"

[model_providers.caft-litellm]
name = "caft via LiteLLM"
base_url = "http://127.0.0.1:4000/v1"
env_key = "LITELLM_API_KEY"
wire_api = "responses"

use_chat_completions_api makes LiteLLM call Chat Completions. The drop rule removes web_search_options, which Codex's web search adds; or set web_search = "disabled". A "model metadata not found" warning is harmless. CCR also serves /v1/responses if you already run it.

Check the connection

Send a short message, then ask the agent to read a small file in a test folder. A text reply alone doesn't prove tool calls work. If either fails, see Troubleshooting.