config.example.yaml
Rama main · réplica de lectura del repositorio original.
# Server host/interface to bind to. Default is empty ("") to bind all interfaces (IPv4 + IPv6).
# Use "127.0.0.1" or "localhost" to restrict access to local machine only.
host: ""
# OAuth client credentials for provider login flows.
# Gemini CLI / Code Assist and Antigravity OAuth use their official OAuth clients by default.
# Set credentials only when you intentionally want to override those clients.
# You can set overrides either in config.yaml or via environment variables:
# - Gemini: CLIRELAY_GEMINI_OAUTH_CLIENT_ID / CLIRELAY_GEMINI_OAUTH_CLIENT_SECRET
# - Antigravity: CLIRELAY_ANTIGRAVITY_OAUTH_CLIENT_ID / CLIRELAY_ANTIGRAVITY_OAUTH_CLIENT_SECRET
oauth-clients:
gemini:
client-id: ""
client-secret: ""
antigravity:
client-id: ""
client-secret: ""
# Server port
port: 8317
# Maximum time in seconds the main API server may spend reading request headers + body
# from downstream clients before returning a timeout.
# Increase this if clients send large JSON or multimodal payloads through slow Docker /
# reverse-proxy links. Default is 120 seconds.
main-api-read-timeout-seconds: 120
# Request body handling for public model API endpoints.
# The limit is applied after gzip/br/zstd/deflate decompression. Management and
# upload endpoints keep narrower endpoint-specific limits.
request-body:
model-max-mb: 128
# Decoded request bodies at or above this size are cached in a temporary file
# for downstream reuse instead of being retained in memory for the whole request.
disk-threshold-mb: 8
# Optional dedicated directory for large reusable request-body temp files.
# Empty uses the OS temp directory under a CliRelay-specific subdirectory.
cache-dir: ""
# Project timezone (IANA name). Affects "today" boundaries and day-based aggregation in monitoring/usage pages.
# Examples: "Asia/Shanghai", "UTC", "America/Los_Angeles"
timezone: ""
# PostgreSQL 15+ is the runtime primary database.
postgres:
dsn: "postgres://cliproxy:cliproxy@127.0.0.1:5432/cliproxy?sslmode=disable"
max-open-conns: 16
max-idle-conns: 4
# Redis 7+ settings for cache, locks, queues, limits, and rebuildable snapshots.
redis:
enable: false
addr: "127.0.0.1:6379"
password: ""
db: 0
# Riding out a short database outage (a restart or a primary failover).
# All fields are optional; the defaults below apply when the block is absent.
# db-resilience:
# # Request logs the database cannot take are kept here and replayed in order
# # once it is back, also after a restart. Must be persistent storage.
# # Empty: <auth-dir parent>/data/usage-spool when that data directory exists,
# # else <auth-dir parent>/usage-spool. Env override: CLIRELAY_USAGE_SPOOL_DIR.
# usage-spool-dir: ""
# # Disk cap; when full the oldest records are dropped (logged). -1 disables
# # spooling and restores dropping records the database refuses.
# usage-spool-max-size-mb: 1024
# # How old the last successful quota usage read may be and still admit a
# # request while the database cannot be read. -1 refuses with 503 at once.
# quota-stale-seconds: 120
# TLS settings for HTTPS. When enabled, the server listens with the provided certificate and key.
tls:
enable: false
cert: ""
key: ""
# Explicit browser origins allowed to call API routes cross-origin.
# Leave empty to disable cross-origin browser access by default.
# Same-host browser origins are always allowed. Everything else must be listed.
# Chrome extensions are NOT allowed by default; add either a precise ID or the
# controlled pattern chrome-extension://* (also accepts chrome-extension:*) to
# allow any installed extension. Prefer precise IDs in production.
# Examples:
# cors-allow-origins:
# - "https://admin.example.com"
# - "http://localhost:5173"
# - "chrome-extension://abcdefghijklmnop"
# - "chrome-extension://*"
cors-allow-origins: []
# Reverse proxies whose X-Forwarded-For / X-Real-IP headers may be trusted.
# Leave empty for direct exposure. For Docker bridge + Nginx, trust only the
# proxy/container subnet, for example:
# trusted-proxies:
# - "172.18.0.0/16"
trusted-proxies: []
# Management API settings
remote-management:
# Whether to allow remote (non-localhost) management access.
# When false, only localhost can access management endpoints (a key is still required).
allow-remote: false
# Management key. If a plaintext value is provided here, it will be hashed on startup.
# All management requests (even from localhost) require this key.
# Leave empty to disable the Management API entirely (404 for all /v0/management routes).
secret-key: ""
# Disable the bundled management control panel asset download and HTTP route when true.
disable-control-panel: false
# GitHub repository for the management control panel. Accepts a repository URL or releases API URL.
panel-github-repository: "https://github.com/kittors/codeProxy"
# Login throttling and session token lifetimes. Every key is optional and
# zero-means-default, so leaving this block commented out keeps the shipped
# behaviour. Uncomment only the keys you actually want to override.
# auth:
# # Sliding window (seconds) used to count login failures. Failures older
# # than this are discarded, so a stale mistype never contributes to a lock.
# login-failure-window-seconds: 900
# # Failures within the window that arm a staged cooldown for one account.
# account-failure-limit: 5
# # Wrong management keys from one client IP that arm a per-IP ban.
# management-key-failure-limit: 10
# # Credential-less management requests allowed per client per hour. Over the
# # limit returns 429; it never arms a credential ban.
# unauthenticated-request-limit: 300
# # Quiet period (hours) that clears failure counters and backoff escalation.
# failure-reset-hours: 12
# # How long a just-rotated refresh token stays usable so a retry or a second
# # browser tab does not lose the session. Clamped to 60 seconds.
# refresh-grace-seconds: 30
# # How many times one rotated refresh token may be replayed inside the grace
# # window before it is treated as a stolen-token replay.
# refresh-grace-max-reuse: 2
# # How long the previous access token stays valid after rotation, so
# # in-flight requests are not rejected. Must exceed the panel request timeout.
# access-token-grace-seconds: 60
# # Hard session ceiling (hours). Rotation never extends past login time plus
# # this value. 1440 hours is 60 days.
# absolute-refresh-ttl-hours: 1440
# # How often expired session tokens and revoked sessions are garbage collected.
# session-reaper-interval-minutes: 60
# Docker-first automatic update checks. The updater sidecar is installed by the
# Docker Compose deployment path; non-Docker deployments can disable this.
auto-update:
enabled: true
# main is the default stable update channel; use dev to follow dev images.
channel: main
repository: https://github.com/kittors/CliRelay
docker-image: ghcr.io/kittors/clirelay
updater-url: http://clirelay-updater:8320
# Background re-probe of AI account quota status.
#
# Without it a quota snapshot only advances while someone has the accounts panel
# open. That is enough while this proxy is the only thing spending the
# allowance, but a Grok subscription is billed across surfaces the proxy never
# sees: an account drained by Grok Chat on the web reads as untouched until a
# human happens to look. The per-account min-gap and in-flight dedupe still
# apply, so a scheduled round overlapping a manual refresh costs no extra
# upstream calls.
account-status-refresh:
enabled: true
# How often each account is re-probed. Floors at 5.
interval-minutes: 15
# Delay before the first round, so boot does not fire one probe per credential at once.
startup-delay-seconds: 60
# Authentication directory (supports ~ for home directory).
# In Docker/cloud deployments, AUTH_PATH overrides this value at runtime.
auth-dir: "~/.cli-proxy-api"
# Client API keys for /v1, /v1beta and the other client routes.
# Create them on the API Keys page of the management panel. Keys listed here are
# only imported while the database holds no API keys yet, and are then removed
# from this file.
# None is configured by default: every client request is rejected until you add
# one (unless allow-unauthenticated below is turned on).
# The your-api-key-* values are placeholders and are rejected even if uncommented;
# use long random values of your own.
# api-keys:
# - "your-api-key-1"
# - "your-api-key-2"
# - "your-api-key-3"
# When true, allow /v1 and /v1beta requests without API keys when no keys/providers
# are configured. Not recommended for production.
allow-unauthenticated: false
# Enable debug logging
debug: false
# Enable pprof HTTP debug server (host:port). Keep it bound to localhost for safety.
pprof:
enable: false
addr: "127.0.0.1:8316"
allow-remote: false
# When true, disable high-overhead HTTP middleware features to reduce per-request memory usage under high concurrency.
commercial-mode: false
# When true, write application logs to rotating files instead of stdout
logging-to-file: false
# Maximum total size (MB) of log files under the logs directory. When exceeded, the oldest log
# files are deleted until within the limit. Default is 512. Set to 0 to disable.
logs-max-total-size-mb: 512
# Maximum number of error log files retained when request logging is disabled.
# When exceeded, the oldest error log files are deleted. Default is 10. Set to 0 to disable cleanup.
error-logs-max-files: 10
# When false, disable in-memory usage statistics aggregation
usage-statistics-enabled: false
# Cache expensive management system-stat fields (database sizes, log directory scan,
# and channel latency) for this many seconds. CPU, memory, network, and concurrency stay live.
system-stats-cache-seconds: 60
# Rotate only the management system-monitor WebSocket after this many seconds so
# nginx reloads can retire old workers. Public LLM streaming is not affected.
system-stats-websocket-max-age-seconds: 300
# Detailed request/response body retention settings for PostgreSQL request-log storage.
request-log-storage:
# When true, persist full request and response bodies in PostgreSQL.
# When false, request details remain available but request/response bodies are not stored.
# Disabled by default to limit database growth.
store-content: false
# Keep full request/response bodies for the last N days.
# Set to 0 to retain full content indefinitely.
# The lightweight request metadata rows are retained separately.
content-retention-days: 30
# Run background content cleanup every N minutes.
cleanup-interval-minutes: 1440
# Cap the total size of stored request/response bodies (MB).
# When exceeded, the oldest full bodies are pruned early even if their retention days are not over.
# Default is 1024 (≈1GB). Set to 0 to disable the size cap.
max-total-size-mb: 1024
# Proxy URL. Supports socks5/http/https protocols. Example: socks5://user:pass@192.168.1.1:1080/
proxy-url: ""
# When true, disables TLS certificate verification for all upstream HTTPS connections.
# Use only when upstream APIs use self-signed certificates or in trusted internal networks.
# Default is false (verification enabled).
insecure-skip-verify: false
# Path to a PEM-encoded CA certificate file for verifying upstream server certificates.
# When empty, the system default root CA pool is used.
ca-cert: ""
# When true, unprefixed model requests only use credentials without a prefix (except when prefix == model name).
force-model-prefix: false
# When true, forward filtered upstream response headers to downstream clients.
# Default is false (disabled).
passthrough-headers: false
# Number of times to retry a request. Retries will occur if the HTTP response code is 403, 408, 500, 502, 503, or 504.
request-retry: 3
# Maximum wait time in seconds for a cooled-down credential before triggering a retry.
max-retry-interval: 30
# When true, a credential that answers 429, 408 or 5xx is not taken out of rotation:
# the error goes back to the client and the next request may use it again. A reset
# time the upstream announces with a usage limit (for example a Codex limit or a
# Claude OAuth window) is still waited out. Each provider entry and each auth file can
# override this with its own disable-cooling (auth files: "disable_cooling"); leave it
# unset there to follow this value. 401, 403 and 404 still park a credential.
disable-cooling: false
# Behavior when an AI account reaches the `concurrency_limit` set on its auth file.
# Requests first fail over to any account with a free slot; only when every candidate
# is busy do they queue here, in arrival order, and resume as soon as a slot frees up.
account-concurrency:
# Seconds a request may queue before giving up with HTTP 429. Default is 30.
# Set to 0 to disable queuing and fail as soon as all candidate accounts are busy.
wait-timeout-seconds: 30
# Maximum queued requests per account; 0 means unbounded. Set this when a stalled
# upstream should shed load instead of letting callers pile up behind it.
max-queue-depth: 0
# Quota exceeded behavior
quota-exceeded:
switch-project: true # Whether to automatically switch to another project when a quota is exceeded
switch-preview-model: true # Whether to automatically switch to a preview model when a quota is exceeded
# Antigravity provider behavior.
# By default, CliRelay automatically obfuscates known upstream-filtering keywords (like Claude Agent SDK, Hermes Agent, Nous Research)
# with zero-width spaces in system instructions to prevent false 429 RESOURCE_EXHAUSTED errors.
# You can explicitly configure additional sensitive words or override the list:
# antigravity:
# sensitive-words: # optional: words to obfuscate with zero-width characters in system instructions
# - "Claude Agent SDK"
# - "Hermes Agent"
# - "Nous Research"
# Routing strategy for selecting credentials when multiple match.
# The first start stores this section in the database and removes it from this
# file. From then on edit routing on the Channel Groups page of the management
# panel: a routing section written here again is ignored, and a panel save of
# config.yaml that changes it is rejected.
routing:
strategy: "round-robin" # round-robin (default), fill-first
include-default-group: true
# channel-groups:
# - name: "pro"
# description: "Paid channels"
# priority: 100
# match:
# prefixes: ["pro"]
# # Every model these channels serve, including ones the upstream adds
# # later, except these. Accepts '*' wildcards, and a route prefix on
# # either side is ignored ("xai/grok-4.7" also covers "grok-4.7").
# excluded-models: ["grok-imagine-*"]
# - name: "team-a"
# description: "Team A channels"
# match:
# prefixes: ["team-a"]
# channels: ["Team A Codex"]
# # A fixed allow list instead: exact ids, no wildcards. Models the
# # upstream adds later are refused until they are listed here.
# allowed-models: ["gpt-5.5", "gpt-5.6-sol"]
# path-routes:
# - path: "/pro"
# group: "pro"
# strip-prefix: true
# fallback: "none"
# - path: "/team-a"
# group: "team-a"
# strip-prefix: true
# fallback: "default"
# Optional client API keys with per-key permissions. Empty allowed-* arrays mean "no restriction".
# Like api-keys above, they are only imported while the database holds no API
# keys yet.
# api-key-entries:
# - key: "sk-user-pro"
# name: "Pro User"
# daily-spending-limit: 2.0
# allowed-channel-groups: ["pro"]
# - key: "sk-team-a"
# name: "Team A"
# allowed-channel-groups: ["team-a", "pro"]
# allowed-channels: ["Team A Codex"]
# When true, enable authentication for the WebSocket API (/v1/ws).
ws-auth: false
# When > 0, emit blank lines every N seconds for non-streaming responses to prevent idle timeouts.
nonstream-keepalive-interval: 0
# Streaming behavior (SSE keep-alives + safe bootstrap retries).
streaming:
keepalive-seconds: 15 # Default: 15. Set < 0 to disable keep-alives.
# How many times a stream that fails before its first byte moves to another
# account. Leave it unset for the default (2, and never more than the accounts
# that can serve the request); 0 turns it off.
# bootstrap-retries: 2
# Process-wide cap on requests waiting at once for a cooling account. It only
# matters when a channel group turns busy waiting on (busy-wait-max-seconds in
# the group's settings, off by default). Every waiter holds its client
# connection open, idle, and counts against the reverse proxy's limit on
# connections to this process (nginx max_conns), so keep it well below that
# limit. Unset, 0 or negative take the default (64); it never means unlimited.
# A request over the cap fails at once, as if the group had waiting off.
# Streaming clients get keep-alive comments while they wait; non-streaming
# requests and image/video submissions wait silently, so a client whose own
# timeout is shorter than the group's wait counts the wait as a failure.
# busy-wait-max-waiters: 64
# Gemini API keys
# gemini-api-key:
# - api-key: "AIzaSy...01"
# prefix: "test" # optional: require calls like "test/gemini-3-pro-preview" to target this credential
# base-url: "https://generativelanguage.googleapis.com"
# headers:
# X-Custom-Header: "custom-value"
# proxy-url: "socks5://proxy.example.com:1080"
# models:
# - name: "gemini-2.5-flash" # upstream model name
# alias: "gemini-flash" # client alias mapped to the upstream model
# excluded-models:
# - "gemini-2.5-pro" # exclude specific models from this provider (exact match)
# - "gemini-2.5-*" # wildcard matching prefix (e.g. gemini-2.5-flash, gemini-2.5-pro)
# - "*-preview" # wildcard matching suffix (e.g. gemini-3-pro-preview)
# - "*flash*" # wildcard matching substring (e.g. gemini-2.5-flash-lite)
# - api-key: "AIzaSy...02"
# Chat model that carries the image_generation tool for Codex image requests.
# Codex OAuth has no standalone image endpoint: /v1/images and image-only
# /v1/responses calls are sent as a tool attached to an ordinary chat completion,
# so some chat model has to carry them. Leave this unset to follow the live Codex
# manifest, which is the only source that knows what an account may call. Set it
# only to pin a specific carrier, e.g. to control cost.
# codex-image-base-model: "gpt-5.5"
# Compress the request body of Codex OAuth (ChatGPT account) POST /responses calls
# with zstd, as the official Codex client does. On by default. It only applies to
# chatgpt.com; API-key accounts, custom base URLs, /responses/compact and
# websockets are unaffected, and request logs keep the plain JSON. Set false to
# send plain JSON, e.g. to read the bytes on the wire through an inspecting proxy.
# codex-request-zstd: false
# Client-facing Responses WebSocket (GET /v1/responses, /backend-api/codex/responses).
# Over it Codex sends only what a turn adds (previous_response_id plus the new
# input items); over HTTP it re-sends the whole conversation every turn,
# screenshots included. Codex uses it when its provider sets
# supports_websockets = true.
# responses-websocket:
# disabled: false # true answers the upgrade with 426, and Codex falls back to HTTP at once
# compression: true # permessage-deflate for clients that offer it
# max-message-mb: 128 # limit of one client message
# max-transcript-mb: 64 # transcript kept between turns; past it the connection closes after the turn
# idle-timeout-seconds: 600 # close a connection that waits this long for its next turn; negative disables
# Codex API keys
# codex-api-key:
# - api-key: "sk-atSM..."
# alpha-search: false # opt in only when this upstream supports the Codex alpha search endpoint
# prefix: "test" # optional: require calls like "test/gpt-5-codex" to target this credential
# base-url: "https://www.example.com" # use the custom codex API endpoint
# headers:
# X-Custom-Header: "custom-value"
# proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override
# models:
# - name: "gpt-5-codex" # upstream model name
# alias: "codex-latest" # client alias mapped to the upstream model
# excluded-models:
# - "gpt-5.1" # exclude specific models (exact match)
# - "gpt-5-*" # wildcard matching prefix (e.g. gpt-5-medium, gpt-5-codex)
# - "*-mini" # wildcard matching suffix (e.g. gpt-5-codex-mini)
# - "*codex*" # wildcard matching substring (e.g. gpt-5-codex-low)
# Claude API keys
# claude-api-key:
# - api-key: "sk-atSM..." # use the official claude API key, no need to set the base url
# - api-key: "sk-atSM..."
# prefix: "test" # optional: require calls like "test/claude-sonnet-latest" to target this credential
# base-url: "https://www.example.com" # use the custom claude API endpoint
# headers:
# X-Custom-Header: "custom-value"
# proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override
# models:
# - name: "claude-3-5-sonnet-20241022" # upstream model name
# alias: "claude-sonnet-latest" # client alias mapped to the upstream model
# excluded-models:
# - "claude-opus-4-5-20251101" # exclude specific models (exact match)
# - "claude-3-*" # wildcard matching prefix (e.g. claude-3-7-sonnet-20250219)
# - "*-thinking" # wildcard matching suffix (e.g. claude-opus-4-5-thinking)
# - "*haiku*" # wildcard matching substring (e.g. claude-3-5-haiku-20241022)
# cloak: # optional: request cloaking for non-Claude-Code clients
# mode: "auto" # "auto" (default): cloak only when client is not Claude Code
# # "always": always apply cloaking
# # "never": never apply cloaking
# strict-mode: false # false (default): prepend Claude Code prompt to user system messages
# # true: strip all user system messages, keep only Claude Code prompt
# sensitive-words: # optional: words to obfuscate with zero-width characters
# - "API"
# - "proxy"
# cache-user-id: true # optional: default is false; set true to reuse cached user_id per API key instead of generating a random one each request
# # MiniMax API docs: https://platform.minimax.io/docs/api-reference/api-overview
# - name: "minimax-global-anthropic"
# api-key: "<MINIMAX_API_KEY>"
# base-url: "https://api.minimax.io/anthropic"
# skip-anthropic-processing: true
# models:
# - name: "MiniMax-M3"
# alias: "MiniMax-M3"
# - name: "MiniMax-M2.7"
# alias: "MiniMax-M2.7"
# # MiniMax China API docs: https://platform.minimaxi.com/docs/api-reference/api-overview
# - name: "minimax-cn-anthropic"
# api-key: "<MINIMAX_API_KEY>"
# base-url: "https://api.minimaxi.com/anthropic"
# skip-anthropic-processing: true
# models:
# - name: "MiniMax-M3"
# alias: "MiniMax-M3"
# - name: "MiniMax-M2.7"
# alias: "MiniMax-M2.7"
# Default headers for Claude API requests. Update when Claude Code releases new versions.
# These are used as fallbacks when the client does not send its own headers.
# claude-header-defaults:
# user-agent: "claude-cli/2.1.44 (external, sdk-cli)"
# package-version: "0.74.0"
# runtime-version: "v24.3.0"
# timeout: "600"
# Codex tool bridge (codex-tool-bridge on openai-compatibility and
# opencode-go-api-key entries). Off by default.
# Codex Desktop's Computer Use and Browser plugins do not reach models behind an
# OpenAI-compatible upstream as usable tools. With codex-tool-bridge: true, every
# request sent through that entry that already declares tools gets a fixed set of
# function definitions appended for them: ten mcp__computer_use__* functions and
# mcp__node_repl__js (a JavaScript kernel). Turning it on costs roughly 1.4k extra
# input tokens per such request, and the upstream model is offered these tools
# whether or not the client declared them. Enable it only on entries that serve
# Codex Desktop with those plugins.
# OpenCode Go API keys (the upstream endpoint is fixed)
# opencode-go-api-key:
# - api-key: "<OPENCODE_GO_API_KEY>"
# codex-tool-bridge: false # opt in only for Codex Desktop Computer Use / Browser, see above
# OpenAI compatibility providers
# openai-compatibility:
# - name: "openrouter" # The name of the provider; it will be used in the user agent and other places.
# prefix: "test" # optional: require calls like "test/kimi-k2" to target this provider's credentials
# base-url: "https://openrouter.ai/api/v1" # The base URL of the provider.
# headers:
# X-Custom-Header: "custom-value"
# codex-tool-bridge: false # opt in only for Codex Desktop Computer Use / Browser, see above
# disable-cooling: true # optional: keep sending to this provider when it answers 429/5xx; omit to follow the global disable-cooling
# api-key-entries:
# - api-key: "sk-or-v1-...b780"
# proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override
# - api-key: "sk-or-v1-...b781" # without proxy-url
# models: # The models supported by the provider.
# - name: "moonshotai/kimi-k2:free" # The actual model name.
# alias: "kimi-k2" # The alias used in the API.
# - name: "minimax-global"
# base-url: "https://api.minimax.io/v1"
# api-key-entries:
# - api-key: "<MINIMAX_API_KEY>"
# models:
# - name: "MiniMax-M3"
# alias: "MiniMax-M3"
# - name: "MiniMax-M2.7"
# alias: "MiniMax-M2.7"
# - name: "minimax-cn"
# base-url: "https://api.minimaxi.com/v1"
# api-key-entries:
# - api-key: "<MINIMAX_API_KEY>"
# models:
# - name: "MiniMax-M3"
# alias: "MiniMax-M3"
# - name: "MiniMax-M2.7"
# alias: "MiniMax-M2.7"
# Vertex API keys (Vertex-compatible endpoints, use API key + base URL)
# vertex-api-key:
# - api-key: "vk-123..." # x-goog-api-key header
# prefix: "test" # optional: require calls like "test/vertex-pro" to target this credential
# base-url: "https://example.com/api" # e.g. https://zenmux.ai/api
# proxy-url: "socks5://proxy.example.com:1080" # optional per-key proxy override
# headers:
# X-Custom-Header: "custom-value"
# models: # optional: map aliases to upstream model names
# - name: "gemini-2.5-flash" # upstream model name
# alias: "vertex-flash" # client-visible alias
# - name: "gemini-2.5-pro"
# alias: "vertex-pro"
# Amp Integration
# ampcode:
# # Configure upstream URL for Amp CLI OAuth and management features
# upstream-url: "https://ampcode.com"
# # Optional: Override API key for Amp upstream (otherwise uses env or file)
# upstream-api-key: ""
# # Per-client upstream API key mapping
# # Maps client API keys (from top-level api-keys) to different Amp upstream API keys.
# # Useful when different clients need to use different Amp accounts/quotas.
# # If a client key isn't mapped, falls back to upstream-api-key (default behavior).
# upstream-api-keys:
# - upstream-api-key: "amp_key_for_team_a" # Upstream key to use for these clients
# api-keys: # Client keys that use this upstream key
# - "your-api-key-1"
# - "your-api-key-2"
# - upstream-api-key: "amp_key_for_team_b"
# api-keys:
# - "your-api-key-3"
# # Restrict Amp management routes (/api/auth, /api/user, etc.) to localhost only (default: false)
# restrict-management-to-localhost: false
# # Force model mappings to run before checking local API keys (default: false)
# force-model-mappings: false
# # Amp Model Mappings
# # Route unavailable Amp models to alternative models available in your local proxy.
# # Useful when Amp CLI requests models you don't have access to (e.g., Claude Opus 4.5)
# # but you have a similar model available (e.g., Claude Sonnet 4).
# model-mappings:
# - from: "claude-opus-4-5-20251101" # Model requested by Amp CLI
# to: "gemini-claude-opus-4-5-thinking" # Route to this available model instead
# - from: "claude-sonnet-4-5-20250929"
# to: "gemini-claude-sonnet-4-5-thinking"
# - from: "claude-haiku-4-5-20251001"
# to: "gemini-2.5-flash"
# Global OAuth model name aliases (per channel)
# These aliases rename model IDs for both model listing and request routing.
# Supported channels: gemini-cli, vertex, aistudio, antigravity, claude, codex, qwen, xai, iflow, kimi.
# NOTE: Aliases do not apply to gemini-api-key, codex-api-key, claude-api-key, openai-compatibility, vertex-api-key, or ampcode.
# You can repeat the same name with different aliases to expose multiple client model names.
# oauth-model-alias:
# gemini-cli:
# - name: "gemini-2.5-pro" # original model name under this channel
# alias: "g2.5p" # client-visible alias
# fork: true # when true, keep original and also add the alias as an extra model (default: false)
# vertex:
# - name: "gemini-2.5-pro"
# alias: "g2.5p"
# aistudio:
# - name: "gemini-2.5-pro"
# alias: "g2.5p"
# antigravity:
# - name: "gemini-3-pro-high"
# alias: "gemini-3-pro-preview"
# claude:
# - name: "claude-sonnet-4-5-20250929"
# alias: "cs4.5"
# codex:
# - name: "gpt-5"
# alias: "g5"
# qwen:
# - name: "qwen3-coder-plus"
# alias: "qwen-plus"
# xai:
# - name: "grok-4.3"
# alias: "grok"
# iflow:
# - name: "glm-4.7"
# alias: "glm-god"
# kimi:
# - name: "kimi-k2.5"
# alias: "k2.5"
# OAuth provider excluded models
# oauth-excluded-models:
# gemini-cli:
# - "gemini-2.5-pro" # exclude specific models (exact match)
# - "gemini-2.5-*" # wildcard matching prefix (e.g. gemini-2.5-flash, gemini-2.5-pro)
# - "*-preview" # wildcard matching suffix (e.g. gemini-3-pro-preview)
# - "*flash*" # wildcard matching substring (e.g. gemini-2.5-flash-lite)
# vertex:
# - "gemini-3-pro-preview"
# aistudio:
# - "gemini-3-pro-preview"
# antigravity:
# - "gemini-3-pro-preview"
# claude:
# - "claude-3-5-haiku-20241022"
# codex:
# - "gpt-5-codex-mini"
# qwen:
# - "vision-model"
# iflow:
# - "tstars2.0"
# kimi:
# - "kimi-k2-thinking"
# Optional payload configuration
# payload:
# default: # Default rules only set parameters when they are missing in the payload.
# - models:
# - name: "gemini-2.5-pro" # Supports wildcards (e.g., "gemini-*")
# protocol: "gemini" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
# params: # JSON path (gjson/sjson syntax) -> value
# "generationConfig.thinkingConfig.thinkingBudget": 32768
# default-raw: # Default raw rules set parameters using raw JSON when missing (must be valid JSON).
# - models:
# - name: "gemini-2.5-pro" # Supports wildcards (e.g., "gemini-*")
# protocol: "gemini" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
# params: # JSON path (gjson/sjson syntax) -> raw JSON value (strings are used as-is, must be valid JSON)
# "generationConfig.responseJsonSchema": "{\"type\":\"object\",\"properties\":{\"answer\":{\"type\":\"string\"}}}"
# override: # Override rules always set parameters, overwriting any existing values.
# - models:
# - name: "gpt-*" # Supports wildcards (e.g., "gpt-*")
# protocol: "codex" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
# params: # JSON path (gjson/sjson syntax) -> value
# "reasoning.effort": "high"
# override-raw: # Override raw rules always set parameters using raw JSON (must be valid JSON).
# - models:
# - name: "gpt-*" # Supports wildcards (e.g., "gpt-*")
# protocol: "codex" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
# params: # JSON path (gjson/sjson syntax) -> raw JSON value (strings are used as-is, must be valid JSON)
# "response_format": "{\"type\":\"json_schema\",\"json_schema\":{\"name\":\"answer\",\"schema\":{\"type\":\"object\"}}}"
# filter: # Filter rules remove specified parameters from the payload.
# - models:
# - name: "gemini-2.5-pro" # Supports wildcards (e.g., "gemini-*")
# protocol: "gemini" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
# params: # JSON paths (gjson/sjson syntax) to remove from the payload
# - "generationConfig.thinkingConfig.thinkingBudget"
# - "generationConfig.responseJsonSchema"