Something went wrong. Try again.
sloproxy
Something went wrong. Try again.
cliproxyapi config.example.yaml
50 kB · 870 lines
YAML
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871# 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: ""
# Server portport: 8317
# TLS settings for HTTPS. When enabled, the server listens with the provided certificate and key.tls: enable: false cert: "" key: ""
# Management API settingsremote-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
# Disable automatic periodic background updates of the management panel from GitHub (default: false). # When enabled, the panel is only downloaded on first access if missing, and never auto-updated afterward. # disable-auto-update-panel: false
# GitHub repository for the management control panel. Accepts a repository URL or releases API URL. panel-github-repository: "https://github.com/router-for-me/Cli-Proxy-API-Management-Center"
# Authentication directory (supports ~ for home directory)auth-dir: "~/.cli-proxy-api"
# API keys for authenticationapi-keys: - "your-api-key-1" - "your-api-key-2" - "your-api-key-3"
# Enable debug loggingdebug: false
# Enable pprof HTTP debug server (host:port). Keep it bound to localhost for safety.pprof: enable: false addr: "127.0.0.1:8316"
# Credential concurrency is configured by Home in Home mode. The synthesized Home config is# authoritative and local values, including the values below, are ignored. Do not use local# configuration to override a Home concurrency policy.# credential-concurrency:# lifecycle-config-revision: 1# observation-barrier-revision: 0# cpa-heartbeat-timeout: "3s"# cpa-cancel-bound: "5s"# reclaim-grace: "5s"# cleanup-interval: "5s"# release-flush-interval: 250ms# release-max-backoff: 2s# busy-retry-min: 250ms# busy-retry-max: 1s# max-limit: 1000000
# Credential in-flight observation snapshot contract.# credential-in-flight:# snapshot-interval: 2s# stale-after: 10s# max-part-bytes: 262144# max-part-count: 64# max-revision-bytes: 16777216# max-aggregate-groups: 100000# max-details: 10000# max-string-bytes: 256# staging-retention: 1m
# Standard dynamic library plugins are trusted in-process code. They are disabled by default.# Build Go examples with go build -buildmode=c-shared for the target GOOS/GOARCH.# Other languages can implement the same C ABI and JSON method protocol.# Plugin executors require a matching auth record with the same provider key.# If the same provider is configured as OpenAI-compatible, the native executor wins.# Plugin command-line flags and Management API routes are optional capabilities.# Existing native flags/routes and higher-priority plugin flags/routes cannot be replaced.# Plugin list Management API reads Logo and ConfigFields from plugin metadata for management UI display.# Per-plugin enabled only controls plugins.configs.<pluginID>.enabled and does not implicitly change global plugins.enabled.plugins: enabled: false dir: "plugins" # Additional plugin store registries. The built-in official registry is always included. # store-sources: # - "https://example.com/cliproxy-plugins/registry.json" # Optional plugin store auth rules. Values are read from environment variables; # tokens are not written into plugin manifests or node status. # store-auth: # - match: "https://example.com/cliproxy-plugins/" # apply-to: ["registry", "artifact"] # type: bearer # token-env: "CLIPROXY_PLUGIN_STORE_TOKEN" configs: example: enabled: true priority: 1 config1: true config2: "string" config3: 3 mode: "safe" # enum example: safe, fast
# When true, disable high-overhead request logging and 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 stdoutlogging-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. Set to 0 to disable.logs-max-total-size-mb: 0
# 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 aggregationusage-statistics-enabled: false
# How long (in seconds) usage queue items are retained in memory for the Management API.# The local Redis RESP usage output is disabled.# Default: 60. Max: 3600.redis-usage-queue-retention-seconds: 60
# Proxy URL. Supports socks5/http/https protocols. Example: socks5://user:pass@192.168.1.1:1080/# Per-entry proxy-url also supports "direct" or "none" to bypass both the global proxy-url and environment proxies explicitly.proxy-url: ""
# 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 additional credential retry rounds after the first round exhausts# its eligible credentials. Round 0 is the initial round; round r only admits# credentials whose effective request-retry is at least r. Explicit non-negative# credential/provider overrides take precedence; omitted or negative overrides# inherit this global value, and explicit 0 only admits round 0. New CPA nodes# send retry_round=0 for the initial round and increment it for additional rounds;# legacy dispatch methods omit the field and keep old semantics.# Additional rounds apply to HTTP 403, 408, 429, 500, 502, 503, and 504 failures.# Individual credential/provider overrides take precedence; 0 disables additional# rounds, while an omitted or negative override inherits this global setting.request-retry: 3
# Maximum number of different credentials to try in each credential retry round# after per-credential round filtering. Set to 0 to try all available# credentials. Credentials skipped by this cap still age with the global round,# so the cap does not guarantee a fixed number of actual retries per credential.max-retry-credentials: 0
# Maximum cooldown wait in seconds between retry rounds.# Set to 0 or below to never wait for credential cooldown.# Retry rounds that need no wait remain controlled by request-retry.max-retry-interval: 30
# When true, disable auth/model cooldown scheduling globally (prevents blackout windows after failure states).# A credential/provider disable-cooling value, when present, overrides this global value.disable-cooling: false
# When true, persist per-auth cooldown status as .cds files next to auth files.# Default is false; when false, cooldown status is kept in memory only.save-cooldown-status: false
# Cooldown duration in seconds for transient upstream errors (408/500/502/503/504).# Set to 0 to keep the legacy 60-second cooldown; set to -1 to disable transient error cooldowns.transient-error-cooldown-seconds: 0
# When true, globally disable Claude request cloaking (the Claude Code CLI disguise and# system prompt replacement), so the original system prompt is passed through to Claude as-is.# Individual credentials can still override this: a claude-api-key entry via its "cloak.mode",# or a Claude OAuth/token file via a "cloak_mode" value. Default false keeps the per-client# "auto" behavior (cloak only non-Claude-Code clients).disable-claude-cloak-mode: false
# Claude Code compatibility settings.claude-code: # When true, return original model IDs in Anthropic model list responses instead of cloaked IDs. disable-cloaking-model-list: false
# disable-image-generation supports: false (default), true, "chat", or "passthrough".# - true: disable image_generation everywhere (also returns 404 for /v1/images/generations and /v1/images/edits).# - "chat": disable image_generation injection on non-images endpoints, but keep /v1/images/generations and /v1/images/edits enabled.# - "passthrough": never inject or strip image_generation on non-images endpoints (forward the client payload unchanged); behaves like "chat" on /v1/images/* endpoints.disable-image-generation: false
# Base model used by the legacy hosted image_generation tool path when a Codex image request is not proxied directly through the Image API.# Must start with "gpt-" (case-insensitive). If unset or invalid, defaults to "gpt-5.4-mini".# gpt-image-2-base-model: "gpt-5.4-mini"
# How long video IDs returned by /openai/v1/videos and xAI video creation stay bound# to the credential that created them. Default: 3h.video-result-auth-cache-ttl: "3h"
# Core auth auto-refresh worker pool size (OAuth/file-based auth token refresh).# When > 0, overrides the default worker count (16).# auth-auto-refresh-workers: 16
# Quota exceeded behaviorquota-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-credits: true # Whether to use credits as last-resort fallback when all free-tier auths are exhausted for Claude models
# Routing strategy for selecting credentials when multiple match.routing: strategy: "round-robin" # round-robin (default), weighted-round-robin, fill-first # weighted-round-robin uses each credential's integer weight (default 1, maximum 1,000,000). # Non-positive weights exclude the credential while this strategy is active. # For OAuth/file credentials, add a top-level numeric "weight" field to the auth JSON. # Enable universal session-sticky routing for all clients. # Explicit Claude Code, Codex, OpenCode, and pi session headers are preferred, # followed by prompt_cache_key, Responses conversation IDs, legacy body IDs, # execution or derived session identity, and the existing first-message hash fallback. # Automatic failover is always enabled when bound auth becomes unavailable. # An established binding outranks credential priority: once a session is bound, that # credential is kept even if a higher-priority credential recovers. Credential priority # still decides cold bindings, requests without a session, and post-failover rebinding. session-affinity: false # default: false # How long session-to-auth bindings are retained. Default: 1h session-affinity-ttl: "1h" # When true (default), subagents (child sessions with parent references) inherit and bind # to the parent's upstream credential across all providers (Claude, Codex, Antigravity, Gemini), # maximizing Prompt/KV Cache reuse and minimizing TTFT. # When false, subagents are distributed across the credential pool via the fallback selector # for maximum parallel concurrency. # Ignored when routing.session-affinity is false. session-affinity-subagents: true
# Codex provider behavior.codex: # When true, and routing.strategy is fill-first or routing.session-affinity is true, # remap Codex prompt_cache_key and installation identity per selected auth. # Some superstitious users believe request tracking identifiers can be used # as evidence for TOS enforcement bans; this option only satisfies those odd concerns. identity-confuse: false # Disable forcing the official Codex User-Agent and Originator headers on HTTP/SSE and WebSocket requests. disable-codex-cloaking: false # Hold back the initial handshake events (response.created, response.in_progress and the # websocket metadata frames) until the upstream emits its first generated event. # Why: the upstream smuggles `server_is_overloaded` rejections *inside* an HTTP 200 stream, # right after those handshake events, instead of returning 503 on the wire. Buffering them # keeps the downstream response headers uncommitted long enough to transparently retry on # another credential. Only overload/rate-limit rejections trigger failover; every other # terminal failure is still delivered in-stream exactly as before. # Trade-off: response headers are delayed until generation starts, which can trip client or # reverse-proxy read timeouts (e.g. nginx proxy_read_timeout) on long reasoning requests. # Default: false stream-bootstrap-buffering: false # When true, optimize Codex Desktop, codex-tui, and codex_cli_rs requests for multi-agent v2. # This refreshes Codex spawn_agent model details, removes message parameter encryption, # normalizes encrypted agent_message content for Codex, and converts agent_message input # into standard user messages for non-Codex upstream protocols. optimize-multi-agent-v2: false # When true, enable opt-in compatibility for orphan Codex delegation outputs. # Converts orphan function_call_output items from codex_app/create_thread and # codex_app/send_message_to_thread (which lack a valid call_id or matching function_call) # into standard user messages across Responses and non-Codex protocols when the request # header contains X-Openai-Subagent: collab_spawn. orphan-delegation-compatibility: false # Terminate and relay Codex Live WebRTC audio and DataChannel traffic in this process. # This requires inbound UDP reachability. Keep disabled to preserve direct media behavior. live-media-relay: enabled: false # Maximum concurrent media sessions. Zero uses the default of 32. max-sessions: 32 # Reject downstream SDP candidates that target private, loopback, link-local, or unspecified IPs. # Keep false for local or trusted-network Codex Desktop connections. disable-private-remote-ips: false # Public IPv4 or IPv6 address advertised when CPA is behind 1:1 NAT. public-ip: "" # Optional UDP allocation range. Both values must be set together and provide at least two ports per session. udp-port-min: 0 udp-port-max: 0 # Optional STUN/TURN servers. TURN credentials are never returned by the JSON config API. # Without a concrete global/per-auth proxy-url, WebRTC uses normal direct ICE/STUN/TURN connectivity. # With http, https, socks5, or socks5h proxy-url, the OpenAI-facing leg is forced through # authenticated ICE-TCP over that proxy and never falls back to UDP or a direct connection. # The Codex Desktop-facing leg remains direct, and configured ICE servers still apply to it. # ice-servers: # - urls: # - "stun:stun.example.com:3478" # - urls: # - "turn:turn.example.com:3478?transport=udp" # username: "user" # credential: "secret"
# Antigravity provider behavior.# antigravity:# sensitive-words: # optional: words to obfuscate with zero-width characters in system instructions# - "API"# - "proxy"
# xAI provider behavior.xai: # When true, inject the native x_search tool when the request does not declare it. # The injected tool is also added to tool_choice.allowed_tools when applicable. inject-x-search: false
# When true, enable authentication for the WebSocket API (/v1/ws).ws-auth: true
# 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: 0 (disabled). <= 0 disables keep-alives.# bootstrap-retries: 1 # Default: 0 (disabled). Retries before first byte is sent.
# Signature cache validation for thinking blocks (Antigravity/Claude).# When true (default), cached signatures are preferred and validated.# When false, client signatures are used directly after normalization (bypass mode for testing).# antigravity-signature-cache-enabled: true
# Bypass mode signature validation strictness (only applies when signature cache is disabled).# When true, validates full Claude protobuf tree (Field 2 -> Field 1 structure).# When false (default), only checks R/E prefix + base64 + first byte 0x12.# antigravity-signature-bypass-strict: false
# Gemini API keys# gemini-api-key:# - api-key: "AIzaSy...01"# weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000# prefix: "test" # optional: require calls like "test/gemini-3-pro-preview" to target this credential# disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global# request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global# request-scoped-errors: # optional: custom rules to classify upstream errors by status and body patterns# - status: 400 # HTTP status code to match# match: # optional: string contains matching# - "maximum_context_length"# - "context_length_exceeded"# match-regexr: # optional: regular expression matching# - "maximum_context_length$"# - "^context_length_exceeded"# action: "stop" # "stop" (return error, no cooling), "stop-and-cooldown" (return error and cool down),# # "continue" (try next credential, no cooling), "continue-and-cooldown" (try next credential and cool down)# base-url: "https://generativelanguage.googleapis.com"# headers:# X-Custom-Header: "custom-value"# # Values starting with "$" dynamically copy the header value from downstream client requests.# # If the client did not send the specified header, the header is omitted.# # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header# proxy-url: "socks5://proxy.example.com:1080"# # proxy-url: "direct" # optional: explicit direct connect for this credential# models:# - name: "gemini-2.5-flash" # upstream model name# alias: "gemini-flash" # client alias mapped to the upstream model# display-name: "Gemini Flash" # optional catalog display name# max-context-length: 1048576 # optional: override Codex client context window metadata# is-compat: false # optional: preserve thinking blocks with empty signatures for compatible upstreams# thinking: # optional: exact thinking capability for this configured model# levels: ["high", "medium", "low", "none", "auto"]# 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"
# Native Interactions API keys# These keys are used only for direct /v1beta/interactions execution. Regular gemini-api-key entries still# send Gemini generateContent/streamGenerateContent requests when the client enters through the interactions API.# interactions-api-key:# - api-key: "AIzaSy...03"# weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000# prefix: "native" # optional: require calls like "native/gemini-3-pro-preview" to target this credential# disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global# request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global# request-scoped-errors: # optional: custom rules to classify upstream errors by status and body patterns# - status: 400# match:# - "invalid_argument"# action: "continue"# base-url: "https://generativelanguage.googleapis.com"# headers:# X-Custom-Header: "custom-value"# # Values starting with "$" dynamically copy the header value from downstream client requests.# # If the client did not send the specified header, the header is omitted.# # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header# proxy-url: "socks5://proxy.example.com:1080"# # proxy-url: "direct" # optional: explicit direct connect for this credential# models:# - name: "gemini-2.5-flash" # upstream model name# alias: "native-gemini-flash" # client alias mapped to the upstream model# max-context-length: 1048576 # optional: override Codex client context window metadata# is-compat: false # optional: preserve thinking blocks with empty signatures for compatible upstreams# thinking: # optional: exact thinking capability for this configured model# levels: ["high", "medium", "low", "none", "auto"]# excluded-models:# - "gemini-2.5-pro"
# Codex API keys# codex-api-key:# - api-key: "sk-atSM..."# weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000# prefix: "test" # optional: require calls like "test/gpt-5-codex" to target this credential# disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global# request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global# request-scoped-errors: # optional: custom rules to classify upstream errors by status and body patterns# - status: 400# match:# - "context_window_exceeded"# action: "stop-and-cooldown"# base-url: "https://www.example.com" # use the custom codex API endpoint# alpha-search: false # optional: allow this key to serve /v1/alpha/search via base-url + /alpha/search# headers:# X-Custom-Header: "custom-value"# # Values starting with "$" dynamically copy the header value from downstream client requests.# # If the client did not send the specified header, the header is omitted.# # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header# proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override# # proxy-url: "direct" # optional: explicit direct connect for this credential# models:# - name: "gpt-5-codex" # upstream model name# alias: "codex-latest" # client alias mapped to the upstream model# display-name: "Codex Latest" # optional catalog display name# max-context-length: 1048576 # optional: override Codex client context window metadata# force-mapping: true # optional: rewrite response model fields back to the alias# # When true and codex.optimize-multi-agent-v2 is also true, convert Codex# # MultiAgentV2 agent_message items into portable Responses message/user input# # for third-party Responses-compatible endpoints that reject agent_message.# # Default false keeps agent_message unchanged for native OpenAI/Codex endpoints.# # It also preserves thinking blocks with empty signatures for compatible upstreams.# is-compat: false# thinking: # optional: exact thinking capability for this configured model# levels: ["xhigh", "high", "medium", "low"]# 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)
# xAI API keys# Uses the native xAI executor, including its Responses namespace-tool handling.# xai-api-key:# - api-key: "xai-..."# weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000# prefix: "xai" # optional: require calls like "xai/grok-4.5" to target this credential# disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global# request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global# request-scoped-errors: # optional: custom rules to classify upstream errors by status and body patterns# - status: 400# match:# - "rate_limit_exceeded"# action: "continue-and-cooldown"# base-url: "https://api.x.ai/v1" # xAI-compatible Responses API endpoint# websockets: true # optional: use the xAI upstream websocket transport for downstream websocket requests# headers:# X-Custom-Header: "custom-value"# # Values starting with "$" dynamically copy the header value from downstream client requests.# # If the client did not send the specified header, the header is omitted.# # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header# proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override# # proxy-url: "direct" # optional: explicit direct connect for this credential# models:# - name: "grok-4.5" # upstream model name# alias: "grok-latest" # client alias mapped to the upstream model# display-name: "Grok Latest" # optional catalog display name# max-context-length: 1048576 # optional: override Codex client context window metadata# force-mapping: true # optional: rewrite response model fields back to the alias# is-compat: false # optional: preserve thinking blocks with empty signatures for compatible upstreams# thinking: # optional: exact thinking capability for this configured model# levels: ["xhigh", "high", "medium", "low"]# excluded-models:# - "grok-4.1" # exclude specific models (exact match)# - "grok-3-*" # wildcard matching prefix
# 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..."# weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000# prefix: "test" # optional: require calls like "test/claude-sonnet-latest" to target this credential# disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global# request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global# request-scoped-errors: # optional: custom rules to classify upstream errors by status and body patterns# - status: 400# match:# - "prompt is too long"# action: "stop"# base-url: "https://www.example.com" # use the custom claude API endpoint# headers:# X-Custom-Header: "custom-value"# # Values starting with "$" dynamically copy the header value from downstream client requests.# # If the client did not send the specified header, the header is omitted.# # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header# proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override# # proxy-url: "direct" # optional: explicit direct connect for this credential# models:# - name: "claude-3-5-sonnet-20241022" # upstream model name# alias: "claude-sonnet-latest" # client alias mapped to the upstream model# display-name: "Claude Sonnet" # optional catalog display name# max-context-length: 1048576 # optional: override Codex client context window metadata# force-mapping: true # optional: rewrite response model fields back to the alias# is-compat: false # optional: preserve thinking blocks with empty signatures for compatible upstreams# thinking: # optional: exact thinking capability for this configured model# levels: ["max", "xhigh", "high", "medium", "low", "minimal", "none", "auto"]# 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)# rebuild-mid-system-message: false # optional: default is false; when true, move caller-supplied messages with role "system" into the top-level Claude system field# cloak: # optional: explicitly enable request cloaking for non-Claude-Code clients# mode: "auto" # "auto" (default inside this block): cloak only when client is not Claude Code# # "always": cloak every unconfirmed client; confirmed native Claude Code still passes through# # "never": never apply cloaking# # This "cloak" block applies to this claude-api-key entry only. For Claude OAuth# # credentials, set the same options in the auth/token JSON file via "cloak_mode" /# # "cloak_strict_mode" / "cloak_sensitive_words" / "cloak_cache_user_id". OAuth token# # JSON also accepts "rebuild_mid_system_message": "true" for the option above. The top-level# # "disable-claude-cloak-mode: true" disables cloaking for all Claude credentials at once.# strict-mode: false # false (default): preserve caller instructions in top-level system;# # cloaking never inserts them into conversation messages# # true: strip caller prompts and keep only Claude Code billing and identity blocks# 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# # Every custom tool on a cloaked OAuth request automatically uses a caller-stable opaque mcp__<server>__<tool> alias.## # fingerprint-profile (optional, top-level on this claude-api-key entry; not a cloak sub-field):# # OAuth and API-key fingerprints are different contracts.# # - Real Claude OAuth stays on the strict Claude Code CLI wire fingerprint.# # - API keys (official Anthropic, custom gateways, Kimi) stay loose and# # caller-owned unless this field is set.# ## # Default (omit / empty): keep the caller request fingerprint and headers.# # Official api.anthropic.com API keys do not add extra CLI betas/identity unless# # this field is set. Custom gateways and delegated providers are the same.# ## # Controls request fingerprint only on /v1/messages (and related Claude executor paths).# # Auth scheme stays API key (x-api-key on api.anthropic.com; Bearer on custom base-url).# # Does NOT enable OAuth refresh, profile fetch, or OAuth-cancellation semantics.# ## # Values:# # omit / empty = caller-owned API-key fingerprint (respects caller)# # "claude-code-cli" = same Messages fingerprint as Claude Code OAuth CLI,# # including official Anthropic API keys: OAuth Anthropic-Beta# # set, CCH signing on api.anthropic.com, stable CLI# # metadata.user_id / session_id / device identity.# # API keys seed identity from the key;# # delegated OAuth providers use stable auth ID instead of# # rotating access tokens. "oauth-cli" is a legacy alias.# ## # count_tokens keeps the native model/messages/tools shape for every origin, including# # Kimi opt-in. It does not send billing/CCH, currentDate, metadata, or diagnostics.# ## # CCH: the billing block may carry a per-request cch hash. CPA emits it exactly where# # Claude Code does, which is api.anthropic.com (first-party) and Vertex only. An opt-in# # on any other gateway (including Kimi) still sends the billing block, but without cch,# # so a per-request hash cannot bust that gateway's prompt cache. api.anthropic.com# # strips the block itself (0 tokens, no cache impact). Kimi drops the whole block by# # default and keeps it, unsigned, after an explicit fingerprint opt-in.# # A real Claude OAuth credential always signs, on every upstream: a downstream Claude# # Code pointed at CPA cannot produce that value itself.# ## # Example (official Anthropic or a custom Messages gateway):# # - api-key: "your-key"# # # base-url: "https://gateway.example" # omit for api.anthropic.com# # fingerprint-profile: "claude-code-cli"# # cloak:# # mode: "always" # recommended when upstream rejects non-CLI clients# ## # Delegated Anthropic Messages OAuth files (Kimi, etc.) use "fingerprint_profile"# # in the auth JSON. Refresh keeps it. Example:# # {# # "type": "kimi",# # "access_token": "...",# # "refresh_token": "...",# # "fingerprint_profile": "claude-code-cli"# # }# # Legacy "fingerprint-profile" credentials remain supported and are normalized at load time.# # fingerprint-profile: "claude-code-cli" # optional claude-api-key provider field; default is empty (caller-owned); uncomment to opt in# experimental-cch-signing: false # deprecated compatibility field; CCH is generated automatically# # for real Claude OAuth on any upstream, and for claude-code-cli profiles# # only on api.anthropic.com; Vertex keeps provider-native signing
# Anthropic-Beta is assembled per request rather than sent as a fixed list, matching# Claude Code: context-1m sits right after claude-code, mid-conversation-system# is added only for models that accept a role=system turn, advanced-tool-use only when# the request declares tools, and server-side-fallback / fallback-credit /# structured-outputs trail effort. On direct api.anthropic.com a caller may only ask for# betas real Claude Code also sends, and they are placed at their observed positions;# anything else is dropped so the outgoing set stays one a real client could produce.# Other Anthropic-compatible upstreams still forward caller betas verbatim.## Default headers for Claude API requests. Update only after measuring a new Claude Code release.# Unconfirmed clients use this CLI baseline. Verified native Claude Code CLI, sdk-cli,# and VSCode requests preserve their measured entrypoint and software shape only when the# Claude Code version, package version, and runtime version exactly match this configured# baseline; unmeasured versions fall back to it. In legacy mode, timeout is a fallback and# verified native OS/arch values remain client-supplied. When stabilize-device-profile is# enabled, OS/arch are pinned to the values below and cached profiles remain constrained to# the same exact software baseline rather than learning newer client versions.# claude-header-defaults:# user-agent: "claude-cli/2.1.258 (external, cli)"# package-version: "0.112.1"# runtime-version: "v26.3.0"# os: "MacOS"# arch: "arm64"# timeout: "600"# timezone: "Asia/Singapore" # fallback IANA timezone for cloaked currentDate; a credential JSON "timezone" takes priority# stabilize-device-profile: false # optional, default false; set true to enable per-auth/API-key fingerprint pinning
# Default headers for Codex OAuth model requests.# These are used only for file-backed/OAuth Codex requests when the client# does not send the header. `user-agent` applies to HTTP and websocket requests;# `beta-features` only applies to websocket requests. They do not apply to codex-api-key entries.# codex-header-defaults:# user-agent: "codex_cli_rs/0.114.0 (Mac OS 14.2.0; x86_64) vscode/1.111.0"# beta-features: "multi_agent"
# OpenAI compatibility providers# openai-compatibility:# - name: "openrouter" # The name of the provider; it will be used in the user agent and other places.# disabled: false # optional: set to true to disable this provider without removing it# 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.# support-prompt-cache-key: false # optional: derive prompt_cache_key for requests from all input protocols# disable-cooling: false # optional provider override: true disables cooling, false enables it; omit to inherit global# request-retry: 3 # optional per-provider override; 0 disables additional rounds; omit or set < 0 to inherit global# request-scoped-errors: # optional: custom rules to classify upstream errors by status and body patterns# - status: 400# match:# - "maximum_context_length"# - "context_length_exceeded"# match-regexr:# - "maximum_context_length$"# - "^context_length_exceeded"# action: "stop" # "stop", "stop-and-cooldown", "continue", "continue-and-cooldown"# headers:# X-Custom-Header: "custom-value"# # Values starting with "$" dynamically copy the header value from downstream client requests.# # If the client did not send the specified header, the header is omitted.# # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header# api-key-entries:# - api-key: "sk-or-v1-...b780"# weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000# proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override# # proxy-url: "direct" # optional: explicit direct connect for this credential# - 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.# display-name: "Kimi K2" # optional catalog display name# max-context-length: 1048576 # optional: override Codex client context window metadata# image: false # optional: set true to allow this model on /v1/images/generations and /v1/images/edits (not chat/responses image input)# input-modalities: [text, image] # optional: declare /v1/chat/completions and /v1/responses multimodal input for Codex clients. Use [text] for upstreams that reject multimodal tool result content.# output-modalities: [text] # optional: declare output modalities when known# is-compat: false # optional: preserve Claude thinking blocks for compatible upstreams# thinking: # optional: omit to default to levels ["low","medium","high"]# levels: ["low", "medium", "high"]# # You may repeat the same alias to build an internal model pool.# # The client still sees only one alias in the model list.# # Requests to that alias will round-robin across the upstream names below,# # and if the chosen upstream fails before producing output, the request will# # continue with the next upstream model in the same alias pool.# - name: "deepseek-v3.1"# alias: "claude-opus-4.66"# - name: "glm-5"# alias: "claude-opus-4.66"# - name: "kimi-k2.5"# alias: "claude-opus-4.66"
# Vertex API keys (Vertex-compatible endpoints, base-url is optional)# vertex-api-key:# - api-key: "vk-123..." # x-goog-api-key header# weight: 5 # optional: weighted-round-robin share; omitted defaults to 1; maximum 1,000,000# prefix: "test" # optional: require calls like "test/vertex-pro" to target this credential# disable-cooling: false # optional override: true disables cooling, false enables it; omit to inherit global# request-retry: 3 # optional per-auth override; 0 disables additional rounds; omit or set < 0 to inherit global# base-url: "https://example.com/api" # optional, e.g. https://zenmux.ai/api; falls back to Google Vertex when omitted# proxy-url: "socks5://proxy.example.com:1080" # optional per-key proxy override# # proxy-url: "direct" # optional: explicit direct connect for this credential# headers:# X-Custom-Header: "custom-value"# # Values starting with "$" dynamically copy the header value from downstream client requests.# # If the client did not send the specified header, the header is omitted.# # X-Claude-Code-Session-Id: "$ABC" # copies client's "ABC" header# models: # optional: map aliases to upstream model names# - name: "gemini-2.5-flash" # upstream model name# alias: "vertex-flash" # client-visible alias# display-name: "Vertex Flash" # optional catalog display name# thinking: # optional: exact thinking capability for this configured model# levels: ["high", "medium", "low", "none", "auto"]# - name: "gemini-2.5-pro"# alias: "vertex-pro"# excluded-models: # optional: models to exclude from listing# - "imagen-3.0-generate-002"# - "imagen-*"
# Global OAuth model name aliases (per channel)# These aliases rename model IDs for both model listing and request routing.# Supported channels: vertex, aistudio, antigravity, claude, codex, kimi, xai.# NOTE: Aliases do not apply to gemini-api-key, interactions-api-key, codex-api-key, xai-api-key, claude-api-key, openai-compatibility, or vertex-api-key.# NOTE: Because aliases affect the merged /v1 model list and merged request routing, overlapping# client-visible names can become ambiguous across providers. For strict backend pinning, use# unique aliases/prefixes or avoid overlapping names.# You can repeat the same name with different aliases to expose multiple client model names.# Optional per-entry fields:# fork: true # keep the upstream model and also expose the alias as a separate client-visible model# display-name: "Model Name" # override the human-readable name shown in model catalogs# force-mapping: true # rewrite upstream response model fields back to the client-visible alias (example below uses antigravity only)# Per-auth OAuth aliases can also be stored in an OAuth auth JSON file as "model_aliases".# Legacy "model-aliases" credentials remain supported and are normalized at load time.# They apply only to that selected auth and take precedence over global aliases for the same client-visible alias.# Example auth JSON:# {# "type": "codex",# "email": "user@example.com",# "model_aliases": [# {"name": "gpt-5.3-codex-spark", "alias": "gpt-5.5"},# {"name": "gpt-5.3-codex-spark", "alias": "gpt-5.4"}# ]# }# oauth-model-alias:# vertex:# - name: "gemini-2.5-pro"# alias: "g2.5p"# aistudio:# - name: "gemini-2.5-pro"# alias: "g2.5p"# antigravity:# - name: "gemini-pro-agent" # upstream Antigravity model id# alias: "gemini-3.1-pro-preview" # client-visible id (Gemini 3.1 Pro Preview)# display-name: "Antigravity Gemini 3.1 Pro" # optional catalog display name# fork: true# force-mapping: true# claude:# - name: "claude-sonnet-4-5-20250929"# alias: "cs4.5"# codex:# - name: "gpt-5"# alias: "g5"# kimi:# - name: "kimi-k2.5"# alias: "k2.5"# xai:# - name: "grok-4.3"# alias: "grok-latest"# sample-provider: # plugin provider keys are supported for OAuth plugins# - name: "sample-model-latest"# alias: "sample-latest"
# OAuth provider excluded models# oauth-excluded-models:# 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"# kimi:# - "kimi-k2-thinking"# xai:# - "grok-3-mini"
# OAuth provider request-scoped error rules (custom error classification for OAuth credentials)# oauth-request-scoped-errors:# vertex:# - status: 400# match:# - "maximum_context_length"# - "context_length_exceeded"# match-regexr:# - "maximum_context_length$"# - "^context_length_exceeded"# action: "stop" # options: "stop", "stop-and-cooldown", "continue", "continue-and-cooldown"# aistudio:# - status: 400# match:# - "invalid_argument"# action: "stop"# antigravity:# - status: 500# match:# - "internal_server_error"# action: "stop-and-cooldown"# claude:# - status: 400# match:# - "prompt is too long"# action: "stop"# codex:# - status: 400# match:# - "context_window_exceeded"# action: "stop"# kimi:# - status: 400# match:# - "length_limit"# action: "stop"# xai:# - status: 400# match:# - "max_tokens_exceeded"# action: "stop"
# 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# from-protocol: "responses" # restricts the rule to the source protocol, options: openai, responses, gemini, claude# headers: # all configured request headers must match; values support "*" wildcards# X-Client-Tier: "tenant-*-region-*"# match: # all payload JSON paths must equal the configured values# - "metadata.client": "codex"# not-match: # payload JSON paths must not equal the configured values# - "metadata.mode": "dev"# exist: # all payload JSON paths must exist and not be null# - "tools.#(type==\"web_search\").type"# not-exist: # all payload JSON paths must be missing or null# - "metadata.disable_payload"# 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-5.4-fast"# protocol: "codex"# - name: "gpt-5.5-fast"# protocol: "codex"# params:# service_tier: priority# - 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"# - models:# - name: "claude-fable-5-1"# protocol: "claude"# params:# max_tokens: 128000 # override the final Claude Messages output budget after protocol translation# 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"