Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuration

ccode uses YAML configuration files with a two-level merge system: a user-level config for secrets and an optional project-level config for model settings.

Config locations

LevelPathPurpose
User (Windows)%APPDATA%\ccode\config.yamlAPI keys, personal defaults
User (Linux/macOS)~/.config/ccode/config.yamlAPI keys, personal defaults
Project./ccode.yamlModel settings for this project
Project (alt)./.claude/ccode.yamlSame, tucked into .claude/

Field naming

Every profile field maps 1:1 to a Claude Code environment variable. The YAML field name is the lowercased env var name:

ANTHROPIC_BASE_URL        ->  anthropic_base_url
ANTHROPIC_MODEL           ->  anthropic_model  (or use the models: block below)
models: model: model:     ->  ANTHROPIC_MODEL
CLAUDE_CODE_EFFORT_LEVEL  ->  claude_code_effort_level

For the full list of ~200+ supported fields, see the Config Reference.

Merge behavior

When both user and project configs exist, ccode merges them field-by-field:

  1. User config is loaded first (base layer, carries secrets)
  2. Project config is overlaid on top (model settings override user values)
  3. --config flag replaces the project config in the merge chain

Launch modes

ccode can automatically enable Claude Code’s launch modes via config. Each has a --flag/--no-flag CLI override.

ConfigCLI overrideEffect
always_control: true--control / --no-controlRemote control mode - sessions show up at claude.ai/code
always_auto: true--auto / --no-autoAuto permissions mode (--permission-mode auto)
always_yolo: true--yolo / --no-yoloSkip permissions mode (--dangerously-skip-permissions)

always_yolo takes priority over always_auto (they’re mutually exclusive permission modes). always_control can be combined with either.

Note: At the time of writing, claude remote-control does not accept custom permission flags (--dangerously-skip-permissions or --permission-mode auto). Combining --control with --auto or --yolo will print a warning but still attempt to pass the flags, in case a future Claude Code update enables it. Auto permissions can be set in the Claude app/web UI instead.

Global env

The top-level env: block sets environment variables for all profiles. This is useful for settings you want everywhere:

env:
  DISABLE_TELEMETRY: "1"
  CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: "80"

profiles:
  # Passthrough - launches Claude Code as-is with your subscription
  default: {}

  # DeepSeek - https://platform.deepseek.com/
  deepseek:
    anthropic_base_url: "https://api.deepseek.com/anthropic"
    anthropic_auth_token: "YOUR_DEEPSEEK_API_KEY_HERE"

Each profile can also have its own env: block for per-profile overrides. Priority order: global env < profile fields < profile env.

Example user config

default_profile: "deepseek"

profiles:
  # Passthrough - launches Claude Code as-is with your subscription
  default: {}

  # DeepSeek (Pro tier) - https://platform.deepseek.com/
  deepseek:
    anthropic_base_url: "https://api.deepseek.com/anthropic"
    anthropic_auth_token: "YOUR_DEEPSEEK_API_KEY_HERE"
    models:
      model:
        model: "deepseek-v4-pro[1m]"
      opus:
        model: "deepseek-v4-pro[1m]"
      sonnet:
        model: "deepseek-v4-pro[1m]"
      haiku:
        model: "deepseek-v4-flash"
      subagent:
        model: "deepseek-v4-flash"
    claude_code_effort_level: "max"
    env:
      CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: "1"

Split config example

User config (~/.config/ccode/config.yaml) - has secrets, never committed:

default_profile: "deepseek"

profiles:
  # DeepSeek - https://platform.deepseek.com/
  deepseek:
    anthropic_auth_token: "YOUR_DEEPSEEK_API_KEY_HERE"

  # OpenRouter - https://openrouter.ai/
  openrouter:
    anthropic_auth_token: "YOUR_OPENROUTER_API_KEY_HERE"

Project config (./ccode.yaml) - safe to commit:

default_profile: "deepseek"

profiles:
  # DeepSeek (Pro tier) - model settings only, auth comes from user config
  deepseek:
    anthropic_base_url: "https://api.deepseek.com/anthropic"
    models:
      model:
        model: "deepseek-v4-pro[1m]"
      opus:
        model: "deepseek-v4-pro[1m]"
      sonnet:
        model: "deepseek-v4-pro[1m]"
      haiku:
        model: "deepseek-v4-flash"
      subagent:
        model: "deepseek-v4-flash"
    claude_code_effort_level: "max"
    env:
      CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: "1"

The merged result has both the API key (from user config) and the model settings (from project config).

The idea is that the project configs could allow using a faster model (like DeepSeek V4 Flash) for one project, and demand using a bigger model (like DeepSeek V4 Pro) for another, all while the actual API keys per-user remain private and there’s lower risk of accidentally committing and pushing them somewhere public.

If you need per-project API keys or want them committed to your private repositories you can do that too, just please be careful.

More info

  • Importing configuration - using ccode add-profile interactively, from a file, or from a URL (with hosted examples for every provider)
  • Usage > Practical examples - three worked split-config scenarios (per-project default profile, per-project model, per-project env/telemetry)
  • Providers - setup guides for every supported provider
  • Config Reference - complete list of all YAML fields