cc-switch Documentation

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io

RAW Doc

Technical Documentation: farion1231/cc-switch

ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference

Overview (`README.md`)

Want to appear here?

Click to collapse

Kimi K3 is Moonshot AI's most capable model and the world's first open 3T-class model. With 2.8 trillion parameters, native vision, and a 1-million-token context window, K3 delivers frontier performance across long-horizon coding, knowledge work, and reasoning. CC Switch makes it easy to configure and switch to Kimi across agentic tools.

Try a Kimi Code plan (中文站 | Global), or use the API through the Kimi Open Platform (中文站 | Global).

New user top-up bonus: register and complete your first top-up via the API links above to receive 10% of the amount as bonus API credit, up to CNY ¥1,000.


Thanks to PackyCode for sponsoring this project! PackyCode is a reliable and efficient API relay service provider, offering relay services for Claude Code, Codex, Gemini, and more. PackyCode provides special discounts for our software users: register using this link and enter the "cc-switch" promo code during first recharge to get 10% off.
Thanks to ZetaAPI for sponsoring this project! ZetaAPI focuses on real model fidelity, no watered-down responses, no quality degradation, and pricing as low as 35% of official rates. The platform does not mix traffic, secretly replace models with lower-quality alternatives, or use fake model routing. It supports Claude Code, Codex, Gemini, ChatGPT, and other mainstream AI models, helping users significantly reduce API costs while maintaining reliable model quality. At the same time, ZetaAPI provides enterprise-grade SLA-backed stability, standard API compatibility, one API key for multiple models, fast integration, and pay-as-you-go billing, making it suitable for AI products, coding agents, internal business tools, customer service systems, content generation, and automation workflows. If any model is verified to be inconsistent with its stated quality, ZetaAPI backs it with a 10x compensation guarantee, giving users a more stable, transparent, and trustworthy experience. Register via this link and use the promo code CC-SWITCH during your first recharge to enjoy an exclusive 10% discount on your first top-up, just for CC Switch users!
Thanks to APINEBULA for sponsoring this project! APINEBULA, an enterprise-grade AI aggregation platform under Galaxy Video Bureau, leverages extensive platform resources to provide developers, teams, and enterprises with stable, cost-effective access to large language model APIs. The platform integrates leading, full-powered models like Claude, GPT, and Gemini, allowing you to connect to the world's top AI models through a single API, with prices starting as low as 10% of the original cost. Designed for AI programming, Agent development, and business system integration, APINEBULA supports enterprise-grade high concurrency, formal contracts, corporate bank transfers, and invoicing services. APINEBULA provides special discounts for our software users: register using this link and enter the "ccswitch" promo code during your first recharge to get 10% off.
Thanks to AICodeMirror for sponsoring this project! AICodeMirror provides official high-stability relay services for Claude Code / Codex / Gemini CLI, with enterprise-grade concurrency, fast invoicing, and 24/7 dedicated technical support.
Claude Code / Codex / Gemini official channels at 38% / 2% / 9% of original price, with extra discounts on top-ups! AICodeMirror offers special benefits for CC Switch users: register via this link to enjoy 20% off your first top-up, and enterprise customers can get up to 25% off!
Thanks to PatewayAI for sponsoring this project! PatewayAI is an API relay service provider built for heavy AI developers, focused on directly relaying official high-quality model APIs. It offers the full Claude lineup and the Codex series, 100% sourced from official channels — no dilution, no fakes, verification welcome. Billing is transparent and every token-level invoice can be audited line by line.
It also supports enterprise-grade concurrency and provides a dedicated management platform for enterprise customers — formal contracts and invoicing are available; visit the official website for contact details.
Register now via this link to receive $3 in trial credit. Top-ups go as low as 60% of the original price, with a two-way referral bonus of up to $150!
Thanks to Fenno.ai for sponsoring this project! Fenno.ai is a stable and efficient API relay service provider, currently focused on Codex relay. It is compatible with the OpenAI and Anthropic protocols and can be flexibly used from Codex, Claude Code, OpenCode, and other mainstream coding tools. It reliably supports enterprise-grade workloads of hundreds of billions of tokens per day, with corporate (B2B) settlement and invoicing for both domestic and overseas entities. Fenno.ai offers an exclusive benefit for CC Switch users: subscribe via this link to the $1.99 Trial Plan worth $50 in credits (valid for 7 days), and earn up to 20% in referral rewards — invite more, earn more!
Thanks to RunAPI for sponsoring this project! RunAPI is a high-performance and reliable AI model API gateway — one API key gives you access to 150+ mainstream models including OpenAI, Claude, Gemini, DeepSeek, and Grok, with prices as low as 10% of the official rate and excellent stability. It works seamlessly with Claude Code, OpenClaw, and other tools. Exclusive benefit for CC Switch users: register via this link and enjoy a 10% discount on your first top-up!
Thanks to OpenModel for sponsoring this project! OpenModel offers client-specific discounts of up to 90% for Codex and 60% for Claude Code across supported models, helping developers cut API costs without changing how they work. Just connect your OpenModel API key and keep using Codex or Claude Code as usual — supported clients are detected automatically and discounted routes are applied with no extra parameters or manual routing required. You can also configure fallback behavior per API key, choosing whether to continue at standard pricing or stop when a discounted route is temporarily unavailable. CC Switch users can register via this link and use promo code "cc-switch" to get 10% off their first top-up.
Thanks to GrooRoute Pro for sponsoring this project! GrooRoute Pro is a reliable, smooth AI API relay platform with access to OpenAI, Claude, DeepSeek, and other mainstream models. Deployed on overseas servers, it lets you choose your own pricing-multiplier tier and offers both pay-as-you-go billing and subscription plans, so you can use it however suits you best — with stable routes and fast responses that make calling all kinds of AI capabilities easier. Exclusive benefit for CC Switch users: register via this link to get ¥5 in free trial credit!
Thanks to Shengsuanyun for sponsoring this project! Shengsuanyun is a super factory serving AI Native Teams — an industrial-grade AI task parallel execution platform. Its model marketplace aggregates Claude, ChatGPT, Gemini, and other domestic and international LLM and multimedia model capabilities with direct supply. Absolutely no reverse engineering or dilution — platform-wide model SLA availability reaches 99.7%, with monitoring dashboards showing green across the board. It also offers enterprise-grade custom gateways for fine-grained team cost and permission management, smart routing, security protection, and BYOK (Bring Your Own Key) hosting. The platform charges on a pay-per-use and tokens plan (coming soon) basis, with invoicing available. Register via this link as a new user to receive ¥10 in credits plus a 10% bonus on your first top-up.
Thanks to AIGoCode for sponsoring this project! AIGoCode is an all-in-one platform that integrates Claude Code, Codex, and the latest Gemini models, providing you with stable, efficient, and highly cost-effective AI coding services. The platform offers flexible subscription plans, zero risk of account suspension, direct access with no VPN required, and lightning-fast responses. AIGoCode has prepared a special benefit for CC Switch users: if you register via this link, you'll receive an extra 10% bonus credit on your first top-up!
Thanks to AICoding for sponsoring this project! AICoding — Global AI Model API Relay Service at Unbeatable Prices! Claude Code at 19% of original price, GPT at just 1%! Trusted by hundreds of enterprises for cost-effective AI services. Supports Claude Code, GPT, Gemini and major domestic models, with enterprise-grade high concurrency, fast invoicing, and 24/7 dedicated technical support. CC Switch users who register via this link get 10% off their first top-up!
Thanks to SubRouter for sponsoring this project! SubRouter is a marketplace and smart routing platform for AI service operators. Merchants can launch operating sites, publish packages, manage users, models, and pricing, while users discover services and access reliable AI models through one unified API. Register via this link!
Thanks to FluxA & Baidu AI Cloud for sponsoring this project! FluxA and Baidu AI Cloud jointly launched AgenticPlan, which gives AI agents the ability to buy, manage and use models, APIs and tools on their own. It includes Baidu Qianfan TokenPlan at up to 40% off, with access to flagship models such as DeepSeek V4, GLM 5.2 and Kimi, plus bonus FluxA AgentMarket API credits that unlock 13,000+ paid APIs for search, data scraping, social media, finance, crypto, image generation, video and more.With the user's authorization, an AI agent can also pay with the official Visa card to procure resources on its own, manage API keys, monitor usage and plan renewals — taking agents from "completing tasks autonomously" to genuinely "planning their own budget and completing tasks". Buy via this link!
Thanks to 88API Token Aggregation Platform for sponsoring this project! 88API is a one-stop multi-model API platform operated by a Hong Kong company, built mainly for developers, creators and AI application users. A unified interface gives access to text, image, speech and video models, covering common workflows such as AI coding, smart translation, content creation, voice-over, image generation and video generation. You can add it as a provider and switch to it right inside CC Switch. 88API supports major international payment methods, can issue invoices, and provides enterprise-grade stable service. Register via this link to receive exclusive bonus credits!
Thanks to APIKEY.FUN for sponsoring this project! APIKEY.FUN is a professional enterprise-grade AI relay platform dedicated to providing stable, efficient, and low-cost AI model API access for enterprises and individual developers. The platform supports popular mainstream models such as Claude, OpenAI, and Gemini, with prices as low as 7% of official rates. Register through this project's exclusive link to enjoy an exclusive offer of up to permanent 5% off top-ups.
Thanks to 9527CODE for sponsoring this project! 9527 CODE is an enterprise-grade, full-capability AI relay platform focused on stability and service quality, providing fast, stable, and high-quality relay services for Claude Code, Codex, and other mainstream AI models. It places greater emphasis on long-term stability, route quality, and sustained availability, offering enterprises and heavy AI users a stable and efficient one-stop model access solution. With one year of continuous operation, 99.9% service stability, and 7×24 human technical support. Register through this project's exclusive link; new users can contact customer service to receive trial credit, and referral cashback is unlimited!
Thanks to TeamoRouter for sponsoring this project! TeamoRouter is an enterprise-grade Agentic LLM gateway built for developers, AI teams, and businesses. Without requiring any subscriptions, it lets you access Claude Code, Codex, Gemini CLI, OpenAI Codex, and other popular AI agents through a single unified API, while offering API pricing at discounts of up to 90%.
Unlike typical API relay services, TeamoRouter aggregates hundreds of official model providers and trusted infrastructure partners, including OpenAI, Anthropic, Vertex, Azure, and AWS bedrock. Every provider is verified for 100% Agent protocol compatibility, cache performance, and request traceability, ensuring stable quality instead of reverse-engineered or diluted endpoints. The platform delivers near-official TTFT, 99.6% SLA, enterprise-scale throughput up to 5,000 QPM, and industry-leading cache hit rates that dramatically reduce token costs for long-running agent workflows.
TeamoRouter also offers enterprise features including centralized billing, team management, BYOK, smart routing, usage analytics, dynamic provider optimization, and dedicated support. For an even simpler experience, Teamo Desktop lets you use Claude Code, Codex, Gemini CLI, and other popular AI agents with one-click setup—no API key management or manual gateway configuration required. Register via this link as a new user to receive 10% off your first top-up.
Thanks to PPIO for sponsoring this project! PPIO is a leading independent Agentic Cloud provider in China, co-founded in 2018 by PPTV founder Yao Xin and former PPTV chief architect Wang Wenyu. A single API key gives you access to every flagship open-source model, including DeepSeek-V4-Flash, Kimi-K3, GLM-5.2, and MiniMax-M3; the enterprise Token Plan is available at up to 40% off and supports 200 seats, and the Fusion blended model matches Fable5 at one-tenth of the price. Register via this link and complete identity verification to receive a ¥10 credit voucher — invite friends to top up and earn up to 15% cashback on their spend.
Thanks to the open-source AI infrastructure project new-api for its strong support of this project! new-api is an open-source AI infrastructure project from QuantumNous and one of the leading unified LLM access-and-distribution projects by activity and adoption, focused on helping developers, teams, and enterprises build manageable, scalable AI service platforms at lower cost. As a fellow project rooted in the open-source ecosystem, new-api hopes to sponsor and support the continued growth of more outstanding open-source projects. 🌟 Star new-api to show your support: https://github.com/QuantumNous/new-api. Website: https://www.newapi.ai/.
Thanks to ClaudeCN for sponsoring this project! ClaudeCN is an enterprise-grade AI gateway platform operated by a registered company. It delivers high-availability commercial API access to popular models including Claude, GPT, and DeepSeek, and is built around formal enterprise procurement workflows — corporate bank transfers, signed contracts, and full compliance. Register via this link!
Thanks to Dola seed for sponsoring this project! Dola Seed 2.0 is a full‑modal general large model independently developed by ByteDance for the global market. Built on a unified multimodal architecture, it supports joint understanding and generation of text, images, audio, and video. It natively enables agent collaboration, with strong reasoning, long‑task execution, tool integration, and coding capabilities. It is widely applicable to smart cockpits, personal assistants, education, customer support, marketing, retail, and other scenarios. It excels in multimodal perception, end‑to‑end complex task delivery, stable interaction, and data security, and is readily accessible and deployable via the ModelArk platform. Register via this link to get 500,000 tokens of free inference quota per model. >>中国大陆地区的开发者请点击这里
Thanks to SiliconFlow for sponsoring this project! SiliconFlow is a high-performance AI infrastructure and model API platform, providing fast and reliable access to language, speech, image, and video models in one place. With pay-as-you-go billing, broad multimodal model support, high-speed inference, and enterprise-grade stability, SiliconFlow helps developers and teams build and scale AI applications more efficiently. Register via this link and complete real-name verification to receive ¥16 in bonus credit, usable across models on the platform. SiliconFlow is also now compatible with OpenClaw, allowing users to connect a SiliconFlow API key and call major AI models for free.
Thanks to A6API for sponsoring this project! A6API is a one-stop AI model API aggregation platform covering Claude, GPT, Gemini, Codex, and other mainstream models. Multiple vendors can list their supply on the platform, so the same model can be quoted competitively by several upstream providers. Smart routing automatically picks the more stable, lower-priced route available and fails over automatically, helping you reduce failed requests, cut costs, and improve stability. Whether you are an individual developer, an AI product team, or a studio, you can integrate quickly through a unified interface — compatible with all formats, with low migration cost. New users who register via this link receive free trial credits: try it first, then use it at a low price.
Thanks to Compshare for sponsoring this project! Compshare is UCloud's AI cloud platform, providing stable and comprehensive domestic and international model APIs with just one key. Featuring cost-effective monthly and per-use domestic-model Coding Plan packages, alongside stable officially-relayed overseas models. Supports Claude Code, Codex, and API access. Enterprise-grade high concurrency, 24/7 technical support, and self-service invoicing. Users who register via this link will receive a free 5 CNY platform trial credit!
Thanks to CCSub for sponsoring this project! CCSub is a stable, affordable AI API relay platform — your drop-in replacement for a Claude.ai subscription. One API key gives you access to Claude Opus 4.8, Sonnet, Haiku, GPT-5, Gemini, and DeepSeek at roughly 30% of direct API cost, with no VPN required from anywhere in the world. Compatible with Claude Code, Codex, Cursor, Cline, Continue, Windsurf, and all major AI coding tools. Register via this link and get $5 free credit on sign-up.
Thanks to SSSAiCode for sponsoring this project! SSSAiCode is a stable and reliable API relay service, dedicated to providing stable, reliable, and affordable Claude and Codex model services, with same-day fast invoicing. SSSAiCode offers a special deal for CC Switch users: register via this link to enjoy $10 extra credit on every top-up!
Thanks to SoleAPI for supporting this project! SoleAPI is an AI model gateway for developers and enterprises: one API key gives you access to 30+ leading models including Claude, GPT and Gemini. It is natively compatible with the OpenAI and Anthropic protocols, so Claude Code, Codex, Cursor and your existing SDKs work by simply changing the Base URL. Requests are routed in real time by latency and upstream health, with millisecond-level automatic failover to backup channels, 99.99% service availability and 24/7 technical support. Every call lands on a single bill with per-request token and cost breakdowns you can inspect at any time. Sign up through this project's referral link to receive free trial credits, and earn ongoing cashback by inviting friends who top up!
Thanks to Micu API for sponsoring this project! Micu API is a global LLM relay service provider dedicated to delivering the best cost-performance ratio with high stability. Backed by a registered enterprise for core assurance, eliminating any risk of service discontinuation, with fast official invoicing support! We champion "zero cost to try": top up from as low as ¥1 with no minimum, and get fee-free refunds anytime! Micu API offers an exclusive deal for CC Switch users: register via this link and enter promo code "ccswitch" when topping up to enjoy a 10% discount!
Thank you to Right Code for sponsoring this project! Right Code reliably provides routing services for models such as Claude Code, Codex, and Gemini, with both pay-as-you-go and monthly subscription billing options available. Invoices are available upon top-up, and enterprise and team users can receive dedicated one-on-one support. Right Code also offers an exclusive discount for CC Switch users: register via this link, and with every top-up you will receive pay-as-you-go credit equivalent to 5% of the amount paid.
Thanks to Cubence for sponsoring this project! Cubence is a reliable and efficient API relay service provider, offering relay services for Claude Code, Codex, Gemini, and more with flexible billing options including pay-as-you-go and monthly plans. Cubence provides special discounts for CC Switch users: register using this link and enter the "CCSWITCH" promo code during recharge to get 10% off every top-up!
Thanks to Crazyrouter for sponsoring this project! Crazyrouter is a high-performance AI API aggregation platform — one API key for 300+ models including Claude Code, Codex, Gemini CLI, and more. All models at 55% of official pricing with auto-failover, smart routing, and unlimited concurrency. Crazyrouter offers an exclusive deal for CC Switch users: register via this link and contact customer support to claim $2 free credit, plus enter promo code CCSWITCH on your first top-up for an extra 30% bonus credit!
Thanks to DMXAPI for sponsoring this project! DMXAPI provides global large model API services to 200+ enterprise users. One API key for all global models. Features include: instant invoicing, unlimited concurrency, starting from $0.15, 24/7 technical support. GPT/Claude/Gemini all at 32% off, domestic models 20-50% off, Claude Code exclusive models at 66% off! Register here

Why CC Switch?

AI coding tools like Claude Code, Codex, and Gemini CLI each have their own configuration format. Switching API providers means hand-editing JSON, TOML, YAML, or .env files, and MCP, Skills, and prompts have to be maintained separately in every tool.

CC Switch brings all of this into a single desktop app: pick a preset, enter your key, and switch in one click. Switching replaces only the connection details — endpoint, key, and model — so plugins, hooks, MCP, and comments you added yourself stay as they are.

  • One App, Ten Tools — Claude Code, Claude Desktop, Codex, Gemini CLI, Grok Build, OpenCode, OpenClaw, Hermes, Pi, and MiniMax Code
  • No More Manual Editing — 90+ provider presets including AWS Bedrock, NVIDIA NIM, and community relays
  • Direct, Routing, or Aggregation — Your Choice — Direct connects the tool straight to the provider; Routing forwards requests through your machine, converting API formats and failing over automatically, so you can use GPT in Claude Code and Claude in Codex; Aggregation puts models from several providers into one model list in Claude Code or Codex, and each request goes to the provider of the model you pick
  • Centralized MCP, Skills & Prompts — Add MCP servers and Skills once, then choose which tools to sync them to; prompts are maintained separately for each tool
  • Sessions You Can Read — Turns each tool's session logs into a reading view: what each turn did, which files changed, and which step failed, all at a glance
  • Usage & Quotas at a Glance — Track token usage and spending even without local routing; remaining subscription quota and account balances show right on provider cards and in the tray
  • Cross-Platform — Native desktop app for Windows, macOS, and Linux, built with Tauri 2

Screenshots

Main Interface Apps Page
Aggregation Mode Aggregated Model List in Codex
Session Reading View Usage

Download & Installation

System Requirements

  • Windows: Windows 10 and above
  • macOS: macOS 12 (Monterey) and above
  • Linux: x86_64 or ARM64 with glibc 2.35+ and WebKitGTK 4.1 — e.g. Ubuntu 22.04+, Debian 12+, and recent Fedora releases; RHEL / Rocky / Alma 8–9 are not supported yet

Windows Users

Download the latest CC-Switch-v{version}-Windows.msi installer or CC-Switch-v{version}-Windows-Portable.zip portable version from the Releases page. On Windows on ARM, download CC-Switch-v{version}-Windows-arm64.msi or CC-Switch-v{version}-Windows-arm64-Portable.zip.

macOS Users

Method 1: Install via Homebrew (Recommended)

bash
brew install --cask cc-switch

Update:

bash
brew upgrade --cask cc-switch

Method 2: Manual Download

Download CC-Switch-v{version}-macOS.dmg (recommended) or .zip from the Releases page. It's a Universal build that runs natively on both Apple Silicon and Intel Macs.

Note: CC Switch for macOS is code-signed and notarized by Apple. You can install and open it directly.

Arch Linux Users

Install via paru (Recommended)

bash
paru -S cc-switch-bin

Linux Users

Download the latest Linux build from the Releases page:

  • CC-Switch-v{version}-Linux-x86_64.deb / -Linux-arm64.deb (Debian/Ubuntu)
  • CC-Switch-v{version}-Linux-x86_64.rpm / -Linux-arm64.rpm (Fedora and other RPM distros that ship WebKitGTK 4.1)
  • CC-Switch-v{version}-Linux-x86_64.AppImage / -Linux-arm64.AppImage (any distro meeting the requirements above)

Flatpak: Not included in official releases. You can build it yourself from the .deb — see flatpak/README.md for instructions.

Quick Start

Basic Usage

  1. Add Provider: Select the tool you want to manage in the sidebar, then click "+" (Add Provider) in the top-right corner of the page → Choose a preset or create a custom configuration
  2. Switch Provider:
    • Main UI: Select provider → Click "Enable" (for OpenCode, OpenClaw, Hermes, and MiniMax Code the button is "Add", and for Pi it's "Enable" / "Remove"; these five are coexist-mode tools, so you can add several providers at once)
    • System Tray: One row per tool showing "name · mode · provider · quota"; click a provider name in its submenu to switch (Claude Code, Claude Desktop, Codex, Gemini CLI, and Grok Build)
  3. Takes Effect: Claude Code needs no restart; for Codex, Gemini CLI, and Grok Build, restart your terminal or the CLI tool; for Claude Desktop, restart the app itself (see FAQ)
  4. Back to Official Login: Switch to the built-in official provider in the list (e.g. "Claude Official"), restart the tool, then follow its login/OAuth flow
  5. Routing & Aggregation (optional): The Claude Code, Codex, Gemini CLI, and Grok Build pages have "Direct" / "Routing" tabs at the top, and Claude Code and Codex also have "Aggregation". Clicking a tab only changes what you're looking at and doesn't touch your configuration; to actually switch, click "Start routing" or "Switch to Aggregation" on the page, and click "Back to direct" to return. Use Routing to use OpenAI- or Gemini-format providers in Claude Code, or Claude in Codex; use Aggregation to mix models from several providers in one model list
  6. Manage Tools: The "Apps" page in the sidebar shows each AI coding tool's version, install location, and source in one place; you can install, upgrade, or upgrade all, and choose which tools appear in the sidebar

MCP, Prompts, Skills, Projects & Sessions

  • MCP: Click "MCP" in the sidebar → Add servers via templates or custom config (or "Import Existing") → Toggle sync for each tool
  • Prompts: Click "Prompts" in the sidebar → Create prompts with the Markdown editor → Enable one to write it to that tool's prompt file
  • Skills: Click "Skills" in the sidebar → "Discover Skills" → Search skills.sh or browse GitHub repos → One-click install to supported tools
  • Projects: First turn on "Show project switcher" in "Settings → General", then on the Claude Code, Claude Desktop, or Codex page, open the project switcher at the top → "New project" to save the current configuration; later, pick it from the switcher to switch the whole setup at once
  • Sessions: Click "Sessions" in the sidebar → Browse and search conversation history, open the reading view, or restore each tool's sessions
  • Accounts: Click "Accounts" in the sidebar to sign in to GitHub Copilot, ChatGPT, and xAI (Grok) accounts and use your subscriptions as providers

Note: On first launch, CC Switch automatically imports your existing Claude Code, Codex, Gemini CLI, and Grok Build configuration as a provider named default and adds an official provider for each of these tools and Claude Desktop, so nothing you had configured is lost.

For detailed guides on every feature, check out the User Manual, covering provider management, MCP/Prompts/Skills, local routing & failover, and more.

Features

Full Changelog | v4.0 Release Notes

Supported Features by Tool

Tool Providers Local Routing Aggregation Tray Switching MCP Skills Prompts Sessions Usage Stats
Claude Code Switch ✓ ✓ ✓ ✓ ✓ CLAUDE.md ✓ ✓
Claude Desktop Switch Model Mapping only – ✓ – – – – Model Mapping only
Codex Switch ✓ ✓ ✓ ✓ ✓ AGENTS.md ✓ ✓
Gemini CLI Switch ✓ – ✓ ✓ ✓ GEMINI.md ✓ ✓
Grok Build Switch ✓ – ✓ ✓ ✓ AGENTS.md ✓ ✓
OpenCode Coexist – – – ✓ ✓ AGENTS.md ✓ ✓
OpenClaw Coexist – – – – – Workspace editor ✓ –
Hermes Coexist – – – ✓ ✓ Memory ✓ –
Pi Coexist – – – ✓ ✓ AGENTS.md, SYSTEM.md, prompt templates ✓ ✓
MiniMax Code Coexist – – – ✓ ✓ AGENTS.md ✓ ✓
  • Switch: only one provider is active at a time; Coexist: multiple providers are written into the tool's own config at the same time, and you pick one inside the tool.
  • Local Routing: CC Switch forwards requests on your machine and converts API formats; see Local Routing & Failover below. Claude Desktop providers can use "Direct" or "Model Mapping"; with "Model Mapping", requests go through local routing.
  • Aggregation: Puts models from several providers into one model list and sends each request to the provider of the model you pick; see Aggregation Mode below.
  • Sessions: Browse and search conversation history, open the reading view, and copy a resume command to continue a conversation (resuming OpenClaw and Hermes sessions isn't supported yet). Hermes shows only the 500 most recent sessions.
  • Usage Stats: Without local routing, usage is collected from each tool's local session logs; requests that go through local routing are counted as well.
  • The MCP, Skills, Prompts, and Sessions panels opened from the Claude Desktop page apply to Claude Code.

Provider Management

  • 90+ provider presets — Pick a preset and enter your key to add a provider, or create a custom configuration. The add panel lets you search by name (including Chinese names) and domain, and a vendor's different plans and regions are merged into one row
  • Key fields only — Switching replaces only the connection details such as the endpoint, key, and model; plugins, hooks, MCP, settings you added yourself, and comments stay as they are. The editor shows what the config file will look like after switching, and CC Switch automatically backs up each config file before rewriting it for the first time
  • Projects — Save Claude Code's or Codex's current provider, MCP, Skills, and prompt files as a project (for Claude Desktop, only the provider is saved), then switch the whole setup in one click from the project switcher at the top of the page or from the tray; when you switch to another project, the current state is automatically saved back to the previous project. The project switcher is hidden by default; turn on "Show project switcher" in "Settings → General"
  • Accounts (Beta) — Sign in to multiple GitHub Copilot, ChatGPT, and xAI (Grok) accounts under "Accounts" in the sidebar and use those subscriptions as providers in Claude Code, Claude Desktop, and Codex (everything except Codex's OpenAI Official has to be used in Routing mode). Using a subscription outside the official client may violate the vendor's terms of service; assess the risk yourself
  • Third-party providers for Claude Desktop — Connect directly to Anthropic-compatible endpoints; for non-Claude models, choose "Model Mapping" to map tiers like Sonnet, Opus, and Haiku to the provider's actual models through local routing
  • Universal providers — One config syncs to Claude Code, Codex, and Gemini CLI
  • One-click switching, system tray quick switching (Claude Code, Claude Desktop, Codex, Gemini CLI, Grok Build), drag-and-drop sorting, import/export

Local Routing & Failover

  • API format conversion — Local routing converts requests between Anthropic Messages, OpenAI Chat Completions, OpenAI Responses, and Gemini Native: Claude Code and Claude Desktop can use OpenAI- or Gemini-format providers, and Codex and Grok Build can use Chat Completions or Anthropic Messages providers
  • Per-tool toggle — Claude Code, Codex, Gemini CLI, and Grok Build can each enter Routing mode separately: click "Start routing" on the "Routing" tab at the top of the page. In Routing mode, switching providers takes effect immediately for subsequent requests (Codex, Gemini CLI, and Grok Build may still need a restart if the switch changes the model). When you quit CC Switch, it writes the direct configuration back first and reconnects the next time it starts
  • Auto-failover — Configure a failover queue for each tool; when a request fails, CC Switch automatically moves on to the next provider in the queue, backed by a circuit breaker and provider health monitoring
  • Rectifier — Automatically fixes certain requests that some upstreams can't handle (e.g. Thinking signatures, or falling back when images aren't supported)
  • Official providers (e.g. Claude Official) can't go through local routing (except Codex's OpenAI Official)
  • The routing service's status, listen address, and failover settings are all in "Settings → Local routing"
  • Guides: Using GPT in Claude Code · Using Claude in Codex

Aggregation Mode

  • One model list, many providers — On the Claude Code or Codex page, switch to "Aggregation" and add a few providers; their models all appear in the client's model picker. Each request goes to the provider of the model you pick, with no need to switch in CC Switch
  • Add and remove anytime — Click "Add" or "Remove" on a provider card, then pick one provider as the default; requests that don't name an aggregated model go to it. Codex's OpenAI Official can only be the default provider; Claude official subscriptions are currently unsupported in Aggregation
  • Notes — Aggregation doesn't provide failover; Claude Code requires version 2.1.243 or later; Codex needs a restart after the aggregated list changes, while Claude Code doesn't. When you switch models within a session, the new model has to rebuild its prompt cache, so the first turn costs a bit more
  • Much of Aggregation mode's design draws on opencodex — thanks to its author and contributors
  • Documentation: Aggregation mode manual · Illustrated guide (Chinese)

MCP, Prompts & Skills

  • Unified MCP panel — Manage all MCP servers in one place, choose which tools to sync each one to (Claude Code, Codex, Gemini CLI, Grok Build, OpenCode, Hermes, Pi, MiniMax Code), import existing configs from each tool, and import via Deep Link
  • Prompts — A per-tool prompt library with a Markdown editor; enabling a prompt writes it to that tool's prompt file (CLAUDE.md / AGENTS.md / GEMINI.md), and the file's existing content is saved back to the library first, so nothing is lost. Pi can also edit SYSTEM.md, APPEND_SYSTEM.md, and prompt templates
  • Skills — Search skills.sh, or install in one click from GitHub repos or ZIP files; check for updates and update all in one click; sync to each tool automatically, via symlinks only, or via copies only; you can optionally store them in ~/.agents/skills
  • All three panels support search, and MCP and Skills can also be enabled or disabled all at once per tool; providers, MCP servers, and prompts are edited full-page in the content area, and you're warned before leaving with unsaved changes

Usage & Cost Tracking

  • Usage dashboard — Works without local routing: by default it automatically scans each tool's local session logs and tracks requests, tokens, cache hit rate, output speed, and spending by provider and model, with trend charts, a full-year heatmap, and per-request logs
  • Quotas & balances — Provider cards and the tray show what's left and the reset countdown, e.g. "5h 94% left": official subscription quotas (Claude, ChatGPT, Gemini, SuperGrok), Coding Plan 5-hour / weekly / monthly quotas (Kimi, Zhipu GLM, MiniMax, Volcengine Ark, etc.), and account balances (DeepSeek, OpenRouter, SiliconFlow, etc.); some need to be turned on first via "Configure usage query" on the provider card, and for other providers you can write a custom usage script. ChatGPT subscriptions also show remaining limit resets and the Codex Credits balance
  • Custom pricing — Set per-model prices, or import them from models.dev

Session Manager & Workspace

  • Session reading view — Parses each tool's session logs into structured content: text, thinking, tool calls, tool results, and images are shown separately; each turn of work collapses into a one-line summary (how many steps, how many files changed, how many failures), with failed steps marked in red; a conversation outline sits on the right, with in-session search, Markdown export, and copying a single turn or the whole conversation
  • List & resume — Group by project or time, search titles, directories, messages, or session IDs, and delete in bulk; copy a resume command to continue a conversation, and on macOS resume in a terminal with one click
  • Workspace editor (OpenClaw) — Edit agent files (AGENTS.md, SOUL.md, etc.) and daily memory
  • Memory (Hermes) — Edit Hermes's MEMORY.md and USER.md

System & Platform

  • Cloud sync — Sync across devices via WebDAV (Jianguoyun, Nextcloud, Synology NAS, etc.) or S3-compatible storage (AWS S3, Cloudflare R2, Alibaba Cloud OSS, Tencent Cloud COS, etc.); you can also put the CC Switch configuration directory in a cloud drive folder such as Dropbox, OneDrive, or iCloud
  • CLI tool management — On the "Apps" page in the sidebar, see the current and latest versions of command-line tools like Claude Code and Codex, install, upgrade, or upgrade all in one click, and diagnose duplicate installations; on Windows it can also manage tools inside WSL (see FAQ)
  • Deep Link (ccswitch://) — Import providers, MCP servers, and prompts, or add skill repositories, in one click via a link; create links with the online generator; site owners who want an import button can follow the integration guide
  • Built-in utilities — Skip Claude Code's first-run confirmation, hide AI attribution, have the VS Code Claude Code extension follow CC Switch's provider switches, and more
  • Dark / Light / System theme, auto-launch, auto-updater, atomic writes, auto-backups (see where every backup lives and how much space it takes in "Settings → Data"), i18n (zh/zh-TW/en/ja, plus community-translated Turkish)

FAQ

Which AI tools does CC Switch support?

CC Switch supports ten tools: Claude Code, Claude Desktop, Codex, Gemini CLI, Grok Build, OpenCode, OpenClaw, Hermes, Pi, MiniMax Code. Each tool has dedicated provider presets and configuration management; see Supported Features by Tool for what each one supports.

Do I need to restart the terminal after switching providers?

It depends on the tool:

  • Claude Code: supports hot-switching of provider data — no restart needed.
  • Codex, Gemini CLI, Grok Build: restart your terminal or the CLI tool for changes to take effect (CC Switch reminds you after switching). In Routing mode, requests go to the new provider immediately, but all three tools may still need a restart if the switch changes the model.
  • Aggregation mode: changes to Claude Code's aggregated models take effect immediately; for Codex, entering or leaving Aggregation and changing the aggregated model list all require a full restart — see the next entry.
  • Claude Desktop: fully quit and reopen Claude Desktop; when using "Model Mapping", also keep CC Switch running.
  • OpenCode, OpenClaw, Hermes, Pi, MiniMax Code: these are coexist-mode tools — clicking "Add" ("Enable" for Pi) writes the provider into the tool's own config alongside the others; you then pick the model you want inside the tool.

In Aggregation mode, why don't the aggregated models show up in Codex's /model?

Codex reads its model list only at startup. After entering or leaving Aggregation mode, adding or removing an aggregated provider, or changing a provider's aggregated models, fully restart Codex to see the new list:

  • Codex CLI: Closing the terminal and running codex again isn't enough. Every codex in every terminal shares one background daemon, and it has to be restarted to pick up the new list. When CC Switch detects that Codex is still using the old list, it shows a notice at the top of the Codex page; click "Restart Codex daemon" in the notice. Restarting interrupts any tasks running in the daemon.
  • Codex desktop app: Quit it completely and reopen it (press ⌘Q on macOS; closing the window isn't enough).
  • Editor extensions: Reopen the editor window.

Claude Code isn't affected: changes to aggregated models take effect immediately.

Will switching providers change my plugins, hooks, or other settings?

No. When you switch providers for Claude Code, Codex, Gemini CLI, or Grok Build, CC Switch replaces only the key fields in the config file: the endpoint, key, model name, and API protocol (plus the reasoning effort for Codex and the auth method for Gemini CLI), along with a few compatibility options that belong to the provider (such as Claude Code's "Disable Artifact Tool" and the context window). Plugins, hooks, permissions, MCP, environment variables you added yourself, comments, and formatting all stay as they are and apply to every provider.

You can change these shared settings in the tool itself or by editing the config file by hand. You can also edit any provider in CC Switch: the editor shows "what the config file will look like after switching to this provider". When you save, the key fields are stored in that provider, and every other change is written to the config file and applies to every provider.

So the old "Common Config Snippet" is no longer needed, and its buttons have been removed. Settings that were in your snippet before the upgrade were already written into the config file when you switched, so they stay. Before CC Switch rewrites each config file for the first time, it also backs up the original to ~/.cc-switch/backups/live-first-write/.

I changed the model inside the tool — why does it go back after I switch away and back?

The model is a key field and belongs to the provider. A model you pick inside the tool (such as with /model in Claude Code) stays in effect until the next switch; when you switch, the model in the config file is replaced with the one saved in the target provider, and CC Switch doesn't save the model you picked back to the previous provider. To keep using a model long-term, edit that provider in CC Switch.

Older versions saved the whole config file back to the provider when you switched away. That no longer happens: it froze plugins and other shared settings into one provider, so they were lost when you switched to another one.

Why can't I delete the provider currently in use?

CC Switch follows a "minimal intrusion" design principle — even if you uninstall the app, your tools will continue to work normally.

So for tools that use one active provider at a time (Claude Code, Claude Desktop, Codex, Gemini CLI, Grok Build), the system always keeps one configuration in use, because deleting all configurations would make the corresponding tool unusable; to delete it, switch to another provider first. Likewise, the default provider in Aggregation mode can't be removed; make another provider the default first. Coexist-mode tools (OpenCode, OpenClaw, Hermes, Pi, and MiniMax Code) aren't subject to this restriction — you can delete any provider directly. If you rarely use a tool, you can hide it from the sidebar on the "Apps" page. To switch back to official login, see the next question.

How do I switch back to official login?

In CC Switch, the provider lists for Claude Code, Claude Desktop, Codex, Gemini CLI, and Grok Build each include a built-in official provider (Claude Official, Claude Desktop Official, OpenAI Official, Google Official, Grok Official); if you deleted it, add it back from the presets. After switching to the official provider, follow the tool's own login flow (e.g. /login in Claude Code, codex login for Codex), and then you can freely switch between the official provider and third-party providers.

For Codex, you can also sign in to multiple ChatGPT accounts inside CC Switch via "Sign in with ChatGPT" and choose an "Account to use" for each OpenAI Official card, so switching between multiple Plus, Pro, or Team accounts takes one click; cards set to "Follow Codex login" keep using the Codex CLI's own login.

Note: official subscriptions use the tool's own login and don't go through local routing. Official providers can't be selected in Routing mode (Codex's OpenAI Official cards are the exception); switch back to Direct first.

After I start routing, why does my config file point to 127.0.0.1?

In Routing mode, the tool's requests first go to CC Switch's local routing (http://127.0.0.1:15721 by default), and CC Switch then forwards them to the provider you selected. That's why the tool's config file only contains the local address and the placeholder key PROXY_MANAGED; for Claude Code, the model name is also written as a fixed alias such as claude-sonnet-5 (the /model menu still shows the real model name). The real provider address, key, and model are all stored in CC Switch. Aggregation mode works the same way.

In the request logs under "Usage" in the sidebar, you can see "requested model → actual model" for each request.

In Routing mode, switching changes the provider that routing uses; the provider you were using before you entered Routing stays the same and is labeled "Direct" on its card. When you click "Back to direct", the config file is written back to this direct provider's configuration. Quitting CC Switch also writes back the direct provider first, and it reconnects the next time CC Switch starts.

Can I use OpenAI-compatible APIs, Gemini, or local models in Claude Code?

Yes, but you need to use Routing. When editing the provider, set "Upstream Format" under "Advanced Options" to match the provider's API: choose "OpenAI Chat Completions" for services that only offer a Chat Completions endpoint (as many local model servers do), "OpenAI Responses API" for services that offer a Responses endpoint, and "Gemini Native generateContent" for Gemini. Then click "Start routing" on the "Routing" tab of the Claude Code page. Choosing the wrong format or not starting routing usually results in a 404 or 405 error.

Conversely, choosing "Anthropic Messages" as the "Upstream Format" in Codex or Grok Build lets you use Claude-format providers; this also requires Routing. See Using GPT in Claude Code and Using Claude in Codex for details.

"Connectivity check" passed, so why do requests still fail?

The "Connectivity check" on a provider card only checks whether the provider address is reachable; it doesn't send a real model request, so it can't verify whether the API key and model name are correct. When requests fail, check the key, model name, and upstream format; for requests that go through Routing, you can also see the exact error in the request logs under "Usage" in the sidebar.

Where is my data stored?

By default, everything is stored in the .cc-switch folder in your home directory (C:\Users\\.cc-switch on Windows):

  • Database: cc-switch.db (SQLite — providers, MCP, prompts, Skills, projects, usage records, etc.)
  • Local settings: settings.json (device-level settings such as each tool's config directory, backup policy, and cloud sync connection details)
  • Backups: backups/ (backed up automatically every 24 hours by default, keeping the 10 most recent; adjustable in "Settings → Data → Backup & Restore"; "Other Backups" below it lists the location and size of every other backup, which you can clean up by category)
  • Skills: skills/ (can be changed to ~/.agents/skills in Settings), synced to each tool via symlinks by default, falling back to copying if that fails
  • Skill Backups: skill-backups/ (created automatically before uninstalling or updating a skill, keeping the 20 most recent)
  • OAuth login credentials: copilot_auth.json, codex_oauth_auth.json, xai_oauth_auth.json
  • Logs: logs/cc-switch.log and crash.log — please attach them when reporting an issue
  • Device state: live-state.json (whether each tool is currently in Direct, Routing, or Aggregation mode, and what was last written), codex-login-stash.json (the official Codex login moved aside when you switch to a third-party provider, restored when you switch back to an official one)
  • Original config files: backups/live-first-write/ (each tool's config file as it was before CC Switch first rewrote it)

After you change "CC Switch Configuration Directory" in "Settings → Data → Location", all of the files above except settings.json, the device state, and the original config files are stored in the new directory. CC Switch doesn't move existing files automatically, so copy them over manually first. settings.json, the device state, and the original config files belong to this computer only: they always stay in the default directory and are not included in cloud sync.

How do I manage tools inside WSL on Windows?

CC Switch doesn't detect WSL automatically. In "Settings → App config", change the config directory for the corresponding tool to a path inside WSL, e.g. \\wsl.localhost\Ubuntu\home\\.claude; after you save, CC Switch reads and writes the config inside WSL (supported for Claude Code, Codex, Gemini CLI, Grok Build, OpenCode, OpenClaw, Hermes, and Pi). Once this is set, the "Apps" page in the sidebar also detects and upgrades that tool in the corresponding WSL distribution.

Note: Routing and Aggregation write 127.0.0.1 as the address into the config. In WSL2's default NAT networking mode, 127.0.0.1 inside WSL can't reach local routing on Windows; switch WSL to mirrored networking mode instead.

Is there a command-line or headless version?

CC Switch itself only ships as a desktop app that requires a graphical interface (see Download & Installation for system requirements). For servers, SSH sessions, or machines without a desktop environment, we recommend the community-maintained CC Switch CLI: it offers both an interactive terminal UI (TUI) and a command-line mode, supports Claude Code, Codex, Gemini CLI, OpenCode, OpenClaw, Hermes, and Pi, and can be installed via Homebrew (brew install cc-switch-cli) or an install script.

By default, CC Switch CLI shares the ~/.cc-switch data directory with the desktop app and is compatible with the desktop app's WebDAV sync. The two projects are released separately, and the database version the CLI supports sometimes lags behind the desktop app; if you see a "database version is too new" message, upgrade the CLI or wait for it to catch up.

Linux (Wayland + NVIDIA): clicks don't register and the window black-screens on resize

The AppImage forces GDK_BACKEND=x11 (XWayland) to avoid a historical native-Wayland crash. On newer Wayland + NVIDIA setups this can leave the web content area unclickable (the title-bar buttons still work) and black-screen on resize. Launch with the opt-in escape hatch to switch back to native Wayland:

bash
CC_SWITCH_GDK_BACKEND=wayland ./CC-Switch-*.AppImage

If you launch from a desktop icon, add it to the .desktop Exec= line (e.g. env CC_SWITCH_GDK_BACKEND=wayland /path/to/AppImage) or set it in your session environment. The variable is generic: on tiling Wayland compositors (sway/Hyprland) where clicks don't register, try CC_SWITCH_GDK_BACKEND=x11 instead. Leaving it unset keeps the default behavior.

For more questions, see the FAQ in the User Manual.

Contributing

Issues and suggestions are welcome! Before developing a new feature, please open an issue to discuss the approach first; feature PRs that aren't a good fit for the project may be closed.

For development setup, pre-submit checks, and architecture notes, see CONTRIBUTING.md; for usage questions, check SUPPORT.md first; report security vulnerabilities privately as described in SECURITY.md.

Tech stack: Tauri 2 · Rust · React 18 · TypeScript · SQLite

Star History

License

MIT © Jason Young


Overview (`flatpak/README.md`)

Flatpak Build Guide

This directory contains the Flatpak manifest (com.ccswitch.desktop) for CC Switch, used to convert the generated .deb artifact into an installable .flatpak package via CI or local builds.

Dependencies

  • flatpak
  • flatpak-builder
  • Flathub remote (for installing org.gnome.Platform//46 runtime)

For Ubuntu/Debian:

bash
sudo apt install flatpak flatpak-builder
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak install -y --user flathub org.gnome.Platform//46 org.gnome.Sdk//46

Local Build (Generate .flatpak from .deb)

  1. Build the deb on Linux first:
bash
pnpm tauri build --bundles deb

The last step of this build signs the auto-update bundles, which requires the release private key TAURI_SIGNING_PRIVATE_KEY. Without the key, the .deb is still produced but the command exits with an error. To skip updater bundle generation instead:

bash
pnpm tauri build --bundles deb -c '{"bundle":{"createUpdaterArtifacts":false}}'
  1. Copy the generated deb to this directory:
bash
cp "$(find src-tauri/target/release/bundle -name '*.deb' | head -n 1)" flatpak/cc-switch.deb
  1. Build the local Flatpak repository and export the .flatpak:
bash
flatpak-builder --force-clean --user --disable-cache --repo flatpak-repo flatpak-build flatpak/com.ccswitch.desktop.yml
flatpak build-bundle --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo flatpak-repo CC-Switch-Linux.flatpak com.ccswitch.desktop
  1. Install and run:
bash
flatpak install --user ./CC-Switch-Linux.flatpak
flatpak run com.ccswitch.desktop

Permissions Note

The current manifest uses --filesystem=home by default for "download and run" convenience, allowing the app to directly read/write CLI configuration files and app data on the host (and supporting the "directory override" feature).

If you prefer minimal permissions (e.g., for Flathub submission or security concerns), you can replace --filesystem=home in flatpak/com.ccswitch.desktop.yml with more precise grants:

yaml
- --filesystem=~/.cc-switch:create
  - --filesystem=~/.claude:create
  - --filesystem=~/.claude.json
  - --filesystem=~/.codex:create
  - --filesystem=~/.gemini:create
  - --filesystem=~/.config/opencode:create
  - --filesystem=~/.openclaw:create

Note: Flatpak's :create modifier only works with directories, not files. Therefore, ~/.claude.json cannot use :create. If this file doesn't exist on the user's machine, the app may not be able to create it with restricted permissions. Users should either run Claude Code once to generate it, or manually create an empty JSON file (content: {}).

If you plan to publish on Flathub or want stricter permission control, adjust the finish-args in flatpak/com.ccswitch.desktop.yml accordingly.


Overview (`docs/user-manual/README.md`)

CC Switch User Manual / 用户手册 / ユーザーマニュアル

Claude Code / Claude Desktop / Codex / Gemini CLI / OpenCode / OpenClaw / Hermes

Language / 语言 / 言語

Language Link
中文 简体中文用户手册
English English User Manual
日本語 日本語ユーザーマニュアル

Version / 版本 / バージョン

  • Documentation version: v3.16.0
  • Last updated: 2026-05-29
  • Compatible with CC Switch v3.16.0+

Overview (`src/whats-new/README.md`)

更新摘要(应用内弹窗)

用户升级后第一次打开 CC Switch,会弹一个窗口,列出从上次看过的版本到当前版本之间每一版的几条摘要。数据就是这个目录下的文件,构建时打进安装包(src/lib/whatsNew.ts),弹窗不联网。

详细内容仍在 docs/release-notes/。弹窗里每个版本的「详情」链到官网 https://ccswitch.io/<zh|en|ja>/changelog/<version>,所以发版后要照常同步官网更新日志。

每个版本一个文件

文件名是版本号,例如 4.0.2.json:

json
{
  "version": "4.0.2",
  "items": [
    {
      "type": "new",
      "zh": "OpenCode 可以选择思考档位",
      "zh-TW": "OpenCode 可以選擇思考檔位",
      "en": "OpenCode can now pick a thinking level",
      "ja": "OpenCode で思考レベルを選べるように"
    }
  ]
}
  • type:new(新增)、fix(修复)、improve(改进)。
  • 每版最多 4 条,每条一句话:中文、繁中不超过 40 字,日文不超过 50 字,英文不超过 100 个字符。四种语言都要写。
  • 写用户能感知到的变化,按影响大小排序。从中文发布说明里挑最重要的几条,不要照搬原文。
  • "items": [] 表示这一版不弹窗,适合纯构建、CI 之类的版本。文件仍然要有。

规则由 tests/config/whatsNewEntries.test.ts 检查。

什么时候写

和三语发布说明一起,放进打 tag 之前的 docs(release) 提交。release.yml 会先检查 src/whats-new/<版本>.json 是否存在,缺了直接失败,不会白跑构建。


Overview (`docs/user-manual/en/README.md`)

CC Switch User Manual

All-in-One Assistant for Claude Code / Claude Desktop / Codex / Gemini CLI / Grok Build / OpenCode / OpenClaw / Hermes / Pi / MiniMax Code

Table of Contents

text
📚 CC Switch User Manual
│
├── 1. Getting Started
│   ├── 1.1 Introduction
│   ├── 1.2 Installation Guide
│   ├── 1.3 Interface Overview
│   ├── 1.4 Quick Start
│   └── 1.5 Personalization
│
├── 2. Provider Management
│   ├── 2.1 Add Provider
│   ├── 2.2 Switch Provider
│   ├── 2.3 Edit Provider
│   ├── 2.4 Sort & Duplicate
│   ├── 2.5 Usage Query
│   └── 2.6 Claude Desktop
│
├── 3. Extensions
│   ├── 3.1 MCP Server Management
│   ├── 3.2 Prompts Management
│   ├── 3.3 Skills Management
│   ├── 3.4 Session Manager
│   └── 3.5 Workspace & Memory
│
├── 4. Local Routing & High Availability
│   ├── 4.1 Local Routing Service
│   ├── 4.2 App Routing
│   ├── 4.3 Failover
│   ├── 4.4 Usage Statistics
│   ├── 4.5 Connectivity Check
│   └── 4.6 Aggregation Mode
│
└── 5. FAQ
    ├── 5.1 Configuration Files
    ├── 5.2 FAQ
    ├── 5.3 Deep Link Protocol
    └── 5.4 Environment Variable Conflicts

File List

1. Getting Started

File Description
1.1-introduction.md Introduction, core features, supported platforms
1.2-installation.md Windows/macOS/Linux installation guide
1.3-interface.md Sidebar layout, connection mode tabs, provider cards
1.4-quickstart.md 5-minute quick start tutorial
1.5-settings.md The six Settings groups: General, App config, Local routing, Network, Data, About

2. Provider Management

File Description
2.1-add.md Using presets, custom configuration, universal providers
2.2-switch.md Direct / Routing / Aggregation, tray switching, activation methods
2.3-edit.md Edit configuration, modify API Key, global settings and edit conflicts
2.4-sort-duplicate.md Drag-to-reorder, duplicate provider, delete
2.5-usage-query.md Usage query, remaining balance, multi-plan display
2.6-claude-desktop.md Claude Desktop third-party providers, direct mode, and model mapping

3. Extensions

File Description
3.1-mcp.md MCP protocol, add servers, app binding
3.2-prompts.md Create prompts, enable/switch, target files
3.3-skills.md Discover skills, install/uninstall, repository management
3.4-sessions.md Session Manager: browse, search, resume, delete sessions
3.5-workspace.md Workspace files and daily memory (OpenClaw)

4. Local Routing & High Availability

File Description
4.1-service.md Start local routing, configuration, API format conversion
4.2-routing.md App routing, configuration changes, status indicators
4.3-failover.md Failover queue, circuit breaker, health status
4.4-usage.md Usage statistics, trend charts, pricing configuration
4.5-model-test.md Connectivity check, check parameters
4.6-aggregation.md Aggregation mode, default provider, ccs- prefix, Codex restart

5. FAQ

File Description
5.1-config-files.md CC Switch storage, CLI configuration file formats
5.2-questions.md Frequently asked questions
5.3-deeplink.md Deep link protocol, generation and usage
5.4-env-conflict.md Environment variable conflict detection and resolution

Version Information

  • Documentation version: v4.0.4
  • Last updated: 2026-10-07
  • Applicable to CC Switch v4.0.4+

Recent Major Changes (v4.0)

  • Redesigned interface: the top navigation is replaced by a left sidebar, with separate pages for Usage, Accounts, MCP, Skills, Prompts, Sessions, and Apps; Settings is split into six groups: General, App config, Local routing, Network, Data, About — see 1.3 Interface Overview and 1.5 Personalization
  • Three connection modes: Direct / Routing / Aggregation: chosen at the top of each app page; going back to direct is one step — see 2.2 Switch Provider
  • New Aggregation mode: Claude Code and Codex can mix models from several providers in one session — see 4.6 Aggregation Mode
  • Switching only changes key fields: everything other than the address, key, model, and other key fields is left as is; common config snippets are no longer used — see 2.3 Edit Provider
  • Accounts: ChatGPT, GitHub Copilot, xAI, and other sign-ins are managed in one place under Accounts in the sidebar — see 1.5 Personalization
  • Apps page: install and upgrade each CLI tool, and choose which apps show in the sidebar — see 1.2 Installation Guide
  • For the full list of changes, see the v4.0 release notes

Contributing

Feel free to submit Issues or PRs to improve the documentation:


Overview (`docs/user-manual/ja/README.md`)

CC Switch ユーザーマニュアル

Claude Code / Claude Desktop / Codex / Gemini CLI / Grok Build / OpenCode / OpenClaw / Hermes / Pi / MiniMax Code オールインワンアシスタント

目次構成

text
📚 CC Switch ユーザーマニュアル
│
├── 1. はじめに
│   ├── 1.1 ソフトウェア紹介
│   ├── 1.2 インストールガイド
│   ├── 1.3 インターフェース概要
│   ├── 1.4 クイックスタート
│   └── 1.5 個人設定
│
├── 2. プロバイダー管理
│   ├── 2.1 プロバイダーの追加
│   ├── 2.2 プロバイダーの切り替え
│   ├── 2.3 プロバイダーの編集
│   ├── 2.4 並べ替えと複製
│   ├── 2.5 使用量クエリ
│   └── 2.6 Claude Desktop
│
├── 3. 拡張機能
│   ├── 3.1 MCP サーバー管理
│   ├── 3.2 Prompts プロンプト管理
│   ├── 3.3 Skills スキル管理
│   ├── 3.4 セッションマネージャー
│   └── 3.5 ワークスペースとメモリー
│
├── 4. ローカルルーティングと高可用性
│   ├── 4.1 ローカルルーティングサービス
│   ├── 4.2 アプリケーションルーティング
│   ├── 4.3 フェイルオーバー
│   ├── 4.4 使用量統計
│   ├── 4.5 接続チェック
│   └── 4.6 集約モード
│
└── 5. よくある質問
    ├── 5.1 設定ファイルの説明
    ├── 5.2 FAQ
    ├── 5.3 ディープリンクプロトコル
    └── 5.4 環境変数の競合

ファイル一覧

1. はじめに

ファイル 内容
1.1-introduction.md ソフトウェア紹介、主要機能、対応プラットフォーム
1.2-installation.md Windows/macOS/Linux インストールガイド
1.3-interface.md サイドバーのレイアウト、接続モードのタブ、プロバイダーカードの説明
1.4-quickstart.md 5 分でできるクイックスタートチュートリアル
1.5-settings.md 設定の 6 グループ:一般、アプリ設定、ローカルルーティング、ネットワーク、データ、情報

2. プロバイダー管理

ファイル 内容
2.1-add.md プリセットの使用、カスタム設定、統一プロバイダー
2.2-switch.md 直接接続/ルーティング/集約、トレイでの切り替え、反映方法
2.3-edit.md 設定の編集、API Key の変更、グローバル設定と編集の競合
2.4-sort-duplicate.md ドラッグで並べ替え、プロバイダーの複製、削除
2.5-usage-query.md 使用量クエリ、残額表示、複数プラン表示
2.6-claude-desktop.md Claude Desktop サードパーティプロバイダー、直結モード、モデルマッピング

3. 拡張機能

ファイル 内容
3.1-mcp.md MCP プロトコル、サーバーの追加、アプリバインド
3.2-prompts.md プロンプトの作成、有効化の切り替え、対象ファイル
3.3-skills.md スキルの発見、インストール・アンインストール、リポジトリ管理
3.4-sessions.md セッションマネージャー:閲覧、検索、再開、削除
3.5-workspace.md ワークスペースファイルとデイリーメモリー(OpenClaw)

4. ローカルルーティングと高可用性

ファイル 内容
4.1-service.md ローカルルーティングの起動、設定項目、API フォーマット変換
4.2-routing.md アプリケーションルーティング、設定変更、ステータス表示
4.3-failover.md フェイルオーバーキュー、サーキットブレーカー、ヘルスステータス
4.4-usage.md 使用量統計、トレンドグラフ、料金設定
4.5-model-test.md 接続チェック、チェックパラメータ
4.6-aggregation.md 集約モード、デフォルトプロバイダー、ccs- プレフィックス、Codex の再起動

5. よくある質問

ファイル 内容
5.1-config-files.md CC Switch のストレージ、CLI 設定ファイル形式
5.2-questions.md よくある質問と回答
5.3-deeplink.md ディープリンクプロトコル、生成と使用方法
5.4-env-conflict.md 環境変数の競合検出と対処

クイックリンク

バージョン情報

  • ドキュメントバージョン:v4.0.4
  • 最終更新:2026-10-07
  • CC Switch v4.0.4+ 対応

最近の主な変更(v4.0)

  • インターフェースの刷新:上部のナビゲーションが左サイドバーになり、使用量、アカウント、MCP、Skills、プロンプト、セッション、アプリがそれぞれ独立したページになりました。設定は一般、アプリ設定、ローカルルーティング、ネットワーク、データ、情報の 6 グループに分かれています — 詳細は 1.3 インターフェース概要、1.5 個人設定
  • 直接接続 / ルーティング / 集約の 3 つの接続モード:各アプリページの上部で選び、直接接続へは 1 ステップで戻せます — 詳細は 2.2 プロバイダーの切り替え
  • 集約モードを追加:Claude Code と Codex で、1 つのセッションの中で複数のプロバイダーのモデルを使い分けられます — 詳細は 4.6 集約モード
  • 切り替えはキーとなるフィールドだけを変更:アドレス、キー、モデルなど以外の設定はそのまま残り、共通設定スニペットは使われなくなりました — 詳細は 2.3 プロバイダーの編集
  • アカウント:ChatGPT、GitHub Copilot、xAI などのログインをサイドバーの「アカウント」でまとめて管理します — 詳細は 1.5 個人設定
  • 「アプリ」ページ:各 CLI ツールのインストールとアップグレード、サイドバーに表示するアプリの選択ができます — 詳細は 1.2 インストールガイド
  • すべての変更点は v4.0 リリースノート をご覧ください

コントリビュート

Issue や PR でドキュメントの改善にご協力ください:


Overview (`docs/user-manual/zh/README.md`)

CC Switch 用户手册

Claude Code / Claude Desktop / Codex / Gemini CLI / Grok Build / OpenCode / OpenClaw / Hermes / Pi / MiniMax Code 全方位辅助工具

目录结构

text
📚 CC Switch 用户手册
│
├── 1. 快速入门
│   ├── 1.1 软件介绍
│   ├── 1.2 安装指南
│   ├── 1.3 界面概览
│   ├── 1.4 快速上手
│   └── 1.5 个性化配置
│
├── 2. 供应商管理
│   ├── 2.1 添加供应商
│   ├── 2.2 切换供应商
│   ├── 2.3 编辑供应商
│   ├── 2.4 排序与复制
│   ├── 2.5 用量查询
│   └── 2.6 Claude Desktop
│
├── 3. 扩展功能
│   ├── 3.1 MCP 服务器管理
│   ├── 3.2 Prompts 提示词管理
│   ├── 3.3 Skills 技能管理
│   ├── 3.4 会话管理器
│   └── 3.5 工作区文件与每日记忆
│
├── 4. 本地路由与高可用
│   ├── 4.1 本地路由服务
│   ├── 4.2 应用路由
│   ├── 4.3 故障转移
│   ├── 4.4 用量统计
│   ├── 4.5 连通检测
│   └── 4.6 聚合模式
│
└── 5. 常见问题
    ├── 5.1 配置文件说明
    ├── 5.2 FAQ
    ├── 5.3 深度链接协议
    └── 5.4 环境变量冲突

文件列表

1. 快速入门

文件 内容
1.1-introduction.md 软件介绍、核心功能、支持平台
1.2-installation.md Windows/macOS/Linux 安装指南
1.3-interface.md 侧栏布局、连接模式标签、供应商卡片说明
1.4-quickstart.md 5 分钟快速上手教程
1.5-settings.md 设置六个分组:通用、应用配置、本地路由、网络、数据、关于

2. 供应商管理

文件 内容
2.1-add.md 使用预设、自定义配置、统一供应商
2.2-switch.md 直连/路由/聚合、托盘切换、生效方式
2.3-edit.md 编辑配置、修改 API Key、全局设置与编辑冲突
2.4-sort-duplicate.md 拖拽排序、复制供应商、删除
2.5-usage-query.md 用量查询、剩余额度、多套餐显示
2.6-claude-desktop.md Claude Desktop 第三方供应商、直连与模型映射

3. 扩展功能

文件 内容
3.1-mcp.md MCP 协议、添加服务器、应用绑定
3.2-prompts.md 创建提示词、启用切换、目标文件
3.3-skills.md 发现技能、安装卸载、仓库管理
3.4-sessions.md 会话浏览、搜索过滤、恢复与删除
3.5-workspace.md OpenClaw 工作区文件、每日记忆

4. 本地路由与高可用

文件 内容
4.1-service.md 启动本地路由、配置项、接口格式转换
4.2-routing.md 应用路由、配置修改、状态指示
4.3-failover.md 故障转移队列、熔断器、健康状态
4.4-usage.md 用量统计、趋势图表、定价配置
4.5-model-test.md 连通检测、检测参数
4.6-aggregation.md 聚合模式、默认供应商、ccs- 前缀、Codex 重启

5. 常见问题

文件 内容
5.1-config-files.md CC Switch 存储、CLI 配置文件格式
5.2-questions.md 常见问题解答
5.3-deeplink.md 深度链接协议、生成和使用方法
5.4-env-conflict.md 环境变量冲突检测与处理

快速链接

版本信息

  • 文档版本:v4.0.4
  • 最后更新:2026-10-07
  • 适用于 CC Switch v4.0.4+

近期主要变化(v4.0)

  • 界面改版:顶部导航换成左侧栏,用量统计、授权中心、MCP、Skills、提示词、会话、应用各占一页;设置分为通用、应用配置、本地路由、网络、数据、关于六组 — 详见 1.3 界面概览、1.5 个性化配置
  • 直连 / 路由 / 聚合三种连接模式:在每个应用页顶部选择,回到直连只需一步 — 详见 2.2 切换供应商
  • 新增聚合模式:Claude Code 和 Codex 可以在一个会话里按模型混用多家供应商 — 详见 4.6 聚合模式
  • 切换只改关键字段:地址、密钥、模型等关键字段以外的设置原样保留,不再使用通用配置片段 — 详见 2.3 编辑供应商
  • 授权中心:ChatGPT、GitHub Copilot、xAI 等账号集中在侧栏「授权中心」管理 — 详见 1.5 个性化配置
  • 「应用」页:安装、升级各 CLI 工具,选择侧栏显示哪些应用 — 详见 1.2 安装指南
  • 完整变化见 v4.0 发布说明

贡献

欢迎提交 Issue 或 PR 改进文档:


User Manual En 1 Getting Started 1.4 Quickstart (`docs/user-manual/en/1-getting-started/1.4-quickstart.md`)

1.4 Quick Start

This section helps you complete the initial setup in 5 minutes.

Step 1: Add a Provider

  1. Select the tool you want to manage in the left sidebar, then click the + (Add Provider) button in the top-right corner of the page
  2. Select your provider under "Provider Preset"
    • Common presets: Zhipu GLM, MiniMax, DeepSeek, Kimi, PackyCode
    • Or select "Custom" for manual configuration
  3. Enter your API Key
  4. Click "Add"

💡 Tip: The add panel supports searching by Chinese name and domain, and different plans and regions of the same provider are merged into one row. Presets auto-fill the endpoint URL, so you only need to enter your API Key.

Step 2: Switch Provider

After adding, the provider appears in the list.

Option 1: Switch from the app page

  • Click the "Switch" button on the provider card, and its status changes to "In use"
  • OpenCode, OpenClaw, Hermes, and MiniMax Code are coexist apps: the button is "Add" (for Pi, "Enable"), and you can add multiple providers at the same time

Option 2: Quick switch via system tray

  • Right-click the CC Switch icon in the system tray
  • Each tool has one row showing "name · mode · provider · quota"; click a provider name directly in the submenu (supported for Claude Code, Claude Desktop, Codex, Gemini CLI, and Grok Build)

Step 3: Activation

After switching providers, each CLI tool activates differently:

Application Activation Method
Claude Code ✅ Instant effect (supports hot reload)
Claude Desktop Requires restarting Claude Desktop
Codex Requires closing and reopening the terminal
Gemini Requires restarting Gemini CLI
Grok Build Requires restarting Grok Build
OpenCode Requires closing and reopening the terminal
OpenClaw Requires closing and reopening the terminal
Hermes / Pi / MiniMax Code Once added, the provider is written into the tool's configuration; for Pi and MiniMax Code, choose the model to use inside the tool; for Hermes, click "Enable" on the card to make it the current provider

In Routing mode, switching providers for Claude Code, Codex, Gemini CLI, and Grok Build takes effect immediately for subsequent requests; however, if the switch changes the model, Codex, Gemini CLI, and Grok Build may still need a restart.

Direct, Routing, and Aggregation (Optional)

The pages of Claude Code, Codex, Gemini CLI, and Grok Build have "Direct / Routing" tabs at the top, and Claude Code and Codex also have "Aggregation". Clicking a tab only changes what you are viewing and does not change any configuration; to actually switch, click the button on the page that spells out the consequences: "Start routing" or "Switch to Aggregation", and "Back to direct" to return to Direct.

  • Direct (default): The client connects to the provider directly; choose it for everyday use
  • Routing: Requests go through CC Switch on this machine (default 127.0.0.1:15721), which can convert API formats and do failover. Choose it if you want to use an OpenAI- or Gemini-format provider in Claude Code, or Claude in Codex
  • Aggregation: Puts models from several providers into one model list, and a request goes to whichever provider owns the model you pick; no failover

Routing and Aggregation need CC Switch to keep running; quitting CC Switch automatically returns to Direct, and it reconnects the next time you start it. Official subscriptions do not go through routing (Codex's OpenAI Official is the exception). See Enable local routing for details.

Claude Code First Launch Prompt

If Claude Code prompts you to log in or shows an onboarding wizard on first launch, enable the "Skip Claude Code first-run confirmation" option in CC Switch:

  1. Open CC Switch "Settings → App config" and find the Claude Code block
  2. Enable the "Skip Claude Code first-run confirmation" toggle
  3. Restart Claude Code

⚠️ Note: This option writes hasCompletedOnboarding: true to ~/.claude.json, skipping the official first-run confirmation flow.

Verify Configuration

After restarting, launch the corresponding CLI tool and enter a simple question to test:

bash
# Claude Code - enter a test question after launching
claude
> Hello, please briefly introduce yourself

# Codex - enter a test question after launching
codex
> Hello, please briefly introduce yourself

# Gemini - enter a test question after launching
gemini
> Hello, please briefly introduce yourself

# OpenCode - enter a test question after launching
opencode
> Hello, please briefly introduce yourself

# OpenClaw - enter a test question after launching
openclaw
> Hello, please briefly introduce yourself

If the AI responds normally, the configuration is successful.

Note: On first launch, CC Switch automatically imports the existing configuration of Claude Code, Codex, Gemini CLI, and Grok Build as a provider named default, and adds an official provider for these tools and Claude Desktop. Your original configuration is not lost.

Next Steps

Congratulations! You have completed the basic configuration. Next, you can:

Common Issues

Not taking effect after switching?

Make sure you restarted the terminal or CLI tool. The configuration file is updated at switch time, but running programs do not automatically reload it.

Can't find a preset?

If your provider is not in the preset list, select "Custom" for manual configuration. See Add Provider for configuration format details.

How to restore official login?

The provider lists for Claude Code, Claude Desktop, Codex, Gemini CLI, and Grok Build each come with a built-in official provider (such as Claude Official, OpenAI Official, Google Official, and Grok Official). Switch to it, restart the client, and follow the tool's own login flow. If it is missing from the list (for example, because you deleted it or upgraded from an older version), you can add it again from the presets.


User Manual Ja 1 Getting Started 1.4 Quickstart (`docs/user-manual/ja/1-getting-started/1.4-quickstart.md`)

1.4 クイックスタート

このセクションでは、5 分で初回設定を完了する方法を説明します。

ステップ 1:プロバイダーの追加

  1. 左サイドバーで管理したいツールを選び、ページ右上の +(プロバイダーを追加)をクリック
  2. 「プロバイダータイプ」からプロバイダーを選択
    • よく使われるプリセット:Zhipu GLM、MiniMax、DeepSeek、Kimi、PackyCode
    • または「カスタム」を選択して手動設定
  3. API Key を入力
  4. 「追加」をクリック

💡 ヒント:追加パネルは中国語名とドメインでの検索に対応しており、同じ提供元のプランやリージョンは 1 行にまとめられます。プリセットではエンドポイントアドレスが自動入力されるため、API Key のみ入力すれば使用できます。

ステップ 2:プロバイダーの切り替え

追加が完了すると、プロバイダーがリストに表示されます。

方法 1:アプリページで切り替え

  • プロバイダーカードの「切り替え」ボタンをクリックすると、状態が「使用中」になります
  • OpenCode、OpenClaw、Hermes、MiniMax Code は共存型アプリで、ボタンは「追加」(Pi は「有効化」)です。複数のプロバイダーを同時に追加できます

方法 2:トレイで素早く切り替え

  • システムトレイアイコンを右クリック
  • ツールごとに 1 行、「名前 · モード · プロバイダー · クォータ」と表示されます。サブメニューでプロバイダー名を直接クリックします(Claude Code、Claude Desktop、Codex、Gemini CLI、Grok Build に対応)

ステップ 3:反映方法

プロバイダーを切り替えた後、各 CLI ツールの反映方法は異なります:

アプリ 反映方法
Claude Code ✅ 即時反映(ホットリロード対応)
Claude Desktop Claude Desktop の再起動が必要
Codex ターミナルの再起動が必要
Gemini Gemini CLI の再起動が必要
Grok Build Grok Build の再起動が必要
OpenCode ターミナルの再起動が必要
OpenClaw ターミナルの再起動が必要
Hermes / Pi / MiniMax Code プロバイダーを追加するとツールの設定に書き込まれます。Pi と MiniMax Code ではツール側で使用するモデルを選択し、Hermes ではカードの「有効化」をクリックして現在のプロバイダーに設定できます

ルーティングモードの場合、Claude Code、Codex、Gemini CLI、Grok Build でのプロバイダー切り替えは以降のリクエストに即座に反映されます。ただし、切り替えによってモデルが変わる場合、Codex、Gemini CLI、Grok Build は再起動が必要になることがあります。

直接接続、ルーティング、集約(任意)

Claude Code、Codex、Gemini CLI、Grok Build のページ上部には「直接接続 / ルーティング」のタブがあり、Claude Code と Codex には「集約」もあります。タブをクリックしても表示が切り替わるだけで設定は変更されません。実際に切り替えるには、ページ上の結果が明記されたボタン「ルーティングを開始」「集約に切り替え」を押します。直接接続に戻すときは「直接接続に戻す」を押します。

  • 直接接続(デフォルト):クライアントがプロバイダーに直接接続します。日常の利用ではこれを選びます
  • ルーティング:リクエストをこのマシン上の CC Switch 経由で転送し(デフォルトは 127.0.0.1:15721)、API フォーマットの変換やフェイルオーバーができます。Claude Code で OpenAI や Gemini 形式のプロバイダーを使いたい場合や、Codex で Claude を使いたい場合に選びます
  • 集約:複数プロバイダーのモデルを 1 つのモデルリストにまとめ、選んだモデルのプロバイダーへリクエストを送ります。フェイルオーバーは行いません

ルーティングと集約は CC Switch が起動し続けている必要があります。CC Switch を終了すると自動的に直接接続に戻り、次回起動時に再び接続されます。公式サブスクリプションはルーティングを経由しません(Codex の OpenAI Official は例外)。詳細は ローカルルーティングの有効化 を参照してください。

Claude Code の初回インストール時の注意

Claude Code を初めて起動するときにログインの要求や初期化ガイドが表示される場合は、CC Switch で「Claude Code の初回確認をスキップ」オプションを有効にしてください:

  1. CC Switch の「設定 → アプリ設定」を開き、Claude Code のブロックを探す
  2. 「Claude Code の初回確認をスキップ」スイッチをオンにする
  3. Claude Code を再起動

⚠️ 注意:このオプションは ~/.claude.json に hasCompletedOnboarding: true を書き込み、公式の初回インストール確認フローをスキップします。

設定の確認

再起動後、対応する CLI ツールを起動して簡単な質問でテストします:

bash
# Claude Code - 起動後にテスト質問を入力
claude
> こんにちは、簡単に自己紹介してください

# Codex - 起動後にテスト質問を入力
codex
> こんにちは、簡単に自己紹介してください

# Gemini - 起動後にテスト質問を入力
gemini
> こんにちは、簡単に自己紹介してください

# OpenCode - 起動後にテスト質問を入力
opencode
> こんにちは、簡単に自己紹介してください

# OpenClaw - 起動後にテスト質問を入力
openclaw
> こんにちは、簡単に自己紹介してください

AI が正常に回答すれば、設定は成功です。

注意:初回起動時、CC Switch は Claude Code、Codex、Gemini CLI、Grok Build の既存設定を default という名前のプロバイダーとして自動的にインポートし、これらのツールと Claude Desktop に公式プロバイダーを追加します。既存の設定は失われません。

次のステップ

基本設定が完了しました。次に以下のことができます:

よくある質問

切り替えても反映されない場合

ターミナルまたは CLI ツールを再起動してください。設定ファイルは切り替え時に更新されますが、実行中のプログラムは自動的に設定を再読み込みしません。

プリセットが見つからない場合

プロバイダーがプリセットリストにない場合は、「カスタム」を選択して手動設定してください。設定形式については プロバイダーの追加 を参照してください。

公式ログインに戻すには

Claude Code、Claude Desktop、Codex、Gemini CLI、Grok Build のプロバイダーリストには、それぞれ公式プロバイダー(Claude Official、OpenAI Official、Google Official、Grok Official など)が最初から含まれています。そちらに切り替えてクライアントを再起動し、各ツール自身のログインフローに従ってください。リストにない場合(削除した場合や旧バージョンからアップグレードした場合など)は、プリセットから追加し直せます。


User Manual Zh 1 Getting Started 1.4 Quickstart (`docs/user-manual/zh/1-getting-started/1.4-quickstart.md`)

1.4 快速上手

本节帮助你在 5 分钟内完成首次配置。

第一步:添加供应商

  1. 在左侧栏选中要管理的工具,点击页面右上角的 +(添加供应商)
  2. 在「预设供应商」中选择你的供应商
    • 常用预设:智谱 GLM、MiniMax、DeepSeek、Kimi、PackyCode
    • 或选择「自定义」手动配置
  3. 填写 API Key
  4. 点击「添加」

💡 提示:添加面板支持按中文名和域名搜索,同一家的不同套餐和地区合并成一行。预设会自动填充端点地址,你只需要填写 API Key。

第二步:切换供应商

添加完成后,供应商会出现在列表中。

方式一:应用页切换

  • 点击供应商卡片的「切换」按钮,状态会显示为「使用中」
  • OpenCode、OpenClaw、Hermes、MiniMax Code 是共存式应用,按钮为「添加」(Pi 为「启用」),可以同时添加多个供应商

方式二:托盘快速切换

  • 右键系统托盘图标
  • 每个工具一行,显示「名称 · 模式 · 供应商 · 额度」,在子菜单里直接点击供应商名称(支持 Claude Code、Claude Desktop、Codex、Gemini CLI、Grok Build)

第三步:生效方式

切换供应商后,各 CLI 工具的生效方式不同:

应用 生效方式
Claude Code ✅ 即时生效(支持热重载)
Claude Desktop 需要重启 Claude Desktop
Codex 需要关闭并重新打开终端
Gemini 需要重启 Gemini CLI
Grok Build 需要重启 Grok Build
OpenCode 需要关闭并重新打开终端
OpenClaw 需要关闭并重新打开终端
Hermes / Pi / MiniMax Code 供应商添加后写入工具的配置;Pi、MiniMax Code 在工具里选择要使用的模型,Hermes 可在卡片上点击「启用」设为当前供应商

处于路由模式时,Claude Code、Codex、Gemini CLI、Grok Build 切换供应商会立即作用于后续请求;但如果切换改变了模型,Codex、Gemini CLI 和 Grok Build 仍可能需要重启。

直连、路由和聚合(可选)

Claude Code、Codex、Gemini CLI、Grok Build 的页面顶部有「直连 / 路由」标签,Claude Code 和 Codex 还有「聚合」。点标签只是切换查看的内容,不会改动配置;真正切换要点页面上写明后果的按钮:「开始路由」、「切换到聚合模式」,回到直连点「回到直连」。

  • 直连(默认):客户端直接连供应商,日常使用选它
  • 路由:请求经本机 CC Switch 转发(默认 127.0.0.1:15721),可以转换接口格式、做故障转移。想在 Claude Code 里用 OpenAI 或 Gemini 格式的供应商,或在 Codex 里用 Claude,选它
  • 聚合:把多家供应商的模型放进同一个模型列表,选哪个模型请求就发给哪一家,不做故障转移

路由和聚合需要 CC Switch 保持运行;退出 CC Switch 会自动回到直连,下次启动再接上。官方订阅不经过路由(Codex 的 OpenAI Official 例外)。详见 开启本地路由。

Claude Code 首次安装提示

如果 Claude Code 首次启动时提示需要登录或显示初始化引导,请在 CC Switch 中开启「跳过 Claude Code 初次安装确认」选项:

  1. 打开 CC Switch「设置 → 应用配置」,找到 Claude Code 一块
  2. 开启「跳过 Claude Code 初次安装确认」开关
  3. 重新启动 Claude Code

⚠️ 注意:此选项会在 ~/.claude.json 中写入 hasCompletedOnboarding: true,跳过官方的初次安装确认流程。

验证配置

重启后,启动对应的 CLI 工具并输入简单的问题进行测试:

bash
# Claude Code - 启动后输入测试问题
claude
> 你好,请简单介绍一下自己

# Codex - 启动后输入测试问题
codex
> 你好,请简单介绍一下自己

# Gemini - 启动后输入测试问题
gemini
> 你好,请简单介绍一下自己

# OpenCode - 启动后输入测试问题
opencode
> 你好,请简单介绍一下自己

# OpenClaw - 启动后输入测试问题
openclaw
> 你好,请简单介绍一下自己

如果 AI 能正常回复,说明配置成功。

注意:首次启动时,CC Switch 会自动把 Claude Code、Codex、Gemini CLI、Grok Build 的现有配置导入为名为 default 的供应商,并为这几个工具和 Claude Desktop 添加官方供应商,原有配置不会丢失。

下一步

恭喜!你已经完成了基础配置。接下来可以:

常见问题

切换后不生效?

确保重启了终端或 CLI 工具。配置文件在切换时已经更新,但运行中的程序不会自动重新加载。

找不到预设?

如果你的供应商不在预设列表中,选择「自定义」手动配置。参考 添加供应商 了解配置格式。

如何恢复官方登录?

Claude Code、Claude Desktop、Codex、Gemini CLI、Grok Build 的供应商列表里都自带一个官方供应商(如 Claude Official、OpenAI Official、Google Official、Grok Official),切换过去后重启客户端,按工具自身的登录流程操作即可。如果列表里没有(例如删掉了,或从旧版本升级),可以从预设里重新添加。


Pi Frontend Uiux Guidelines Zh (`docs/pi-frontend-uiux-guidelines-zh.md`)

Pi 前端 UI/UX 需求与规范

状态:当前 Pi 前端的评审基线
适用范围:供应商、提示词、Skills、Sessions,以及以后考虑接入的 Pi 原生设置
最后更新:2026-08-05

这份文档面向 cc-switch 的设计者、开发者和评审者。它不是功能清单,也不是用户手册。新增 Pi 界面或字段时,应先用本文判断该能力是否该由 cc-switch 提供,再讨论具体组件。

文中的“必须”是合并前要求;“应该”允许有明确理由的例外;“不得”表示当前产品边界。

1. 产品目标

Pi 界面必须同时满足两类用户:

  • 第一次使用的小白能看懂哪些供应商已加入 Pi,知道从哪里添加供应商,并能完成 API Key、请求地址和模型配置。
  • 熟悉 Pi 的用户可以在第一次创建时配置接口格式、模型能力和请求头,不需要先保存一份错误配置再回来修改。

“简单”指默认路径短、入口少、术语清楚,不是删除必要能力。普通字段直接展示,少用解释文字;只有在不解释就可能误用、丢数据或改变 Pi 行为时才保留提示。

稳定性优先于覆盖所有边界。P0、P1 问题必须解决;罕见且低影响的 P2 可以记录后延期。不要为了单条评审意见叠加新的影子状态、特殊分支或一次性组件。

2. 设计来源与家族化原则

Pi 不建立独立设计系统。交互参考顺序如下:

  1. OpenCode:供应商是可累加配置,最接近 Pi 的供应商管理方式。
  2. Hermes:模型详情、可选能力和原生设置的渐进展示。
  3. Claude Code、Codex:供应商表单、请求头、配置 JSON、卡片和操作按钮的视觉语言。

应该复用现有的 ProviderPresetSelector、BasicFormFields、ApiKeySection、EndpointField、RequestHeadersEditor、JsonEditor、供应商卡片、图标、分类与合作伙伴排序。只有 Pi 原生语义无法用现有组件表达时,才增加 Pi 专用组件。

同一种信息在不同应用中应使用相同的层级、字号、间距和操作位置。Pi 可以有不同的数据语义,不能因此出现一套完全不同的布局。

3. Pi 原生语义是最高约束

所有认证、模型、文件路径、加载顺序和传输行为,必须由开发时最新 Pi 或 request capture 验证。源码阅读和经验判断只能用于提出假设,不能作为产品状态的依据。实现取舍见 Pi 原生契约与实现边界。

前端必须遵守以下规则:

  • Pi 原生文件和目录采用 exists = active,不得再增加一个 enabled 字段。
  • Pi 全局保存的当前供应商和模型只由后端读取:默认供应商仅用于移除或删除前的条件提醒。它们不作为供应商页面的展示状态,也不从数据库元数据猜测。
  • 后端无法读取 models.json 时,涉及 Pi 供应商成员关系的写操作必须失败关闭。无法读取全局默认项时不阻止成员关系操作。
  • 已存在但暂未暴露的 Pi 字段必须原样透传,结构化表单不能把未知字段清空。
  • 前端只展示后端已经稳定实现的状态。没有可靠读取和写入契约的按钮不得出现。

4. 供应商页面

4.1 信息架构

供应商页面采用统一结构:

  1. CC Switch 中保存的供应商列表。
  2. 页面右上角唯一的“+”添加入口。

供应商卡片不展示模型列表。模型只在添加或编辑表单中配置,避免卡片高度失控和信息重复。

列表中的常规操作沿用家族组件:

  • 启用:把供应商加入 Pi 原生配置。
  • 移除:从 Pi 原生配置移除,但保留 CC Switch 中的供应商。
  • 编辑:修改供应商配置。
  • 删除:删除 CC Switch 中的供应商。
  • 复制、连通性检测和用量配置继续使用现有上下文操作,不增加第二个主入口。
  • 不提供“导入当前原生供应商”等第二个添加入口;需要托管的供应商统一从右上角“+”创建。

供应商标识是成员身份。Pi models.json 中存在该标识即表示已启用,不再比较整份 JSON 来制造“漂移”或“所有权”状态。凡是显式存在于 models.json.providers 的供应商都应同步到供应商列表,包括与 Pi 内置供应商同名的 ID;原生修改同步回已保存档案,原生移除只改变启用状态。只存在于 auth.json、/login 或环境变量中的认证状态始终由 Pi 管理,不生成 CC Switch 卡片。详细规则见 Pi 显式供应商同步需求。

4.2 Pi 当前选择的安全边界

CC Switch 不设置、展示或标记 Pi 的当前供应商和模型。

  • 当前供应商和模型完全交给 Pi 原生 /model。
  • 供应商页只管理供应商是否加入 Pi 原生配置,不显示“当前使用”“当前默认”、所有权或当前模型。
  • Pi 全局默认项指向待移除或删除的供应商时,在原有确认框中增加一条非阻塞提醒,说明 Pi 会尝试其他可用模型,并允许用户继续。
  • 移除或删除供应商不得修改 defaultProvider 或 defaultModel;失效引用及后续选择由 Pi 原生逻辑和 /model 管理。
  • models.json 状态未知时,启用、移除和删除操作应禁用。全局默认项读取失败时不显示条件提醒,也不阻止供应商成员关系操作。

不得用“列表第一个模型”推导默认模型,也不得在保存供应商时偷偷修改 Pi 默认选择。

项目级 .pi/settings.json 依赖启动 Pi 时的工作目录,供应商页没有权威项目上下文,不扫描目录或猜测活动会话。因此条件提醒只基于全局默认项;项目级选择仍由对应 Pi 会话管理。

4.3 添加流程

添加流程的心智模型是:

选择预设或自定义配置 → 填写凭证与请求信息 → 配置模型 → 保存

具体要求:

  • 新建页默认选中“自定义配置”,并从打开时就展示完整基础表单;预设选择器用于快速填充,不作为进入表单的门槛。
  • 选择预设后直接填入供应商知识,例如请求地址、接口格式和模型;用户通常只需填写 API Key。
  • 自定义配置显示供应商标识,并在创建后锁定。
  • 不使用 1、2、3 编号步骤,不增加向导专属页面。
  • piProviderPresets 是独立维护的 Pi 原生预设目录。可以参考其他应用的供应商知识,但不得在运行时导入或派生另一个应用的预设;Pi 的协议、请求根地址和模型能力必须在自己的目录中明确表达。
  • 预设供应商必须自带完整模型能力。从“获取模型列表”选中模型时按 4.5 的规则补全能力;手动输入模型 ID 不补全。
  • 提交前完成必填、重复模型、正数和请求地址校验,并把焦点移动到错误字段。

4.4 字段暴露范围

供应商级字段分为三类:

字段 前端处理 原因
供应商标识 自定义创建时显示,编辑时锁定 Pi models.json 的稳定键
显示名称 直接展示 列表识别所必需
备注、官网链接 直接展示 cc-switch 家族元数据
API Key 直接展示 API Key 供应商的核心凭证
请求地址 baseUrl 直接展示 自定义供应商通常必填
接口格式 api 直接展示 决定 Pi 调用的原生协议
模型 models 直接展示 新建自定义供应商必须声明;已有显式内置节点可为空
请求头 headers 直接展示,复用家族请求头编辑器 常见兼容需求,且是 Pi 原生字段
配置 JSON 可编辑、默认展开,与结构化字段双向同步 与 Claude Code、Codex 等应用的配置编辑行为一致
接口兼容性 compat 直接展示键值编辑器 Pi 当前稳定支持的供应商级兼容选项
oauth、authHeader、modelOverrides 等罕见字段 不做结构化入口,原样透传 不属于普通创建路径

接口格式默认使用 OpenAI Chat Completions。可选项来自 Pi 已验证支持的协议:

  • OpenAI Chat Completions
  • OpenAI Responses
  • Anthropic Messages
  • Google Generative AI
  • Amazon Bedrock

创建时不提供“自定义接口格式”。编辑已有未知格式时,应显示并保留该值,不能因为下拉列表不认识就覆盖。

请求地址的示例沿用家族写法 https://api.example.com/v1。占位文字只作格式示例,不推导实际路径。

接口兼容性与模型配置采用相同的信息层级,不使用折叠箭头。默认只显示说明和“添加”按钮;点击后,键值行直接向下追加。未配置时不向 Pi JSON 写入空的 compat。

4.5 模型配置

一个供应商拥有多个模型。供应商级请求地址和接口格式是默认值,不为每个模型重复创建“模型 API”和“模型基础地址”字段。

模型行默认只显示:

  • 模型 ID
  • 显示名称
  • 展开按钮
  • 移除按钮

选择或填写模型 ID 后,仅在显示名称仍为空时同步模型 ID。预设供应商已经填好模型能力;从“获取模型列表”选中模型时按下述规则补全能力,手动输入不补全。展开区只放 Pi 原生且常用的能力:

  • 支持扩展思考 reasoning
  • 支持图片输入 input
  • 上下文长度 contextWindow
  • 最大输出 Token 数 maxTokens
  • 思考档位 thinkingLevelMap

自定义模型默认关闭扩展思考并使用文本输入;上下文长度和最大输出 Token 必须是正数才能保存。

从“获取模型列表”选中模型时,按以下规则补全能力(实现在 src/lib/modelMetadata.ts,与 Codex、OpenCode 等应用共用):

  • 来源依次为:同一请求地址的 Pi 预设模型、models.dev 中按请求地址认出的同一家供应商、models.dev 中该模型的原厂条目。不引用其他应用的预设。
  • 必须先确定供应商再查模型,不得按模型名跨供应商投票或取最新值:同一模型在不同供应商处的上下文长度可能相差数倍。早期实现按名称投票,填出的值不可靠,曾因此整体移除。认不出供应商、原厂有歧义或查不到时保持默认值,也不根据模型前缀或相似版本猜测。
  • 只补空字段:上下文长度和最大输出 Token 只在为空时填写;扩展思考和图片输入只从关闭改为开启,不替用户关闭。
  • thinkingLevelMap 只在模型还没有映射、且已支持扩展思考时补:同一请求地址的 Pi 预设里人工核对过的映射优先,但映射只在预设的协议和 compat 下成立,所以要求协议相同,并把预设依赖、模型里还没写的 compat 一并补上;用户已写的 compat 与预设冲突时不套用预设映射;openai-completions 还要求补完 compat 后,Pi 按地址和 compat 探测出的思考格式及是否发送 reasoning_effort 与预设一致(预设可能没写 compat、依赖 Pi 的默认探测)。模型单独写了 baseUrl 时,按模型实际请求的地址查找预设和 models.dev。否则仅当 Pi 会把档位原样作为 reasoning_effort 发给上游时(openai-responses,或 Pi 按供应商 ID 和地址探测为 OpenAI 思考格式且支持 reasoning_effort 的 openai-completions,compat 里写明的值优先),按 Pi 官方从 models.dev 生成内置模型目录的同一规则,用按上述来源查到的 effort 档位生成(中转站认不出时取原厂条目,绝大多数中转与原厂档位一致):列出的档位发同名值,没列出的写 null,off 在列出 none 时发 "none"。Anthropic 等需要额外 compat 的协议不生成。
  • 补全后用一条提示说明来源并请用户核对。不显示“自动值”“已覆盖自动值”或“恢复自动值”等持久状态,补进来的值与手填值没有区别。
  • models.dev 不可用时只用预设值,不报错。

thinkingLevelMap 排在上下文长度和最大输出 Token 之后,作为最后一项模型能力提供渐进式编辑。它默认折叠并保持整行宽度、左侧对齐;展开后用七行轻量列表直接展示字符串、Pi 默认和不可用三种状态,点击某一行才在表单中部打开该档位的编辑浮层。关闭“支持扩展思考”时整段隐藏,但不删除已有映射。

所有推理预设模型都显式提供 thinkingLevelMap;已确认的接口组合写入对应映射,其余预设使用 {} 明确沿用 Pi 默认行为。自定义模型只在从上游列表选中时按上述规则补映射,手动输入不补,用户可以随时修改。模型级 api、baseUrl、cost 等少见字段不做结构化入口,但编辑保存必须保留。

4.6 请求头

请求头使用 Pi 原生 headers,不得增加“请求头身份”“Claude Code”“Codex”等模板选择器,也不得自动把 API Key 塞进某个 Header。

  • 没有请求头时,沿用家族编辑器的说明、空状态和“添加请求头”按钮。
  • 添加后显示名称和值两列。
  • Header 名称按 Enter 必须先提交名称,不能触发表单保存或静默丢失。
  • 已有 Header 必须完整回显并原样保存。
  • API Key 的认证方式由 Pi 和接口格式决定,请求头编辑器只管理用户明确填写的 Header。

4.7 配置 JSON 与敏感信息

名称统一使用“配置 JSON”,不使用“配置 JSON 预览”。

配置 JSON 默认展开并允许编辑,复用共享 JSON 编辑器的语法校验和格式化操作。结构化字段只改写自己负责的键;合法 JSON 会回填结构化字段。输入暂时不合法时保留原始草稿,不用旧结构化状态覆盖,保存前必须完成校验。

配置编辑器需要显示用户正在编辑的真实值。API Key、Authorization、Token、Secret、Password 等敏感值不得出现在编辑器以外的日志、toast、列表或测试输出中。

原配置缺少可选字段时,用户未主动修改就应保持缺失。例如根级 api 不存在时,界面可以显示默认协议帮助理解,但保存不能自动补写该字段。

4.8 认证边界

Pi 原生订阅登录和 OAuth 由 Pi 管理:

  • 用户在 Pi 中使用 /login。
  • CC Switch 不复制 auth.json,不保存或刷新 OAuth Token。
  • CC Switch 不展示一套独立的“已登录”状态,也不提供 OAuth 供应商按钮。
  • API Key 供应商由 CC Switch 管理。

界面不得出现“CC Switch 显示已登录,但 Pi 仍使用旧凭证或旧请求路径”的半状态。

4.9 路由与故障转移

Pi 前端不提供路由、网关和故障转移:

  • 不显示“需要路由”“不支持路由”或 gatewayStatus。
  • 不显示故障转移端点管理。
  • 不显示网关凭证和网关诊断。
  • 不从预设写入 allowGateway 等能力字段。

后端不得为 Pi 建立路由投影、网关状态或故障转移配置。通用代理基建遇到 Pi 时应明确跳过。

5. 提示词页面

Pi 提示词沿用 cc-switch 的列表、标签页、全屏编辑器和顶部主操作,不创建侧边栏专用设计。页面使用三个标签:

  • 全局提示:管理提示库,并选择一项写入 Pi 全局 AGENTS.md。
  • 全局系统提示:管理 APPEND_SYSTEM.md 和 SYSTEM.md。
  • 提示词模板:管理 Pi 原生模板。

全局提示同一时间只允许一项与 AGENTS.md 精确匹配。原生文件与提示库内容不一致时,显示“外部 AGENTS.md”,不得假装某个数据库选项仍在使用。编辑或停用旧选项不能覆盖外部内容;用户明确选择另一项时,先把非空的外部内容保存进提示库,再写入所选项。

APPEND_SYSTEM.md 是普通用户的推荐入口。SYSTEM.md 会完整替换系统提示,创建前必须明确警告。文件存在就是生效,不增加启用开关。

APPEND_SYSTEM.md、SYSTEM.md 与提示词模板复用全局提示的全屏编辑表单。内容区只使用应用统一的外边距,不增加固定最大宽度;编辑器随窗口宽度伸缩。

顶部“+”根据当前标签执行对应的添加动作;系统提示标签直接编辑两个固定文件,不显示无意义的添加按钮。

提示文字只保留以下情况:

  • 不解释就无法区分 APPEND_SYSTEM.md 与 SYSTEM.md。
  • 操作需要在已打开的 Pi 中重新加载。
  • 原生文件与 CC Switch 状态发生冲突。

不要在页面上重复显示操作完成后 toast 已经说明的内容。

6. Skills、Sessions 与后续能力

Skills

Pi Skills 复用统一 Skills 页面和已有卡片。是否被 Pi 发现必须来自原生目录检查,不读取通用 skill.apps.pi 作为第二状态源。

全局 Skills 页的应用矩阵常驻 Pi 列(和其他应用列并排;只有在「应用」页把 Pi 设为隐藏时才不显示)。Pi 列的状态仍按上面的原生目录检查来:看 ~/.pi/agent/skills 里有没有这个目录(后端 get_installed_skills 返回前用这次检查覆盖 apps.pi,不是数据库里的开关),列头和批量弹层用「?」说明这个判断方式。

Sessions

Pi Sessions 复用现有会话管理器。相对 session 目录缺少项目上下文时,应说明需要项目目录;目录不可用时显示错误。不要制造 CC Switch 专用的 Pi 会话格式。

Extensions 与 Themes

Pi Packages、Extensions 与 Themes 由 Pi 原生管理,当前不进入 CC Switch 产品界面。CC Switch 不复制扩展文件,也不维护第二套安装、启用或更新状态。

7. 文案与视觉规范

固定术语如下:

使用 不使用
请求地址 供应商 API、供应商基础地址
接口格式 自定义接口格式(作为重复标题)
模型配置 默认模型配置、模型 API
请求头 请求头身份
配置 JSON 配置 JSON 预览
启用、移除 切换、设为默认

普通字段 Label、模型配置标题和请求头标题使用同一视觉等级。当前实现基准为 14px / 400 / 20px。不要仅把某一组字段加粗,造成虚假的一级分区。

按钮、图标、圆角、边框和 hover 状态使用现有设计令牌。交互动画保持 150–300ms,并支持 prefers-reduced-motion。深色和浅色主题都必须保证文字、边框和禁用状态可辨认。

每个输入都有可关联的 Label。图标按钮需要可访问名称。动态错误使用 role="alert" 或合适的 live region。键盘操作不能丢失尚未提交的输入。

8. 新字段和新功能的准入条件

计划新增任何 Pi 设置时,依次回答:

  1. 这是开发时最新 Pi 已验证的原生能力吗?
  2. 它是创建或日常管理中常见、必要的字段吗?
  3. 这项操作属于 CC Switch,还是应该交给 Pi 的 /login、/model 等原生命令?
  4. 后端能稳定读取、写入并无损往返吗?

四项都满足才进入默认界面。Pi 原生但罕见的字段优先透传;需要专业用户偶尔修改的字段可以进入渐进区域;不属于 CC Switch 或缺少可靠后端支持的能力不进入 UI。

参考 OpenCode 或 Hermes 时只复用相同问题的成熟交互。不能因为另一个应用有某个字段,就假设 Pi 也需要。

9. 错误处理与安全

  • 状态未知时,不用猜测值恢复写操作。
  • 删除和移除必须有确认;目标是 Pi 全局默认供应商时,在同一个确认框内增加非阻塞提醒。
  • 保存失败后保留用户输入,显示具体错误。
  • 表单错误就地显示并聚焦对应字段。
  • 日志、toast、列表和测试输出不得泄露 API Key 或 Header 中的凭证。
  • 外部原生内容发生变化时,刷新列表会按精确 ID 自动同步,不增加确认或 ownership 状态。

10. 验收

功能验收至少覆盖:

  • 首次进入默认选中“自定义配置”,能同时看到预设选择和可立即填写的基础表单。
  • 预设创建、自定义创建、模型获取、模型能力预填和手动覆盖。
  • Header 的添加、Enter 提交、编辑、移除与无损回显。
  • 配置 JSON 与结构化字段双向同步,格式化可用,并与实际保存内容一致。
  • 已有未知字段、缺失可选字段和精确模型 ID 的无损往返。
  • Pi 供应商配置加载、错误、外部新增、修改、删除与启用状态同步。
  • Pi /model、/login 的所有权没有被 CC Switch 接管。
  • 中、英、日、繁中术语覆盖。
  • 键盘、浅色/深色主题和常见窗口宽度。

真实联调应使用已安装的 Pi,验证添加、启用、移除、编辑、模型获取、请求发送和 Pi 原生命令后的状态同步。协议与能力结论必须保留 oracle 或 request-capture 证据。


Pi Live Provider Sync Requirements Zh (`docs/pi-live-provider-sync-requirements-zh.md`)

Pi 显式供应商同步需求

背景

Pi 会读取 ~/.pi/agent/models.json 中的 providers,并把同名显式供应商配置与自己的内置供应商、内置模型合并。当前 CC Switch 会跳过 anthropic、openai、deepseek 等 Pi 内置供应商 ID,导致 Pi 已经加载了显式配置,但 CC Switch 页面没有对应的已启用卡片,也无法正常移除、编辑或重新启用。

这类供应商是否属于 CC Switch 可管理范围,应只由配置来源决定,不能再由供应商 ID 或认证类型决定。

目标架构

整体行为与 OpenCode 的累加式供应商管理保持一致:

OpenCode Pi
opencode.json.provider models.json.providers
显式 provider 同步为 CC Switch 卡片 显式 provider 同步为 CC Switch 卡片
/connect 认证由 OpenCode 管理 /login 与 auth.json 由 Pi 管理
添加和移除 provider 节点 启用和移除 provider 节点
数据库保留未添加供应商 数据库保留未启用供应商
不管理当前供应商 不管理默认供应商和默认模型

Pi 额外需要支持同名内置供应商的显式覆盖:只要供应商节点存在于 models.json.providers,无论 ID 是否为 anthropic、openai、deepseek 或其他 Pi 内置 ID,都必须按普通显式供应商处理。

显式供应商同步规则

  • models.json.providers 是 Pi 当前启用的显式供应商集合。
  • 任意精确 provider ID 都可被同步,不使用内置供应商集合过滤。
  • 数据库中没有对应记录时,按精确 provider ID 自动导入并 upsert。
  • 数据库中已有记录时,用 Pi 当前的显式配置同步对应记录。
  • provider 节点存在于 models.json 时,卡片显示为已启用。
  • provider 只存在于 CC Switch 数据库时,卡片保留并显示为未启用。
  • 已启用卡片沿用 OpenCode 的蓝色高亮。
  • 外部修改 models.json 后,刷新供应商页面即自动同步,不要求二次确认。
  • 不再出现“不是 CC Switch 管理的值”或“配置刚发生变化,请确认后重试”等 ownership 冲突提示。
  • PI_BUILTIN_PROVIDER_KEYS 或等价集合不能参与配置归属判断,也不能用于跳过 live provider 同步。

认证边界

边界按配置来源划分:

  • models.json.providers 中的显式配置由 CC Switch 管理。
  • Pi /login 写入 auth.json 的凭证始终由 Pi 管理,无论其类型为 OAuth 还是 API Key。
  • CC Switch 不读取、复制、修改或删除 auth.json 中的凭证。
  • CC Switch 不刷新 OAuth Token。
  • 只有 auth.json 凭证、没有 models.json.providers 节点的供应商,不生成 CC Switch 卡片。
  • 环境变量中的凭证不导入 CC Switch。
  • 同一供应商同时存在显式配置和 Pi 登录时,CC Switch 只管理显式配置。
  • 移除显式配置不退出 Pi 登录,也不删除 auth.json。
  • 用户在 CC Switch 中创建的 API Key 供应商仍由 CC Switch 保存并写入 models.json;用户通过 Pi /login 保存的 API Key 仍属于 Pi 原生认证状态。

启用与移除

启用

  • 将 CC Switch 数据库中保存的完整配置写入 models.json.providers.。
  • 成功后卡片变为蓝色已启用状态。
  • 不修改 Pi 默认供应商、默认模型或 auth.json。

移除

  • 只删除 models.json.providers.。
  • 不删除 CC Switch 数据库记录。
  • 卡片继续保留并变为未启用,之后可以再次启用。
  • 不修改 auth.json、环境变量或 Pi 原生登录状态。
  • 不因供应商当前正被 Pi 使用而阻止移除。
  • 不提供“设为默认”操作;删除当前默认供应商后的回退行为由 Pi 处理。

所有配置写入复用现有原子文件更新能力,并保留与目标供应商无关的内容。

Pi 内置模型合并语义

  • 接受 Pi 对同名内置供应商的原生合并行为。
  • 供应商卡片只根据显式 provider 节点判断启用状态。
  • 编辑页面只展示该 provider 在 models.json 中显式保存的模型。
  • 不把 Pi 的内置模型复制到 CC Switch 数据库或 models.json。
  • 不根据 Pi 运行时出现的模型扩充供应商预设。
  • 模型 ID 按精确字符串处理,不做大小写或相似名称合并。
  • 同名内置供应商的显式配置必须完整保留。
  • 读取、同步、编辑和保存后,未知 JSON 字段不能丢失。

piProviderPresets、models.json.providers 和 Pi 内置模型目录是三个独立数据源,不互相替代。

实现范围

优先复用 OpenCode 已有能力:

  • live provider 导入与 upsert;
  • 累加模式下的启用和移除;
  • live_config_managed 或等价状态;
  • 供应商列表刷新;
  • 原子配置文件写入;
  • 未知字段保留。

主要修改范围:

  • Pi live provider 配置读取;
  • Pi 供应商列表同步;
  • 内置 provider ID 过滤规则;
  • 启用和移除操作;
  • 页面刷新后的状态更新。

不增加数据库 Schema,也不建立新的 ownership 状态。

明确不做:

  • OAuth 或 /login 凭证管理;
  • auth.json 管理;
  • 环境变量导入;
  • 默认供应商或默认模型管理;
  • 路由与故障转移;
  • 插件管理;
  • 自动重写 Pi 内置模型。

真实 Pi 验收

  1. 在 models.json.providers 中分别加入带 API Key 的 anthropic、openai 和 deepseek,刷新后均出现已启用卡片。
  2. Pi /model 能显示并使用这些显式配置激活的模型。
  3. 点击移除后,仅删除对应 provider 节点;数据库卡片保留并变为未启用。
  4. 在没有 auth.json 凭证和相关环境变量时重启 Pi,被显式配置激活的模型不再可用。
  5. 再次启用后完整配置恢复,Pi 可以继续使用。
  6. 在 CC Switch 外部新增、修改或删除 provider,刷新页面后自动同步。
  7. Pi /login 写入的 OAuth 或 API Key 凭证不被读取或修改。
  8. 移除供应商前后 auth.json 内容与文件状态完全不变。
  9. 自定义 Header、模型能力字段和未知 JSON 字段在同步、编辑、保存、移除与重新启用后不丢失。
  10. 所有操作前后 Pi 当前默认供应商和默认模型保持不变。
  11. 模型 ID 大小写按原值保存,不进行任何模糊合并。

Pi Native Contract Zh (`docs/pi-native-contract-zh.md`)

Pi 原生契约与实现边界

验证原则:开发和验收使用当时最新发布的 Pi;CC Switch 不绑定某个 Pi 版本。

这份文档记录 CC Switch 当前实际消费的 Pi 原生契约。它不是 Pi 配置格式的完整镜像,也不承诺代理、OAuth 或所有兼容字段。实现和测试只覆盖前端已经提供的能力。

验证方式

供应商字段、继承顺序和配置值解析以开发时最新 Pi 的源码入口和真实 CLI 行为为准。资源与会话行为通过 Pi 的 DefaultResourceLoader、loadSkills、loadPromptTemplates 和 SessionManager 实际运行确认。仓库只保留产品真正消费的最小契约和普通测试,不维护上游源码快照、哈希或版本证据库。

当前消费的契约

资源 CC Switch 行为 状态来源
models.json 管理 providers 中的全部显式供应商节点;精确新增、替换和移除 文件中的实际条目
全局 settings.json 只读 defaultProvider、defaultModel、sessionDir Pi 原生设置
auth.json 不读、不写、不刷新 Pi /login
AGENTS.md 提示库中与文件内容精确匹配的项视为正在使用 文件存在及内容
SYSTEM.md、APPEND_SYSTEM.md 直接编辑固定原生文件;不存在即未配置 文件存在
prompts/*.md 管理顶层斜杠命令模板;空模板是有效原生文件 文件存在
skills/<目录> 目录存在即被 Pi 发现 原生 Skills 目录
Sessions JSONL 读取 Pi 的会话头、树分支、消息和会话名称 原生会话文件

供应商

结构化表单只验证并编辑常用字段:

  • 供应商级 name、baseUrl、apiKey、api、headers
  • 模型级 id、name、reasoning、input、contextWindow、maxTokens

已有配置中的其他字段原样保留。供应商是否可管理只取决于节点是否显式存在于 models.json.providers:anthropic、openai、deepseek 等 Pi 内置 ID,以及带有未知字段的节点,都按普通显式配置同步。CC Switch 不把 Pi 运行时合并出的内置模型复制回配置,也不解析或执行 apiKey、Header 中的环境变量和命令表达式。请求仍由 Pi 自己发出。

Pi 在全局设置中保存的当前供应商和模型不进入供应商列表状态。启用供应商只把条目加入 models.json,不会写 defaultProvider 或 defaultModel。移除或删除全局默认供应商时,前端在原有确认框内给出非阻塞提醒,后端允许继续且不改写默认项。编辑显式供应商同样不修改当前供应商或模型;失效引用和回退由 Pi 原生处理。

项目级 .pi/settings.json 会按启动 Pi 时的工作目录覆盖全局默认项。供应商页没有项目上下文,因此不扫描项目目录或猜测活动会话;条件提醒只读取全局默认供应商。项目级默认项继续由对应 Pi 会话和 /model 管理。

用量查询脚本属于 CC Switch 元数据,只更新数据库,不重写 models.json。

并发与外部修改

供应商标识是成员身份:models.json.providers 中存在该标识即为已启用。CC Switch 每次进入列表及应用启动时同步全部显式节点,不按内置 ID、认证字段或模型完整度过滤。原生配置发生修改后,以原生内容更新同 ID 的已保存档案;原生删除只改变启用状态。移除前保存目标节点的最新内容,数据库中的卡片和完整配置继续保留。

models.json、系统提示文件和模板使用原子写入。进程内写操作串行化;同一次读改写期间的跨进程变化通过 revision 比较发现。列表刷新会先把外部修改同步到数据库;保存时只替换目标 provider 节点,启用和移除只增删目标节点,其他 provider 与顶层字段保持不变。不再维护编辑快照或额外 ownership 状态。

Sessions

全局会话页只枚举绝对 sessionDir、~ 路径或 Pi 默认目录。相对 sessionDir 依赖启动 Pi 时的项目工作目录,CC Switch 没有可靠上下文,因此明确显示“需要项目上下文”,不会猜测目录。

会话解析只消费 UI 所需字段。未知条目被忽略;删除前会验证文件仍在已解析的 Pi 会话根目录中,并核对会话 ID。

明确不做

  • Pi /login、auth.json 中的 OAuth/API Key 登录、令牌保存和刷新
  • 默认供应商或默认模型写入
  • 路由、网关、代理、故障转移和请求头合成
  • Pi 运行时内置供应商与内置模型目录的复制
  • 完整 compat、modelOverrides 和费用编辑器;思考档位只提供 Pi 原生 thinkingLevelMap 的轻量入口
  • 相对会话目录的全局猜测

Pi 发布新版本时,通过正常开发和验收重新运行供应商、提示词、Skills 和 Sessions 契约测试。没有进入产品界面的上游字段不应仅为了“覆盖完整”而扩展后端。


Pi Thinking Level Map Requirements Zh (`docs/pi-thinking-level-map-requirements-zh.md`)

Pi 模型能力与思考档位需求

状态:已实现并完成验收
原则:预设完整可靠,自定义配置只采用能确认来源的值;外部目录不可用时不影响使用。

1. 当前版本边界

模型能力分为两条互不混用的路径:

  • Pi 供应商预设由 CC Switch 维护完整模型配置,选择后可以直接保存。
  • 自定义供应商从“获取模型列表”选中模型时,按 Pi 前端设计指南 4.5 的规则从同地址预设和 models.dev 补全 reasoning、input、contextWindow、maxTokens,并在协议允许时补 thinkingLevelMap(规则见第 4 节)。

预设里的思考映射仍只在开发时人工核对后写入。

这项功能不修改数据库 Schema,不参与显式供应商同步,也不管理 Pi 的默认供应商、默认模型、auth.json、路由、故障转移或插件。

2. 预设模型

src/config/piModelCatalog.ts 只用于复用 Pi 供应商预设中的模型知识,不作为自定义模型的全局识别器。

每个预设模型必须离线包含完整的 Pi 原生字段:

ts
{
  id: string;
  name: string;
  reasoning: boolean;
  input: Array<"text" | "image">;
  contextWindow: number;
  maxTokens: number;
}

规则如下:

  • 同一模型的公共能力在目录中维护一次。
  • 供应商存在特殊限制时,由对应预设显式覆盖。
  • 预设别名只在该预设中有效,不能让自定义供应商中的同名 ID 自动获得能力。
  • 预设数据必须随应用发布,离线可用。
  • GPT-5.6 Sol 的公共上下文长度为 272000。
  • 不从其他应用的预设或 Pi 运行时模型列表动态生成 Pi 预设。

3. `thinkingLevelMap`

Pi 原生档位为:

ts
type PiThinkingLevel =
  | "off"
  | "minimal"
  | "low"
  | "medium"
  | "high"
  | "xhigh"
  | "max";

type PiThinkingLevelMap = Partial<Record<PiThinkingLevel, string | null>>;

必须保留以下语义:

  • 字符串表示发送给上游的实际值。
  • null 表示该档位明确不可用。
  • 缺少某个键表示该档位使用 Pi 默认行为。
  • {} 表示整组明确使用 Pi 默认行为。
  • 稀疏映射不得被自动补齐。
  • reasoning: true 不代表所有档位都可用。

所有支持思考的预设模型都必须显式带有 thinkingLevelMap:

  • 已确认接口语义的组合使用对应的映射。
  • 尚无可靠专用映射的组合使用 {},明确交给 Pi 原生行为。
  • Anthropic 自适应思考等需要额外 Pi 原生兼容字段的预设,应同时写入必要的 compat,不能只让界面显示档位。

预设映射只在请求地址和协议都与预设相同时套用到自定义模型,并连同它依赖的 compat 一起补上(缺的才补;与用户已写的值冲突则不套用)。openai-completions 还要核对补完 compat 后的实际思考行为与预设一致,避免预设依赖 Pi 默认探测、用户又改了 compat 的情况。模型级 baseUrl 优先于供应商地址。其他供应商即使输入相同模型 ID,也不会套用预设映射。

4. 自定义模型

用户手动添加模型或从上游模型列表选择模型时:

  • 模型 ID 写入表单。
  • 显示名称在仍为空时同步为模型 ID,用户可以修改。
  • 手动输入的模型 ID 不补全任何能力。从上游模型列表选中时,按设计指南 4.5 补全 reasoning、input、contextWindow、maxTokens,只补空字段、只往“支持”方向补,并提示用户核对。
  • 选中的模型还没有 thinkingLevelMap 且支持扩展思考时补映射:同地址、同协议预设的映射优先,并补上它依赖的 compat;否则只在 Pi 会把档位原样作为 reasoning_effort 发出时(openai-responses,或探测为 OpenAI 思考格式且支持 reasoning_effort 的 openai-completions),按 Pi 官方 getEffortThinkingLevelMap 的规则,用 models.dev 的 effort 档位生成(先找按地址认出的供应商,认不出时取原厂条目)。DeepSeek、z.ai、OpenRouter、Moonshot 等有自己思考格式的地址,以及 Anthropic 等协议不生成。
  • 上下文长度和最大输出 Token 必须是正数才能保存。
  • “支持扩展思考”和“支持图片输入”默认分别为关闭和仅文本,用户可以随时修改。
  • 开启扩展思考后才显示思考档位编辑器。
  • 未填写 thinkingLevelMap 时由 Pi 使用原生默认档位;用户仍可在表单或配置 JSON 中写入字符串、null、稀疏映射或 {}。

界面不显示“自动值”“已覆盖自动值”或“恢复自动值”:补进来的值与手填值没有区别,不保留来源状态。

5. 配置 JSON 与旧配置

  • 结构化字段和配置 JSON 双向同步。
  • 用户已有的模型字段与 thinkingLevelMap 原样回显。
  • 未知 JSON 字段无损保留。
  • JSON 中的稀疏映射、单项 null 和 {} 不得改变语义。
  • 旧模型缺少本版本要求的字段时,只在编辑表单中提示用户补全;用户保存后才落盘。
  • 应用启动、供应商列表刷新和外部配置同步不得静默补写模型能力。

6. 验收

自动化测试至少覆盖:

  • 每个预设模型都有完整的名称、思考能力、输入类型、上下文长度和最大输出 Token。
  • 每个推理预设模型都显式拥有合法 thinkingLevelMap。
  • 所有 GPT-5.6 Sol 预设均使用 272000 上下文。
  • 手动输入模型 ID 不补全能力;从上游列表选中时只补空字段,已有思考映射不改,只在上述协议下按 Pi 官方规则生成映射,查不到时保持默认值。
  • 自定义模型缺少名称、上下文长度或最大输出 Token 时不能保存,并聚焦错误字段。
  • JSON 往返不丢未知字段或改变思考映射语义。

真实 Pi 验收使用隔离配置目录,并确认:

  • 预设生成的完整原生模型配置可被 Pi 加载。
  • Pi 对字符串、null、缺少键和 {} 的档位处理符合原生语义。
  • 需要特殊兼容字段的预设产生正确的真实请求。
  • 测试不修改用户实际的 auth.json、默认供应商或默认模型。

面向自定义供应商的模型数据库留待后续独立设计,不在本版本中提前保留运行时索引、网络回退或来源状态。


Guides Aggregation Mode Guide Zh (`docs/guides/aggregation-mode-guide-zh.md`)

CC Switch 聚合模式使用指南

用 Claude Code 或 Codex 写代码时,你可能不只使用一家供应商:有自己常用的模型,也有想试试的新模型;有官方订阅,也有另外购买的 API 或编程套餐。

过去,想换一家供应商,通常要先回到 CC Switch 主界面或者托盘切换,再返回客户端继续工作。CC Switch 4.0 新增的聚合模式,让这件事可以直接在客户端里完成:把多家供应商的模型放进同一个模型列表,在应用内无感切换,选哪个模型,请求就发给对应的供应商。

目前,聚合模式支持 Claude Code 和 Codex。这篇文章就从实际效果开始,带你完成配置,并讲清默认供应商、重启和日常切换的区别。

在 Codex 里直接选择多家模型

先看开启聚合后的 Codex 桌面版。

原有的 GPT 模型与来自其他供应商的 Grok、Kimi、DeepSeek 等模型,出现在了同一个列表中。第三方模型名称后面标有供应商,方便辨认具体来源。截图中选中的是 Kimi K3(Kimi For Coding),接下来的请求就会发给配置的 Kimi For Coding 供应商。

模型名称与可选范围取决于你自己的配置,截图展示的是一组使用示例。即便两家供应商提供同名模型,你也可以根据条目中的供应商名称,选择想使用的那一条线路。

你可以在一个会话中先讨论方案,再换一个模型继续实现或检查代码,不必为了更换供应商重新开始一段对话。配置完成之后,日常选模型就在客户端里进行。

聚合模式怎样分发请求

聚合模式做了两件事:先把各家的模型整理到客户端的模型列表里,再根据你选中的条目,把请求发给对应供应商。

例如,你选择 Kimi For Coding 提供的模型,CC Switch 就使用这家供应商的连接配置转发请求;换成 DeepSeek 提供的模型,后续请求就交给 DeepSeek。每次请求按所选条目发送,加入多家供应商不会让它们同时回答同一个问题。

有时你会看到带 ccs- 前缀的模型 ID。这是 CC Switch 用来识别供应商和模型的标记,直接在模型列表里选择即可,不需要手动编写。

在 CC Switch 中完成配置

下面以 Codex 为例。Claude Code 的入口和操作方式相同,但两个应用的聚合名单需要分别配置。

截图顶部显示“聚合生效中”,默认供应商是 OpenAI Official,另外添加了 6 家供应商、共 13 个模型。每张卡片旁边也标出了这家供应商配置的模型数量。

第一步 进入聚合页面

在 CC Switch 左侧选择 Codex,然后点击顶部的「聚合」标签。

点标签只是切换正在查看的页面,不代表已经开启聚合。 是否真正生效,要看顶部的模式状态。

第二步 准备供应商和模型列表

如果还没有供应商,点击右上角「添加供应商」,按所选预设填写连接信息,例如 API 地址和密钥;需要登录或绑定账号的供应商,则完成对应的账号配置。已有供应商可以直接点击卡片上的编辑按钮。

在「聚合」页添加或编辑时,表单会集中展示连接信息和「模型列表」。最近的版本进一步强化了模型列表获取和模型信息补全,配置多家供应商时,可以省去不少逐个查找、复制和填写的工作。

一键获取:从供应商拉取模型列表

填好连接信息或完成账号配置后,点击「获取模型列表」,CC Switch 就会向供应商查询可用模型。新版适配了更多供应商的模型接口地址和返回格式,减少了因为接口差异而获取不到列表的情况。

获取成功后,可以搜索、勾选需要的模型,再点击「添加所选模型」批量加入。这一步决定哪些模型会出现在客户端的选择器里:你可以只留下常用的几个,不必把供应商返回的全部模型都加入聚合。

自动补全:选好模型后,补上它的能力信息

勾选需要的模型并加入列表后,CC Switch 会自动从 models.dev 拉取对应模型的资料,补全上下文窗口、思考等级等信息。以本文的 Codex 配置为例,还会根据可用资料补充文字、图片输入能力。选好模型后,这些信息会自动填入空缺的配置项,省去逐项查资料、手动填写的工作。

补全会优先参考与当前供应商地址匹配的内置预设,再结合 models.dev 中的供应商和原厂模型资料。已有的参数会保留,自动补全只填写空缺项;补全后还会提示信息来源,方便核对。不同供应商部署同一模型时,实际支持的窗口和能力可能不同,因此仍应以当前供应商的支持情况为准。

手动添加:用于列表缺失或自定义模型

如果供应商没有开放模型列表接口,或列表里暂时没有你需要的模型,可以点击「手动添加」,填写供应商实际支持的模型 ID,再按需填写显示名称和能力参数。它适合补充自动获取未覆盖的条目,例如供应商提供的自定义模型别名。

这里配置的模型,是之后在客户端里可选的内容。无论自动获取还是手动添加,填写名称和参数都不会改变模型本身的能力。

列表中的 ★ 表示这家供应商的默认模型。在 Claude Code 中,它位于列表第一项;这家成为默认供应商后,启动默认和后台任务等默认角色会使用它。Codex 则使用配置中指定的默认模型。

第三步 把供应商加入聚合名单

在「可添加」区域找到需要的供应商,点击「添加」。添加后,它会进入聚合名单。

添加供应商配置与加入聚合名单是两件事。只是创建了一张供应商卡片,还需要把它加入当前应用的聚合名单。

第一次使用,可以先配好常用的两三家,确认模型能够正常调用,再逐步增加。

第四步 选择默认供应商并开启

点击「切换到聚合模式」,在确认框中选择默认供应商,检查将加入的供应商和模型数量,然后确认。

进入聚合时,CC Switch 会自动启动所需的本地路由服务。看到顶部显示“聚合生效中”,就表示模式已经开启。接下来按客户端要求重新加载模型列表,再选择模型开始使用。

默认供应商负责什么

默认供应商承接没有明确指定聚合供应商的普通模型请求。 你在客户端明确选中了某家聚合模型后,那次请求就会交给对应供应商处理。

如果你在 Codex 中使用官方账号,同时也想调用第三方模型,可以像截图一样,将 OpenAI Official 设为默认供应商,再添加其他供应商。官方模型和第三方模型就能在同一个选择器中使用。

Codex 的官方账号只能作为默认供应商,不能作为普通聚合成员加入。

开启聚合后,想更换默认供应商,可以在目标供应商卡片的「更多」菜单里选择「设为默认」。当前默认供应商不能直接移除,需要先把另一家设为默认。

官方订阅的支持范围与账号风险

Codex 本身支持自定义模型供应商,官方文档也提供了通过代理使用 OpenAI 认证的配置方式。CC Switch 因此支持将 OpenAI Official 设为默认供应商,让官方模型与第三方模型出现在同一个列表中。不过,支持这种接入方式,不等于可以承诺账号“零风险”,使用时仍需遵守平台规则。Codex 官方认证说明

Claude 官方订阅的情况不同。Anthropic 对第三方工具使用订阅凭据有明确限制,包括禁止第三方开发者代用户通过 Free、Pro 或 Max 订阅凭据转发请求,以及收集、存储或中介处理 Claude.ai 登录凭据。这与用户在原版 Claude Code 中正常登录自己的订阅是不同的情况。Claude Code 官方规定

考虑到许多 CC Switch 用户并不熟悉这些接入方式和规则差异,我们选择采取更保守的支持策略:聚合模式暂不支持 Claude 官方订阅。需要使用该订阅时,请回到直连模式,在 Claude Code 中通过官方登录流程使用。这个限制针对官方订阅接入,不代表 Claude Code 的聚合模式不能使用其他已支持的模型供应商。

在 Claude Code 中使用聚合模型

在 CC Switch 左侧选择 Claude Code,配置好它自己的供应商和聚合名单,然后开启聚合。在 Claude Code 中输入 /model,就能看到模型列表。

截图中的 Kimi、Grok、Claude 和 GPT 系列模型来自不同供应商。括号里显示供应商名称,右侧还展示模型 ID 和配置的上下文窗口。

选择所需条目后,就可以继续当前会话。模型的上下文窗口、图片输入和工具能力仍取决于实际模型及上游支持,不能只靠修改显示名称或窗口配置获得。

Claude Code 需要 2.1.243 或更新版本才能显示聚合模型。模型列表修改后可以立即生效,无需重启。CC Switch 改写客户端配置后,如果当前选中的是聚合模型,按提示重新选择一次即可。

Codex 需要怎样重启

Codex 在启动时读取模型列表。因此,进入或退出聚合模式、添加或移除供应商、修改模型列表后,需要重新加载。CC Switch 页面里的黄色提示,就是在提醒客户端还在使用旧列表。

使用方式 操作方法
Codex 桌面版 彻底退出后重新打开。macOS 按 ⌘Q,只关窗口不够。
Codex CLI 按 CC Switch 提示重启 Codex 守护进程,再重新打开 Codex。仅重开命令行客户端可能仍使用旧列表。
编辑器插件 重开编辑器窗口。

所有终端中的 Codex CLI 共用守护进程,重启会中断相关的运行中任务,操作前先等任务结束。

重新加载针对的是配置或模型列表发生变化。 在已经加载好的模型列表里选择另一个模型,不需要每次重启。

聚合和路由怎么选

CC Switch 的三种模式,适合不同的使用习惯。

模式 请求如何发送 适合的需求
直连 客户端直接连接供应商 使用一家供应商,按需在 CC Switch 切换。
路由 经过 CC Switch 本地转发,可配置故障转移 需要接口转换,或者故障后自动换供应商。
聚合 经过 CC Switch 本地转发,按所选模型发送给对应供应商 希望在客户端里随时选择多家模型。

聚合模式不做故障转移。 选中的供应商不可用时,需要手动选择其他可用模型。原有故障转移队列和设置会保留,回到路由模式后可以继续使用。

聚合也不会自动比较价格、挑选最快的模型。它把选择放到你手里:用哪一个模型、走哪一家供应商,由你在客户端决定。

日常使用的几个细节

使用期间保持 CC Switch 运行。 聚合请求需要经过本地服务转发。正常退出 CC Switch 时会自动恢复直连配置,下次启动再接上;之后按页面提示处理客户端刷新。

切换模型后的第一轮,费用可能更高。 在同一会话里换模型,新模型可能需要重新建立提示词缓存。历史对话越长,重新处理上下文的成本越值得留意,缓存通常不能在不同供应商之间直接共享。

模型选中后仍可能受到能力差异影响。 CC Switch 会按配置进行必要的接口转换,但不同模型在图片、推理等级、联网搜索等方面的支持并不完全相同。选择模型时,还要考虑正在进行的任务需要哪些能力。

移除供应商后,记得重新选模型。 如果客户端还保留着已移除供应商的旧聚合选项,请求会报错并提示重新选择,不会自动改发给另一家。切回路由模式后,聚合模型会从列表撤下,聚合名单则会保留。

配置好聚合后,你可以让常用模型保持默认,把其他模型留在选择器中,需要时再切换。在熟悉的 Claude Code 或 Codex 会话里,就能完成从选模型到继续工作的整个过程。

Codex 子 agent 读不到任务怎么办

在 Codex 聚合模式里,主 agent 和子 agent 可以选不同供应商的模型。这个开关现在默认打开;如果你把它关了,子 agent 一启动就可能报错,常见的提示有:

  • Encrypted function output content could not be decrypted
  • stream disconnected before completion
  • CC Switch 返回的 unreadable_encrypted_agent_task,提示里会直接指向下面这个开关

原因在 Codex 新版的子 agent 机制。 主 agent 派任务时,任务内容由主 agent 所在的供应商加密,只有这一家能解开。这好比一封只有寄件方能拆的密封信:子 agent 用的是同一家时能读,换成另一家就拆不开,等于没拿到任务。OpenAI 官方加密的任务,别家同样读不了。

解决方法: 在 CC Switch 的 Codex 聚合页签右上角点齿轮,打开「聚合设置」,把「聚合模式下子 agent 用经典工具」重新打开,然后重启 Codex(重启方法见上文“Codex 需要怎样重启”)。打开后,聚合里的所有模型改用 Codex 经典的子 agent 工具,任务以明文传递,换哪一家都能读。

关于这个开关需要知道几点:

  • 有代价。 经典工具没有 followup_task、interrupt_agent 等新版功能,所以只有主、子 agent 始终在同一家时才可以关掉;这个开关默认打开。
  • 只影响聚合模式。 直连和路由模式下 Codex 的行为不变。
  • 开了仍报错,先查 config.toml。 如果 ~/.codex/config.toml 的 [features] 里有 multi_agent_v2 = true,它的优先级高于这个开关,开关不会生效,「聚合设置」里也会给出提示。删掉这一项后再重启 Codex。

想要新版功能而关掉开关时,就得让子 agent 使用和主 agent 同一家供应商的模型,这样任务才能正常解开。

想固定让子 agent 用另一个模型? 切换到聚合模式的确认框里、以及同一个「聚合设置」里,都有「子代理模型」和「子代理推理强度」:比如主 agent 用 GPT 做规划和审核,子 agent 固定用 DeepSeek 去搜代码、改代码。选好后 CC Switch 写进 config.toml 的 [agents],不用重启 Codex,新开的对话就会用上(已经开着的对话仍按原设置)。这时子 agent 和主 agent 不在同一家,经典子 agent 工具必须开着(默认就是开的)。所选模型如果被移出聚合,子 agent 会暂时跟随主模型,加回来后自动恢复。

官方额度用完后,第三方模型也发不出去怎么办

默认供应商是 OpenAI Official 时,官方的 5 小时额度一旦用完,Codex 可能会锁住发送键,或者把模型选择器收成只剩“Luna Reserve”一项。这时聚合里的第三方模型既选不了,也发不出去。

这是 Codex 客户端自己的限制。 2026 年 9 月起的新版 Codex 会自己向 OpenAI 查询账号额度,发现普通额度用完后,就在请求发出之前把模型换成 Luna Reserve(gpt-reserve),其他模型要等额度恢复才回来。这个判断只看当前配置是否使用官方登录,不管你选的是哪家模型;请求也根本到不了 CC Switch,所以 CC Switch 这一侧没办法放行。

绕开方法: 额度恢复前,暂时让第三方当默认供应商。

  1. 在 Codex 的聚合页,打开任意一家第三方供应商卡片的「更多」菜单,选择「设为默认」。
  2. 彻底重启 Codex(方法见上文“Codex 需要怎样重启”),然后新开一个会话。已经被切到 Luna Reserve 的会话,可能仍保留这个模型。
  3. 官方额度恢复后,再把 OpenAI Official 设回默认,并同样重启 Codex。

期间 OpenAI 官方模型不会出现在选择器里,设回默认后就会回来。它们本来就已经用完额度,所以这样换不会有额外损失。

这个办法依据 Codex 公开源码里的判断条件。如果按上面的步骤操作后仍然被锁,欢迎到 #7962 反馈。

不用聚合、直连第三方供应商时也可能遇到同样的情况。如果在「设置 → 应用配置 → Codex」里打开了「非接管切换时保留官方登录」,Codex 会继续按官方账号判断额度。关掉这个开关,重新切换一次供应商,再重启 Codex 即可;切回官方时,登录会自动恢复。

致敬 opencodex

CC Switch 的聚合模式大量学习和参考了 opencodex:通过供应商前缀区分模型,让多家模型同时出现在客户端的选择器里;让 Codex 在使用第三方模型时也能处理上下文压缩;检测后台服务是否仍在使用旧的模型列表,并提醒用户重启。这些设计都受益于 opencodex 的开源探索。

感谢作者 @lidge-jun 和贡献者们把这些成果分享出来,让其他开发者能够学习、借鉴,并继续改进用户体验。向他们的工作和开源精神致敬!

如果你希望在 Codex 或 Claude Code 中接入更多供应商和模型,也非常推荐了解和试用 opencodex。

相关文档


Guides Claude Codex Routing Guide En (`docs/guides/claude-codex-routing-guide-en.md`)

Using GPT Models in Claude Code with CC Switch

Applies to CC Switch 3.17.0 and later. (Both integration methods in this guide existed in earlier versions, but the gpt-5.6 preset and the client-identity fix landed in 3.17.0; on older versions, requesting new models like gpt-5.6-luna falsely returns 404.) This guide is compiled from the repository's documentation and code, and all sample data has been de-identified.

Why local routing is needed

Claude Code targets the Anthropic Messages protocol — that is, /v1/messages — whereas the upstreams for Codex-family models, whether the OpenAI Responses API exposed by a third-party gateway or the Codex service behind a ChatGPT subscription, all speak the Responses protocol. The two protocols use completely different request bodies, streaming events, and response structures, so putting such an endpoint directly into Claude Code's config leaves the upstream receiving a /v1/messages request it doesn't recognize — which can only fail.

CC Switch's approach is to keep Claude Code always connected to the local route and still sending requests as Anthropic Messages; once the route detects that the active provider is Responses-format, it converts the request into Responses for the upstream, then converts the response back into the Messages shape it returns to Claude Code — tool calls, images, PDFs, and thinking configuration are all within the conversion scope.

This guide covers both integration methods:

  • Method 1 (API Key): you have a gateway endpoint and key compatible with the OpenAI Responses API, and you want to run the GPT-family models behind it inside Claude Code.
  • Method 2 (ChatGPT subscription): you have a ChatGPT Plus/Pro subscription and use its quota directly by signing in through Codex OAuth — no API key needed at any point.

The chain has four main steps:

  1. When Claude Code is taken over, ANTHROPIC_BASE_URL in ~/.claude/settings.json is written as the local route address (default http://127.0.0.1:15721), the auth entry keeps only a placeholder, and real credentials never enter the live config.
  2. The provider's API Format is set to OpenAI Responses, telling the route that the real upstream speaks the Responses protocol.
  3. The route converts the /v1/messages request into a Responses request body for the upstream; Method 2 additionally carries the OAuth token and the official client identity to reach ChatGPT's Codex service.
  4. After the upstream responds, the route converts the Responses JSON/SSE back into the Messages shape Claude Code understands.

Prerequisites

  • CC Switch installed and able to start (3.17.0 or later; see the version note at the top for why).
  • Claude Code installed and run at least once.
  • For Method 1: a service endpoint compatible with the OpenAI Responses API and its API Key; follow the gateway's documentation for the endpoint and model names. Note it's the Responses API, not Chat Completions; a gateway that only offers the Chat format still works — see the API Format note in Step 1.
  • For Method 2: a ChatGPT Plus/Pro subscription account.

Step 1: Add a provider

Method 1: Third-party Responses gateway (API Key)

Open CC Switch, switch to the top-level Claude Code tab, click the plus button in the upper-right corner to add a provider, keep the default Custom Configuration, then fill in:

  • Provider Name: anything you like, e.g. GPT Gateway.
  • API Key: your gateway key. The real key is stored only in CC Switch and injected by the local route when forwarding.
  • API Endpoint: just the gateway's service root, e.g. https://gpt-gateway.example.com, without a trailing slash — the route sends requests to the gateway's Responses endpoint (/v1/responses) automatically. When the gateway path is unusual, turn on the Full URL toggle next to it and paste the complete endpoint verbatim.

Then expand Advanced Options:

  • API Format: change from the default Anthropic Messages (Native) to OpenAI Responses API (Requires routing). If the gateway only offers the Chat Completions protocol, choose OpenAI Chat Completions (Requires routing) here instead; every other step is identical.
  • Auth Field: keep the default ANTHROPIC_AUTH_TOKEN (Default); the route sends Authorization: Bearer <key> to the upstream — exactly the auth header an OpenAI-compatible gateway expects. Unless the gateway's documentation explicitly requires x-api-key, don't switch to ANTHROPIC_API_KEY; the wrong choice typically shows up as 401/403.
  • Model Mapping: map Claude Code's model roles to the real models the gateway recognizes. At minimum, fill in the Default fallback model (e.g. gpt-5.6, per the gateway's documentation) — if left empty, unmatched requests pass through to the upstream under the original Claude model name and error out, while roles you haven't configured individually fall back to it. For finer control, specify per row: put your main model in Sonnet/Opus, and a cheap, fast model in Haiku (Claude Code's background sub-tasks use this tier). The Display name only affects what shows in the /model menu; leave it empty to show the real model name directly.
  • Declare 1M: the 1M checkbox on each model-mapping row declares to Claude Code that the tier supports a 1M context. Check it only when the gateway truly serves that model with a window of one million tokens or more (e.g. a gateway offering gpt-5.6 at its API spec); otherwise long conversations will error out at the upstream's real ceiling.

After saving, a Needs Routing marker appears on the card — providers like this only work while local routing is running.

Method 2: ChatGPT subscription (Codex OAuth)

Again on the Claude Code tab, click the plus button and pick the Codex preset with the OpenAI icon from the preset list — it appearing under the Claude Code tab is not a mistake; this preset is built precisely for "using a ChatGPT subscription inside Claude Code":

  • No API Key and no address needed — requests always go to ChatGPT's Codex service, so the address field in the form needs no changes.
  • Click Sign in with ChatGPT. This is a device-code flow: CC Switch opens the browser automatically and copies the verification code to the clipboard; paste the code on the browser page to complete authorization, while the app shows Waiting for authorization....
  • After a successful sign-in, Auth status shows the signed-in account (email). Multiple accounts are supported: you can Add another account, Set as default, or pin a specific account to this provider; day-to-day management can also go through Settings → OAuth Authentication Center.
  • FAST mode: an optional toggle; when on, requests carry service_tier="priority" for lower latency but consume ChatGPT quota at a higher rate. Keep it off by default.
  • The model tiers are pre-filled: Sonnet/Opus map to gpt-5.6-sol, and Haiku maps to gpt-5.6-luna (used for background sub-tasks — faster and lighter on quota).

The login credentials are stored in ~/.cc-switch/codex_oauth_auth.json (not ~/.codex/), independent of the Codex CLI's own login; the token refreshes automatically before it expires.

Step 2: Enable local routing and take over Claude Code

Go to the Routing page in Settings, expand Local Routing, and complete two toggles:

  1. Turn on the Routing Master Switch to start the local service (the first time you enable it, an explanatory confirmation dialog appears). The default address is 127.0.0.1:15721.
  2. Turn on Claude Code under Routing Enabled. If you only want Claude Code to use routing, leave the other apps off.

After takeover, CC Switch points Claude Code's live config at the local route, with only a placeholder in the auth entry; both Method 1's gateway key and Method 2's OAuth token are injected by the local route on forward.

Note: the live config is read when the Claude Code process starts. After you first enable takeover (or disable it to restore a direct connection), if Claude Code is already running, open a new terminal session. Afterward, switching providers in routing mode is a hot switch and needs no further restart.

Step 3: Switch providers and verify

Return to the Claude Code provider list and click Enable on the target provider. If routing isn't running, CC Switch shows "This provider uses OpenAI Responses API format, requires the routing service to work properly. Start routing first." — this notice doesn't block the switch, but with routing off the request is bound to fail, so go back to Step 2 and turn it on.

Inside Claude Code you can verify step by step:

  • Open a new session and use /model to view the model menu: each tier shows the display name from the model mapping (by default, Method 2 shows gpt-5.6-sol and gpt-5.6-luna). A few spots in the UI may still show Claude-family model names — those are the internal role aliases the routing takeover uses; this is normal, and the /model menu and usage dashboard are authoritative.
  • Send a small question and watch the Current Provider on the Settings → Routing page change to your provider and Total Requests start to climb.
  • In the usage dashboard, these requests show under the upstream's real models: gpt-5.6-sol displays as GPT-5.6 Sol (a plain gpt-5.6 without a suffix, if you enter it manually, also resolves to the Sol tier), while gpt-5.6-luna displays as GPT-5.6 Luna; you can filter by provider to reconcile token usage.
  • The Method 2 provider card also shows subscription quota: utilization and reset countdowns for the 5-hour and 7-day windows, drawn from the ChatGPT account itself and shared with the official Codex client.

Capabilities and known limitations

  • Prompt caching is automatic: the route injects a stable prompt_cache_key per session, and together with OpenAI's automatic prefix caching, long conversations don't resend everything at full price each turn — no configuration needed.
  • Thinking is mapped to reasoning effort: Claude Code's thinking toggle and thinking level are mapped to GPT's reasoning.effort (low/medium/high); GPT's reasoning content round-trips across turns intact in encrypted form, so multi-turn reasoning coherence is unaffected by the conversion. Method 2 also accesses in stateless mode (store:false), leaving no conversation stored on OpenAI's servers.
  • Tools and multimodal are fully converted: multi-turn tool calls, image inputs, and PDF inputs are all fully converted.
  • Context is managed against a 200K window: Claude Code auto-compacts routed providers against a default 200K window. When the upstream's real window is larger (e.g. gpt-5.6 on ChatGPT's Codex service is 372K), anything beyond 200K currently goes unused — compaction triggers early, which is conservative but safe. The only switch to push past 200K today is the 1M checkbox in the model mapping (a strict 1M declaration), for use only with Method 1 and only when the upstream truly serves the model at 1M or more; Method 2's upstream ceiling is 372K, short of 1M, so checking it would instead make long conversations error out at the upstream's real ceiling — keep it at the default.
  • Output ceiling: for Method 2, the output ceiling is controlled by the ChatGPT server (the max_tokens in Claude Code's request is not sent downstream); for Method 1, Claude Code's max_tokens is passed through as-is — no configuration needed.
  • Built-in web search depends on upstream support: the router translates Claude Code's hosted WebSearch tool into the Responses API hosted web_search tool. It works with Codex OAuth and compatible Responses gateways that implement that tool. allowed_domains is preserved. On API-key Responses routes, max_uses maps to the upstream max_tool_calls hard limit. The Codex OAuth request contract rejects that field, so the bridge uses a local response-side limit instead: it adds the limit to the model instructions and, when it observes an extra search call, stops the upstream stream and returns max_uses_exceeded, whether or not the request forces the hosted tool. This cuts off the entire response, including later text and function calls; if another content block is incomplete, the stream fails with stream_truncated rather than returning a partial tool call. This is not a server-enforced quota: excess searches may already have executed upstream before the proxy sees their events. Because Responses has no equivalent deny-list, a request with a non-empty blocked_domains also fails explicitly. Locally executed WebFetch is unaffected.
  • Dashboard dollar amounts are for reference: token counts are accurate, but the dollar figures are estimates converted at public API prices — Method 2's subscription traffic is estimated at GPT-5.6's public price, and Method 1's third-party gateways bill at their own rates, so both may differ from what you're actually charged and serve only for comparison. For Method 2, treat the window utilization on the provider card as authoritative for quota consumption.

FAQ

The upstream returns 401 or 403 (Method 1)

First confirm the Auth Field in Advanced Options is the default ANTHROPIC_AUTH_TOKEN (Default) — switching to ANTHROPIC_API_KEY sends x-api-key, which the vast majority of OpenAI-compatible gateways don't accept. Then confirm the key itself is valid and has balance.

Requesting new models like gpt-5.6-luna returns 404 Model not found (Method 2)

Upgrade to CC Switch 3.17.0 or later. On older versions the client identity wasn't aligned with the official Codex client, so the ChatGPT server resolves new models to a nonexistent engine.

The switch didn't take effect, or the /model menu still shows old names

Both the model menu and the route address are read when Claude Code starts: after first enabling takeover you must open a new terminal session; switching between providers is a hot switch, but the display names in the menu only refresh in a new session.

Claude Code reports "Codex OAuth authentication failed", or the card shows "Session expired" (Method 2)

The login credentials have expired. Go back to the provider form or Settings → OAuth Authentication Center and run through Sign in with ChatGPT again; no command-line steps are needed.

The conversation auto-compacts partway through

See "Capabilities and known limitations": routed providers are managed against a 200K window, so the compaction threshold comes early — this is expected behavior.

Restoring the official Claude setup

Switch back to an official provider, or turn off the Claude Code routing toggle on the Routing page — CC Switch restores the pre-takeover live config, and the official login credentials are unaffected throughout. After restoring, you'll again need to open a new terminal session.

Should you enable FAST mode? (Method 2)

Leaving it off is fine. Turn it on only if you're especially latency-sensitive and willing to accept faster quota consumption; if the ChatGPT server rejects the parameter, turning the toggle off restores things.

Compliance note

Method 2 uses ChatGPT subscription quota outside the official Codex client, and this isn't a gray-area hack: Thibault Sottiaux (@thsottiaux), the OpenAI Codex lead, has publicly demonstrated and encouraged pointing Claude Code (the "orange crab", as he jokingly calls it) at GPT-5.6 Sol — using exactly a "local proxy + model alias" approach, the same category as Method 2 here. As the lead of the Codex product line, his active encouragement to use their own model inside a competitor's client shows that running GPT-family models in Claude Code on a subscription is a use the vendor welcomes and encourages people to try.

Two practical reminders are still worth noting: first, this traffic is counted against the same subscription quota as the official Codex client, so heavy use hits the cap sooner; second, CC Switch's authentication center keeps a compliance notice out of caution ("Use your other subscriptions in Claude Code — please be mindful of compliance risks."), and whether this fits the terms that apply to your account is for you to check. When using a third-party gateway in Method 1, separately read the target gateway's terms on billing, compliance, and data retention.

References


Guides Claude Codex Routing Guide Ja (`docs/guides/claude-codex-routing-guide-ja.md`)

CC Switch を使って Claude Code で GPT モデルを利用する

対象バージョン: CC Switch 3.17.0 以降(本記事の 2 つの接続方法自体はより古いバージョンにもありますが、gpt-5.6 プリセットとクライアントアイデンティティの修正は 3.17.0 から導入されたため、古いバージョンで gpt-5.6-luna のような新しいモデルをリクエストすると 404 が誤って返ることがあります)。本記事はリポジトリ内のドキュメントとコードをもとに整理し、サンプルデータはすべて匿名化しています。

ローカルルーティングが必要な理由

Claude Code が前提としているのは Anthropic Messages プロトコル、つまり /v1/messages です。一方で Codex 系モデルの上流——サードパーティゲートウェイが公開している OpenAI Responses API であれ、ChatGPT サブスクリプションの背後にある Codex サービスであれ——が話すのはすべて Responses プロトコルです。この 2 つのプロトコルは、リクエストボディ、ストリーミングイベント、レスポンス構造がまったく異なります。この種のアドレスをそのまま Claude Code の設定に入れても、上流が受け取るのは自分の知らない /v1/messages リクエストであり、結果は失敗にしかなりません。

CC Switch では、Claude Code が常にローカルルートへ接続し、Anthropic Messages のままリクエストを送るようにします。ルートは現在のプロバイダーが Responses 形式だと判定すると、リクエストを Responses に変換して上流へ送り、最後にレスポンスを Messages 形式へ戻して Claude Code に返します——ツール呼び出し、画像、PDF、思考設定もすべて変換の対象です。

対応する 2 つの接続方法を、本記事はどちらもカバーします:

  • 方式 1(API Key): OpenAI Responses API 互換のゲートウェイエンドポイントと Key を持っていて、その背後の GPT 系モデルを Claude Code で動かしたい場合。
  • 方式 2(ChatGPT サブスクリプション): ChatGPT Plus/Pro のサブスクリプションを持っていて、Codex OAuth ログインでサブスクリプション枠を直接使いたい場合。全工程で API Key は不要です。

この経路は主に 4 つのステップに分かれます:

  1. Claude Code を引き継ぐと、~/.claude/settings.json の ANTHROPIC_BASE_URL がローカルルートのアドレス(デフォルトは http://127.0.0.1:15721)に書き換えられ、認証項目にはプレースホルダーだけが残り、実際の認証情報は live 設定には入りません。
  2. プロバイダーの API フォーマット を OpenAI Responses に設定し、実際の上流は Responses プロトコルだとルートに伝えます。
  3. ルートは /v1/messages リクエストを Responses のリクエストボディへ変換して上流へ送ります。方式 2 ではさらに OAuth token と公式クライアントのアイデンティティを付けて ChatGPT の Codex サービスにアクセスします。
  4. 上流から返ってきた後、ルートは Responses の JSON/SSE を Claude Code が理解できる Messages 形式へ変換して返します。

事前準備

  • インストール済みで起動できる CC Switch(3.17.0 以降、理由は冒頭のバージョン説明を参照)。
  • インストール済みで、少なくとも 1 回は実行したことのある Claude Code。
  • 方式 1 に必要なもの: OpenAI Responses API 互換のサービスエンドポイントと対応する API Key。エンドポイントアドレスとモデル名はゲートウェイのドキュメントに従ってください。注意すべきは Responses API であって Chat Completions ではないという点です。ゲートウェイが Chat 形式しか提供していない場合でも動作します。Step 1 の「API フォーマット」の説明を参照してください。
  • 方式 2 に必要なもの: ChatGPT Plus/Pro のサブスクリプションアカウント。

Step 1: プロバイダーを追加する

方式 1: サードパーティ Responses ゲートウェイ(API Key)

CC Switch を開き、上部の Claude Code タブへ切り替え、右上のプラスボタンからプロバイダーを追加します。デフォルトの カスタム設定 のまま、次の項目を入力します:

  • プロバイダー名: 任意です。たとえば GPT Gateway。
  • API Key: あなたのゲートウェイの Key。実際の Key は CC Switch 内にのみ保存され、ローカルルートが転送時に注入します。
  • API エンドポイント: ゲートウェイのサービスルートアドレスを入力すれば十分です。たとえば https://gpt-gateway.example.com。末尾にスラッシュを付けないでください。ルートが自動的にそのゲートウェイの Responses エンドポイント(/v1/responses)へリクエストを送ります。ゲートウェイのパスが特殊な場合は、隣の フル URL スイッチをオンにして、完全なエンドポイントをそのまま貼り付けてください。

続いて 詳細オプション を展開します:

  • API フォーマット: デフォルトの Anthropic Messages(ネイティブ) から OpenAI Responses API(ルーティングが必要) に変更します。ゲートウェイが Chat Completions プロトコルしか提供していない場合は、ここで OpenAI Chat Completions(ルーティングが必要) を選びます。その他のステップはまったく同じです。
  • 認証フィールド: デフォルトの ANTHROPIC_AUTH_TOKEN(デフォルト) のままにします。ルートは Authorization: Bearer <key> を上流へ送ります——これはまさに OpenAI 互換ゲートウェイが期待する認証ヘッダーです。ゲートウェイのドキュメントが明確に x-api-key を要求している場合を除き、ANTHROPIC_API_KEY に変更しないでください。誤って変更した場合の典型的な症状は 401/403 です。
  • モデルマッピング: Claude Code のモデル役割を、ゲートウェイが認識する実際のモデルへマッピングします。少なくとも 既定フォールバックモデル は入力してください(たとえば gpt-5.6。ゲートウェイのドキュメントに従ってください)——空欄のままだと、一致しなかったリクエストは元の Claude モデル名のまま上流へ転送されてエラーになります。個別に設定していない役割はこのフォールバックへ回帰します。より細かく設定するには、行ごとに指定します:Sonnet/Opus に主力モデル、Haiku に安価で高速なモデル(Claude Code のバックグラウンド小タスクがこの区分を使います)。表示名 は /model メニューでの表示にのみ影響し、空欄なら実際のモデル名がそのまま表示されます。
  • 1M 対応を宣言: モデルマッピングの各行にある 1M チェックボックスは、その区分が 1M コンテキストに対応していることを Claude Code に宣言します。ゲートウェイが実際に 100 万トークン以上のウィンドウでそのモデルを提供している場合(たとえば API 仕様どおりに gpt-5.6 を提供するゲートウェイ)にのみチェックしてください。そうでないと、長い対話が上流の実際の上限で直接エラーになります。

保存すると、カードに ルーティングが必要 のマークが表示されます——この種のプロバイダーは、ローカルルーティングが実行中でなければ正しく動作しません。

方式 2: ChatGPT サブスクリプション(Codex OAuth)

同じく Claude Code タブでプラスボタンを押し、プリセット一覧で OpenAI アイコンの付いた Codex プリセットを選びます——これが Claude Code タブの下に出ていても選択ミスではありません。このプリセットはまさに「Claude Code で ChatGPT サブスクリプションを使う」ために用意されたものです:

  • API Key もアドレスの入力も不要です——リクエストは常に ChatGPT の Codex サービスへ送られるため、フォームのアドレス項目は変更する必要がありません。
  • ChatGPT でログイン をクリックします。これはデバイスコードフローです:CC Switch が自動的にブラウザを開き、認証コードをクリップボードにコピーします。ブラウザのページで認証コードを貼り付けて認可を完了させてください。その間、アプリ内には 認証を待機中... と表示されます。
  • ログインに成功すると、認証状態 にログイン済みアカウント(メールアドレス)が表示されます。複数アカウントに対応しています:別のアカウントを追加、デフォルトに設定、またはこのプロバイダーで特定のアカウントを指定できます。日常的な管理は 設定 → OAuth 認証センター からも行えます。
  • FAST モード: 任意のスイッチです。オンにするとリクエストが service_tier="priority" を伴い、より低い遅延と引き換えに、より高いレートで ChatGPT のクォータを消費します。デフォルトはオフのままにしてください。
  • モデル区分はあらかじめ入力済みです:Sonnet/Opus が gpt-5.6-sol に、Haiku が gpt-5.6-luna に対応します(バックグラウンドの小タスクがこれを使い、より速く、より枠を節約します)。

ログイン認証情報は ~/.cc-switch/codex_oauth_auth.json(~/.codex/ ではありません)に保存され、Codex CLI 自身のログインとは互いに影響しません。token は有効期限前に自動的に更新されます。

Step 2: ローカルルーティングを有効にして Claude Code をルーティングする

設定の ルーティング ページに入り、ローカルルーティング を展開して、2 つのスイッチを設定します:

  1. ルーティング総スイッチ をオンにしてローカルサービスを起動します(初回起動時は説明の確認ダイアログが表示されます)。デフォルトアドレスは 127.0.0.1:15721 です。
  2. ルーティング有効 で Claude Code をオンにします。Claude Code だけをルーティングしたい場合は、その他のアプリはオフのままで構いません。

引き継ぎ後、CC Switch は Claude Code の live 設定をローカルルートへ向け、認証項目にはプレースホルダーだけが入ります。方式 1 のゲートウェイ Key も方式 2 の OAuth token も、いずれもローカルルートが転送時に注入します。

注意: live 設定は Claude Code プロセスの起動時に読み込まれます。初回の引き継ぎを有効にした後(または引き継ぎをオフにして直結に戻した後)、Claude Code が実行中の場合は、ターミナルセッションを開き直してください。その後、ルーティングモードでのプロバイダー切り替えはホットスワップになり、再起動は不要です。

Step 3: プロバイダーを切り替えて確認する

Claude Code のプロバイダー一覧に戻り、目的のプロバイダーの 有効化 をクリックします。ルーティングが実行されていない場合、CC Switch は「このプロバイダーは OpenAI Responses API フォーマットを使用しており、ルーティングサービスが必要です。先にルーティングを起動してください」と表示します——この表示は切り替えを妨げませんが、ルーティングが未起動のままではリクエストは必ず失敗します。Step 2 に戻ってオンにすれば解決します。

Claude Code に入ったら、段階的に確認できます:

  • 新しいセッションを開き、/model でモデルメニューを確認します:各区分にはモデルマッピングの表示名が表示されます(方式 2 のデフォルトは gpt-5.6-sol、gpt-5.6-luna)。画面の一部の箇所には Claude 系のモデル名が現れることがあります——それはルーティング引き継ぎが使う内部の役割エイリアスであり、正常な現象です。/model メニューと使用量ダッシュボードを基準にしてください。
  • 小さな質問を 1 つ送り、設定 → ルーティングページの「現在のプロバイダー」があなたのプロバイダーに変わり、「総リクエスト数」が増え始めるのを確認します。
  • 使用量ダッシュボードでは、これらのリクエストが上流の実際のモデルで表示されます:gpt-5.6-sol は GPT-5.6 Sol と表示され(サフィックスなしの gpt-5.6 を手動で入力した場合も Sol 区分として解析されます)、gpt-5.6-luna は GPT-5.6 Luna と表示されます。プロバイダーで絞り込んで token 使用量を照合できます。
  • 方式 2 のプロバイダーカードには、さらにサブスクリプション枠が表示されます:5 時間ウィンドウと 7 日ウィンドウの利用率とリセットまでのカウントダウンです。データは ChatGPT アカウント自体から取得され、公式 Codex クライアントと同じ枠を共有します。

機能の範囲と既知の制限

  • プロンプトキャッシュが自動で有効: ルートは各セッションに安定した prompt_cache_key を注入し、OpenAI 側の自動プレフィックスキャッシュと組み合わせます。長い対話でも毎回全額で再送されることはなく、設定は不要です。
  • 思考を reasoning effort に換算: Claude Code の思考スイッチと思考レベルは GPT の reasoning.effort(low/medium/high)へ換算されます。GPT の推論内容は暗号化された形態でターンをまたいで完全に再生され、複数ターンの推論の一貫性は変換の影響を受けません。方式 2 は同時にステルスモード(store:false)でアクセスし、OpenAI サーバー側にはセッションを残しません。
  • ツールとマルチモーダルを完全変換: 複数ターンのツール呼び出し、画像、PDF 入力はすべて完全に変換されます。
  • コンテキストは 200K ウィンドウで管理: Claude Code はルーティングプロバイダーに対して、デフォルトの 200K ウィンドウで自動圧縮を行います。上流の実際のウィンドウがより大きい場合(たとえば ChatGPT Codex サービスの gpt-5.6 は 372K)でも、200K を超える部分は現状では使われません——圧縮が早めにトリガーされ、保守的ですが安全です。200K を突破したい場合、現在唯一のスイッチはモデルマッピングの 1M チェックボックス(厳密に 1M を宣言)で、方式 1 に限り、かつ上流が実際に 1M 以上でそのモデルを提供している場合にのみ使用します。方式 2 の上流上限は 372K で 1M には届かないため、チェックするとかえって長い対話が上流の実際の上限でエラーになります。デフォルトのままにしてください。
  • 出力上限: 方式 2 の出力上限は ChatGPT サーバー側が制御します(Claude Code のリクエスト内の max_tokens は下流に送られません)。方式 1 は Claude Code の max_tokens をそのまま透過するため、設定は不要です。
  • 組み込み Web 検索は上流の対応状況に依存: ルーターは Claude Code のホスト型 WebSearch ツールを Responses API のホスト型 web_search ツールへ変換します。このツールを実装する Codex OAuth および互換 Responses ゲートウェイで利用できます。allowed_domains は維持されます。API キーを使う Responses ルートでは、max_uses を上流の max_tool_calls ハード上限へ変換します。Codex OAuth のリクエスト仕様はこのフィールドを拒否するため、ブリッジはレスポンス側で制限します。上限をモデル指示へ追加し、超過検索を観測した時点で上流ストリームを停止して max_uses_exceeded を返します。ツールを強制するかどうかに関係なく適用されます。後続のテキストや関数呼び出しを含むレスポンス全体が打ち切られ、別のコンテンツブロックが未完了なら、不完全なツール呼び出しを返さず stream_truncated エラーにします。これはサーバー側のハード上限ではありません。プロキシがイベントを受信する前に、超過検索が上流で実行済みの場合があります。Responses には同等の拒否リストもないため、空でない blocked_domains を含むリクエストも明示的に失敗します。ローカルで実行される WebFetch は影響を受けません。
  • 使用量ダッシュボードの金額は参考値: token カウントは正確ですが、ドル金額は公開 API 価格に基づく概算です——方式 2 のサブスクリプショントラフィックは GPT-5.6 の公開価格で換算され、方式 1 のサードパーティゲートウェイはそれぞれのレートで課金されます。どちらも実際の請求額と一致しない可能性があり、比較用途に留めてください。方式 2 の枠の消費は、プロバイダーカード上のウィンドウ利用率を基準にしてください。

よくある質問

上流が 401 または 403 を返す(方式 1)

まず詳細オプションの 認証フィールド がデフォルトの ANTHROPIC_AUTH_TOKEN(デフォルト) になっているか確認してください——ANTHROPIC_API_KEY に変更すると x-api-key で送信され、大多数の OpenAI 互換ゲートウェイはこれを受け付けません。あわせて、Key 自体が有効で残高があることも確認してください。

gpt-5.6-luna などの新しいモデルをリクエストすると 404 Model not found が出る(方式 2)

CC Switch 3.17.0 以降にアップグレードしてください。古いバージョンではクライアントアイデンティティが公式 Codex クライアントに揃っておらず、ChatGPT サーバー側が新しいモデルを存在しないエンジンへ解決してしまいます。

切り替えても反映されない、または /model メニューが古い名前のまま

モデルメニューもルーティングアドレスも、Claude Code の起動時に読み込まれます:初回の引き継ぎを有効にした後は必ずターミナルセッションを開き直してください。プロバイダー間の切り替えはホットスワップですが、メニューの表示名は新しいセッションでなければ更新されません。

Claude Code に「Codex OAuth 認証に失敗しました」と出る、またはカードに「セッションが期限切れです」と表示される(方式 2)

ログイン認証情報が失効しています。プロバイダーフォーム、または 設定 → OAuth 認証センター に戻り、ChatGPT でログイン をもう一度実行してください。コマンドライン操作は一切不要です。

対話の途中で自動的に圧縮されてしまう

「機能の範囲」を参照してください:ルーティングプロバイダーは 200K ウィンドウで管理され、圧縮のしきい値もそれに合わせて早まります。想定どおりの動作です。

公式の Claude の使い方に戻したい

公式プロバイダーに切り替えるか、ルーティングページで Claude Code のルーティングスイッチをオフにしてください——CC Switch は引き継ぎ前の live 設定に戻し、公式ログインの認証情報は全工程を通じて影響を受けません。戻した後も同様にターミナルセッションを開き直す必要があります。

FAST モードをオンにすべきか(方式 2)

デフォルトのオフのままで構いません。遅延に特に敏感で、かつクォータのより速い消費を受け入れられる場合にのみオンにしてください。ChatGPT サーバー側がこのパラメータを拒否する場合は、スイッチをオフにすれば復旧します。

コンプライアンスに関する注意

方式 2 は ChatGPT サブスクリプション枠を公式 Codex クライアント以外で使うものですが、これはグレーな手法ではありません:OpenAI Codex の責任者である Thibault Sottiaux(@thsottiaux)自身が、Claude Code(彼が「orange crab」と呼ぶもの)を GPT-5.6 Sol に向けて使うことを公開でデモし、推奨しています——用いているのはまさに「ローカルプロキシ + モデルエイリアス」であり、本記事の方式 2 と同じ類の手法です。Codex という製品ラインの責任者が、競合クライアントで自社モデルを使うことを自ら奨励しているのですから、サブスクリプションで Claude Code に GPT 系モデルを動かすことは、公式が歓迎し、試すことを推奨している使い方だと分かります。

とはいえ、実務上の 2 点は依然として留意する価値があります:1 つは、この部分のトラフィックが公式 Codex クライアントと同じサブスクリプション枠に合算されるため、ヘビーユースではより速く上限に達すること。もう 1 つは、CC Switch の認証センターが念のためコンプライアンス上の注意(「Claude Code で他のサブスクリプションをご利用いただけます。コンプライアンスリスクにご注意ください。」)を残していることです。あなたのアカウントに適用される規約に沿うかどうかは、各自でご確認ください。方式 1 でサードパーティゲートウェイを使う場合は、対象ゲートウェイの課金・コンプライアンス・データ保持に関する規約を別途お読みください。

参考リンク


Guides Claude Codex Routing Guide Zh (`docs/guides/claude-codex-routing-guide-zh.md`)

通过 CC Switch 在 Claude Code 中使用 GPT 模型

适用版本:CC Switch 3.17.0 及以上(更早版本已具备本文两种接入方式,但 gpt-5.6 预设与客户端身份修复自 3.17.0 落地,低版本请求 gpt-5.6-luna 这类新模型会误报 404)。本文根据仓库内文档与代码整理,示例数据均已去敏。

为什么需要本地路由

Claude Code 面向的是 Anthropic Messages 协议,也就是 /v1/messages;而 Codex 系模型的上游——无论是第三方网关暴露的 OpenAI Responses API,还是 ChatGPT 订阅背后的 Codex 服务——说的都是 Responses 协议。两种协议的请求体、流式事件和返回结构完全不同,把这类地址直接填进 Claude Code 的配置里,上游收到的是它不认识的 /v1/messages 请求,结果只能是失败。

CC Switch 的做法是让 Claude Code 始终连本机路由,仍以 Anthropic Messages 发送请求;路由识别当前供应商是 Responses 格式后,把请求转换成 Responses 发给上游,再把响应转换回 Messages 形态返回给 Claude Code——工具调用、图片、PDF、思考配置都在转换范围内。

对应两种接入方式,本文都会覆盖:

  • 方式一(API Key):你手里有某个兼容 OpenAI Responses API 的网关端点和 Key,想在 Claude Code 里跑它背后的 GPT 系模型。
  • 方式二(ChatGPT 订阅):你有 ChatGPT Plus/Pro 订阅,通过 Codex OAuth 登录直接使用订阅额度,全程不需要 API Key。

这条链路主要分成四步:

  1. 接管 Claude Code 后,~/.claude/settings.json 里的 ANTHROPIC_BASE_URL 会被写成本机路由地址(默认 http://127.0.0.1:15721),认证项只留占位符,真实凭据不进 live 配置。
  2. 供应商的 API 格式 设为 OpenAI Responses,告诉路由:真实上游说的是 Responses 协议。
  3. 路由把 /v1/messages 请求转换成 Responses 请求体发给上游;方式二还会带上 OAuth token 与官方客户端身份访问 ChatGPT 的 Codex 服务。
  4. 上游返回后,路由再把 Responses 的 JSON/SSE 转回 Claude Code 能理解的 Messages 形态。

准备工作

  • 已安装并能启动的 CC Switch(3.17.0 及以上,原因见开头的版本说明)。
  • 已安装 Claude Code,并至少运行过一次。
  • 方式一需要:一个兼容 OpenAI Responses API 的服务端点和对应的 API Key,端点地址与模型名以网关文档为准。注意是 Responses API,不是 Chat Completions;网关只提供 Chat 格式时也能走通,见第一步「API 格式」处的说明。
  • 方式二需要:一个 ChatGPT Plus/Pro 订阅账号。

第一步:添加供应商

方式一:第三方 Responses 网关(API Key)

打开 CC Switch,切到顶部的 Claude Code 标签,点击右上角加号添加供应商,保持默认的 自定义配置,然后填写:

  • 供应商名称:随意,例如 GPT Gateway。
  • API Key:你的网关 Key。真实 Key 只保存在 CC Switch 里,由本地路由转发时注入。
  • 请求地址:填网关服务根地址即可,例如 https://gpt-gateway.example.com,不要以斜杠结尾,路由会自动把请求打到该网关的 Responses 端点(/v1/responses)。网关路径特殊时,打开旁边的 完整 URL 开关原样粘贴完整端点。

然后展开 高级选项:

  • API 格式:从默认的 Anthropic Messages (原生) 改成 OpenAI Responses API (需开启路由)。如果网关只提供 Chat Completions 协议,这里改选 OpenAI Chat Completions (需开启路由),其余步骤完全相同。
  • 认证字段:保持默认的 ANTHROPIC_AUTH_TOKEN(默认),路由会以 Authorization: Bearer <key> 发给上游——这正是 OpenAI 兼容网关期望的认证头。除非网关文档明确要求 x-api-key,否则不要改成 ANTHROPIC_API_KEY,改错的典型表现是 401/403。
  • 模型映射:把 Claude Code 的模型角色映射到网关认识的真实模型。至少要填 默认兜底模型(例如 gpt-5.6,以网关文档为准)——留空时未匹配的请求会以原始 Claude 模型名透传给上游而报错,未单独配置的角色则会回落到它。更精细的做法是按行指定:Sonnet/Opus 填主力模型,Haiku 填一个便宜快速的模型(Claude Code 的后台小任务走这一档)。显示名称 只影响 /model 菜单里的展示,留空则直接显示真实模型名。
  • 声明支持 1M:模型映射每行的 1M 复选框会向 Claude Code 声明该档支持 1M 上下文。仅当网关确实以 100 万 token 及以上的窗口服务该模型时才勾选(例如按 API 规格提供 gpt-5.6 的网关),否则长对话会在上游真实上限处直接报错。

保存后,卡片上会出现 需要路由 标记——这类供应商必须在本地路由运行时才能正常工作。

方式二:ChatGPT 订阅(Codex OAuth)

同样在 Claude Code 标签点加号,在预设列表里选择带 OpenAI 图标的 Codex 预设——它出现在 Claude Code 标签下没有选错,这个预设就是为「在 Claude Code 里用 ChatGPT 订阅」准备的:

  • 不需要 API Key,也不需要填地址——请求固定发往 ChatGPT 的 Codex 服务,表单里的地址项无需改动。
  • 点击 使用 ChatGPT 登录。这是设备码流程:CC Switch 会自动打开浏览器并把验证码复制到剪贴板,在浏览器页面粘贴验证码完成授权即可,期间应用内显示 等待授权中...。
  • 登录成功后,认证状态 显示已登录账号(邮箱)。支持多账号:可 添加其他账号、设为默认,或在这个供应商上指定使用某个账号;日常管理也可以走 设置 → OAuth 认证中心。
  • FAST 模式:可选开关,开启后请求携带 service_tier="priority" 换取更低延迟,但会按更高速率消耗 ChatGPT 配额,默认保持关闭。
  • 模型档位已预填好:Sonnet/Opus 对应 gpt-5.6-sol,Haiku 对应 gpt-5.6-luna(后台小任务走它,更快更省额度)。

登录凭据保存在 ~/.cc-switch/codex_oauth_auth.json(不是 ~/.codex/),与 Codex CLI 自己的登录互不影响;token 会在到期前自动刷新。

第二步:开启本地路由并接管 Claude Code

进入设置里的 路由 页面,展开 本地路由,完成两个开关:

  1. 打开 路由总开关,启动本地服务(首次开启会弹出说明确认框)。默认地址是 127.0.0.1:15721。
  2. 在 路由启用 中打开 Claude Code。只想让 Claude Code 走路由的话,其余应用保持关闭。

接管后,CC Switch 会把 Claude Code 的 live 配置指向本机路由,认证项只有占位符;方式一的网关 Key 和方式二的 OAuth token 都由本地路由在转发时注入。

注意:live 配置是 Claude Code 进程启动时读取的。首次开启接管(或关闭接管恢复直连)后,如果 Claude Code 正在运行,请重开一个终端会话。之后在路由模式下切换供应商就是热切换,无需再重启。

第三步:切换供应商并验证

回到 Claude Code 供应商列表,点击目标供应商的 启用。如果路由没有在运行,CC Switch 会提示「此供应商使用 OpenAI Responses 接口格式,需要路由服务才能正常使用,请先启动路由」——这个提示不会拦截切换,但路由未开时请求必然失败,回到第二步打开即可。

进入 Claude Code 后可以逐级验证:

  • 新开会话,用 /model 查看模型菜单:各档显示的是模型映射里的显示名称(方式二默认即 gpt-5.6-sol、gpt-5.6-luna)。界面个别位置仍可能出现 Claude 系的模型字样——那是路由接管使用的内部角色别名,属正常现象,以 /model 菜单和用量看板为准。
  • 发一个小问题,观察设置 → 路由页面的「当前 Provider」变成你的供应商、「总请求数」开始增长。
  • 用量看板里,这些请求会按上游真实模型显示:gpt-5.6-sol 显示为 GPT-5.6 Sol(手动填不带后缀的 gpt-5.6 也会解析为 Sol 档),gpt-5.6-luna 显示为 GPT-5.6 Luna,可按供应商筛选核对 token 用量。
  • 方式二的供应商卡片还会显示订阅额度:5 小时与 7 天窗口的利用率和重置倒计时,数据来自 ChatGPT 账号本身,与官方 Codex 客户端共用同一份额度。

能力边界与已知限制

  • 提示缓存自动生效:路由会为每个会话注入稳定的 prompt_cache_key,配合 OpenAI 侧的自动前缀缓存,长对话不会每轮全价重发,无需任何配置。
  • 思考折算为 reasoning effort:Claude Code 的思考开关与思考等级会被折算成 GPT 的 reasoning.effort(low/medium/high);GPT 的推理内容以加密形态跨轮完整回放,多轮推理连贯性不受转换影响。方式二同时以无痕模式(store:false)访问,不在 OpenAI 服务端留存会话。
  • 工具与多模态完整转换:多轮工具调用、图片与 PDF 输入都被完整转换。
  • 上下文按 200K 窗口管理:Claude Code 对路由供应商按默认 200K 窗口做自动压缩。上游实际窗口更大时(如 ChatGPT Codex 服务的 gpt-5.6 为 372K),超出 200K 的部分当前不会被用到——压缩会提前触发,保守但安全。想突破 200K,目前唯一的开关是模型映射里的 1M 复选框(严格声明 1M),仅限方式一且上游真按 1M 及以上服务该模型时使用;方式二的上游上限是 372K、够不到 1M,勾选反而会让长对话在上游真实上限处报错,请维持默认。
  • 输出上限:方式二的输出上限由 ChatGPT 服务端控制(Claude Code 请求里的 max_tokens 不会下发);方式一则原样透传 Claude Code 的 max_tokens,无需配置。
  • 内置联网搜索取决于上游支持:路由会把 Claude Code 的托管 WebSearch 工具转换为 Responses API 的托管 web_search 工具,可用于 Codex OAuth 和实现该工具的兼容 Responses 网关。allowed_domains 会保留;在 API Key Responses 路由中,max_uses 会映射为上游的 max_tool_calls 硬限制。Codex OAuth 请求协议会拒绝该字段,因此桥接层采用本地响应侧限制:把上限写入模型指令,在观察到额外搜索调用时终止上游流,并返回 max_uses_exceeded,无论请求是否强制使用托管搜索都同样生效。超限会截断整轮响应,包括后续文本和函数调用;如果还有未完成的内容块,则返回 stream_truncated 错误,避免交付残缺的工具调用。这并非服务端硬配额:代理收到事件前,额外搜索可能已经在上游执行。由于 Responses 没有等价的拒绝列表,带有非空 blocked_domains 的请求也会明确失败。本地执行的 WebFetch 不受影响。
  • 用量看板金额是参考值:token 计数准确,但美元金额是按公开 API 价折算的估算——方式二订阅流量按 GPT-5.6 公开价折算,方式一的第三方网关按各自费率计费,两者都可能与真实扣费不符,仅供对比。方式二的额度消耗以供应商卡片上的窗口利用率为准。

常见问题

上游返回 401 或 403(方式一)

先确认高级选项里的 认证字段 是默认的 ANTHROPIC_AUTH_TOKEN(默认)——改成 ANTHROPIC_API_KEY 会以 x-api-key 发送,绝大多数 OpenAI 兼容网关不接受。再确认 Key 本身有效、有余额。

请求 gpt-5.6-luna 等新模型报 404 Model not found(方式二)

升级到 CC Switch 3.17.0 及以上。旧版本的客户端身份未对齐官方 Codex 客户端,ChatGPT 服务端会把新模型解析到不存在的引擎。

切换后没生效,或 /model 菜单还是旧名字

模型菜单和路由地址都是 Claude Code 启动时读取的:首次开启接管后必须重开终端会话;供应商之间切换虽然是热切换,但菜单里的显示名称要新会话才刷新。

Claude Code 报「Codex OAuth 认证失败」或卡片显示「会话已过期」(方式二)

登录凭据已失效。回到供应商表单或 设置 → OAuth 认证中心,重新走一遍 使用 ChatGPT 登录 即可;无需运行任何命令行操作。

对话进行到一半就自动压缩了

见「能力边界」:路由供应商按 200K 窗口管理,压缩阈值随之提前,属预期行为。

想恢复官方 Claude 用法

切回官方供应商,或在路由页面关闭 Claude Code 的路由开关——CC Switch 会恢复接管前的 live 配置,官方登录凭据全程不受影响。恢复后同样需要重开终端会话。

FAST 模式要不要开(方式二)

默认关闭即可。只有当你对延迟特别敏感、且愿意接受配额更快消耗时再打开;如果 ChatGPT 服务端拒绝该参数,关掉开关即可恢复。

合规提示

方式二把 ChatGPT 订阅额度用在官方 Codex 客户端之外,这并不是灰色玩法:OpenAI Codex 负责人 Thibault Sottiaux(@thsottiaux)就公开演示并鼓励过把 Claude Code(他戏称的「orange crab」)指向 GPT-5.6 Sol 使用——用的正是「本地代理 + 模型别名」,和本文方式二属于同一类做法。作为 Codex 这条产品线的负责人,他主动鼓励大家在竞品客户端里用自家模型,可见用订阅在 Claude Code 里跑 GPT 系模型,是官方乐见并鼓励尝试的用法。

两点实务提醒仍值得留意:一是这部分流量与官方 Codex 客户端合并计入同一份订阅额度,重度使用会更快触顶;二是 CC Switch 认证中心出于稳妥保留了合规提示(「在 Claude Code 中使用您的其他订阅,请注意合规风险。」),是否符合你账号所适用的条款可自行留意。方式一使用第三方网关时,请另行阅读目标网关关于计费、合规与数据留存的条款。

参考链接


Guides Codex Claude Routing Guide En (`docs/guides/codex-claude-routing-guide-en.md`)

Using Claude Models in Codex with CC Switch

Applies to CC Switch 3.17.0 and later (the Anthropic Messages upstream was introduced in 3.17.0). This guide is based on the repository documentation and code, and uses a Claude-family relay gateway as the example. Screenshots are generated from the current frontend UI with de-identified sample data to avoid exposing a real API key.

Why local routing is needed

The newer Codex CLI targets the OpenAI Responses API, while the various Claude-family relay gateways and internal enterprise gateways expose the Anthropic Messages protocol — that is, /v1/messages. These two protocols use completely different request bodies, streaming events, and response structures, so putting such a gateway's endpoint directly into Codex configuration can only result in a request to /responses coming back 404.

This feature targets the scenario where all you have is a /v1/messages endpoint: you have a key for some Claude-family relay gateway and want to run Claude-family models with Codex's interaction style; or your company has banned the Claude Code client for compliance reasons and kept only an approved Claude-family gateway — the model itself is available, and all that's missing is a permitted client, which Codex can now fill.

CC Switch's approach is to keep Codex always talking to the local route and still sending Responses API requests; once the route detects that the active provider is Anthropic-format, it converts the request into Anthropic Messages for the upstream, then converts the response back into the Responses shape it returns to Codex.

The chain has four main steps:

  1. When Codex is taken over, the local configuration is written as http://127.0.0.1:15721/v1, and wire_api = "responses" is forcibly kept in place.
  2. The provider's anthropic upstream format tells the route that the real upstream speaks the Anthropic Messages protocol.
  3. The route rewrites /responses to /v1/messages and converts the Responses request body into an Anthropic request body.
  4. After the upstream responds, the route converts the Anthropic JSON or SSE back into the Responses JSON/SSE that Codex understands — reasoning content, tool calls, and images are all within the conversion scope.

Prerequisites

Prepare these three things first:

  • CC Switch installed and able to start (3.17.0 or later).
  • Codex CLI installed and run at least once, so the ~/.codex/ directory structure exists.
  • An API key that can reach an Anthropic Messages protocol endpoint (/v1/messages) — from some Claude-family relay gateway, or an internal enterprise Claude gateway; follow the gateway's documentation for its endpoint and auth method. Note: some providers restrict their Claude API to Claude Code only, so such a key may error out when used through Codex — if you're unsure, check with your provider first.

The Codex tab currently has no built-in Anthropic preset, so the steps below use the Custom Configuration path — just four or five fields from start to finish.

Step 1: Add a Codex provider

Open CC Switch, switch to the top-level Codex tab, click the plus button in the upper-right corner to add a provider, keep the default Custom Configuration, then fill in:

  • Provider Name: anything you like, e.g. Claude Gateway.
  • API Key: your gateway key. The real key is stored only in CC Switch and injected by the local route when forwarding, so it never enters Codex's live config.
  • API Request URL: just the gateway's service root, e.g. https://claude-gateway.example.com. It works with or without a trailing /v1 — the route sends requests to /v1/messages automatically; don't assemble /v1/messages yourself (if your gateway documentation gives you a complete messages URL, you can turn on the Full URL toggle next to it and paste it verbatim). The yellow hint below the address bar, "compatible with OpenAI Response format", is generic copy written for the direct Responses scenario; when you choose the Anthropic format, just fill it in as this guide describes.
  • Default Model: enter a Claude model id the gateway recognizes, e.g. claude-sonnet-5; follow the model names in the gateway's documentation.

Then expand Advanced Options and change Upstream Format from the default Responses (native) to Anthropic Messages (routing required).

After selecting Anthropic Messages, three supporting fields appear below:

  • Auth field: determines which header carries the API key to the upstream; only one of the two is sent — choose per your gateway's documentation.
    • ANTHROPIC_AUTH_TOKEN (Authorization): sends Authorization: Bearer <key>. This is the default, and most Claude-family relay gateways use it.
    • ANTHROPIC_API_KEY (x-api-key): sends x-api-key: <key>. Some gateways that follow Anthropic's native header convention require this. Picking the wrong one usually shows up as 401 / 403.
  • Emulate Claude Code client: off by default. Turn it on only when the gateway or its upstream restricts usage to "Claude Code only"; when enabled, it spoofs the User-Agent, anthropic-beta, and x-app headers and injects the Claude Code identity as the first line of the system prompt. Ordinary gateways don't need it; if you're still rejected after enabling it, see "FAQ".
  • Max output tokens: the Anthropic protocol's max_tokens is required, and when a Codex request carries no output ceiling the route falls back to a conservative 8192, which may truncate long answers or deep reasoning (showing up as an incomplete reply, stop_reason=max_tokens). If you hit truncation, raise this to the model's real ceiling here — but don't exceed it, or the upstream will 400 outright.

The Model Mapping in the same area is optional: add model ids like claude-opus-4-8, claude-sonnet-5, and claude-haiku-4-5-20251001 (use the names your upstream recognizes) one per row, and CC Switch generates a model catalog so Codex's /model menu can list them; you can also leave it empty, in which case Codex just requests the default model.

After you save the provider, a Needs Routing marker appears on the card — providers like this only work while local routing is running.

Step 2: Enable local routing and take over Codex

Go to the Routing page in Settings, expand Local Routing, and complete two toggles:

  1. Turn on the Routing Master Switch to start the local service (the first time you enable it, an explanatory confirmation dialog appears). The default address is 127.0.0.1:15721.
  2. Turn on Codex under Routing Enabled. If you only want Codex to use routing, you can leave Claude and Gemini off.

After takeover, CC Switch points Codex's live config at the local route (base_url = http://127.0.0.1:15721/v1), with only a placeholder in auth.json. The real Claude key stays in the CC Switch provider config and is injected by the local route on forward, using the auth field you selected.

Step 3: Switch providers and restart Codex

Return to the Codex provider list and click Enable on the Claude provider. If routing isn't running, CC Switch shows "This provider uses Anthropic Messages API format, requires the routing service to work properly. Start routing first." — just go back to Step 2 and turn it on.

After switching, restart the current Codex terminal session: config.toml and the model catalog are read when the Codex process starts, and a running process isn't guaranteed to hot-load them.

Inside Codex you can verify step by step:

  • If you configured model mapping, use /model to check whether the Claude models now appear in the menu; without a mapping, Codex just uses the default model.
  • Send a small question and watch the "Current Provider" on the Settings → Routing page change from "Waiting for first request..." to your Claude provider, with "Total Requests" starting to climb.
  • In the usage dashboard, these requests show their model names faithfully as claude-*, and you can filter by provider to reconcile token usage.

Capabilities and known limitations

  • Prompt caching is automatic: the conversion bridge injects standard 5-minute prompt-cache markers (system prompt, tool definitions, and conversation history) per Anthropic's convention, so long conversations don't resend everything at full price each turn — no configuration needed.
  • Reasoning and tools are lossless: extended thinking content round-trips across the bridge intact, and multi-turn tool calls, image inputs, and PDF inputs are all fully converted.
  • Supports the [1m] long-context marker: when the default model or a model id in the mapping ends with [1m] (e.g. claude-sonnet-5[1m]), the route strips the marker and automatically adds the corresponding 1M-context beta header, provided the gateway supports that capability.
  • Web search is unavailable: in Anthropic upstream mode, Codex's built-in web_search is deliberately disabled — the conversion layer can't translate it for the Anthropic endpoint, and disabling it avoids presenting the model with a tool that's guaranteed to fail.
  • Truncation is reported faithfully: when the upstream stops at the output ceiling or the stream is cut off, Codex sees "incomplete" rather than a disguised success, making it easy to notice and raise the max output tokens.

FAQ

The upstream returns 401 or 403

Nine times out of ten the auth field doesn't match what the gateway wants: switch between ANTHROPIC_AUTH_TOKEN (Authorization) and ANTHROPIC_API_KEY (x-api-key) per your gateway's documentation and try again (most gateways use the default Bearer). Also confirm the key itself is valid and has balance.

Codex reports 404 or cannot find /responses

Usually Codex routing takeover isn't enabled, or you manually wrote the gateway's address directly into Codex — an Anthropic-protocol upstream has no /responses endpoint, so that always 404s. Check whether the current provider's base_url in ~/.codex/config.toml points to http://127.0.0.1:15721/v1.

The upstream returns 404 (routing already enabled)

Check the API Request URL: it should be the gateway's service root, not an address carrying another protocol's path such as /chat/completions. When the gateway path is unusual, use the Full URL toggle to paste the complete messages endpoint directly.

Replies often get cut off mid-way

This is the default 8192 output ceiling showing up. Raise it in Max output tokens under the provider form's Advanced Options (don't exceed the model's/gateway's real ceiling), save, and retry.

/model doesn't show the Claude models

Confirm you've added entries to the model mapping, then restart Codex after saving the provider — the model catalog isn't hot-loaded by a running process. When the default model isn't in the mapping, the menu won't list it, but a direct request still works.

Web search doesn't work

By design; see "Capabilities and known limitations". For tasks that need web search, switch back to a Responses/Chat-format provider.

An error says usage is restricted to Claude Code

Some providers restrict their Claude API to the Claude Code client, so it gets rejected when going through this guide's chain via Codex. Try turning on the Emulate Claude Code client toggle in Advanced Options; if it still errors after that, the restriction is enforced on the provider's side — check with your provider whether your key can be used outside Claude Code. Keep this toggle off for ordinary gateways.

Compliance note

Before using this in the "company bans the client but keeps only the gateway" scenario, it's worth confirming that doing so complies with your organization's specific policy — whether what's banned is a specific client or a manner of use differs from one place to the next. When using a third-party relay gateway, read the target gateway's terms on billing, compliance, and data retention.

References


Guides Codex Claude Routing Guide Ja (`docs/guides/codex-claude-routing-guide-ja.md`)

CC Switch を使って Codex で Claude モデルを利用する

対象バージョン: CC Switch 3.17.0 以降(「Anthropic Messages 上流」は 3.17.0 から導入)。本記事はリポジトリ内のドキュメントとコードをもとに整理し、Claude 系中継ゲートウェイを例に説明します。スクリーンショットは現在のフロントエンド UI から、実際の API Key が漏れないよう匿名化したサンプルデータで生成しています。

ローカルルーティングが必要な理由

新しい Codex CLI は OpenAI Responses API を前提にしています。一方で各種 Claude 系中継ゲートウェイや企業内部ゲートウェイが公開しているのは Anthropic Messages プロトコル、つまり /v1/messages です。この 2 つのプロトコルは、リクエストボディ、ストリーミングイベント、レスポンス構造がまったく異なります。この種のゲートウェイのエンドポイントをそのまま Codex 設定に入れても、/responses へのリクエストが 404 になるだけです。

この機能は「手元にあるのが /v1/messages エンドポイントだけ」という場面のためのものです。ある Claude 系中継ゲートウェイの Key を持っていて、Codex の操作感で Claude 系モデルを使いたい。あるいは会社がコンプライアンス方針で Claude Code クライアントを禁止し、承認済みの Claude 系ゲートウェイだけを残している——モデル自体は利用できるのに、許可されたクライアントがないだけです。その空白を Codex で埋められます。

CC Switch では、Codex が常にローカルルートへ接続し、Responses API のままリクエストを送るようにします。ルートは現在のプロバイダーが Anthropic 形式だと判定すると、リクエストを Anthropic Messages に変換して上流へ送り、最後にレスポンスを Responses 形式へ戻して Codex に返します。

この経路は主に 4 つのステップに分かれます:

  1. Codex を引き継ぐと、ローカル設定は http://127.0.0.1:15721/v1 に書き換えられ、wire_api = "responses" が強制的に維持されます。
  2. プロバイダーの上流フォーマット anthropic が、実際の上流は Anthropic Messages プロトコルだとルートに伝えます。
  3. ルートは /responses を /v1/messages に書き換え、Responses のリクエストボディを Anthropic のリクエストボディへ変換します。
  4. 上流から返ってきた後、ルートは Anthropic の JSON または SSE を Codex が理解できる Responses JSON/SSE へ変換して返します——推論内容、ツール呼び出し、画像もすべて変換対象です。

事前準備

先に次の 3 つを用意してください:

  • インストール済みで起動できる CC Switch(3.17.0 以降)。
  • インストール済みの Codex CLI。少なくとも 1 回は実行し、~/.codex/ のディレクトリ構造が存在していること。
  • Anthropic Messages プロトコルのエンドポイント(/v1/messages)へアクセスできる API Key——ある Claude 系中継ゲートウェイ、または企業内部の Claude ゲートウェイのもの。エンドポイントと認証方式はゲートウェイのドキュメントに従ってください。注意:一部のプロバイダーは Claude API を Claude Code 内でのみ利用できるよう制限しており、この種の Key を Codex で使うとエラーになることがあります。判断がつかない場合は、先にプロバイダーへ問い合わせてください。

Codex タブには現時点で Anthropic の内蔵プリセットがないため、以下では「カスタム設定」の手順で進めます。入力する項目は全体でも 4〜5 個です。

Step 1: Codex プロバイダーを追加する

CC Switch を開き、上部の Codex タブへ切り替え、右上のプラスボタンからプロバイダーを追加します。デフォルトの カスタム設定 のまま、次の項目を入力します:

  • プロバイダー名: 任意です。たとえば Claude Gateway。
  • API Key: あなたのゲートウェイの Key。実際の Key は CC Switch 内にのみ保存され、ローカルルートが転送時に注入するため、Codex の live 設定には入りません。
  • API エンドポイント: ゲートウェイのルートアドレスを入力すれば十分です。たとえば https://claude-gateway.example.com。/v1 は付けても付けなくても正しく処理され、ルートが自動的に /v1/messages へリクエストを送ります。自分で /v1/messages を組み立てないでください(ゲートウェイのドキュメントが完全な messages URL を指定している場合は、隣の フル URL スイッチをオンにしてそのまま貼り付けても構いません)。アドレス欄の下に表示される「OpenAI Response 互換」という黄色のヒントは Responses 直結向けの汎用文言です。Anthropic フォーマットを選ぶ場合は本記事のとおりに入力してください。
  • デフォルトモデル: ゲートウェイが認識する Claude モデル ID を入力します。たとえば claude-sonnet-5。ゲートウェイのドキュメントにあるモデル名に従ってください。

続いて 詳細オプション を展開し、上流フォーマット をデフォルトの Responses(ネイティブ) から Anthropic Messages(ルーティング必須) に変更します。

Anthropic Messages を選ぶと、下に 3 つの関連フィールドが追加で表示されます:

  • 認証フィールド: API Key をどのヘッダーで上流へ送るかを決めます。送信されるのはどちらか一方のみで、ゲートウェイのドキュメントに従って選びます。
    • ANTHROPIC_AUTH_TOKEN(Authorization): Authorization: Bearer <key> を送信します。デフォルト値で、多くの Claude 系中継ゲートウェイがこの方式を使います。
    • ANTHROPIC_API_KEY(x-api-key): x-api-key: <key> を送信します。Anthropic ネイティブのヘッダー規約を踏襲する一部のゲートウェイはこちらを要求します。選択を誤ると、通常 401 / 403 という形で現れます。
  • Claude Code クライアントを模倣: デフォルトはオフです。ゲートウェイ(またはその上流)が「Claude Code からのみ利用可能」と制限している場合にのみオンにします。オンにすると User-Agent・anthropic-beta・x-app ヘッダーを偽装し、システムプロンプトの先頭行に Claude Code のアイデンティティを注入します。通常のゲートウェイでは不要です。オンにしても拒否される場合の対処は「よくある質問」を参照してください。
  • 最大出力トークン: Anthropic プロトコルの max_tokens は必須項目です。Codex のリクエストが出力上限を含まない場合、ルートは保守的に 8192 で補います。長い回答や深い思考では切り詰められることがあります(回答が不完全になる、stop_reason=max_tokens になる、といった形で現れます)。切り詰められたら、ここでモデルの実際の上限に合わせて引き上げてください。ただし超えないように——超えると上流が直接 400 を返します。

同じエリアの モデルマッピング は任意です。claude-opus-4-8、claude-sonnet-5、claude-haiku-4-5-20251001 のようなモデル ID(上流が認識する名前に従ってください)を 1 行ずつ追加すると、CC Switch がモデルカタログを生成し、Codex の /model メニューに一覧表示できるようになります。入力しなくても利用でき、その場合 Codex はデフォルトモデルを直接リクエストします。

プロバイダーを保存すると、カードに ルーティングが必要 のマークが表示されます——この種のプロバイダーは、ローカルルーティングが実行中でなければ正しく動作しません。

Step 2: ローカルルーティングを有効にして Codex をルーティングする

設定の ルーティング ページに入り、ローカルルーティング を展開して、2 つのスイッチを設定します:

  1. ルーティング総スイッチ をオンにしてローカルサービスを起動します(初回起動時は説明の確認ダイアログが表示されます)。デフォルトアドレスは 127.0.0.1:15721 です。
  2. ルーティング有効 で Codex をオンにします。Codex だけをルーティングしたい場合は、Claude と Gemini はオフのままで構いません。

引き継ぎ後、CC Switch は Codex の live 設定をローカルルートへ向け(base_url = http://127.0.0.1:15721/v1)、auth.json にはプレースホルダーだけが入ります。実際の Claude Key は CC Switch のプロバイダー設定内に残り、ローカルルートが転送時に、あなたが選んだ認証フィールドに従って注入します。

Step 3: プロバイダーを切り替えて Codex を再起動する

Codex プロバイダー一覧に戻り、Claude プロバイダーの 有効化 をクリックします。ルーティングが実行されていない場合、CC Switch は「このプロバイダーは Anthropic Messages API フォーマットを使用しており、ルーティングサービスが必要です。先にルーティングを起動してください」と表示します——Step 2 に戻ってオンにすれば解決します。

切り替え後は、現在の Codex ターミナルセッションを再起動することをおすすめします。config.toml とモデルカタログは Codex プロセスの起動時に読み込まれるため、実行中のプロセスがホットロードするとは限りません。

Codex に入ったら、段階的に確認できます:

  • モデルマッピングを設定している場合は、/model で Claude モデルがメニューに表示されているか確認します。マッピングを設定していない場合、Codex はデフォルトモデルを直接使います。
  • 小さな質問を 1 つ送り、設定 → ルーティングページの「現在のプロバイダー」が「最初のリクエスト待ち」からあなたの Claude プロバイダーに変わり、「総リクエスト数」が増え始めるのを確認します。
  • 使用量ダッシュボードでは、これらのリクエストのモデル名が claude-* としてそのまま表示され、プロバイダーで絞り込んで token 使用量を照合できます。

機能の範囲と既知の制限

  • プロンプトキャッシュが自動で有効: 変換ブリッジは Anthropic 標準に従って 5 分のプロンプトキャッシュマーカー(システムプロンプト、ツール定義、対話履歴)を注入します。長い対話でも毎回全額で再送されることはなく、設定は不要です。
  • 推論とツールを無損失で往復: extended thinking の内容はブリッジをまたいで往復しても保持され、複数ターンのツール呼び出し、画像、PDF 入力も完全に変換されます。
  • [1m] 長コンテキストマーカーに対応: デフォルトモデルやモデルマッピングのモデル ID が [1m] で終わる場合(例:claude-sonnet-5[1m])、ルートはマーカーを取り除き、対応する 1M コンテキストの beta ヘッダーを自動で補います。ただし、ゲートウェイがその機能に対応していることが前提です。
  • Web 検索は利用不可: Anthropic 上流モードでは Codex の内蔵 web_search が意図的に無効化されます——変換層が Anthropic エンドポイントへ翻訳できないためで、必ず失敗するツールをモデルに提示しないための措置です。
  • 切り詰めをそのまま報告: 上流が出力上限で止まったりストリームが切断されたりすると、Codex は偽装された成功ではなく「未完了」を受け取ります。これにより気づきやすくなり、最大出力トークンを引き上げる判断ができます。

よくある質問

上流が 401 または 403 を返す

ほとんどの場合、認証フィールドがゲートウェイの要求と一致していません。ANTHROPIC_AUTH_TOKEN(Authorization) と ANTHROPIC_API_KEY(x-api-key) を、ゲートウェイのドキュメントに従って切り替えて再試行してください(多くのゲートウェイはデフォルトの Bearer です)。あわせて、Key 自体が有効で残高があることも確認してください。

Codex が 404 を返す、または /responses が見つからない

多くの場合、Codex のルーティング引き継ぎが有効になっていないか、ゲートウェイのエンドポイントを手動で Codex に直接書いています——Anthropic プロトコルの上流には /responses エンドポイントが存在しないため、必ず 404 になります。~/.codex/config.toml の現在の provider の base_url が http://127.0.0.1:15721/v1 を指しているか確認してください。

上流が 404 を返す(ルーティングは有効)

API エンドポイントを確認してください。ゲートウェイのルートアドレスであるべきで、/chat/completions のような別プロトコルのパスが付いたアドレスではいけません。ゲートウェイのパスが特殊な場合は、フル URL スイッチを使って完全な messages エンドポイントをそのまま貼り付けてください。

回答が途中で切り詰められることが多い

これはデフォルトの 8192 出力上限の現れです。プロバイダーフォームの詳細オプションにある 最大出力トークン で引き上げ(モデル / ゲートウェイの実際の上限を超えないように)、保存してから再試行してください。

/model に Claude モデルが表示されない

モデルマッピングにエントリが追加されていることを確認し、プロバイダーを保存してから Codex を再起動してください——モデルカタログは実行中のプロセスにはホットロードされません。デフォルトモデルがマッピングに含まれていない場合、メニューには表示されませんが、直接リクエストは有効です。

Web 検索が使えない

仕様どおりです。「機能の範囲と既知の制限」を参照してください。Web 検索が必要なタスクは、Responses / Chat フォーマットのプロバイダーへ切り替えることをおすすめします。

Claude Code でしか使えないというエラーが出る

一部のプロバイダーは、その Claude API を Claude Code クライアント内でのみ利用できるよう制限しており、本ガイドの経路で Codex から使うと拒否されます。詳細オプションの Claude Code クライアントを模倣 スイッチをオンにして試すことはできますが、それでもエラーになる場合、制限はプロバイダーのサーバー側にあります。その Key を Claude Code 以外で使えるかどうか、プロバイダーへ問い合わせて確認してください。通常のゲートウェイでは、このスイッチはオフのままにしてください。

コンプライアンスに関する注意

「会社がクライアントを禁止し、ゲートウェイだけを残している」という場面で使う前に、この使い方が所属組織の具体的な方針に沿っているかを確認することをおすすめします——禁止されているのが特定のクライアントなのか、それともある種の利用方法なのかは、組織によって解釈が異なります。サードパーティ中継ゲートウェイを使う場合は、対象ゲートウェイの課金・コンプライアンス・データ保持に関する規約を必ずお読みください。

参考リンク


Guides Codex Claude Routing Guide Zh (`docs/guides/codex-claude-routing-guide-zh.md`)

通过 CC Switch 在 Codex 中使用 Claude 模型

适用版本:CC Switch 3.17.0 及以上(「Anthropic Messages 上游」自 3.17.0 引入)。本文根据仓库内文档与代码整理,以 Claude 系中转网关为例演示。截图来自当前前端界面,使用去敏示例数据生成,避免泄露真实 API Key。

为什么需要本地路由

新版 Codex CLI 面向的是 OpenAI Responses API,而各类 Claude 系中转网关、企业内部网关暴露的是 Anthropic Messages 协议,也就是 /v1/messages。这两种协议的请求体、流式事件和返回结构完全不同,把这类网关的接口地址直接填进 Codex 配置里,结果只能是请求 /responses 返回 404。

这个功能面向的就是「手里只有 /v1/messages 端点」的场景:你有某个 Claude 系中转网关的 Key,想用 Codex 的交互习惯跑 Claude 系列模型;或者公司出于合规策略禁用了 Claude Code 客户端、只保留了经批准的 Claude 系网关——模型本身可用,缺的只是一个被允许的客户端,现在 Codex 可以补上这个位置。

CC Switch 的做法是让 Codex 始终连本机路由,仍以 Responses API 发送请求;路由识别当前供应商是 Anthropic 格式后,把请求转换成 Anthropic Messages 发给上游,再把响应转换回 Responses 形态返回给 Codex。

这条链路主要分成四步:

  1. Codex 接管时,本地配置会被写成 http://127.0.0.1:15721/v1,并强制保持 wire_api = "responses"。
  2. 供应商的上游格式 anthropic 会告诉路由:真实上游说的是 Anthropic Messages 协议。
  3. 路由把 /responses 改写到 /v1/messages,并把 Responses 请求体转换成 Anthropic 请求体。
  4. 上游返回后,路由再把 Anthropic 的 JSON 或 SSE 转回 Codex 能理解的 Responses JSON/SSE——推理内容、工具调用、图片都在转换范围内。

准备工作

你需要先准备好三样东西:

  • 已安装并能启动的 CC Switch(3.17.0 及以上)。
  • 已安装 Codex CLI,并至少运行过一次,让 ~/.codex/ 目录结构存在。
  • 一个能访问 Anthropic Messages 协议端点(/v1/messages)的 API Key——来自某个 Claude 系中转网关,或企业内部的 Claude 网关;端点地址和认证方式以网关文档为准。注意:部分供应商会限制其 Claude API 只能在 Claude Code 中使用,这类 Key 走 Codex 可能会报错,拿不准就先咨询供应商。

Codex 页签目前没有 Anthropic 内置预设,下面走「自定义配置」路径,全程也就四五个字段。

第一步:添加 Codex 供应商

打开 CC Switch,切到顶部的 Codex 标签,点击右上角的加号添加供应商,保持默认的 自定义配置,然后填写:

  • 供应商名称:随意,例如 Claude Gateway。
  • API Key:你的网关 Key。真实 Key 只保存在 CC Switch 里,由本地路由转发时注入,不会进入 Codex 的 live 配置。
  • API 请求地址:填网关服务根地址即可,例如 https://claude-gateway.example.com。带不带 /v1 都能被正确处理,路由会自动把请求打到 /v1/messages;不要自己拼 /v1/messages(如果网关文档给的就是完整 messages URL,打开旁边的 完整 URL 开关原样粘贴也可以)。地址栏下方那句「兼容 OpenAI Response 格式」的黄色提示是为 Responses 直连场景写的通用文案,选 Anthropic 格式时按本文填写即可。
  • 默认模型:填网关认识的 Claude 模型 id,例如 claude-sonnet-5,以网关文档给出的模型名为准。

然后展开 高级选项,把 上游格式 从默认的 Responses(原生) 改成 Anthropic Messages(需开启路由)。

选中 Anthropic Messages 后,下方会多出三个配套字段:

  • 认证字段:决定 API Key 以哪个请求头发给上游,两者只发其一,按网关文档选择。
    • ANTHROPIC_AUTH_TOKEN(Authorization):发 Authorization: Bearer <key>,是默认值,多数 Claude 系中转网关用这种。
    • ANTHROPIC_API_KEY(x-api-key):发 x-api-key: <key>,部分沿用 Anthropic 原生请求头约定的网关要求这种。选错通常表现为 401 / 403。
  • 模拟 Claude Code 客户端:默认关闭。仅当网关或其上游限制「只能通过 Claude Code 使用」时才打开,开启后会伪装 User-Agent、anthropic-beta、x-app 请求头,并在系统提示首行注入 Claude Code 身份。普通网关不需要开;开启后仍被拒的处理见「常见问题」。
  • 最大输出 tokens:Anthropic 协议的 max_tokens 是必填项,而 Codex 请求未携带输出上限时,路由按保守的 8192 兜底,长回答或深度思考可能被截断(表现为回复不完整、stop_reason=max_tokens)。遇到截断就在这里按模型真实上限调高,但不要超过——超了上游会直接 400。

同区的 模型映射 是可选项:把 claude-opus-4-8、claude-sonnet-5、claude-haiku-4-5-20251001 这类模型 id(以你上游认识的名字为准)逐行加进去,CC Switch 会生成模型目录让 Codex 的 /model 菜单能列出它们;不填也能用,Codex 会直接请求默认模型。

保存供应商后,卡片上会出现 需要路由 标记——这类供应商必须在本地路由运行时才能正常工作。

第二步:开启本地路由并接管 Codex

进入设置里的 路由 页面,展开 本地路由,完成两个开关:

  1. 打开 路由总开关,启动本地服务(首次开启会弹出一个说明确认框)。默认地址是 127.0.0.1:15721。
  2. 在 路由启用 中打开 Codex。如果只想让 Codex 走路由,可以保持 Claude、Gemini 关闭。

接管后,CC Switch 会把 Codex 的 live 配置指向本机路由(base_url = http://127.0.0.1:15721/v1),auth.json 里只有占位符。真实 Claude Key 仍保存在 CC Switch 的供应商配置里,由本地路由在转发时按你选的认证字段注入。

第三步:切换供应商并重启 Codex

回到 Codex 供应商列表,点击 Claude 供应商的 启用。如果路由没有在运行,CC Switch 会提示「此供应商使用 Anthropic Messages 接口格式,需要路由服务才能正常使用,请先启动路由」——回到第二步打开即可。

切换后建议重启当前 Codex 终端会话:config.toml 和模型目录是 Codex 进程启动时读取的,运行中的进程不保证热加载。

进入 Codex 后可以逐级验证:

  • 配置了模型映射的话,用 /model 查看 Claude 模型是否已出现在菜单里;没配映射时 Codex 直接用默认模型。
  • 发一个小问题,观察设置 → 路由页面的「当前 Provider」从「等待首次请求」变成你的 Claude 供应商、「总请求数」开始增长。
  • 用量看板里,这些请求的模型名会如实显示为 claude-*,可按供应商筛选核对 token 用量。

能力边界与已知限制

  • 提示缓存自动生效:转换桥会按 Anthropic 标准注入 5 分钟提示缓存标记(系统提示、工具定义与对话历史),长对话不会每轮全价重发,无需任何配置。
  • 推理与工具无损:extended thinking 内容跨桥往返保留,多轮工具调用、图片与 PDF 输入都被完整转换。
  • 支持 [1m] 长上下文标记:默认模型或模型映射里的模型 id 以 [1m] 结尾(如 claude-sonnet-5[1m])时,路由会剥掉标记并自动补发对应的 1M 上下文 beta 头,前提是网关支持该能力。
  • 联网搜索不可用:Anthropic 上游模式下 Codex 的内置 web_search 会被主动禁用——转换层无法把它翻译给 Anthropic 端点,禁用是为了不给模型呈现一个必然失败的工具。
  • 截断如实上报:上游停在输出上限或流被掐断时,Codex 会看到「未完成」而不是被伪装的成功,方便你察觉并调高最大输出 tokens。

常见问题

上游返回 401 或 403

十有八九是认证字段与网关要求不符:在 ANTHROPIC_AUTH_TOKEN(Authorization) 与 ANTHROPIC_API_KEY(x-api-key) 之间按网关文档换一个再试(多数网关用默认的 Bearer)。另外确认 Key 本身有效、有余额。

Codex 报 404 或找不到 /responses

通常是没有开启 Codex 路由接管,或者你手动把网关的地址直接写给了 Codex——Anthropic 协议的上游没有 /responses 端点,这样一定 404。检查 ~/.codex/config.toml 里当前 provider 的 base_url 是否指向 http://127.0.0.1:15721/v1。

上游返回 404(路由已开启)

检查 API 请求地址:应该是网关的服务根地址,而不是带 /chat/completions 之类其它协议路径的地址。网关路径特殊时,用 完整 URL 开关直接粘贴完整的 messages 端点。

回复经常中途截断

这是默认 8192 输出上限的表现。在供应商表单高级选项的 最大输出 tokens 里调高(不要超过模型/网关真实上限),保存后重试。

/model 看不到 Claude 模型

确认模型映射里已添加条目,保存供应商后重启 Codex——模型目录不会被运行中的进程热加载。默认模型不在映射里时菜单不会列出它,但直接请求仍然有效。

联网搜索用不了

设计如此,见「能力边界」。需要联网搜索的任务建议切回 Responses/Chat 格式的供应商。

报错提示只能在 Claude Code 中使用

部分供应商会限制其 Claude API 只能在 Claude Code 客户端中使用,经 Codex 走本攻略的链路时会被拒绝。可以尝试打开高级选项里的 模拟 Claude Code 客户端 开关;若开启后仍然报错,说明限制在供应商服务端,请咨询供应商确认你的 Key 能否在 Claude Code 之外使用。普通网关请保持该开关关闭。

合规提示

在「公司禁客户端、只留网关」的场景下使用前,建议确认这样做符合你所在组织的具体政策——被禁的是特定客户端还是某种使用方式,各家口径不同。使用第三方中转网关时,请阅读目标网关关于计费、合规与数据留存的条款。

参考链接


Guides Codex Deepseek Routing Guide En (`docs/guides/codex-deepseek-routing-guide-en.md`)

Using Chat-Format APIs in Codex: Local Routing Guide and DeepSeek Migration Notes

Applies to CC Switch 3.20.4 and later. This guide is based on the repository documentation and code. Screenshots are generated with de-identified sample data to avoid exposing a real API key or account balance.

Most DeepSeek users no longer need this guide: since 3.19.1 the DeepSeek preset connects directly over native Responses, and deepseek-v4-pro can now connect directly too. This guide is now mainly for two groups of readers: providers that are still Chat-format (such as SiliconFlow and ModelScope), and older DeepSeek cards saved before 3.19.1 that still go through Chat. Read the next section first to find out which case you are in.

First, check whether you still need this guide

There is exactly one way to tell: look for the Needs Routing badge on the Codex provider card.

  • Has the Needs Routing badge → this provider is Chat-format, and the whole guide applies.
  • No badge → it already connects directly over native Responses, so the routing steps here are pointless for it. Just use it.
  • Has the No Routing Support badge → this is an official provider, and CC Switch blocks it from going through local routing (see the FAQ at the end).

The badge is driven by the API format recorded when the provider was saved, so upgrading CC Switch does not change how an existing provider behaves. For DeepSeek specifically, there are three cases:

Your situation Routing needed? Notes
A DeepSeek provider saved before 3.19.1 Yes, badge still shown Preset changes only affect newly created providers; a saved configuration is kept as-is. To move it to a direct connection, see the end of Step 1
A DeepSeek provider created from the preset after 3.19.1 No Connects directly to api.deepseek.com and picks up DeepSeek's official model catalog; since 3.20.4 the preset's default model is deepseek-flash (V4.1 Flash)
You want to use deepseek-v4-pro No DeepSeek opened its Codex integration for that model in August 2026, so a direct connection works; it is already in the preset's model menu

It is not just DeepSeek: the Codex presets for Kimi, Zhipu GLM, MiniMax, and 千问AI平台 have since moved to native direct connections as well. The presets that are still Chat-format and need this guide are mainly SiliconFlow, ModelScope, the Tencent Token Plan series, Baidu Qianfan Coding Plan / Token Plan, StepFun, and others; the steps below apply to them in full.

Why local routing is needed

The newer Codex CLI targets the OpenAI Responses API, while many providers expose the OpenAI Chat Completions shape, usually /chat/completions. These two protocols use different request bodies, streaming events, and response structures. If you put a Chat endpoint directly into Codex configuration, common results include an incorrect model list, 404/400 requests, or streaming responses that Codex cannot parse correctly.

CC Switch solves this by making Codex always talk to a local route and continue sending Responses API requests. The route detects whether the active provider is Chat-format, rewrites the request into Chat Completions for the upstream provider, and finally converts the Chat response back into the Responses shape that Codex understands.

The chain has four main steps:

  1. When Codex routing is enabled, the local configuration is written as http://127.0.0.1:15721/v1, while wire_api = "responses" is kept in place.
  2. The provider's meta.apiFormat = "openai_chat" tells the route that the real upstream is Chat Completions.
  3. The route rewrites /responses or /v1/responses to /chat/completions, and converts the Responses request body into a Chat request body.
  4. After the upstream responds, the route converts the Chat JSON or SSE stream back into Responses JSON/SSE.

For a provider that is natively Responses — such as the current DeepSeek preset — steps 2 through 4 never happen: the request goes straight to the upstream with no format rewriting at all.

Prerequisites

Prepare these three things first:

  • CC Switch installed and able to start.
  • Codex CLI installed and run at least once, so the ~/.codex/config.toml directory structure exists.
  • An API key for the provider you want to use.

OpenAI-compatible base URLs vary from provider to provider: a /v1 suffix is common (SiliconFlow, for instance, uses https://api.siliconflow.cn/v1), some use a longer path (Baidu Qianfan Coding Plan uses https://qianfan.baidubce.com/v2/coding), and the Chat API path is /chat/completions. CC Switch's presets are already configured from each provider's documentation, so prefer a preset and do not manually assemble the endpoint path.

Step 1: Add a Codex provider

Open CC Switch, switch to the top-level Codex tab, and click the plus button in the upper-right corner to add a provider.

Using a preset (recommended): select the provider in the preset list, enter your API key, and save. The preset already carries the request base URL, default model, and model menu, and sets the upstream format for you; once a Chat-format preset is saved, the Needs Routing badge appears on its card. Thinking/reasoning parameters are preconfigured by the preset — you do not need to fill them in.

Using a custom configuration: enter the API key and base URL from the provider's documentation, then expand Advanced Options at the bottom of the form and set Upstream Format to Chat Completions (routing required). The dropdown offers three options:

  • Responses (native) — the upstream natively supports the Responses API; connects directly with no conversion and no routing.
  • Chat Completions (routing required) — the case this guide covers.
  • Anthropic Messages (routing required) — the upstream only offers the native Anthropic protocol, which the route converts as well.

Only Responses (native) works without routing takeover; the other two require it. For custom providers, CC Switch infers the thinking parameters from the provider name and address; you only need to expand Reasoning Capability and override them manually when that inference is wrong.

Converting an existing DeepSeek provider: change Upstream Format to Responses (native) — there is no need to delete and recreate it. The next time you switch to it, CC Switch recognises the deepseek.com address and applies DeepSeek's official model catalog, so freeform apply_patch, the GPT-5 harness, the low/high/max reasoning levels, and web_search all take effect as usual.

The one small difference is the context window: a provider's own saved model rows take priority, so the 1000000 stored before 3.19.1 overrides the officially declared 1048576, costing you a little over 40k tokens. If that bothers you, open Advanced Options → Model Mapping and change that row's Context Window to 1048576, or simply create a fresh provider from the preset.

One more thing: the official model catalog used by the direct connection requires Codex CLI 0.144.0 or newer (the freeform apply_patch registration it carries needs that release), and CC Switch does not verify this for you. The generated catalog file also grows to roughly 75 KB, because it contains the full GPT-5 harness text.

Step 2: Enable local routing and route Codex

Go to the Routing page in Settings, expand Local Routing, and complete two toggles:

  1. Turn on the Routing Master Switch to start the local service. The default address is 127.0.0.1:15721.
  2. Turn on Codex under Routing Enabled. If you only want Codex to use local routing, you can leave Claude and Gemini off.

After routing is enabled, CC Switch points Codex's live configuration to the local route and manages authentication with a placeholder. The real API key stays in the CC Switch provider configuration and is injected by the local route while forwarding requests, so you do not need to expose the key in Codex's live configuration.

Step 3: Switch providers and restart Codex

Return to the Codex provider list and click Enable on the provider you want. If it carries the Needs Routing marker while routing is not running, CC Switch shows a prompt saying the routing service is required.

After switching, restart the current Codex terminal session. This is recommended because:

  • The Codex process may already have read the old config.toml.
  • After model_catalog_json is generated, the /model menu usually needs a fresh process before it refreshes.

Inside Codex, use /model to check whether the current model comes from the matching preset. Then send a small test prompt and confirm that the request count increases in the routing panel, or that a Codex request appears in usage/request logs.

Usage attribution changes once you connect directly

This is worth calling out on its own: once a provider connects directly, its requests no longer pass through the local route, so the per-request proxy usage accounting cannot see them.

The usage itself is not lost — Codex session-log import still records it — but that path carries no provider identity: all Codex usage that did not go through the local proxy is grouped under a single entry named Codex (Session). To tell them apart, look at the model: every usage row keeps its own model id, and the usage panel's Model Stats table lists them per model, with separate cost and token figures.

If you genuinely need to reconcile by provider — comparing the same model across several aggregators, for instance — keep Upstream Format on Chat and leave routing takeover enabled.

FAQ

Codex reports 404 or cannot find /responses

Usually Codex routing is not enabled, or the upstream Chat base URL was written directly into Codex manually. Check whether ~/.codex/config.toml points to http://127.0.0.1:15721/v1.

The upstream reports 404

If you are using a built-in preset, first confirm that the active provider really comes from the preset and that Codex routing is enabled. Only custom providers require extra base URL checks: it should be the service endpoint given in the provider's documentation, not the full endpoint path with /chat/completions.

/model does not show the provider's models

Restart Codex after saving the provider. CC Switch generates cc-switch-model-catalog.json and writes its path to model_catalog_json, but a running Codex process may not hot-load the model catalog.
The Codex app currently does not support multi-model selection, so it uses the first configured model by default.
If the command-line /model menu works but the Codex desktop app model picker still cannot see custom models, that is the upstream Codex desktop app's own model-gating behavior. See Can't See Custom Models in the Codex Desktop App? (FAQ).

Routing is enabled, but requests still go to the wrong provider

Confirm that all three states match: the current provider under the Codex tab is the right one; the local routing service is running; and the Codex toggle is enabled under Routing Enabled.

Can I use an official OpenAI Codex account through local routing?

Not recommended. CC Switch blocks switching to official providers while local routing takeover is enabled, because accessing official APIs through a proxy may create account risk. Routing is mainly intended for third-party, aggregator, or protocol-conversion scenarios.

References


Guides Codex Deepseek Routing Guide Ja (`docs/guides/codex-deepseek-routing-guide-ja.md`)

Codex で Chat 形式 API を使う: ローカルルーティングガイドと DeepSeek 移行の説明

対象バージョン: CC Switch 3.20.4 以降。本記事はリポジトリ内のドキュメントとコードをもとに整理しています。スクリーンショットは実際の API Key やアカウント残高が漏れないよう匿名化したサンプルデータで生成しています。

DeepSeek ユーザーの多くは、もう本記事を必要としません: 3.19.1 から DeepSeek プリセットはネイティブ Responses による直結に変わり、deepseek-v4-pro も直結できるようになりました。本記事は現在、主に 2 種類の読者に向けたものです。Chat 形式のままのプロバイダー(SiliconFlow、ModelScope など)を使う人と、3.19.1 より前に保存され Chat のままになっている DeepSeek の旧カードを使う人です。まず次のセクションで、自分がどのケースに当てはまるかを確認してください。

まず、このガイドが今も必要か確認する

判別方法は 1 つだけです。Codex プロバイダーカードに ルーティングが必要 バッジが付いているかを見てください。

  • ルーティングが必要 バッジあり → このプロバイダーは Chat 形式で、本記事がそのまま当てはまります。
  • バッジなし → すでにネイティブ Responses で直結しているため、本記事のルーティング手順は不要です。そのまま使えます。
  • ルーティング非対応 バッジあり → 公式プロバイダーであり、CC Switch はローカルルーティング経由での使用をブロックします(末尾のよくある質問を参照)。

このバッジはプロバイダー保存時に記録された API 形式で決まるため、CC Switch をアップグレードしても既存プロバイダーの挙動は変わりません。DeepSeek に関しては、次の 3 つのケースがあります。

あなたの状況 ルーティングは必要か 説明
3.19.1 より前に保存した DeepSeek プロバイダー 必要(バッジも表示されたまま) プリセットの変更は新規作成したプロバイダーにのみ影響し、保存済みの設定はそのまま維持されます。直結に変えたい場合は Step 1 の末尾を参照してください
3.19.1 以降にプリセットから新規作成した DeepSeek 不要 api.deepseek.com へ直結し、DeepSeek 公式のモデルカタログを取得します。3.20.4 からプリセットのデフォルトモデルは deepseek-flash(V4.1 Flash)です
deepseek-v4-pro を使いたい 不要 DeepSeek は 2026 年 8 月にこのモデルの Codex 連携を開放したため、直結で使えます。プリセットのモデルメニューにもすでに含まれています

DeepSeek だけでなく、Kimi、Zhipu GLM、MiniMax、千问AI平台 の Codex プリセットも順次ネイティブ直結に変わりました。現在も Chat 形式のままで本記事が必要なプリセットは、主に SiliconFlow、ModelScope、Tencent Token Plan シリーズ、Baidu Qianfan Coding Plan / Token Plan、StepFun などで、以下の手順はそれらに完全に当てはまります。

ローカルルーティングが必要な理由

新しい Codex CLI は OpenAI Responses API を前提にしています。一方で多くのプロバイダーが実際に公開しているのは OpenAI Chat Completions 形式、つまり /chat/completions です。この 2 つのプロトコルは、リクエストボディ、ストリーミングイベント、レスポンス構造が異なります。Chat エンドポイントをそのまま Codex 設定に入れると、モデル一覧が合わない、リクエストが 404/400 になる、ストリーミングレスポンスを Codex が正しく解析できない、といった問題が起きがちです。

CC Switch では、Codex が常にローカルルートへ接続し、Responses API のままリクエストを送るようにします。ルート内部で現在のプロバイダーが Chat 形式かどうかを判定し、必要ならリクエストを Chat Completions に書き換えて上流へ送り、最後に Chat レスポンスを Codex が理解できる Responses 形式へ戻します。

この経路は主に 4 つのステップに分かれます:

  1. Codex ルーティングを有効にすると、ローカル設定は http://127.0.0.1:15721/v1 に書き換えられ、wire_api = "responses" は維持されます。
  2. Provider の meta.apiFormat = "openai_chat" が、実際の上流は Chat Completions だとルートに伝えます。
  3. ルートは /responses または /v1/responses を /chat/completions に書き換え、Responses のリクエストボディを Chat のリクエストボディへ変換します。
  4. 上流から返ってきた後、ルートは Chat の JSON または SSE ストリームを Responses JSON/SSE へ変換して返します。

上流がもともとネイティブ Responses のプロバイダー(現在の DeepSeek プリセットなど)では、ステップ 2〜4 は発生しません。リクエストはそのまま上流へ送られ、形式の書き換えは一切行われません。

事前準備

先に次の 3 つを用意してください:

  • インストール済みで起動できる CC Switch。
  • インストール済みの Codex CLI。少なくとも 1 回は実行し、~/.codex/config.toml のディレクトリ構造が存在していること。
  • 対象プロバイダーの API Key。

OpenAI 互換 base URL の書き方は各社でまちまちです。よくあるのは /v1 付きのもの(たとえば SiliconFlow の https://api.siliconflow.cn/v1)で、より長いパスのものもあります(たとえば Baidu Qianfan Coding Plan の https://qianfan.baidubce.com/v2/coding)。Chat API のパスは /chat/completions です。CC Switch のプリセットには各社のドキュメントに従った設定がすでに入っているため、まずはプリセットを使い、エンドポイントパスを手で組み立てる必要はありません。

Step 1: Codex プロバイダーを追加する

CC Switch を開き、上部の Codex タブへ切り替え、右上のプラスボタンからプロバイダーを追加します。

プリセットを使う(推奨): プリセット一覧から対象プロバイダーを選び、API Key を入力して保存するだけです。プリセットにはリクエスト先、デフォルトモデル、モデルメニューがすでに含まれ、上流フォーマットも自動的に設定されます。Chat 形式のプリセットは保存するとカードに ルーティングが必要 バッジが表示されます。thinking / reasoning パラメータもプリセットで設定済みのため、手動入力は不要です。

カスタム設定を使う: 相手側のドキュメントに従って API Key と base URL を入力し、フォーム下部の 詳細オプション を展開して、上流フォーマット を Chat Completions(ルーティング必須) に設定します。このドロップダウンには 3 つの選択肢があります:

  • Responses(ネイティブ)——上流が Responses API をネイティブにサポートしている場合。変換なしで直結でき、ルーティングは不要です。
  • Chat Completions(ルーティング必須)——本記事が扱うケースです。
  • Anthropic Messages(ルーティング必須)——上流がネイティブ Anthropic プロトコルのみを提供している場合。こちらもルーティングが変換します。

ルーティング接管が不要なのは Responses(ネイティブ) だけで、残りの 2 つは必要です。カスタムプロバイダーの thinking パラメータは CC Switch が名前とアドレスから自動推論するため、推論が正しくないときにだけ 思考能力 を展開して手動で上書きしてください。

既存の DeepSeek プロバイダーを移行する場合: 上流フォーマット を Responses(ネイティブ) に変更するだけでよく、削除して作り直す必要はありません。次回そのプロバイダーへ切り替えたとき、CC Switch が deepseek.com のアドレスを認識して DeepSeek 公式のモデルカタログを適用するため、freeform apply_patch、GPT-5 harness、low/high/max の思考レベル、web_search はいずれも通常どおり有効になります。

唯一わずかに異なるのはコンテキストウィンドウです。プロバイダー自身が保存したモデル行のほうが優先されるため、3.19.1 より前に保存された 1000000 が公式宣言の 1048576 を上書きし、4 万トークン強が失われます。気になる場合は 詳細オプション → モデルマッピング でその行の コンテキストウィンドウ を 1048576 に変更するか、いっそプリセットから新規作成してください。

なお、直結で使われる公式モデルカタログは Codex CLI 0.144.0 以降を必要とします(カタログに含まれる freeform apply_patch の登録がこのバージョンを要求します)。CC Switch はこれを検証しません。また、生成されるカタログファイルは GPT-5 harness の全文を含むため 75 KB 程度まで大きくなります。

Step 2: ローカルルーティングを有効にして Codex をルーティングする

設定の ルーティング ページに入り、ローカルルーティング を展開して、次の 2 つのスイッチを設定します:

  1. ルーティング総スイッチ をオンにしてローカルサービスを起動します。デフォルトアドレスは 127.0.0.1:15721 です。
  2. ルーティング有効 で Codex をオンにします。Codex だけをルーティングしたい場合は、Claude と Gemini はオフのままで構いません。

ルーティングを有効にすると、CC Switch は Codex の live 設定をローカルルートへ向け、認証はプレースホルダーで管理します。実際の API Key は CC Switch の Provider 設定内に残り、ローカルルートが転送時に注入します。そのため、Codex の live 設定に Key を露出させる必要はありません。

Step 3: プロバイダーを切り替えて Codex を再起動する

Codex プロバイダー一覧に戻り、対象プロバイダーの 有効化 をクリックします。ルーティングが必要 の表示があるのにルーティングが起動していない場合、CC Switch は「ルーティングサービスが必要」という趣旨のメッセージを表示します。

切り替え後は、現在の Codex ターミナルセッションを再起動することをおすすめします。理由は次のとおりです:

  • Codex プロセスがすでに古い config.toml を読み込んでいる可能性があります。
  • model_catalog_json の生成後、/model メニューの更新には通常、新しいプロセスが必要です。

Codex に入ったら、/model で現在のモデルが該当プリセット由来かどうかを確認します。その後、小さな質問を 1 つ送って、ルーティングパネルのリクエスト数が増えるか、usage / リクエストログに Codex リクエストが出るかを確認します。

直結に切り替えると、使用量の帰属が変わる

これは単独で触れておく価値があります。プロバイダーが直結に変わると、そのリクエストはローカルルートを通らなくなるため、リクエスト単位で計上するプロキシ使用量統計からは見えなくなります。

使用量そのものが失われるわけではありません——Codex のセッションログ取り込みは通常どおり記録します——ただしこの経路はプロバイダーの識別情報を持ちません。ローカルプロキシを通らなかった Codex の使用量は、すべて Codex (Session) という 1 つの項目にまとめられます。見分けるにはモデルを見てください: 各使用量レコードはそれぞれのモデル ID を保持しており、使用量パネルの モデル統計 がモデルごとに行を分けて表示するため、費用もトークンも別々に確認できます。

プロバイダー単位で突き合わせる必要が本当にある場合(複数の集約サービスで同じモデルを比較する場合など)は、上流フォーマット を Chat のままにして、ルーティング接管を有効にしておいてください。

よくある質問

Codex が 404 を返す、または /responses が見つからない

多くの場合、Codex ルーティングが有効になっていないか、上流 Chat base URL を手動で Codex に直接書いています。~/.codex/config.toml が http://127.0.0.1:15721/v1 を指しているか確認してください。

上流が 404 を返す

内蔵プリセットを使っている場合は、まず現在のプロバイダーが本当にプリセット由来であること、そして Codex ルーティングが有効であることを確認してください。カスタムプロバイダーを使っている場合だけ、base URL を追加で確認します。base URL は相手側のドキュメントが示すサービスエンドポイントであり、/chat/completions 付きの完全なエンドポイントパスではありません。

/model にプロバイダーのモデルが表示されない

プロバイダーを保存した後、Codex を再起動してください。CC Switch は cc-switch-model-catalog.json を生成し、そのパスを model_catalog_json に書き込みますが、実行中の Codex プロセスがモデルカタログをホットロードするとは限りません。
現在の Codex app は複数モデル選択に対応していないため、設定内の最初のモデルをデフォルトで使用します。
コマンドラインの /model は正常なのに Codex デスクトップアプリのモデルセレクタでカスタムモデルが見えない場合、それは Codex デスクトップアプリ上流自身のモデルゲーティング挙動です。詳しくは Codex デスクトップアプリでカスタムモデルが見えない?(よくある質問) を参照してください。

ルーティングを有効にしたのに、リクエストが別のプロバイダーへ行く

次の 3 つの状態が一致しているか確認してください:Codex タブの現在のプロバイダーが正しいこと、ローカルルーティングサービスが実行中であること、ルーティング有効 で Codex スイッチがオンであること。

公式 OpenAI Codex アカウントをローカルルーティング経由で使えますか

おすすめしません。CC Switch はローカルルーティング有効中、公式プロバイダーへの切り替えをブロックします。プロキシ経由で公式 API にアクセスすると、アカウントリスクが発生する可能性があるためです。ルーティングは主にサードパーティ、集約サービス、またはプロトコル変換のための機能です。

参考リンク


Guides Codex Deepseek Routing Guide Zh (`docs/guides/codex-deepseek-routing-guide-zh.md`)

在 Codex 中使用 Chat 格式 API:本地路由攻略与 DeepSeek 迁移说明

适用版本:CC Switch 3.20.4 及以上。本文根据仓库内文档与代码整理。截图使用去敏示例数据生成,避免泄露真实 API Key 或账户余额。

DeepSeek 用户多数已不需要本文:3.19.1 起 DeepSeek 预设改为原生 Responses 直连,deepseek-v4-pro 也已可以直连。本文现在主要写给两类读者:仍是 Chat 格式的供应商(如 SiliconFlow、ModelScope),以及 3.19.1 之前保存、仍走 Chat 的 DeepSeek 旧卡片。请先读下一节,确认你属于哪种情况。

先确认你是否还需要这篇攻略

判断方法只有一个,看 Codex 供应商卡片上有没有 需要路由 徽章:

  • 带 需要路由 徽章 → 这个供应商走 Chat 格式,本文全部适用。
  • 没有徽章 → 它已经是 Responses 原生直连,本文的路由步骤对它没有意义,可以直接用。
  • 带 不支持路由 徽章 → 这是官方供应商,CC Switch 会阻止它走本地路由(见文末常见问题)。

徽章由供应商保存时记录的 API 格式决定,所以升级 CC Switch 不会改变已有供应商的行为。具体到 DeepSeek,有三种情况:

你的情况 是否需要路由 说明
3.19.1 之前保存的 DeepSeek 供应商 需要,仍带徽章 预设改动只影响新建的供应商,已保存的配置原样保留;想改走直连见第一步末尾
3.19.1 之后用预设新建的 DeepSeek 不需要 直连 api.deepseek.com,并会拿到 DeepSeek 官方的模型目录;3.20.4 起预设默认模型为 deepseek-flash(V4.1 Flash)
想用 deepseek-v4-pro 不需要 DeepSeek 已于 2026 年 8 月为该模型开通 Codex 集成,直连即可;预设的模型菜单里已包含它

不只 DeepSeek,Kimi、智谱 GLM、MiniMax、千问AI平台的 Codex 预设也已先后改为原生直连。目前仍是 Chat 格式、需要本文的预设主要有 SiliconFlow、ModelScope、腾讯 Token Plan 系列、百度千帆 Coding Plan / Token Plan、StepFun 等,下文的步骤对它们完全适用。

为什么需要本地路由

新版 Codex CLI 面向的是 OpenAI Responses API,而很多供应商实际暴露的是 OpenAI Chat Completions 形态,也就是 /chat/completions。这两种协议的请求体、流式事件和返回结构不同,直接把 Chat 接口填进 Codex 配置里,常见结果就是模型列表不对、请求 404/400,或者流式响应无法被 Codex 正确解析。

CC Switch 的做法是让 Codex 始终连本机路由,仍以 Responses API 发送请求;路由在内部识别当前供应商是否是 Chat 格式,再把请求改写成 Chat Completions 发给上游,最后把 Chat 响应转换回 Responses 形态返回给 Codex。

这条链路主要分成四步:

  1. Codex 接管时,本地配置会被写成 http://127.0.0.1:15721/v1,并强制保持 wire_api = "responses"。
  2. Provider 的 meta.apiFormat = "openai_chat" 会告诉路由:真实上游是 Chat Completions。
  3. 路由把 /responses 或 /v1/responses 改写到 /chat/completions,并把 Responses 请求体转换成 Chat 请求体。
  4. 上游返回后,路由再把 Chat 的 JSON 或 SSE 转回 Codex 能理解的 Responses JSON/SSE。

供应商原生就是 Responses 的(如现在的 DeepSeek 预设),第 2~4 步不发生:请求直接发往上游,不做任何格式改写。

准备工作

你需要先准备好三样东西:

  • 已安装并能启动的 CC Switch。
  • 已安装 Codex CLI,并至少运行过一次,让 ~/.codex/config.toml 目录结构存在。
  • 目标供应商的 API Key。

各家 OpenAI 兼容 base URL 的写法不一:常见的是带 /v1(例如 SiliconFlow 的 https://api.siliconflow.cn/v1),也有路径更长的(例如百度千帆 Coding Plan 的 https://qianfan.baidubce.com/v2/coding),Chat API 路径则是 /chat/completions。CC Switch 的预设已按各家文档配好,请优先使用预设,不需要手动拼接口路径。

第一步:添加 Codex 供应商

打开 CC Switch,切到顶部的 Codex 标签,点击右上角的加号添加供应商。

用预设(推荐):在预设列表里选中目标供应商,填入 API Key,保存即可。预设已经内置请求地址、默认模型、模型菜单,并会自动设好上游格式;Chat 格式的预设保存后卡片上就会出现 需要路由 徽章。思考参数(thinking / reasoning)预设已自动配置好,不需要手动填。

用自定义配置:按对方文档填 API Key 和 base URL,然后展开表单底部的 高级选项,把 上游格式 选为 Chat Completions(需开启路由)。这个下拉共有三个选项:

  • Responses(原生)——上游原生支持 Responses API,直连不转换,无需路由。
  • Chat Completions(需开启路由)——本文讲的情况。
  • Anthropic Messages(需开启路由)——上游只提供原生 Anthropic 协议,同样由路由转换。

只有 Responses(原生) 不需要开启路由接管,另外两个都需要。自定义供应商的思考参数由 CC Switch 按名称与地址自动推断,只有在识别不准时才需要展开 思考能力 手动覆盖。

改造已有的 DeepSeek 供应商:把 上游格式 改成 Responses(原生) 即可,不必删掉重建。下次切换到它时,CC Switch 会认出 deepseek.com 地址并套用 DeepSeek 官方的模型目录,freeform apply_patch、GPT-5 harness、low/high/max 思考档与 web_search 都会照常生效。

唯一的小差别是上下文窗口:供应商自己保存的模型行优先级更高,3.19.1 之前存下的 1000000 会盖掉官方声明的 1048576,少 4 万多 token。介意的话,在 高级选项 → 模型映射 里把该行的 上下文窗口 改成 1048576 就行,或者干脆用预设新建一个。

另外,直连所用的官方模型目录要求 Codex CLI 0.144.0 或更新(它带的 freeform apply_patch 注册需要这个版本),CC Switch 不会替你校验;生成的目录文件也会涨到 75 KB 左右,因为其中包含完整的 GPT-5 harness 文本。

第二步:开启本地路由并接管 Codex

进入设置里的 路由 页面,展开 本地路由,完成两个开关:

  1. 打开 路由总开关,启动本地服务。默认地址是 127.0.0.1:15721。
  2. 在 路由启用 中打开 Codex。如果只想让 Codex 走路由,可以保持 Claude、Gemini 关闭。

接管后,CC Switch 会把 Codex 的 live 配置指向本机路由,并用占位符管理认证。真实 API Key 仍保存在 CC Switch 的 Provider 配置里,由本地路由在转发时注入,不需要你把 Key 暴露给 Codex live 配置。

第三步:切换供应商并重启 Codex

回到 Codex 供应商列表,点击目标供应商的 启用。如果它带 需要路由 标记而路由没有启动,CC Switch 会弹出“需要路由服务才能正常使用”的提示。

切换后建议重启当前 Codex 终端会话。原因是:

  • Codex 进程可能已经读取过旧的 config.toml。
  • model_catalog_json 生成后,/model 菜单通常需要新进程才能刷新。

进入 Codex 后,可以用 /model 查看当前模型是否来自对应预设。随后发一个小问题,确认路由面板的请求数增长,或者在用量/请求日志里看到 Codex 请求即可。

走直连之后,用量归属会变

这一点值得单独提醒:供应商改走直连后,它的请求不再经过本地路由,按请求计费的代理用量统计也就看不到它了。

用量本身不会丢——Codex 的会话日志导入照常记录——但这条路径不携带供应商身份:所有没走本地代理的 Codex 用量会一起归入名为 Codex (Session) 的条目。要区分它们,看模型:每条用量记录都带着自己的模型 ID,用量面板的「模型统计」按模型逐行列出,费用与 token 都是分开的。

如果你确实需要按供应商维度对账(比如比较多个聚合商上的同一个模型),那就保持 上游格式 为 Chat 并开着路由接管。

常见问题

Codex 报 404 或找不到 /responses

通常是没有开启 Codex 接管,或者你手动把上游 Chat base URL 直接写给了 Codex。检查 ~/.codex/config.toml 是否指向 http://127.0.0.1:15721/v1。

上游报 404

如果用的是内置预设,先确认当前供应商确实来自预设,并且 Codex 路由已启用。只有在使用自定义供应商时,才需要额外检查 base URL:它应该是对方文档给出的服务端点,而不是带 /chat/completions 的完整接口路径。

/model 看不到供应商的模型

保存供应商后重启 Codex。CC Switch 会生成 cc-switch-model-catalog.json 并把路径写入 model_catalog_json,但正在运行的 Codex 进程不一定会热加载模型目录。
目前 Codex app 不支持多模型选择,默认使用配置的第一个模型。
如果命令行 /model 正常,但 Codex 桌面应用的模型选择器仍看不到自定义模型,这是 Codex 桌面应用上游自身的模型门控行为,详见 Codex 桌面应用里看不到自定义模型?(常见问题)。

开了路由但请求仍走错供应商

确认三处状态一致:Codex 标签下当前供应商正确;本地路由服务正在运行;路由启用 里 Codex 开关已打开。

可以用官方 OpenAI Codex 账号走本地路由吗

不建议。CC Switch 会在本地路由接管模式下阻止切到官方供应商,因为用代理访问官方 API 可能带来账号风险。路由主要用于第三方、聚合或协议转换场景。

参考链接


Guides Codex Desktop Custom Model Visibility En (`docs/guides/codex-desktop-custom-model-visibility-en.md`)

Can't See Custom Models in the Codex Desktop App? (FAQ)

Applies to CC Switch v3.16.1 and later. This article explains "why the Codex desktop app can't see custom models" and the available mitigation; for the detailed step-by-step setup with screenshots, see Keep Codex Remote Control and Official Plugins While Using Third-Party APIs.

Symptom

After you switch Codex to a third-party / custom model in CC Switch (DeepSeek, Kimi, GLM, MiniMax, an aggregator, etc.):

  • The model picker in the Codex desktop app doesn't show these custom models — often only the official default model remains, and the reasoning level falls back to the official default;
  • but everything works fine in the command-line codex /model menu.

Many users have run into this. Here's why, and what you can do about it.

Why this happens

This is not a CC Switch local-config problem and not a CC Switch bug — it is the Codex desktop app's (the upstream closed-source client's) own model-gating behavior.

The Codex desktop app's model picker decides which models to allow based on your current login identity: when it can't detect an official ChatGPT / Codex login state, it forces the picker back to the official default model and hides the custom models you configured through config.toml (the reasoning level falls back to the official default too). The upstream has marked "exposing custom-provider models in the desktop GUI" as not planned, so CC Switch cannot fully fix this at the desktop-GUI level.

The command-line codex /model menu and request routing both recognize the custom providers in config.toml correctly — only the desktop GUI picker is constrained by this gating layer.

Mitigation: keep the official login

The workaround is to keep the official login state so the desktop app's gating allows your custom models through. The key points are below (the full step-by-step setup with screenshots is in the linked guide):

  1. Log in once with an official ChatGPT / Codex account in Codex (a Free subscription is enough) to keep the official login state.
  2. In CC Switch, enable Settings -> General -> Codex App Enhancements -> Keep official login for direct switches (off by default). While routing takeover is enabled, the official login is always preserved, regardless of this toggle.
  3. If this third-party provider shows the Needs Routing badge (Chat Completions protocol, such as SiliconFlow or ModelScope), enable local routing and route Codex through it; presets that connect directly, such as DeepSeek, Kimi, and MiniMax, do not need this step.
  4. Fully quit and restart Codex.

Once enabled, CC Switch preserves the official login state in ~/.codex/auth.json when switching to a third-party provider and writes the third-party key into config.toml, so the desktop app still recognizes the official login identity, the gating lets your models through, and the custom models you configured reappear in the picker. The preserved official token is never sent to the third party — third-party model requests are still sent with the key you configured (forwarded through the local route when routing takeover is enabled).

Detailed step-by-step setup: Keep Codex Remote Control and Official Plugins While Using Third-Party APIs

Still can't see them?

  • Confirm the toggle is on: this toggle is off by default, and while it is off, a direct switch to a third-party provider deletes auth.json. That is how many people lose the official login state the first time they switch to a third-party provider, which is exactly why the models disappear — follow steps 1 and 2 above.
  • The official login state expires: if you haven't used the official login for several days, the picker may go empty again once the token expires — log in to the official account once more to restore it.
  • Command-line fallback diagnosis: run codex debug models to list the models actually available on the CLI side and confirm the model itself is configured correctly (the CLI is unaffected by this gating).
  • Individual Codex desktop versions may behave slightly differently; this is in the upstream client's domain, and no CC Switch version can fully fix it at the desktop-GUI level.

References


Guides Codex Desktop Custom Model Visibility Ja (`docs/guides/codex-desktop-custom-model-visibility-ja.md`)

Codex デスクトップアプリでカスタムモデルが見えない?(よくある質問)

対象バージョン: CC Switch v3.16.1 以降。本記事は「なぜ Codex デスクトップアプリでカスタムモデルが見えないのか」と、使える緩和策を解説します。図入りの詳細な設定手順は サードパーティ API 利用時に Codex のリモート操作と公式プラグインを保持する を参照してください。

現象

CC Switch で Codex をサードパーティ / カスタムモデル(DeepSeek、Kimi、GLM、MiniMax、中継サービスなど)へ切り替えた後:

  • Codex デスクトップアプリのモデルセレクタにこれらのカスタムモデルが表示されず、多くの場合は公式の既定モデルだけが残り、思考レベルも公式の既定へ戻ってしまう。
  • 一方でコマンドライン codex の /model ではすべて正常に表示される。

多くのユーザーがこの現象に遭遇しています。以下で原因と対処を解説します。

なぜこうなるのか

これは CC Switch のローカル設定の問題でも、CC Switch のバグでもありません。Codex デスクトップアプリ(上流のクローズドソースクライアント)自身のモデルゲーティング挙動です。

Codex デスクトップアプリのモデルセレクタは、あなたの現在のログイン ID に応じてどのモデルを通すかを決めます。公式 ChatGPT / Codex のログイン状態を検出できないとき、セレクタを公式の既定モデルへ強制的に戻し、config.toml で設定したカスタムモデルを隠します(思考レベルもあわせて公式の既定へ戻ります)。公式は「デスクトップ GUI でカスタムプロバイダーのモデルを公開する」ことを not planned としてマークしているため、CC Switch がデスクトップ GUI のレベルでこれを根本的に修正することはできません。

コマンドライン codex の /model とリクエストルーティングは config.toml 内のカスタムプロバイダーを正常に認識できます。デスクトップ GUI のセレクタだけがこのゲーティングの制限を受けます。

緩和策: 公式ログインを保持する

対処は公式ログイン状態を保持することで、デスクトップアプリのゲーティングにあなたのカスタムモデルを通させます。要点は次のとおりです(完全な図入り手順は下のリンク先のガイドを参照してください):

  1. まず Codex で公式 ChatGPT / Codex に一度ログインし(Free サブスクリプションで構いません)、公式ログイン状態を保持する。
  2. CC Switch で 設定 → 一般 → Codex アプリ拡張 → 直接切替時に公式ログインを保持 をオンにする(デフォルトはオフ)。ルーティング接管中は、このスイッチに関係なく公式ログインが常に保持されます。
  3. そのサードパーティプロバイダーに ルーティングが必要 バッジが付いている場合(Chat Completions プロトコル。たとえば SiliconFlow、ModelScope)は、ローカルルーティングを有効化し、Codex のルーティングをオンにする。DeepSeek、Kimi、MiniMax などネイティブ直結のプリセットでは、この手順は不要です。
  4. Codex を完全に終了して再起動する。

オンにすると、CC Switch はサードパーティプロバイダーへ切り替える際に ~/.codex/auth.json 内の公式ログイン状態を保持し、サードパーティの Key を config.toml へ書き込みます。これにより、デスクトップアプリは引き続き公式ログイン ID を認識してゲーティングを通すため、設定したカスタムモデルがセレクタに再び表示されます。保持された公式 Token がサードパーティへ送られることはありません——サードパーティのモデルリクエストは引き続き、設定した Key で送られます(ルーティング接管を有効にしている場合はローカルルーティング経由で転送されます)。

詳細な図入り手順: サードパーティ API 利用時に Codex のリモート操作と公式プラグインを保持する

それでも見えない場合は

  • スイッチがオンか確認する: このスイッチはデフォルトでオフで、オフのままルーティング接管なしでサードパーティへ切り替える(直接切替)と auth.json が削除されます。多くの人は初めてサードパーティへ切り替えたときにこうして公式ログイン状態を失っており、その結果見えなくなっています——上記の手順 1、2 に従って操作してください。
  • 公式ログイン状態は期限切れになる: 数日間公式ログインを使わないと、Token が失効した後にセレクタが再び空になることがあります——公式に一度ログインし直せば回復します。
  • コマンドラインでの確認: codex debug models を使うと CLI 側で実際に利用可能なモデルを一覧でき、モデル自体が正しく設定されていることを確認できます(CLI はこのゲーティングの影響を受けません)。
  • 個々の Codex デスクトップ版で挙動が多少異なる場合があります。これは上流クライアントの範疇であり、CC Switch のどのバージョンでもデスクトップ GUI のレベルで根本解決することはできません。

参考リンク


Guides Codex Desktop Custom Model Visibility Zh (`docs/guides/codex-desktop-custom-model-visibility-zh.md`)

Codex 桌面应用里看不到自定义模型?(常见问题)

适用版本:CC Switch v3.16.1 及以上。本文解释「为什么 Codex 桌面应用看不到自定义模型」以及可用的缓解办法;详细的图文配置步骤见 使用第三方 API 时保留 Codex 远程操作和官方插件。

现象

在 CC Switch 里把 Codex 切换到第三方 / 自定义模型(DeepSeek、Kimi、GLM、MiniMax、中转站等)后:

  • Codex 桌面应用的模型选择器里看不到这些自定义模型,往往只剩官方默认模型,思考等级也回落到官方默认;
  • 但命令行 codex 的 /model 里一切正常。

很多用户都遇到过这个现象,下面解释原因与办法。

为什么会这样

这不是 CC Switch 的本地配置问题,也不是 CC Switch 的 bug,而是 Codex 桌面应用(上游闭源客户端)自身的模型门控行为。

Codex 桌面应用的模型选择器会按你当前的登录身份来决定放行哪些模型:当它检测不到官方 ChatGPT / Codex 登录态时,会把选择器强制回落到官方默认模型,把你通过 config.toml 配置的自定义模型藏起来(思考等级也会一并回落到官方默认)。官方已把「在桌面 GUI 里暴露自定义供应商模型」标记为 not planned,因此 CC Switch 无法从桌面 GUI 层面彻底修复它。

命令行 codex 的 /model 与请求路由都能正常识别 config.toml 里的自定义供应商,唯独桌面 GUI 的选择器受这层门控限制。

怎么缓解:保留官方登录

办法是保留官方登录态,让桌面应用的门控放行你的自定义模型。要点如下(完整图文步骤见下方链接的攻略):

  1. 先在 Codex 里登录一次官方 ChatGPT / Codex(Free 订阅即可),保留官方登录态。
  2. 在 CC Switch 开启 设置 → 通用 → Codex 应用增强 → 非接管切换时保留官方登录(默认关闭)。开启路由接管期间官方登录始终保留,不受这个开关影响。
  3. 如果该第三方供应商带 需要路由 徽章(Chat Completions 协议,如 SiliconFlow、ModelScope),开启本地路由并接管 Codex;DeepSeek、Kimi、MiniMax 等原生直连的预设不需要这一步。
  4. 完全退出并重启 Codex。

开启后,CC Switch 在切换第三方供应商时会保留 ~/.codex/auth.json 里的官方登录态、把第三方 Key 写进 config.toml,于是桌面应用仍识别官方登录身份、门控放行,你配置的自定义模型就会重新出现在选择器里。保留的官方 Token 不会被发往第三方——第三方模型请求仍用你配置的 Key 发出(开启路由接管时经本地路由转发)。

详细图文步骤:使用第三方 API 时保留 Codex 远程操作和官方插件

仍然看不到怎么办

  • 确认开关已开:该开关默认关闭,关闭时直连切到第三方会删除 auth.json。很多人第一次切到第三方就这样丢了官方登录态,所以才看不到——按上面第 1、2 步操作即可。
  • 官方登录态会过期:如果连续几天没用过官方登录,Token 失效后选择器可能又变空——重新登录一次官方即可恢复。
  • 命令行兜底诊断:用 codex debug models 可以列出 CLI 端实际可用的模型,确认模型本身已正确配置(CLI 不受此门控影响)。
  • 个别 Codex 桌面版本的行为可能略有差异;这属于上游客户端范畴,CC Switch 各版本都无法从桌面 GUI 层根治。

参考链接


Guides Codex Kimi Routing Guide En (`docs/guides/codex-kimi-routing-guide-en.md`)

Use Kimi in Codex: Direct Connections and Legacy Routing

Since v3.20.3: Prefer Native Responses Connections

The official Codex presets for the Kimi Open Platform and Kimi For Coding now use Responses, without local routing for protocol conversion. Existing cards retain their original preset snapshot and do not update automatically.

  1. Upgrade to CC Switch v3.20.3 or later. In the Codex tab, choose the latest Kimi or Kimi For Coding preset according to where your API key comes from. For a key from the international site (kimi.ai), choose Kimi Global or Kimi For Coding Global (available since v3.20.4).
  2. Enter the matching API key, save and enable the provider. For an older card, adding the preset again is recommended; for manual migration, verify the endpoint and change Upstream Format to Responses.
  3. Restart Codex to load the configuration and model catalog. Native Responses can also use standard proxy routing, but Responses-to-Chat conversion is no longer required.

See the v3.20.3 release notes and Adding Providers. The following instructions and screenshots describe legacy Chat configurations, retained for troubleshooting existing Chat cards; they do not describe the latest presets.

Applies to CC Switch 3.16.5 and nearby versions. This guide is based on the repository documentation and code, and uses Kimi as an example of an OpenAI Chat Completions-compatible API. Screenshots are generated from the current frontend UI with de-identified sample data to avoid exposing a real API key or account balance.

Why Legacy Chat Configurations Need Local Routing

The newer Codex CLI targets the OpenAI Responses API, while both the Kimi Open Platform and Kimi For Coding expose the OpenAI Chat Completions shape, /chat/completions. These two protocols use different request bodies, streaming events, and response structures. If you put a Kimi endpoint directly into Codex configuration, the usual result is a 404 on /responses, or streaming responses that Codex cannot parse correctly.

When this guide was first written, Kimi For Coding did not officially support Codex. Legacy Chat configurations needed a protocol conversion layer, which CC Switch Local Routing provided. The newer Responses presets no longer have this limitation.

CC Switch solves this by making Codex always talk to a local route and continue sending Responses API requests. The route detects whether the active provider is Chat-format, rewrites the request into Chat Completions for the upstream provider, and finally converts the Chat response back into the Responses shape that Codex understands.

The chain has four main steps:

  1. When Codex routing is enabled, the local configuration is written as http://127.0.0.1:15721/v1, while wire_api = "responses" is kept in place.
  2. The provider's meta.apiFormat = "openai_chat" tells the route that the real upstream is Chat Completions.
  3. The route rewrites /responses or /v1/responses to /chat/completions, and converts the Responses request body into a Chat request body.
  4. After the upstream responds, the route converts the Chat JSON or SSE stream back into Responses JSON/SSE.

Prerequisites

Prepare these three things first:

  • CC Switch installed and able to start.
  • Codex CLI installed and run at least once, so the ~/.codex/config.toml directory structure exists.
  • A Kimi API key.

Kimi API keys come from two different places, matching two different built-in presets in CC Switch:

  • Kimi Open Platform (platform.kimi.com): pay-as-you-go API keys billed by token usage, matching the Kimi preset. The OpenAI-compatible base URL is https://api.moonshot.cn/v1 and the default model is kimi-k2.7-code.
  • Kimi For Coding (kimi.com/code): a dedicated key generated from the Kimi Code membership benefits, matching the Kimi For Coding preset. The base URL is https://api.kimi.com/coding/v1 and the unified model is kimi-for-coding.

Both presets already contain the correct endpoint and model details, so prefer the presets and do not manually assemble the endpoint path.

Step 1: Add a Codex provider

Open CC Switch, switch to the top-level Codex tab, and click the plus button in the upper-right corner to add a provider.

Depending on which kind of key you have, choose the built-in Kimi preset (Open Platform, pay-as-you-go) or Kimi For Coding preset (membership subscription). You only need to do two things:

  • Enter the matching Kimi API key.
  • Save the provider.

The preset already includes Kimi's request base URL, default model, model menu, thinking/reasoning parameters, and presets Upstream Format under Advanced Options to Chat Completions (routing required). You can adjust the default model or model display names if needed — for example, the Open Platform preset defaults to kimi-k2.7-code, and you can switch to kimi-k2.7-code-highspeed following the official documentation. The protocol conversion is handled by the routing layer.

Step 2: Enable local routing and route Codex

Go to the Routing page in Settings, expand Local Routing, and complete two toggles:

  1. Turn on the Routing Master Switch to start the local service. The default address is 127.0.0.1:15721.
  2. Turn on Codex under Routing Enabled. If you only want Codex to use local routing, you can leave Claude and Gemini off.

After routing is enabled, CC Switch points Codex's live configuration to the local route and manages authentication with a placeholder. The real Kimi key stays in the CC Switch provider configuration and is injected by the local route while forwarding requests, so you do not need to expose the key in Codex's live configuration.

Step 3: Switch providers and restart Codex

Return to the Codex provider list and click Enable on the Kimi provider. If you see the Needs Routing marker, that provider must be used while routing is running; when the route is not started, CC Switch shows a prompt saying the routing service is required.

After switching, restart the current Codex terminal session. This is recommended because:

  • The Codex process may already have read the old config.toml.
  • After model_catalog_json is generated, the /model menu usually needs a fresh process before it refreshes.

Inside Codex, use /model to check whether the current model comes from the Kimi preset, such as Kimi K2.7 Code or Kimi For Coding. The Codex app currently does not support multi-model selection, so it defaults to the first configured model. Then send a small test prompt and confirm that the request count increases in the routing panel, or that a Codex request appears in usage/request logs.

How to handle other Chat providers

SiliconFlow, ModelScope, and other common Chat-format providers already have presets in CC Switch, so use presets first. Only choose custom configuration for providers that are not covered by presets; in that case, fill in the API key, base URL, and models according to the provider's documentation, and set Upstream Format under Advanced Options to Chat Completions (routing required).

If the upstream provider directly supports the OpenAI Responses API, set Upstream Format to Responses; CC Switch then connects through Responses directly without Chat conversion.

FAQ

Codex reports 404 or cannot find /responses

Usually Codex routing is not enabled, or the Kimi Chat base URL was written directly into Codex manually — the Kimi upstream has no /responses endpoint, so that always 404s. Check whether ~/.codex/config.toml points to http://127.0.0.1:15721/v1.

Kimi upstream reports 401 or 403

First confirm the key matches the preset: Open Platform keys only work with the Kimi preset, and Kimi Code membership keys only work with the Kimi For Coding preset. The two key families are not interchangeable.

Kimi upstream reports 404

If you are using a built-in Kimi preset, first confirm that the active provider really comes from the preset and that Codex routing is enabled. Only custom providers require extra base URL checks: the base URL should be the service root, not the full endpoint path with /chat/completions.

/model does not show Kimi models

Restart Codex after saving the provider. CC Switch generates cc-switch-model-catalog.json and writes its path to model_catalog_json, but a running Codex process may not hot-load the model catalog.
The Codex app currently does not support multi-model selection, so it uses the first configured model by default.
If the command-line /model menu works but the Codex desktop app model picker still cannot see custom models, that is the upstream Codex desktop app's own model-gating behavior. See Can't See Custom Models in the Codex Desktop App? (FAQ).

Routing is enabled, but requests still go to the wrong provider

Confirm that all three states match: the current provider under the Codex tab is Kimi; the local routing service is running; and the Codex toggle is enabled under Routing Enabled.

Can I use an official OpenAI Codex account through local routing?

Not recommended. CC Switch blocks switching to official providers while local routing takeover is enabled, because accessing official APIs through a proxy may create account risk. Routing is mainly intended for third-party, aggregator, or protocol-conversion scenarios.

References


Guides Codex Kimi Routing Guide Ja (`docs/guides/codex-kimi-routing-guide-ja.md`)

Codex で Kimi を使う: 直接接続と旧版ルーティング

v3.20.3 以降:ネイティブ Responses で直接接続

Kimi オープンプラットフォームと Kimi For Coding の公式 Codex プリセットは Responses に移行しました。プロトコル変換のためのローカルルーティングは不要です。既存カードには作成時のプリセットが保存されており、自動更新はされません。

  1. CC Switch v3.20.3 以降に更新し、Codex タブで API Key の発行元に応じた最新の Kimi または Kimi For Coding プリセットを選択します。国際版(kimi.ai)の Key には Kimi Global または Kimi For Coding Global(v3.20.4 から提供)を選択します。
  2. 対応する API Key を入力し、保存して有効にします。旧カードはプリセットの追加し直しを推奨します。手動で移行する場合は、エンドポイントを確認して「上流フォーマット」を Responses に変更します。
  3. Codex を再起動し、設定とモデルカタログを読み込みます。ネイティブ Responses を通常のプロキシ経由で転送することもできますが、Responses→Chat 変換は不要です。

詳細は v3.20.3 更新情報とプロバイダーの追加を参照してください。以下は既存の Chat カードのトラブルシュート用に残した旧版の手順と画像であり、最新プリセットの設定ではありません。

対象バージョン: CC Switch 3.16.5 およびその前後のバージョン。本記事はリポジトリ内のドキュメントとコードをもとに整理し、OpenAI Chat Completions 互換 API の例として Kimi を使用します。スクリーンショットは現在のフロントエンド UI から、実際の API Key やアカウント残高が漏れないよう匿名化したサンプルデータで生成しています。

旧版 Chat 設定にローカルルーティングが必要な理由

新しい Codex CLI は OpenAI Responses API を前提にしています。一方で Kimi オープンプラットフォームと Kimi For Coding が実際に公開しているのは、いずれも OpenAI Chat Completions 形式、つまり /chat/completions です。この 2 つのプロトコルは、リクエストボディ、ストリーミングイベント、レスポンス構造が異なります。Kimi のエンドポイントをそのまま Codex 設定に入れると、/responses へのリクエストが 404 になる、ストリーミングレスポンスを Codex が正しく解析できない、といった問題が起きがちです。

本記事の初稿時点では、Kimi For Coding は Codex を公式にサポートしておらず、旧版の Chat 設定にはプロトコル変換レイヤーが必要でした。その役割を CC Switch のローカルルーティングが担っていました。新しい Responses プリセットにはこの制限はありません。

CC Switch では、Codex が常にローカルルートへ接続し、Responses API のままリクエストを送るようにします。ルート内部で現在のプロバイダーが Chat 形式かどうかを判定し、必要ならリクエストを Chat Completions に書き換えて上流へ送り、最後に Chat レスポンスを Codex が理解できる Responses 形式へ戻します。

この経路は主に 4 つのステップに分かれます:

  1. Codex ルーティングを有効にすると、ローカル設定は http://127.0.0.1:15721/v1 に書き換えられ、wire_api = "responses" は維持されます。
  2. Provider の meta.apiFormat = "openai_chat" が、実際の上流は Chat Completions だとルートに伝えます。
  3. ルートは /responses または /v1/responses を /chat/completions に書き換え、Responses のリクエストボディを Chat のリクエストボディへ変換します。
  4. 上流から返ってきた後、ルートは Chat の JSON または SSE ストリームを Responses JSON/SSE へ変換して返します。

事前準備

先に次の 3 つを用意してください:

  • インストール済みで起動できる CC Switch。
  • インストール済みの Codex CLI。少なくとも 1 回は実行し、~/.codex/config.toml のディレクトリ構造が存在していること。
  • Kimi の API Key。

Kimi の API Key には 2 つの取得元があり、CC Switch の 2 つの内蔵プリセットに対応します:

  • Kimi オープンプラットフォーム(platform.kimi.com): トークン使用量に応じた従量課金の API Key。プリセット Kimi に対応し、OpenAI 互換 base URL は https://api.moonshot.cn/v1、デフォルトモデルは kimi-k2.7-code です。
  • Kimi For Coding(kimi.com/code): Kimi メンバーシップの Kimi Code 特典から生成する専用 Key。プリセット Kimi For Coding に対応し、base URL は https://api.kimi.com/coding/v1、モデルは kimi-for-coding に統一されています。

どちらのプリセットにも公式情報に基づくエンドポイントとモデルがすでに設定されているため、まずはプリセットを使い、エンドポイントパスを手で組み立てる必要はありません。

Step 1: Codex プロバイダーを追加する

CC Switch を開き、上部の Codex タブへ切り替え、右上のプラスボタンからプロバイダーを追加します。

手元の Key の種類に応じて、内蔵プリセットの Kimi(オープンプラットフォーム・従量課金)または Kimi For Coding(メンバーシップ)を選びます。必要なのは次の 2 つだけです:

  • 対応する Kimi API Key を入力する。
  • プロバイダーを保存する。

プリセットには Kimi のリクエスト先、デフォルトモデル、モデルメニュー、thinking/reasoning パラメータがすでに含まれており、詳細オプション の 上流フォーマット も Chat Completions(ルーティング必須) にプリセットされています。必要に応じてデフォルトモデルやモデル表示名を調整できます。たとえばオープンプラットフォームのプリセットはデフォルトが kimi-k2.7-code で、公式ドキュメントに従って kimi-k2.7-code-highspeed に変更することもできます。プロトコル変換はルーティング層に任せれば十分です。

Step 2: ローカルルーティングを有効にして Codex をルーティングする

設定の ルーティング ページに入り、ローカルルーティング を展開して、次の 2 つのスイッチを設定します:

  1. ルーティング総スイッチ をオンにしてローカルサービスを起動します。デフォルトアドレスは 127.0.0.1:15721 です。
  2. ルーティング有効 で Codex をオンにします。Codex だけをルーティングしたい場合は、Claude と Gemini はオフのままで構いません。

ルーティングを有効にすると、CC Switch は Codex の live 設定をローカルルートへ向け、認証はプレースホルダーで管理します。実際の Kimi Key は CC Switch の Provider 設定内に残り、ローカルルートが転送時に注入します。そのため、Codex の live 設定に Key を露出させる必要はありません。

Step 3: プロバイダーを切り替えて Codex を再起動する

Codex プロバイダー一覧に戻り、Kimi プロバイダーの 有効化 をクリックします。ルーティングが必要 の表示が見える場合、そのプロバイダーはルーティング実行中に使う必要があります。ルーティングが起動していない場合、CC Switch は「ルーティングサービスが必要」という趣旨のメッセージを表示します。

切り替え後は、現在の Codex ターミナルセッションを再起動することをおすすめします。理由は次のとおりです:

  • Codex プロセスがすでに古い config.toml を読み込んでいる可能性があります。
  • model_catalog_json の生成後、/model メニューの更新には通常、新しいプロセスが必要です。

Codex に入ったら、/model で現在のモデルが Kimi プリセット由来かどうかを確認します。たとえば Kimi K2.7 Code や Kimi For Coding などです。現在の Codex app は複数モデル選択に対応していないため、設定内の最初のモデルをデフォルトで使用します。その後、小さな質問を 1 つ送って、ルーティングパネルのリクエスト数が増えるか、usage / リクエストログに Codex リクエストが出るかを確認します。

他の Chat プロバイダーの場合

SiliconFlow、ModelScope など一般的な Chat 形式プロバイダーは CC Switch にプリセットがあるため、まずはプリセットを使ってください。プリセットにないプロバイダーだけ、カスタム設定を選びます。その場合は相手側のドキュメントに従って API Key、base URL、モデルを入力し、詳細オプション の 上流フォーマット を Chat Completions(ルーティング必須) に設定します。

上流が OpenAI Responses API を直接サポートしている場合は、上流フォーマット を Responses にすれば、CC Switch は Responses のまま直結でき、Chat 変換は行いません。

よくある質問

Codex が 404 を返す、または /responses が見つからない

多くの場合、Codex ルーティングが有効になっていないか、Kimi の Chat base URL を手動で Codex に直接書いています。Kimi の上流には /responses エンドポイントが存在しないため、必ず 404 になります。~/.codex/config.toml が http://127.0.0.1:15721/v1 を指しているか確認してください。

Kimi 上流が 401 または 403 を返す

まず Key とプリセットの組み合わせを確認してください。オープンプラットフォームの Key はプリセット Kimi 専用、Kimi Code 特典の Key はプリセット Kimi For Coding 専用で、2 種類の Key は相互に使えません。

Kimi 上流が 404 を返す

内蔵 Kimi プリセットを使っている場合は、まず現在のプロバイダーが本当にプリセット由来であること、そして Codex ルーティングが有効であることを確認してください。カスタムプロバイダーを使っている場合だけ、base URL を追加で確認します。base URL はサービスのルートであり、/chat/completions 付きの完全なエンドポイントパスではありません。

/model に Kimi モデルが表示されない

プロバイダーを保存した後、Codex を再起動してください。CC Switch は cc-switch-model-catalog.json を生成し、そのパスを model_catalog_json に書き込みますが、実行中の Codex プロセスがモデルカタログをホットロードするとは限りません。
現在の Codex app は複数モデル選択に対応していないため、設定内の最初のモデルをデフォルトで使用します。
コマンドラインの /model は正常なのに Codex デスクトップアプリのモデルセレクタでカスタムモデルが見えない場合、それは Codex デスクトップアプリ上流自身のモデルゲーティング挙動です。詳しくは Codex デスクトップアプリでカスタムモデルが見えない?(よくある質問) を参照してください。

ルーティングを有効にしたのに、リクエストが別のプロバイダーへ行く

次の 3 つの状態が一致しているか確認してください:Codex タブの現在のプロバイダーが Kimi であること、ローカルルーティングサービスが実行中であること、ルーティング有効 で Codex スイッチがオンであること。

公式 OpenAI Codex アカウントをローカルルーティング経由で使えますか

おすすめしません。CC Switch はローカルルーティング有効中、公式プロバイダーへの切り替えをブロックします。プロキシ経由で公式 API にアクセスすると、アカウントリスクが発生する可能性があるためです。ルーティングは主にサードパーティ、集約サービス、またはプロトコル変換のための機能です。

参考リンク


Guides Codex Kimi Routing Guide Zh (`docs/guides/codex-kimi-routing-guide-zh.md`)

在 Codex 中使用 Kimi:新版直连与旧版路由

v3.20.3 起:优先使用原生 Responses 直连

Kimi 开放平台和 Kimi For Coding 的官方 Codex 预设已切换为 Responses,无需为了协议转换开启本地路由。旧卡片保存的是创建时的快照,不会自动更新。

  1. 升级到 CC Switch v3.20.3 或更新版本,在 Codex 标签下按 API Key 来源选择最新的 Kimi 或 Kimi For Coding 预设。国际站(kimi.ai)的 Key 选 Kimi Global 或 Kimi For Coding Global(v3.20.4 起提供)。
  2. 填入对应 API Key,保存并启用。旧卡片建议重新添加预设;若手动迁移,确认端点正确后将「上游格式」改为 Responses。
  3. 重启 Codex,使配置和模型目录生效。原生 Responses 也可经标准代理转发,但不再需要 Responses→Chat 转换。

详见 v3.20.3 更新说明与添加供应商。下文保留的是旧版 Chat 格式教程与截图,仅供已有 Chat 卡片排障参考,不代表新版预设的配置。

适用版本:CC Switch 3.16.5 及附近版本。本文根据仓库内文档与代码整理,并用 Kimi 作为 OpenAI Chat Completions 兼容接口的示例。截图来自当前前端界面,使用去敏示例数据生成,避免泄露真实 API Key 或账户余额。

旧版 Chat 配置为什么需要本地路由

新版 Codex CLI 面向的是 OpenAI Responses API,而 Kimi 开放平台和 Kimi For Coding 实际暴露的都是 OpenAI Chat Completions 形态,也就是 /chat/completions。这两种协议的请求体、流式事件和返回结构不同,直接把 Kimi 的接口地址填进 Codex 配置里,常见结果就是请求 /responses 返回 404,或者流式响应无法被 Codex 正确解析。

本文最初编写时,Kimi For Coding 官方支持的第三方工具尚未覆盖 Codex,旧版 Chat 配置需要一层协议转换——这正是 CC Switch 本地路由做的事。新版 Responses 预设不再受此限制。

CC Switch 的做法是让 Codex 始终连本机路由,仍以 Responses API 发送请求;路由在内部识别当前供应商是否是 Chat 格式,再把请求改写成 Chat Completions 发给上游,最后把 Chat 响应转换回 Responses 形态返回给 Codex。

这条链路主要分成四步:

  1. Codex 接管时,本地配置会被写成 http://127.0.0.1:15721/v1,并强制保持 wire_api = "responses"。
  2. Provider 的 meta.apiFormat = "openai_chat" 会告诉路由:真实上游是 Chat Completions。
  3. 路由把 /responses 或 /v1/responses 改写到 /chat/completions,并把 Responses 请求体转换成 Chat 请求体。
  4. 上游返回后,路由再把 Chat 的 JSON 或 SSE 转回 Codex 能理解的 Responses JSON/SSE。

准备工作

你需要先准备好三样东西:

  • 已安装并能启动的 CC Switch。
  • 已安装 Codex CLI,并至少运行过一次,让 ~/.codex/config.toml 目录结构存在。
  • 一个 Kimi API Key。

Kimi 的 API Key 有两个来源,对应 CC Switch 里两个不同的内置预设:

  • Kimi 开放平台(platform.kimi.com):按 token 用量计费的 API Key,对应预设 Kimi,OpenAI 兼容 base URL 是 https://api.moonshot.cn/v1,默认模型 kimi-k2.7-code。
  • Kimi For Coding(kimi.com/code):Kimi 会员 Kimi Code 权益生成的专用 Key,对应预设 Kimi For Coding,base URL 是 https://api.kimi.com/coding/v1,模型统一为 kimi-for-coding。

两个预设都已经按官方信息配好接口地址和模型,请优先使用预设,不需要手动拼接口路径。

第一步:添加 Codex 供应商

打开 CC Switch,切到顶部的 Codex 标签,点击右上角的加号添加供应商。

按你手里 Key 的类型,在内置预设里选择 Kimi(开放平台按量计费)或 Kimi For Coding(会员订阅),然后只需要做两件事:

  • 填入对应的 Kimi API Key。
  • 保存供应商。

预设已经内置 Kimi 的请求地址、默认模型、模型菜单、thinking/reasoning 参数,并把 高级选项 里的 上游格式 预设为 Chat Completions(需开启路由)。你可以按需调整默认模型或模型显示名——例如开放平台预设默认是 kimi-k2.7-code,也可以按官方文档换成 kimi-k2.7-code-highspeed;协议转换交给路由层完成即可。

第二步:开启本地路由并接管 Codex

进入设置里的 路由 页面,展开 本地路由,完成两个开关:

  1. 打开 路由总开关,启动本地服务。默认地址是 127.0.0.1:15721。
  2. 在 路由启用 中打开 Codex。如果只想让 Codex 走路由,可以保持 Claude、Gemini 关闭。

接管后,CC Switch 会把 Codex 的 live 配置指向本机路由,并用占位符管理认证。真实 Kimi Key 仍保存在 CC Switch 的 Provider 配置里,由本地路由在转发时注入,不需要你把 Key 暴露给 Codex live 配置。

第三步:切换供应商并重启 Codex

回到 Codex 供应商列表,点击 Kimi 供应商的 启用。如果看到 需要路由 标记,说明这个供应商必须在路由运行时使用;没有启动路由时,CC Switch 会弹出“需要路由服务才能正常使用”的提示。

切换后建议重启当前 Codex 终端会话。原因是:

  • Codex 进程可能已经读取过旧的 config.toml。
  • model_catalog_json 生成后,/model 菜单通常需要新进程才能刷新。

进入 Codex 后,可以用 /model 查看当前模型是否来自 Kimi 预设,例如 Kimi K2.7 Code 或 Kimi For Coding。目前 Codex app 不支持多模型选择时,会默认使用配置里的第一个模型。随后发一个小问题,确认路由面板的请求数增长,或者在用量/请求日志里看到 Codex 请求即可。

其它 Chat 供应商怎么处理

SiliconFlow、ModelScope 等常见 Chat 格式供应商在 CC Switch 里已有预设,优先用预设即可。只有预设里没有的供应商,才需要选择自定义配置;这时按对方文档填 API Key、base URL 和模型,并把 高级选项 里的 上游格式 选为 Chat Completions(需开启路由)。

如果上游直接支持 OpenAI Responses API,把 上游格式 选为 Responses 即可;这时 CC Switch 按 Responses 直连,不做 Chat 转换。

常见问题

Codex 报 404 或找不到 /responses

通常是没有开启 Codex 接管,或者你手动把 Kimi 的 Chat base URL 直接写给了 Codex——Kimi 上游没有 /responses 端点,这样一定会 404。检查 ~/.codex/config.toml 是否指向 http://127.0.0.1:15721/v1。

Kimi 上游报 401 或 403

先确认 Key 和预设是否匹配:开放平台的 Key 只能配 Kimi 预设,Kimi Code 会员权益的 Key 只能配 Kimi For Coding 预设,两套 Key 不能混用。

Kimi 上游报 404

如果用的是内置 Kimi 预设,先确认当前供应商确实来自预设,并且 Codex 路由已启用。只有在使用自定义供应商时,才需要额外检查 base URL:它应该是服务根地址,而不是带 /chat/completions 的完整接口路径。

/model 看不到 Kimi 模型

保存供应商后重启 Codex。CC Switch 会生成 cc-switch-model-catalog.json 并把路径写入 model_catalog_json,但正在运行的 Codex 进程不一定会热加载模型目录。
目前 Codex app 不支持多模型选择,默认使用配置的第一个模型。
如果命令行 /model 正常,但 Codex 桌面应用的模型选择器仍看不到自定义模型,这是 Codex 桌面应用上游自身的模型门控行为,详见 Codex 桌面应用里看不到自定义模型?(常见问题)。

开了路由但请求仍走错供应商

确认三处状态一致:Codex 标签下当前供应商是 Kimi;本地路由服务正在运行;路由启用 里 Codex 开关已打开。

可以用官方 OpenAI Codex 账号走本地路由吗

不建议。CC Switch 会在本地路由接管模式下阻止切到官方供应商,因为用代理访问官方 API 可能带来账号风险。路由主要用于第三方、聚合或协议转换场景。

参考链接


Guides Codex Official Auth Preservation Guide En (`docs/guides/codex-official-auth-preservation-guide-en.md`)

Keep Codex Remote Control and Official Plugins While Using Third-Party APIs: CC Switch Setup Guide

Applies to CC Switch v3.20.1 and later; UI text follows v3.20.4. This guide is based on the current code, user manual, and the v3.16.1 / v3.20.1 release notes. Screenshots use de-identified sample data and do not include real Access Tokens or API keys. Some screenshots were taken on older versions; where a switch name differs, the text of this guide takes precedence.

What this guide solves

Many Codex users want both of these at the same time:

  1. Use models from DeepSeek, Kimi, GLM, MiniMax, SiliconFlow, or other third-party APIs, or use GPT models through an aggregator.
  2. Keep Codex official-app capabilities such as mobile remote control and official plugins.

Previously, when switching to a third-party provider, the old behavior wrote the third-party API key into Codex auth.json, which could overwrite the original official ChatGPT / Codex login cache. The third-party model worked, but features that depend on the official login state disappeared.

The Codex App Enhancements switch added in v3.16.1 solves this conflict: the official Access Token stays in auth.json, while third-party provider information is written to config.toml. Codex App can still see an official account, but actual model requests follow the third-party provider currently selected in CC Switch.

This behavior already existed in v3.16.0 and was enabled by default. After some users reported that they did not want this behavior, v3.16.1 turned it into an explicit switch.

Since v3.20.1, the switching logic has been simplified one step further: third-party API keys are only ever written to config.toml and never to auth.json. This switch now decides just one thing: when you switch directly to a third-party provider, whether the official login in auth.json is kept or deleted.

Quick answer

Recommended order:

  1. In the CC Switch Codex panel, switch to OpenAI Official.
  2. Start Codex and log in once with an official ChatGPT / Codex account. A Free subscription is enough.
  3. Return to CC Switch and enable Settings -> General -> Codex App Enhancements -> Keep official login for direct switches.
  4. Add or switch to a third-party Codex provider.
  5. If the provider uses the Chat Completions protocol (its card shows the Needs Routing badge, for example SiliconFlow or ModelScope), also enable local routing and route Codex through it. Presets such as DeepSeek, Kimi, MiniMax, and Zhipu GLM already connect directly, so they do not need this step.
  6. Restart Codex so config.toml and the model catalog are reloaded.

Prerequisites

Prepare the following:

  • CC Switch v3.20.1 or later.
  • Codex installed and able to start. Installing both the app and CLI is recommended.
  • An official ChatGPT / Codex account that can log in to Codex. A Free subscription is enough.
  • A third-party API key, such as DeepSeek, Kimi, GLM, MiniMax, OpenRouter, SiliconFlow, or similar.

Do not manually copy or share the contents of ~/.codex/auth.json. It stores official login cache and Access Tokens, so it is sensitive.

Step 1: Switch back to OpenAI Official and complete official login

Open CC Switch and switch to the top-level Codex tab. First select the OpenAI Official provider, or add it from the preset providers if it is missing, and make it the current provider.

Then start Codex, preferably the CLI, and follow the official login flow to sign in with your ChatGPT / Codex account. This account can be on the Free plan. In this setup, it mainly preserves the official identity required by Codex App, and does not pay for third-party model usage.

After login, Codex stores the official login cache in ~/.codex/auth.json. The key point for the following steps is: do not let third-party provider switching overwrite this file again.

Step 2: Enable Codex App Enhancements

Return to CC Switch and open:

text
Settings -> General -> Codex App Enhancements

Enable:

text
Keep official login for direct switches

This switch is off by default because some users do not want this behavior. Enable it only when you explicitly want "third-party API + official remote control / official plugins" at the same time.

After it is enabled, when you switch to a third-party provider without routing takeover:

  • auth.json: keeps the official ChatGPT / Codex login cache.
  • config.toml: stores the active third-party provider's model, endpoint, model_provider, and provider-scoped experimental_bearer_token.

The config.toml half has nothing to do with the switch: it is written the same way when the switch is off. The switch only controls whether auth.json is kept or removed. While routing takeover is enabled, the official login is always preserved, regardless of this switch.

Step 3: Add a third-party Codex provider

Return to the Codex panel and click the plus button in the upper-right corner to add a provider. Prefer built-in presets such as DeepSeek, Kimi, MiniMax, GLM, or SiliconFlow. After selecting a preset, you only need to enter the API key; the preset automatically configures the base URL, default model, model catalog, and upstream format.

After saving, check the badge on the provider card:

  • No badge: the upstream natively supports the OpenAI Responses API and can connect directly, without local routing. The DeepSeek, Kimi, MiniMax, Zhipu GLM, and 千问AI平台 presets, as well as aggregators that offer GPT models, all fall into this group.
  • Has the Needs Routing badge: the upstream format is Chat Completions (routing required), for example SiliconFlow or ModelScope. Local routing must be enabled for these providers so CC Switch can convert Codex Responses requests into Chat Completions requests.

For a custom provider, choose the upstream format under Advanced Options -> Upstream Format at the bottom of the form.

Step 4: Enable local routing and route Codex when needed

Open:

text
Settings -> Routing -> Local Routing

Complete two actions:

  1. Turn on the Routing Master Switch to start the local service. The default address is usually 127.0.0.1:15721.
  2. Under Routing Enabled, turn on Codex.

After takeover, Codex's live config.toml temporarily points to the CC Switch local route, and the token field holds the placeholder PROXY_MANAGED. The real third-party API key remains in the CC Switch provider configuration and is injected by the local route when it forwards requests. During takeover, the official login in auth.json is always preserved.

Step 5: Switch to the third-party provider and restart Codex

Return to the Codex provider list and enable the third-party provider you just added. After switching, restarting Codex is recommended for two reasons:

  • Codex reads config.toml at startup.
  • The Codex /model menu usually needs a restart before it reloads model_catalog_json.

After restart, you can run a quick verification:

  • In Codex App, the account information still shows the official account. This is expected.
  • In CC Switch, the current Codex provider is the third-party provider.
  • If local routing is enabled, request logs or routing stats show Codex requests going through the local route.
  • The third-party provider dashboard or balance records show actual model requests.

How it works

Codex mainly uses two configuration files:

text
~/.codex/auth.json
~/.codex/config.toml

They have different responsibilities:

  • auth.json stores the official ChatGPT / Codex login cache, which Codex App needs to identify the official account and enable remote control and official plugins.
  • config.toml stores runtime configuration such as the current model provider, base URL, model, model catalog, and provider-scoped token.

When you switch directly to a third-party provider, CC Switch takes the third-party provider API key from the provider configuration and writes it under the current provider in config.toml (this step does not depend on the switch):

toml
model_provider = "custom"

[model_providers.custom]
name = "DeepSeek"
base_url = "https://api.deepseek.com"
wire_api = "responses"
experimental_bearer_token = "sk-..."

With Keep official login for direct switches enabled, auth.json keeps the official login cache unchanged. Codex App can still identify the official account, while model requests follow the current provider and base URL in config.toml.

If the provider uses the Chat Completions protocol, CC Switch local routing adds another conversion layer:

text
Codex Responses request
        |
CC Switch local route
        |
Third-party Chat Completions API
        |
Converted back to Codex Responses response

This is why you can keep using official plugins / mobile remote control while moving model traffic to a third-party API.

Side effects to understand

Codex still shows the official account

This is the easiest part to misunderstand. After this capability is enabled, Codex App reads the official login state from auth.json, so it continues to display the official account.

That does not mean model requests are still going to official OpenAI. Actual traffic is determined by the current Codex provider in CC Switch, config.toml, and local routing logs.

Do not use the Codex account display to judge billing

If you switch to DeepSeek, Codex can still display the official account, while model requests go to the DeepSeek API. Billing, quota, error codes, and data policy should all be understood according to the third-party provider. You can inspect specific request details in the usage panel.

Restart Codex after changing model mappings

Codex reads the model catalog at startup. Even if CC Switch has generated a new model catalog, a running Codex process may not hot-load it, so restart Codex after editing model mappings.

With the switch off, direct switches delete the official login

If Keep official login for direct switches is turned off, switching to a third-party provider without routing takeover makes CC Switch delete auth.json. Codex App then loses its official login state, so official remote control and official plugins stop working. The third-party API key is still written only to config.toml, never to auth.json.

Routing takeover is not affected by this switch: while routing takeover is enabled, the official login is always preserved. If your goal is to keep official remote control and official plugins long term, keep this switch enabled.

FAQ

I switched to a third-party API. Why does Codex still show the official account?

This is expected. Official account information comes from auth.json; the actual model provider comes from config.toml and the current provider in CC Switch.

Is a Free subscription really enough?

Yes. The official account is mainly used to obtain and preserve the official login state required by Codex App. Third-party model requests use the third-party API key configured in CC Switch.

What should I do if official plugins or mobile remote control still do not work?

Switch back to OpenAI Official, restart Codex, and complete official login once. Then confirm Settings -> General -> Codex App Enhancements -> Keep official login for direct switches is enabled in CC Switch before switching back to the third-party provider.

What if third-party requests return 404, the model list is wrong, or streaming responses are broken?

If the provider uses Chat Completions, confirm that Upstream Format under Advanced Options in the provider form is set to Chat Completions (routing required), and that Settings -> Routing has both the Routing Master Switch and Codex takeover turned on.

Can I switch back to OpenAI Official while local routing is enabled?

Not recommended. CC Switch tries to prevent switching to official providers while local routing takeover is active, because accessing official APIs through a proxy may create account risk. Use official login only to preserve auth.json, and route model traffic to third-party providers.

Why is this flow so complex? Can it be simplified?

Because Codex App Enhancements and routing takeover can create unnecessary trouble for users who do not need them, these features are explicit switches instead of always-on behavior.

References


Guides Codex Official Auth Preservation Guide Ja (`docs/guides/codex-official-auth-preservation-guide-ja.md`)

サードパーティ API 利用時に Codex のリモート操作と公式プラグインを保持する: CC Switch 設定ガイド

対象バージョン: CC Switch v3.20.1 以降。画面の文言は v3.20.4 に準拠しています。本記事は現在のコード、ユーザーマニュアル、v3.16.1 / v3.20.1 Release Note をもとに整理しています。スクリーンショットは匿名化したサンプルデータを使用しており、実際の Access Token や API Key は含まれていません。一部のスクリーンショットは旧バージョンで撮影したものです。スイッチ名は本文の表記に従ってください。

このガイドで解決すること

Codex を使うとき、多くのユーザーには次の 2 つの要望があります。

  1. DeepSeek、Kimi、GLM、MiniMax、SiliconFlow などのサードパーティ API、または中継サービス上の GPT モデルを使いたい。
  2. Codex 公式アプリのモバイルリモート操作、公式プラグインなどの機能は残したい。

以前は、サードパーティプロバイダーへ切り替えると、旧動作ではサードパーティ API Key が Codex の auth.json に書き込まれ、元の公式 ChatGPT / Codex ログインキャッシュを上書きする可能性がありました。これによりサードパーティモデルは使えるものの、公式ログイン状態に依存する機能が消えてしまうことがありました。

v3.16.1 で追加された Codex アプリ拡張 スイッチは、この矛盾を解決するためのものです。公式 Access Token は auth.json に残し、サードパーティプロバイダー情報は config.toml に書き込みます。これにより Codex App は引き続き公式アカウントでログインしていると認識しつつ、実際のモデルリクエストは CC Switch で現在選択されているサードパーティプロバイダーへ流れます。

この機能自体は v3.16.0 から存在し、当時はデフォルトで有効でした。ただし一部のユーザーから不要というフィードバックがあったため、v3.16.1 で明示的なスイッチになりました。

v3.20.1 からは切り替えロジックがさらに一段シンプルになりました。サードパーティ API Key は常に config.toml にだけ書き込まれ、auth.json に書き込まれることは決してありません。このスイッチが決めるのは今や 1 つだけです。ルーティング接管なしでサードパーティプロバイダーへ切り替えるとき(直接切替)、auth.json 内の公式ログインを保持するか削除するか、です。

まず結論

おすすめの手順は次のとおりです。

  1. CC Switch の Codex パネルで OpenAI Official に切り替える。
  2. Codex を起動し、公式 ChatGPT / Codex アカウントで一度ログインする。Free サブスクリプションでも構いません。
  3. CC Switch に戻り、設定 → 一般 → Codex アプリ拡張 → 直接切替時に公式ログインを保持 をオンにする。
  4. サードパーティ Codex プロバイダーを追加、または切り替える。
  5. そのプロバイダーが Chat Completions プロトコル(カードに ルーティングが必要 バッジが付いているもの。たとえば SiliconFlow、ModelScope)の場合は、ローカルルーティングも有効化し、Codex のルーティングをオンにする。DeepSeek、Kimi、MiniMax、Zhipu GLM などのプリセットはすでにネイティブ直結のため、この手順は不要です。
  6. Codex を再起動し、config.toml とモデルカタログを再読み込みさせる。

事前準備

次のものを用意してください。

  • CC Switch v3.20.1 以降。
  • インストール済みで起動できる Codex。app と CLI の両方を入れておくことをおすすめします。
  • Codex にログインできる公式 ChatGPT / Codex アカウント。Free サブスクリプションで構いません。
  • DeepSeek、Kimi、GLM、MiniMax、OpenRouter、SiliconFlow などのサードパーティ API Key。

~/.codex/auth.json の内容を手動でコピーしたり共有したりしないでください。このファイルには公式ログインキャッシュと Access Token が保存されており、機密情報です。

Step 1: OpenAI Official に戻して公式ログインを完了する

CC Switch を開き、上部の Codex タブへ切り替えます。まず OpenAI Official プロバイダーを選択します。存在しない場合は、プリセットプロバイダーから追加して現在のプロバイダーにしてください。

次に Codex を起動します。CLI の起動がおすすめです。Codex の公式ログインフローに従い、ChatGPT / Codex アカウントでログインします。このアカウントは Free プランでも問題ありません。この構成では、主に Codex App が必要とする公式ログイン ID を保持する役割であり、サードパーティモデルの課金には使いません。

ログイン後、Codex は ~/.codex/auth.json に公式ログインキャッシュを保存します。以降の重要なポイントは、サードパーティプロバイダー切り替えでこのファイルを上書きさせないことです。

Step 2: Codex アプリ拡張を有効化する

CC Switch に戻り、次を開きます。

text
設定 → 一般 → Codex アプリ拡張

次のスイッチをオンにします。

text
直接切替時に公式ログインを保持

このスイッチはデフォルトでオフです。一部のユーザーはこの機能を必要としていないためです。「サードパーティ API + 公式リモート操作 / 公式プラグイン」を同時に使いたい場合だけ有効化してください。

有効化すると、ルーティング接管を有効にしていない状態でサードパーティプロバイダーへ切り替えたときに、次のようになります。

  • auth.json: 公式 ChatGPT / Codex ログインキャッシュを保持します。
  • config.toml: 現在のサードパーティプロバイダーのモデル、endpoint、model_provider、provider-scoped experimental_bearer_token を書き込みます。

config.toml 側はスイッチとは無関係で、スイッチがオフでも同じように書き込まれます。スイッチが扱うのは auth.json を残すかどうかだけです。ルーティング接管中は、このスイッチに関係なく公式ログインが常に保持されます。

Step 3: サードパーティ Codex プロバイダーを追加する

Codex パネルに戻り、右上のプラスボタンからプロバイダーを追加します。DeepSeek、Kimi、MiniMax、GLM、SiliconFlow などの内蔵プリセットを優先して使うのがおすすめです。プリセットを選んだ後は API Key を入力するだけで、プリセットが base URL、デフォルトモデル、モデルカタログ、上流フォーマットを自動で構成します。

保存したら、プロバイダーカードのバッジを確認します。

  • バッジなし: 上流が OpenAI Responses API をネイティブにサポートしており、直結できるため、ローカルルーティングは不要です。DeepSeek、Kimi、MiniMax、Zhipu GLM、千问AI平台 のプリセット、そして GPT モデルを提供する中継サービスは、いずれもこちらに当たります。
  • ルーティングが必要 バッジあり: 上流フォーマットが Chat Completions(ルーティング必須) のもので、たとえば SiliconFlow、ModelScope です。この種のプロバイダーはローカルルーティングを必ず有効化し、CC Switch が Codex の Responses リクエストを Chat Completions リクエストへ変換できるようにしてください。

カスタムプロバイダーの上流フォーマットは、フォーム下部の 詳細オプション → 上流フォーマット で選択します。

Step 4: 必要に応じてローカルルーティングと Codex ルーティングを有効化する

次を開きます。

text
設定 → ルーティング → ローカルルーティング

次の 2 つを行います。

  1. ルーティング総スイッチ をオンにし、ローカルサービスを起動する。デフォルトアドレスは通常 127.0.0.1:15721 です。
  2. ルーティング有効 で Codex をオンにする。

ルーティング有効化後、Codex の live config.toml は一時的に CC Switch のローカルルートを指し、トークンの箇所にはプレースホルダー PROXY_MANAGED が書き込まれます。実際のサードパーティ API Key は CC Switch のプロバイダー設定内に残り、ローカルルートが転送時に注入します。ルーティング接管中は、auth.json 内の公式ログインが常に保持されます。

Step 5: サードパーティプロバイダーへ切り替えて Codex を再起動する

Codex プロバイダー一覧に戻り、先ほど追加したサードパーティプロバイダーを有効化します。切り替え後は Codex の再起動をおすすめします。理由は 2 つあります。

  • Codex は起動時に config.toml を読み込みます。
  • Codex の /model メニューは通常、再起動後に model_catalog_json を再読み込みします。

再起動後、簡単に確認できます。

  • Codex App ではアカウント情報が引き続き公式アカウントとして表示される。これは期待される動作です。
  • CC Switch では現在の Codex プロバイダーがサードパーティプロバイダーになっている。
  • ローカルルーティングを有効化している場合、リクエストログまたはルーティング統計で Codex リクエストがローカルルートを通っていることを確認できる。
  • サードパーティプロバイダー側のダッシュボードや残高記録に実際のモデルリクエストが表示される。

仕組み

Codex の設定は主に 2 つのファイルに分かれています。

text
~/.codex/auth.json
~/.codex/config.toml

この 2 つは役割が異なります。

  • auth.json は公式 ChatGPT / Codex ログインキャッシュを保存します。Codex App が公式アカウント、リモート操作、公式プラグインを認識するために必要なログイン材料です。
  • config.toml は現在のモデルプロバイダー、base URL、モデル、モデルカタログ、provider-scoped token などの実行時設定を保存します。

直接切替でサードパーティプロバイダーへ切り替えるとき、CC Switch はサードパーティプロバイダー API Key をプロバイダー設定から取り出し、config.toml の現在の provider 配下へ書き込みます(この処理はスイッチとは無関係です)。

toml
model_provider = "custom"

[model_providers.custom]
name = "DeepSeek"
base_url = "https://api.deepseek.com"
wire_api = "responses"
experimental_bearer_token = "sk-..."

直接切替時に公式ログインを保持 をオンにしている場合、auth.json は公式ログインキャッシュを保持したままです。そのため Codex App 側では公式アカウントを認識でき、モデルリクエストは config.toml の現在の provider と base URL に従ってサードパーティ API へ向かいます。

プロバイダーが Chat Completions プロトコルの場合、CC Switch のローカルルーティングがさらに変換層になります。

text
Codex Responses リクエスト
        |
CC Switch ローカルルート
        |
サードパーティ Chat Completions API
        |
Codex Responses レスポンスへ変換

これにより、公式プラグイン / モバイルリモート操作を使い続けながら、モデル通信だけをサードパーティ API に切り替えられます。

理解しておくべき副作用

Codex 内の表示アカウントは公式アカウントのまま

ここが最も誤解されやすい点です。この機能を有効化すると、Codex App は auth.json 内の公式ログイン状態を見るため、公式アカウント情報を表示し続けます。

ただし、これはモデルリクエストが公式 OpenAI に流れているという意味ではありません。実際の通信先は、CC Switch の現在の Codex プロバイダー、config.toml、ローカルルーティングログで判断してください。

Codex のアカウント表示で課金先を判断しない

DeepSeek に切り替えた場合でも、Codex には公式アカウントが表示されます。しかしモデルリクエストは DeepSeek API へ送られます。課金、上限、エラーコード、データポリシーはサードパーティプロバイダー側の仕様として理解してください。具体的なリクエスト情報は使用量パネルで確認できます。

モデルマッピングを変更したら Codex を再起動する

Codex のモデルカタログは起動時に読み込まれます。CC Switch が新しいモデルカタログを生成していても、実行中の Codex がホットロードするとは限りません。モデルマッピングを変更した後は Codex を再起動してください。

スイッチをオフにすると、直接切替で公式ログインが削除される

直接切替時に公式ログインを保持 をオフにすると、ルーティング接管を有効にしていない状態でサードパーティプロバイダーへ切り替えたとき、CC Switch は auth.json を削除します。これにより Codex App は公式ログイン状態を失い、公式リモート操作や公式プラグインも使えなくなります。サードパーティ API Key はこの場合も config.toml にだけ書き込まれ、auth.json には書き込まれません。

ルーティング接管中はこのスイッチの影響を受けず、公式ログインは常に保持されます。公式リモート操作と公式プラグインを長期的に保持したい場合は、このスイッチをオンのままにすることをおすすめします。

よくある質問

サードパーティ API に切り替えたのに、なぜ Codex はまだ公式アカウントを表示しますか?

これは期待される動作です。公式アカウント情報は auth.json から取得され、実際のモデルプロバイダーは config.toml と CC Switch の現在のプロバイダーで決まります。

Free サブスクリプションで本当に大丈夫ですか?

大丈夫です。ここでの公式アカウントは、Codex App が必要とする公式ログイン状態を取得・保持するために使います。サードパーティモデルリクエストは、CC Switch に設定したサードパーティ API Key を使います。

有効化しても公式プラグインやモバイルリモート操作が使えない場合は?

まず OpenAI Official に戻し、Codex を再起動して一度公式ログインを完了してください。その後、CC Switch の 設定 → 一般 → Codex アプリ拡張 → 直接切替時に公式ログインを保持 がオンになっていることを確認し、再度サードパーティプロバイダーへ切り替えてください。

サードパーティリクエストが 404 になる、モデル一覧が違う、ストリーミング応答がおかしい場合は?

そのプロバイダーが Chat Completions プロトコルの場合、プロバイダーフォームの 詳細オプション にある 上流フォーマット が Chat Completions(ルーティング必須) になっていること、さらに 設定 → ルーティング でルーティング総スイッチと Codex ルーティングがオンになっていることを確認してください。

ローカルルーティング中に OpenAI Official へ戻せますか?

おすすめしません。CC Switch は、ローカルルーティングで Codex を管理している間に公式プロバイダーへ切り替えることをできるだけ防ぎます。プロキシ経由で公式 API にアクセスすると、アカウントリスクが発生する可能性があるためです。公式ログインは auth.json を保持するために使い、モデル通信はサードパーティプロバイダーへ切り替えるのがおすすめです。

なぜ手順がこんなに複雑なのですか?もっと簡単にできますか?

Codex アプリ拡張やルーティング管理は、必要ないユーザーにとっては余計なトラブルになり得るため、常時有効ではなく明示的なスイッチになっています。

参考リンク


Guides Codex Official Auth Preservation Guide Zh (`docs/guides/codex-official-auth-preservation-guide-zh.md`)

使用第三方 API 时保留 Codex 远程操作和官方插件:CC Switch 配置攻略

适用版本:CC Switch v3.20.1 及以上,界面文字以 v3.20.4 为准。本文根据当前代码、用户手册和 v3.16.1 / v3.20.1 Release Note 整理,截图使用去敏示例数据,不包含真实 Access Token 或 API Key。部分截图拍摄于旧版本,开关名称以正文为准。

这篇攻略解决什么问题

很多人使用 Codex 时有两个需求:

  1. 模型使用 DeepSeek、Kimi、GLM、MiniMax、硅基流动等第三方 API,或者在中转站使用 gpt 模型。
  2. 保留 Codex 官方 App 的手机远程操作、官方插件等能力。

之前切换第三方供应商时,旧行为会把第三方 API Key 写进 Codex 的 auth.json,从而覆盖原来的官方 ChatGPT / Codex 登录缓存。这样第三方模型能用了,但依赖官方登录态的功能会消失。

v3.16.1 新增的 Codex 应用增强开关就是为了解决这个矛盾:让官方 Access Token 继续留在 auth.json,而第三方供应商信息写入 config.toml。这样 Codex App 仍然认为你登录的是官方账号,但实际模型请求会走 CC Switch 当前选中的第三方供应商。

v3.16.0 就有这个功能,并且默认开启,但是部分用户反映并不想要这个功能,所以在 v3.16.1 中把这个功能做成了开关。

v3.20.1 起切换逻辑又简化了一步:第三方 API Key 一律只写进 config.toml,永远不会写入 auth.json。这个开关现在只决定一件事:直连切到第三方供应商时,auth.json 里的官方登录是保留还是删除。

先看结论

推荐顺序是:

  1. 在 CC Switch 的 Codex 面板切换到 OpenAI Official。
  2. 启动 Codex,并用官方 ChatGPT / Codex 账号登录一次,Free 订阅也可以。
  3. 回到 CC Switch,打开 设置 → 通用 → Codex 应用增强 → 非接管切换时保留官方登录。
  4. 添加或切换到第三方 Codex 供应商。
  5. 如果该供应商是 Chat Completions 协议(卡片上带 需要路由 徽章,例如 SiliconFlow、ModelScope),需要同时开启本地路由并启用 Codex 接管。DeepSeek、Kimi、MiniMax、智谱 GLM 等预设已是原生直连,不需要这一步。
  6. 重启 Codex,让 config.toml 和模型目录重新加载。

准备工作

你需要准备:

  • CC Switch v3.20.1 或更新版本。
  • 已安装并能启动的 Codex(建议 app 和 cli 都安装)。
  • 一个可以登录 Codex 的官方 ChatGPT / Codex 账号,Free 订阅即可。
  • 一个第三方 API Key,例如 DeepSeek、Kimi、GLM、MiniMax、OpenRouter、硅基流动等。

请不要手动复制或分享 ~/.codex/auth.json 的内容。里面保存的是官方登录缓存和 Access Token,属于敏感信息。

第一步:先切回 OpenAI Official 并完成官方登录

打开 CC Switch,切到顶部的 Codex 标签页。先选择 OpenAI Official 供应商(如果没有的话,就在预设供应商当中添加一个),并把它设为当前供应商。

接着启动 Codex(建议启动 cli),按 Codex 的官方登录流程登录你的 ChatGPT / Codex 账号。这个账号可以是 Free 订阅;在这个方案里,它主要负责保留 Codex 官方 App 需要识别的登录身份,不负责第三方模型的计费。

登录完成后,Codex 会在 ~/.codex/auth.json 中保存官方登录缓存。后面的关键点就是:不要再让第三方供应商切换覆盖这个文件。

第二步:开启 Codex 应用增强

回到 CC Switch,进入:

text
设置 → 通用 → Codex 应用增强

打开:

text
非接管切换时保留官方登录

这个开关默认关闭,是因为部分用户并不想要这个功能。只有在你明确需要“第三方 API + 官方远程操作 / 官方插件”同时存在时,才需要开启它。

开启后,在未开启路由接管时切换到第三方供应商:

  • auth.json:继续保留官方 ChatGPT / Codex 登录缓存。
  • config.toml:写入当前第三方供应商的模型、endpoint、model_provider 和 provider-scoped experimental_bearer_token。

config.toml 这一半与开关无关,关着开关也是这样写;开关只管 auth.json 的去留。开启路由接管期间,官方登录始终保留,不看这个开关。

第三步:添加第三方 Codex 供应商

回到 Codex 面板,点击右上角的加号添加供应商。推荐优先使用内置预设,例如 DeepSeek、Kimi、MiniMax、GLM、SiliconFlow 等。选择预设后只需要填 API Key,预设会自动配置 base URL、默认模型、模型目录和上游格式。

保存后看供应商卡片上的徽章:

  • 没有徽章:上游原生支持 OpenAI Responses API,可以直连,不需要本地路由。DeepSeek、Kimi、MiniMax、智谱 GLM、千问AI平台的预设,以及提供 gpt 模型的中转站,都属于这一类。
  • 带 需要路由 徽章:上游格式是 Chat Completions(需开启路由),例如 SiliconFlow、ModelScope。这类供应商必须启用本地路由,让 CC Switch 把 Codex 的 Responses 请求转换成 Chat Completions 请求。

自定义供应商的上游格式在表单底部的 高级选项 → 上游格式 里选择。

第四步:需要时开启本地路由并接管 Codex

进入:

text
设置 → 路由 → 本地路由

完成两件事:

  1. 打开 路由总开关,启动本地服务。默认地址通常是 127.0.0.1:15721。
  2. 在 路由启用 中打开 Codex。

接管后,Codex 的 live config.toml 会临时指向 CC Switch 本地路由,令牌处写的是占位符 PROXY_MANAGED。真实第三方 API Key 仍然存储在 CC Switch 的供应商配置中,由本地路由在转发时注入。接管期间 auth.json 里的官方登录始终保留。

第五步:切换第三方供应商并重启 Codex

回到 Codex 供应商列表,启用你刚添加的第三方供应商。切换完成后建议重启 Codex,原因有两个:

  • Codex 在启动时读取 config.toml。
  • Codex 的 /model 菜单通常需要重启后才会重新加载 model_catalog_json。

重启后,你可以做一个简单验证:

  • 在 Codex App 里,账号信息仍然显示官方账号,这是预期行为。
  • 在 CC Switch 里,当前 Codex 供应商显示为第三方供应商。
  • 如果开启了本地路由,请求日志或路由统计会看到 Codex 请求经过本地路由。
  • 第三方供应商后台或余额记录会出现实际模型请求。

背后的原理

Codex 的配置主要分成两个文件:

text
~/.codex/auth.json
~/.codex/config.toml

这两个文件承担的职责不同:

  • auth.json 保存官方 ChatGPT / Codex 登录缓存,也就是 Codex App 识别官方账号、远程操作和官方插件所需的登录材料。
  • config.toml 保存当前模型供应商、base URL、模型、模型目录和 provider-scoped token 等运行配置。

直连切换到第三方供应商时,CC Switch 会把第三方供应商 API Key 从供应商配置中取出,写到 config.toml 的当前 provider 下(这一步与开关无关):

toml
model_provider = "custom"

[model_providers.custom]
name = "DeepSeek"
base_url = "https://api.deepseek.com"
wire_api = "responses"
experimental_bearer_token = "sk-..."

开启 非接管切换时保留官方登录 时,auth.json 保持官方登录缓存不变。于是 Codex App 侧依然能识别官方账号;而模型请求会根据 config.toml 的当前 provider 和 base URL 走第三方 API。

如果供应商是 Chat Completions 协议,CC Switch 本地路由会再做一层转换:

text
Codex Responses 请求
        ↓
CC Switch 本地路由
        ↓
第三方 Chat Completions API
        ↓
转换回 Codex Responses 响应

这就是为什么你既能继续使用官方插件 / 手机远程操作,又能把模型流量切到第三方 API。

需要理解的副作用

Codex 里显示的账号始终是官方账号

这是最容易误解的一点。开启该能力后,Codex App 看到的是 auth.json 里的官方登录态,所以它会继续显示官方账号信息。

但这不代表模型请求还在走官方 OpenAI。实际流量以 CC Switch 当前 Codex 供应商、config.toml 和本地路由日志为准。

不要用 Codex 账号信息判断计费方

如果你切到 DeepSeek,Codex 里仍然显示官方账号,但模型请求会走 DeepSeek API。计费、限额、错误码和数据策略都应按第三方供应商理解。可以查看设置用量面板里的具体请求信息。

修改模型映射后要重启 Codex

Codex 的模型目录是启动时读取的。即使 CC Switch 已经生成了新的模型目录,正在运行的 Codex 也不一定会热加载,所以修改模型映射后请重启 Codex。

关闭开关后,直连切换会删除官方登录

如果关闭 非接管切换时保留官方登录,在未开启路由接管时切换到第三方供应商,CC Switch 会删除 auth.json,Codex App 随之失去官方登录态,官方远程操作和官方插件也就用不了。第三方 API Key 照样只写进 config.toml,不会写入 auth.json。

开启路由接管期间不受这个开关影响,官方登录始终保留。如果你的目标是长期保留官方远程操作和官方插件,建议保持该开关开启。

常见问题

我已经切到第三方 API,为什么 Codex 还显示官方账号?

这是预期行为。官方账号信息来自 auth.json,模型请求的实际供应商来自 config.toml 和 CC Switch 当前供应商。

Free 订阅真的可以吗?

可以。这里的官方账号主要用于获取并保留 Codex App 需要的官方登录态。第三方模型请求使用的是你在 CC Switch 里配置的第三方 API Key。

开启后官方插件或手机远程操作还是不可用怎么办?

先切回 OpenAI Official,重新启动 Codex 并完成一次官方登录;然后确认 CC Switch 的 设置 → 通用 → Codex 应用增强 → 非接管切换时保留官方登录 已开启,再切回第三方供应商。

第三方请求 404、模型列表不对或流式响应异常怎么办?

如果该供应商是 Chat Completions 协议,请确认供应商表单 高级选项 里的 上游格式 是 Chat Completions(需开启路由),并且 设置 → 路由 里已经启动路由总开关、启用 Codex 接管。

可以在本地路由模式下切回 OpenAI Official 吗?

不建议。CC Switch 会尽量阻止在本地路由接管模式下切到官方供应商,因为用代理访问官方 API 可能带来账号风险。建议官方登录只用于保留 auth.json,模型流量则切到第三方供应商。

为什么流程做的这么复杂?可以简化吗?

因为 Codex 增强开关和路由接管等一系列功能,如果用户并不需要的话,默认打开会带来不必要的麻烦,所以都做成了开关形式。

参考链接


Guides Codex Unified Session History Guide En (`docs/guides/codex-unified-session-history-guide-en.md`)

Unified Codex Session History: Feature Overview and Usage Guide (CC Switch)

Applies to CC Switch v3.16.x and later. This guide is based on the current code; every command and path can be verified by hand. Examples use de-identified data and contain no real session content or API keys.

What this feature is

"Unified Codex session history" is a switch that CC Switch v3.16.x adds for Codex. You'll find it under Settings -> General -> the "Codex App Enhancements" group ("Codex App Enhancements" is the group title; the switch itself is called "Unified Codex session history"). Once enabled, sessions from your official subscription (ChatGPT login / OpenAI API key) appear in the same history / resume list as sessions from every third-party provider CC Switch manages—they are no longer split into two lists that can't see each other.

What problem it solves

Codex classifies sessions by a "provider tag" (a field called model_provider), and the resume / history list only shows sessions whose tag matches your currently active provider. As a result, sessions are naturally sorted into two separate "drawers":

  • Sessions from your official subscription go under Codex's built-in openai tag;
  • Every third-party provider CC Switch manages goes under the custom tag.

The two drawers can't see each other. If you switch frequently between official and third-party, you'll hit this kind of fragmentation: "the session I was just chatting in with the official account disappeared from the history list after I switched to a third-party provider"—it isn't actually gone, it's just been sorted into the other drawer. This split both makes it easy to believe a session was lost, and makes it inconvenient to review and resume all your sessions in one place.

This switch exists to eliminate that fragmentation: it makes the official subscription run under the custom tag too, so official and third-party sessions merge into one list and everything is easy to find and resume in a single place.

✅ One important premise that runs through this whole guide, please remember it first: this feature (unify / migrate / restore) only ever rewrites that one classification tag model_provider in your session records, and it automatically makes a backup of the original file before every rewrite. It never deletes, clears, or overwrites a single line of your conversations. So whenever this guide later mentions "some sessions are no longer visible," it almost always means "they've been sorted into the other drawer," not "the data is gone." If you're truly worried, jump straight to the symptom reference table and verify the files are still there by hand.

How it works (one-line version)

Think of it as two drawers + automatic backup:

  • By default, official sessions live in the openai drawer and third-party sessions live in the custom drawer, invisible to each other;
  • The switch makes the official side use the custom drawer too, merging the two drawers into one shared list;
  • You can optionally choose to "move" your existing official sessions into the shared drawer as well (this step is called migration; it's optional and requires you to opt in by checking a box), and before anything is moved a backup copy is made first, so the whole process is reversible;
  • Authentication is completely unaffected—your official subscription still uses your ChatGPT login and still goes through the official backend; only the session's classification tag changes.

For the full mechanism (what gets injected, why it's reversible, how migration / restore guarantee no data loss) see The core mental model and the Advanced mechanism appendix at the end.

How to use it (at a glance)

  1. Enable: Settings -> General -> Codex App Enhancements -> turn on "Unified Codex session history" -> in the dialog decide whether to check "Also migrate existing official session history" (check it if you want your earlier official sessions merged into the unified list too; leave it unchecked if you only want unification from now on) -> confirm. See What happens when you enable it.
  2. Disable: turn the same switch off -> in the dialog keep "restore exactly from backup" checked (it's checked by default) -> confirm, and the official sessions you migrated in will be precisely flipped back to the official list. See What happens when you disable it.
  3. Feel like a session is gone? Don't panic—jump to the symptom reference table to locate it by symptom, and use the commands in the verify by hand section to see for yourself that the files are all there.

The core mental model: two drawers + automatic backup

To understand this feature, you only need to remember two things: drawers and backups.

Drawers: how Codex classifies sessions

Every time you start a Codex session, Codex records a tag model_provider in the session file header, marking "which provider this session was chatted with." Codex's resume / history list is filtered precisely by the currently active tag—it only shows sessions whose tag matches "the provider you're on right now."

  • Sessions from your official subscription (ChatGPT login / OpenAI API key) carry the built-in tag openai.
  • Every third-party provider CC Switch manages uses the tag custom.

So by default, official sessions and third-party sessions are inherently invisible to each other—they live in two different drawers. This is Codex's own design, not CC Switch losing anything.

text
Default state (unified switch off):
   ┌───────────────────────┐     ┌──────────────────────────┐
   │  openai drawer        │     │  custom drawer           │
   │  (official sessions)  │     │  (third-party sessions)  │
   └───────────────────────┘     └──────────────────────────┘
       ▲                             ▲
     visible only while            visible only while
     on the official provider       on a third-party provider

   The two drawers can't see each other.

What the "Unified Codex session history" switch does is make the official subscription run under the custom tag too, merging the two drawers into one, so official and third-party sessions appear in the same resume list. Note: authentication doesn't change—your official subscription still uses your ChatGPT login and still goes through the official backend; only the session's "classification tag" changes from openai to custom.

text
After the unified switch is on:
   ┌──────────────────────────────────────────────┐
   │             custom shared drawer             │
   │  official sessions  +  third-party sessions  │
   │  (appear in the same history / resume list)  │
   └──────────────────────────────────────────────┘

Backups: a copy is made before every tag change

"Merging the drawers" requires changing the tag of some official sessions from openai to custom (this step is called migration, and it's optional and requires you to opt in). And before any rewrite, CC Switch first copies the original file untouched to here:

text
~/.cc-switch/backups/codex-official-history-unify-v1/<timestamp>/

This backup is the sole basis for "restore exactly from backup" later. It makes the whole process reversible: at any time you can turn off the switch and precisely flip the official sessions you migrated in back to the openai drawer.

Remember these two words—drawer (a session just gets reclassified) and backup (a copy is always made before a change)—and everything that follows will be easy to understand.


What happens when you enable it: step by step

Step 1: Find the switch

text
Settings -> General -> Codex App Enhancements

In the "Codex App Enhancements" block there are two rows of switches; the second row (the blue history icon) is the subject of this guide:

Unified Codex session history

Below it is a line of description text (verbatim):

When enabled, the official subscription runs under the shared "custom" provider id so official and third-party sessions appear in one history list, optionally migrating existing official sessions in (backed up first). When turning it off, the migrated sessions can be restored from backup. Note: resuming an old session across providers may fail because its encrypted_content reasoning can only be decrypted by the backend that created it.

Note: this single line of description already previews three things—sessions will appear in one list, you can optionally migrate them in with an automatic backup, and resuming across providers "may fail." Here, "fail" means you can't resume / can't generate a new turn, not "the record is lost." This is exactly the core misunderstanding we'll dig into below.

Step 2: Flip the switch from off to on -> a confirmation dialog pops up

The moment you flip the switch on, CC Switch does not save immediately; instead it first pops up a confirmation dialog. The dialog text reads as follows (verbatim):

  • Title: Unified Codex session history

  • Body:

    When enabled, the official subscription and third-party providers share one session history list. Note: resuming an old session across providers may fail because its encrypted_content reasoning cannot be decrypted by another backend.

    You can also migrate your existing official session history into the shared list (originals are backed up to ~/.cc-switch/backups first and can be restored when you turn this off).

  • Checkbox: Also migrate existing official session history

  • Confirm button: I understand, enable

  • Cancel button: Cancel

This checkbox is unchecked by default. This is an important fork in the road:

Your choice Effect Where your data is right now
Unchecked (default) Only switches the tag. Only official sessions created after enabling land in the custom shared drawer Your official sessions from before enabling keep the openai tag, stay exactly where they were, still in ~/.codex/sessions/
Checked In addition to switching the tag, also migrates your existing official sessions from the openai drawer into the custom drawer After being copied to backup, the old sessions' tag is rewritten to custom; the original data is covered by the backup

If you want "my earlier official sessions to appear in the unified list too," you must opt in by checking this box. Otherwise you'll run into "scenario A" in the reference table below—the old sessions look "gone," when in fact they're just sitting in the original drawer.

Click "Cancel" or click outside the dialog: the switch flips straight back to off and nothing happens.
Click "I understand, enable": the switch is saved as on, and CC Switch persists the configuration in the background (and runs the migration if you checked it).

Step 3 (only if you checked migration): how migration runs + data safety

If you check "Also migrate existing official session history," CC Switch runs this procedure on your existing official sessions:

text
For each official (openai tag) session file:
   ① First copy the original file untouched into the backup directory   <- data now has its first safety net
   ② Using "write a temp file -> replace the whole thing" atomic style,
      change only the model_provider in the session_meta line at the header
      from "openai" to "custom"                                          <- not a single byte of the conversation body is touched
   ③ Update the index database state_5.sqlite to switch the tag in the same transaction
  • Backup location: ~/.cc-switch/backups/codex-official-history-unify-v1/<timestamp>/. Each migration produces one timestamped "generation directory," containing jsonl/ (session copies), state/ (index DB copy), and meta.json (recording which Codex directory this migration belongs to).
  • What's changed: only the value of the single field model_provider. Your conversation content, reasoning content, and all body text are kept exactly as is.
  • What's deleted: nothing. The backup is a "copy," the rewrite is an "atomic replacement of the same file," and at no point is any session or index deleted. The file is complete at every moment (either the old content or the new content, never empty or half-written).

After a successful migration, these existing official sessions show up in the unified list. At this moment your data is: ① the original copy in the backup directory; ② in the active file, only the classification tag changed, the content intact.

Note: enabling and migration themselves do not pop a success toast. Migration runs as a side task on the backend during save; in the UI you'll only see the switch turn on. So "I didn't see a migration-success popup" is normal and does not mean failure.


What happens when you disable it: step by step

Step 1: Flip the switch from on to off -> probe for backups -> a confirmation dialog pops up

When disabling, CC Switch first spends a moment probing whether there's a migration backup, then pops up a confirmation dialog (so the disable dialog has a slight delay, which is normal). The text reads as follows (verbatim):

  • Title: Turn off unified session history

  • Body:

    After turning this off, the official subscription and third-party providers return to separate history lists. Sessions created while it was on cannot be attributed to a provider, so they stay in the third-party history and the official subscription will not see them.

  • Checkbox (shown conditionally): Restore the official sessions migrated at enable time back to the official history (exact restore from backup)

  • Confirm button: Turn off

  • Cancel button: Cancel

Key point: the body says the official subscription will not see them—won't see, not delete. The new sessions you chatted during the unified period are still fully present in the custom drawer; after disabling, the official side simply won't see them.

This restore checkbox is checked by default. In other words, the default behavior is "restore the official sessions you migrated in back to the official history at the same time you disable." You only need to keep it checked and click "Turn off."

If the checkbox doesn't appear, the system has determined there's no backup that needs restoring (either you never checked migration, or no backup was found)—in that case your existing official sessions were never touched, and turning off the switch returns them to the openai drawer on their own.

Step 2: How restore runs (precise flip-back per the backup ledger)

If you keep the box checked and click "Turn off," CC Switch's restore flow goes like this:

text
① First copy the current state once more into a separate restore-backup directory
   ~/.cc-switch/backups/codex-official-history-unify-restore-v1/<timestamp>/
   (restore itself backs up first, so restore won't lose data either)
② Comb through all migration backup generations, find the session ids "whose tag was originally openai," and assemble a "ledger"
③ Only for sessions that are [both in the ledger AND currently still custom], change the tag back to "openai"

Note the dual condition in step ③—it must be in the ledger (proving it really was migrated from the official side) AND currently still custom (showing you haven't manually changed it). Only when both conditions hold does it get flipped back. This guarantees the restore is both precise and free of collateral damage.

At this moment your data is: the migrated-back official sessions have their tag changed back to openai and reappear in the official list; meanwhile both the migration backup and the restore backup copies are still on disk.

Step 3: Read the toast, confirm the result

Only the "disable + check restore" path pops a result toast. The toasts you may see (verbatim):

Toast you see Meaning
Official session history restored from backup ({{files}} session files, {{rows}} index rows) Restore succeeded. {{files}} / {{rows}} show the actual numbers
No restorable migration backup for the current Codex directory Nothing to restore (does not mean data is lost, see scenario E in the reference table)
Unified session history was re-enabled; restore skipped You turned the switch back on while restore was queued, so the system deliberately abandoned the restore (see scenario F)
Failed to restore official session history, please try again The restore process errored; just retry, the data is not corrupted
Save failed, please try again The disable save itself failed; in this case restore is never triggered and the switch flips back to its original position

A thoughtful safety design: if the "disable the switch" save fails, CC Switch never runs the restore. Otherwise you'd end up in a torn state of "switch still on, but sessions flipped back to the openai bucket." When the save fails, the switch automatically flips back to its original position, so you won't be stuck in a fake state of "looks off but didn't actually save."


"I feel like my sessions are gone?" symptom reference table

The six scenarios below are the situations where users most easily believe "sessions are gone." The truth in every one is: the data is intact, it just moved drawers or is temporarily out of sight. Use this table to locate your symptom first, then read the detailed explanation below.

Scenario What you see The data truth One-line fix
A Didn't check migration Old official sessions not in the unified list All present, still carry the openai tag Re-enable and check migration, or turn off the switch
B Cross-provider resume fails Can't resume / errors out Files intact, the ciphertext just can't be decrypted across backends Resume on the original provider; to only read content, read the jsonl directly
C Routing takeover / injection refused No migration and no restore Migration was safely skipped, files untouched Exit takeover -> restart and retry; or just turn off the switch
D New sessions didn't return to official after restore New sessions from the unified period aren't on the official side They're in the custom drawer, untouched by design Switch to a third-party provider to see them
E Toast "no restorable backup" Restore "failed" Usually nothing was ever migrated, sessions are in the original drawer Turn off the switch and the official sessions reappear automatically
F Toast "switch was re-enabled, restore skipped" Restore refused Prevents a torn data state, nothing was changed Fully turn off the switch first, then restore

Scenario A: You enabled the switch but didn't check migration -> old official sessions "disappear"

Symptom: you turned on the unified switch, but didn't check "Also migrate existing official session history" in the enable dialog (it's unchecked by default). After enabling, your earlier official sessions seem to be gone from the list.

The truth: 100% of your data is present, not a single line moved. The switch only takes effect on official sessions "created after enabling"; your official sessions from before enabling still carry the openai tag and sit untouched in ~/.codex/sessions/. You're now on the custom drawer, so naturally you can't see the old sessions left in the openai drawer—that's the entire reason for the "apparent disappearance."

What to do (pick either):

  1. Re-enable the switch and check "Also migrate existing official session history," which moves the old sessions to the custom drawer and they immediately appear in the unified list (automatic backup before the rewrite).
  2. Or simply turn off the unified switch, the official side runs on the openai drawer again, and the old sessions reappear right where they were.

Scenario B: Cross-provider resume of an old session fails -> you think "this session is broken / gone"

Symptom: after unification, the list shows an old session chatted with "another provider." You switch to your current provider and click "Resume," but it errors out or can't connect.

The truth: the session file is intact; what's lost is not data, it's "cross-backend decryption ability." A Codex session stores an encrypted block of reasoning content encrypted_content, and this ciphertext can only be decrypted by the backend that originally generated it. Using provider B to resume a session generated by provider A means B can't decrypt A's ciphertext -> resume fails. This is a design limitation of upstream Codex (by design) and has nothing to do with whether CC Switch touched the file. The text content of the session is readable at any time.

This is the only "looks like a real problem" genuine exception in this whole guide—but note: it just means you can't resume (can't generate a new turn), and the original file is still fully present, the conversation text readable at any time.

What to do:

  • Resume with "the provider that originally created this session," so it can decrypt normally and connect.
  • Just want to read the history without continuing? Read that session's .jsonl file directly (commands at the end).
  • Rule of thumb: cross-provider is better suited to "starting a new session"; resume old sessions on their original provider whenever possible.

Scenario C: You enabled the switch and checked migration, but migration was silently skipped -> you think "migration lost the sessions"

Symptom: you enabled the switch and checked migration, but the old official sessions neither entered the unified list nor could be restored when you turned the switch off (or the restore checkbox didn't even appear in the disable dialog, see scenario E). You suspect migration lost the sessions during the process.

The truth: migration never ran, so it couldn't have lost anything—not a single character of your sessions was changed. CC Switch has a safety gate before migration: it checks whether Codex's live config (~/.codex/config.toml) is actually routed to the shared custom drawer right now, and only migrates if the routing truly went there. The following two situations are judged "not yet unified" (internal reason code live_not_unified), so CC Switch deliberately skips the migration, preserves your switch and migration intent, and migrates later once the conditions are met:

  • During routing takeover: CC Switch's local routing has taken over the live config, and the live config during takeover doesn't carry the unified routing marker.
  • Injection refused: your config.toml already has a manually specified model_provider, or there's already a differently-shaped [model_providers.custom] table (possibly with a third-party address). To avoid incorrectly routing official traffic to a third-party backend, CC Switch would rather not inject and not migrate.

Skipping migration = touching no session files. No migration means nothing moved, so there's nothing to lose. This is "safe deferral," not "failure with data loss."

What to do:

  • Exit routing takeover -> restart CC Switch: on startup it automatically retries migration (your migration intent is preserved the whole time).
  • Check ~/.codex/config.toml: if there's a conflicting route you wrote by hand, clean up the conflict before enabling the switch.
  • If you'd rather not bother: just turn off the switch, the official sessions still display normally on the openai drawer, completely intact.

Scenario D: You turned off the switch and restored, but "the new sessions chatted during the unified period" didn't return to official -> you think "the new sessions are gone"

Symptom: during the unified period, you chatted a few more new sessions with the official account. Later you turned off the switch, checked restore, and after restoring you find those new sessions didn't return to the official drawer.

The truth: this is intentional design; the new sessions are perfectly fine in the custom drawer, visible and resumable. Restore is based on "the backup ledger from migration time"—only sessions that were originally migrated in from the openai drawer are recorded in the backup and get precisely flipped back to openai. The sessions you created during the unified period are in no backup ledger; and after unification both official and third-party use the custom tag, so CC Switch can't tell whether a new session was chatted with the official account or a third-party. To avoid wrongly stuffing third-party sessions into the official history, the product decision is: these new sessions all stay in the custom (third-party) history and are never moved automatically. The disable dialog's text says this explicitly too—"Sessions created while it was on cannot be attributed to a provider, so they stay in the third-party history."

What to do:

  • Switch to any third-party provider (the custom drawer) to see these sessions in the history list.
  • To read content, read the .jsonl directly; to resume, follow scenario B's rule (go back to the backend that originally generated it).
  • If you really want to manually return one specific session to official: there's currently no automatic button (deliberately omitted, to avoid misjudging the direction). Advanced users can, after backing up that file first, manually change model_provider in the session_meta of the first line of its .jsonl from custom back to openai (an advanced operation; always make a copy before editing).

Scenario E: Restore toast "No restorable migration backup for the current Codex directory" -> you think "restore failed = data is gone"

Symptom: you checked restore when turning off the switch, and got the toast "No restorable migration backup for the current Codex directory." You panic: restore failed, is the data completely gone?

The truth: "nothing to restore" ≠ "data is lost." On the contrary, it's usually because there was no migration that needed restoring. Common reasons:

  • You never checked "migrate existing official sessions" in the first place: with no migration, there's naturally no migration backup and no sessions to flip back. Your old official sessions have been in the openai drawer all along and reappear after you turn off the switch (same as scenario A). (In this case, the disable dialog may not even show the restore checkbox—because the system can't find any backup.)
  • You've already restored once: the session tags have all been flipped back to openai, so clicking again naturally finds "no targets still in custom to restore"—this is idempotent protection, not failure.
  • You switched Codex directories: restore only recognizes the backup ledger belonging to the current directory; switch directories and it can't find the old directory's ledger. Just switch the directory back.

In all three cases, no session was deleted.

What to do: use the end-of-guide commands to count the total session files in ~/.codex/sessions/ and confirm the files are all there; then check whether ~/.cc-switch/backups/ contains a codex-official-history-unify-v1 directory—if even this directory is absent, you never triggered a migration and the sessions have been in their original drawer all along.

Scenario F: Restore refused, toast "Unified session history was re-enabled; restore skipped"

Symptom: you turned off the switch -> checked restore -> but you were quick and immediately turned the switch back on, then saw the toast "Unified session history was re-enabled; restore skipped."

The truth: this is a safeguard against putting your data into a "torn" state, and again no sessions are lost. The restore action is "flip session tags from custom back to openai," but if the switch is on again at this moment, the live config is routing to custom—flipping history back to openai on one side while new sessions land in custom on the other would artificially tear sessions in two. So when CC Switch detects "the switch is on again," it deliberately abandons this restore and changes nothing. Sessions stay as they are, with no deletion or corruption.

What to do: to truly restore, turn the switch off and keep it off (don't immediately turn it back on), then do disable + check restore; to keep things unified, don't restore, and let the sessions stay in the custom shared drawer for normal use.

The overriding principle: CC Switch's unify / migrate / restore only ever changes a single tag field in a session, and automatically backs up before every rewrite. It never deletes your conversations. Out of sight ≠ gone—look in the other drawer, or use the commands below to confirm with your own eyes.


Verify by hand: your session files are still on disk (the most important section)

No amount of text beats seeing it for yourself. Below are the real paths (taken from the CC Switch source) and how to view session files and backup directories on different systems. The whole process is read-only and changes nothing; you're strongly encouraged to try it by hand.

The simplest way: open it directly in a file manager (no command line at all)

  • macOS (Finder): press Cmd + Shift + G, paste ~/.codex/sessions and hit Enter to see a pile of .jsonl session files and their modification times; for the backup directory paste ~/.cc-switch/backups.
  • Windows (File Explorer): paste %USERPROFILE%\.codex\sessions into the address bar and hit Enter to see the session folders and the .jsonl files inside; for the backup directory paste %USERPROFILE%\.cc-switch\backups.

As long as you can see a batch of .jsonl files here, that proves your session data is intact on disk. The file count and modification times are more intuitive than any amount of text.

Where exactly your session / history files live

Content Real path Notes
Session body (the core) ~/.codex/sessions/ (includes date-based subdirectories, recursive) One .jsonl text file per session—this is your conversation content
Archived sessions ~/.codex/archived_sessions/ Also .jsonl
Session index database ~/.codex/state_5.sqlite The model_provider column of the threads table is the "drawer tag"—this is the actual classification source the resume list reads
Migration backup (auto-created when migration is enabled) ~/.cc-switch/backups/codex-official-history-unify-v1/<timestamp>/ Contains jsonl/, state/, meta.json
Restore backup (auto-created when you restore) ~/.cc-switch/backups/codex-official-history-unify-restore-v1/<timestamp>/ A safety copy taken before restore

Note: if you've changed the Codex directory in CC Switch, or set sqlite_home in config.toml, replace ~/.codex above with your actual directory. Below, ~ = your user home directory.

macOS / Linux commands

1. Count the total number of session files (this is the hard evidence of "nothing lost")

bash
# Count the total number of session files -- as long as this number matches your expectation, the data is all there
find ~/.codex/sessions ~/.codex/archived_sessions -name '*.jsonl' 2>/dev/null | wc -l

# Show the 10 most recently modified session files
find ~/.codex/sessions -name '*.jsonl' 2>/dev/null -print0 \
  | xargs -0 ls -lt 2>/dev/null | head -10

2. (Auxiliary) See how many sessions are in each "drawer"

bash
# Number of session files in the official drawer (openai)
grep -rlE '"model_provider"[[:space:]]*:[[:space:]]*"openai"' ~/.codex/sessions 2>/dev/null | wc -l

# Number of session files in the unified drawer (custom)
grep -rlE '"model_provider"[[:space:]]*:[[:space:]]*"custom"' ~/.codex/sessions 2>/dev/null | wc -l

# See the tag distribution at a glance
grep -rhoE '"model_provider"[[:space:]]*:[[:space:]]*"[^"]*"' ~/.codex/sessions 2>/dev/null | sort | uniq -c

Important note, don't let this step scare you: early versions of Codex did not write the model_provider field into the .jsonl, so these old official sessions can't be counted by the grep above—but they're still classified as openai in the index database state_5.sqlite and still show up in the resume list. So judge "nothing lost" by the total file count from step 1—the per-drawer grep is only there to help you understand the classification, and counting fewer than the total file count is completely normal and never means "a batch was lost."

3. (Advanced) Query the index database state_5.sqlite—the classification the resume list actually reads

bash
# Requires sqlite3 to be installed; skip if you don't have it
sqlite3 ~/.codex/state_5.sqlite \
  "SELECT COALESCE(model_provider,'<empty>'), COUNT(*) FROM threads GROUP BY 1;"

This threads table is the actual classification source Codex's resume list reads; the openai row count ≈ the number of sessions you can see in your official drawer. It may not match step 2's jsonl grep—the reason is exactly what's described above: "old sessions don't write the jsonl field, but they're still openai in the index database." A mismatch between the two is not an anomaly.

4. Read the content of a specific session directly (confirm the conversation text is still there)

bash
# Replace <filename> with one of the .jsonl paths listed by ls above
python3 -m json.tool < "<filename>.jsonl" 2>/dev/null | head -50

# Or just open it in an editor (plain text)
open -e "<filename>.jsonl"      # macOS

5. Look at CC Switch's backup directory (proof that a copy was kept before migration / restore)

bash
ls -la ~/.cc-switch/backups/codex-official-history-unify-v1/ 2>/dev/null
ls -la ~/.cc-switch/backups/codex-official-history-unify-restore-v1/ 2>/dev/null

Windows commands (PowerShell)

The session directory is usually at C:\Users\<your username>\.codex\, and backups at C:\Users\<your username>\.cc-switch\backups\.

powershell
# 1. Total number of session files (hard evidence of "nothing lost")
(Get-ChildItem "$env:USERPROFILE\.codex\sessions","$env:USERPROFILE\.codex\archived_sessions" -Recurse -Filter *.jsonl -ErrorAction SilentlyContinue).Count

# 2. The 10 most recently modified sessions
Get-ChildItem "$env:USERPROFILE\.codex\sessions" -Recurse -Filter *.jsonl |
  Sort-Object LastWriteTime -Descending | Select-Object -First 10 FullName,LastWriteTime

# 3. (Auxiliary) How many session files in the official (openai) / unified (custom) drawers
(Get-ChildItem "$env:USERPROFILE\.codex\sessions" -Recurse -Filter *.jsonl |
  Select-String -Pattern 'model_provider"\s*:\s*"openai"' -List).Count
(Get-ChildItem "$env:USERPROFILE\.codex\sessions" -Recurse -Filter *.jsonl |
  Select-String -Pattern 'model_provider"\s*:\s*"custom"' -List).Count

# 4. Look at the backup directories
Get-ChildItem "$env:USERPROFILE\.cc-switch\backups\codex-official-history-unify-v1" -ErrorAction SilentlyContinue
Get-ChildItem "$env:USERPROFILE\.cc-switch\backups\codex-official-history-unify-restore-v1" -ErrorAction SilentlyContinue

Same reminder: the step-3 grep counting fewer than the total file count is normal (old sessions don't write that field); judge "nothing lost" by the total file count from step 1.


Advanced mechanism appendix (for users who want to truly understand how it works)

1. The bucketing mechanism (the essence of the drawers)

Codex's resume / history list filters by the currently active model_provider id with exact string matching. The first line of a session's .jsonl file is a type:"session_meta" record whose payload.model_provider is the drawer that session belongs to (grep -rl counts a file as long as the tag appears once anywhere in it, so no line-by-line parsing is needed; sessions from old versions that didn't write the field can't be counted). What actually drives the resume list is the threads.model_provider column of the index database state_5.sqlite. When config.toml has no explicit model_provider, the official subscription falls into the built-in default id openai; all of CC Switch's third-party providers uniformly use custom.

2. What the switch does (injection, lives only in live)

When enabled, CC Switch injects the following into the official live config.toml:

toml
model_provider = "custom"

[model_providers.custom]
name = "OpenAI"
requires_openai_auth = true
supports_websockets = true
wire_api = "responses"

Every field has a purpose: requires_openai_auth = true keeps authentication going through the ChatGPT login in auth.json, with the base_url defaulting back to the official Codex backend; name = "OpenAI" lets Codex's official feature gates (web search, remote compaction, etc.) keep matching; supports_websockets = true restores the capability that custom entries lose by default; wire_api = "responses" uses the official responses protocol. The net effect is: authentication is unchanged, only the bucket name changed.

Key invariant: this injection can only exist in the live config.toml, and is never written into the database's stored configuration. When you switch away from the official provider and write live back to the database, CC Switch strips this injection precisely (it strips only when the shape exactly matches the injected artifact; a third-party-customized custom table is kept as is). Precisely because of this, "turning off the switch + switching once" fully restores live, and the database always holds your original clean official configuration—this is the cornerstone of the whole switch's reversibility.

3. The two refusal gates for injection (corresponding to scenario C)

  • config.toml already has an explicit model_provider -> don't override the user's route;
  • A differently-shaped [model_providers.custom] table already exists (possibly with a third-party base_url) -> refuse injection, otherwise ChatGPT OAuth traffic would be routed to the wrong backend.

When injection is refused, live is not unified, and the migration gate (checking whether live's model_provider equals custom after trim) judges live_not_unified -> skip migration, preserve intent, and do it later on the next startup retry. This is "safe deferral," not "failure with data loss."

4. The three session classes (which determine the migration / restore boundary)

  • Class A: existing official sessions migrated in at enable time—the backup is the ledger, and they can be precisely restored back to openai;
  • Class B: created during the unified period—in no backup, and official / third-party can't be distinguished, so they're never moved automatically (stay custom);
  • Class C: pure third-party history from before enabling—never touched.

5. The safety of migration / restore (data is never truly deleted; where the guarantee comes from)

Four layers of design jointly guarantee that under all paths, normal and abnormal, the original session data is never truly deleted.

  • Only change the field, never the body: migration / restore only switch the model_provider value in session metadata between openai and custom; conversation content, response_item, and encrypted_content are all kept exactly as is.
  • Always copy a backup before a rewrite: jsonl uses file copy, the state DB uses a full SQLite copy, both stored in a timestamped generation directory. Migration backups live in codex-official-history-unify-v1/, restore backups in the separate codex-official-history-unify-restore-v1/—the two are kept apart to keep the ledger clean.
  • Only move, never delete + atomic writes: all jsonl rewrites go through "temp file + whole-file replacement," and the state DB goes through a transactional UPDATE, with no deletion of any session or index at any point. The file is complete at every moment.
  • Pessimistic skip + idempotent and retryable: when buckets are inconsistent (live_not_unified), it would rather not migrate; a single process lock serializes migration and restore to avoid "startup retry / post-save background task / disable-time restore" concurrently rewriting the same batch of files in both directions; the completion marker is bound to the Codex directory and written conditionally to prevent missed migrations; restore uses the "in the ledger + currently still custom" dual condition to prevent wrong changes. Restore scans the union of all backup generations, so even after many switch cycles it can still restore early-migrated sessions; a repeated restore returns nothing_to_restore, which is idempotent protection rather than failure.

6. Cross-backend encrypted_content (corresponding to scenario B)

The reasoning ciphertext inside a session can only be decrypted by the backend that generated it; upstream Codex by design does not support cross-backend decryption. This is the root cause of "resume failure" and has nothing to do with file integrity—the session .jsonl sits fully on disk and encrypted_content is intact too. Switching back to the original provider to resume, or starting a new session, both work fine.


References


One last word for you: what you see as "sessions disappeared / resume failed" is essentially the session being moved to another history list (drawer), or the other backend being unable to decrypt the old reasoning content; the files always sit untouched in ~/.codex/sessions/ (and state_5.sqlite). Checking "restore from backup" when you turn off the switch precisely flips the official sessions you migrated in back to the official list; and even if you don't restore, both the original .jsonl files and the backup copies under ~/.cc-switch/backups/codex-official-history-unify-*/ are all still there—the data is never truly lost.


Guides Codex Unified Session History Guide Ja (`docs/guides/codex-unified-session-history-guide-ja.md`)

Codex セッション履歴の統一: 機能紹介と利用ガイド(CC Switch)

対象バージョン: CC Switch v3.16.x 以降。本記事は現在のコードをもとに整理しており、コマンドとパスはご自身で検証できます。例示には匿名化したデータを使用しており、実際のセッション内容や API Key は含まれていません。

この機能とは何か

「Codex セッション履歴を統一」は、CC Switch v3.16.x が Codex 向けに新しく追加したスイッチです。その場所は 設定 → 一般 → 「Codex アプリ拡張」グループ の中にあります(「Codex アプリ拡張」はこのグループの見出しで、スイッチ自体は「Codex セッション履歴を統一」という名前です)。オンにすると、公式サブスクリプション(ChatGPT ログイン / OpenAI API Key)のセッションが、CC Switch で管理するすべてのサードパーティプロバイダーのセッションと同じ履歴 / セッション再開リストに表示されます——もう、互いに見えない 2 つのリストに分断されることはありません。

どんな問題を解決するのか

Codex は「プロバイダーのラベル」(model_provider というフィールド)でセッションを分類しており、しかも セッション再開 / 履歴リストには、現在アクティブなプロバイダーと同じラベルのセッションしか表示しません。そのため、セッションは自然と 2 つの「引き出し」に分けられてしまいます。

  • 公式サブスクリプションのセッションは、Codex 内蔵の openai ラベルに分類されます。
  • CC Switch が管理するすべてのサードパーティプロバイダーは、custom ラベルに分類されます。

2 つの引き出しは互いに見えません。公式とサードパーティを頻繁に切り替えている 場合、この分断に遭遇します——「さっき公式で話したセッションが、サードパーティに切り替えたら履歴リストから消えた」というように。実際にはなくなっておらず、別の引き出しに分けられただけです。この分断は、セッションが失われたと誤解させやすいうえに、すべてのセッションを 1 か所でまとめて振り返ったり再開したりするのにも不便です。

このスイッチは、まさにこの分断を解消するためのものです。公式サブスクリプションも custom ラベルで動作させることで、公式とサードパーティのセッションが同じリストに統合され、探すのも再開するのも 1 か所で済みます。

✅ 本記事全体を貫く重要な前提を、まず覚えておいてください: この機能(統一 / 移行 / 復元)は 常にセッション記録内のあの分類ラベル model_provider 1 つだけを書き換え、しかも毎回書き換える前に自動で元ファイルをバックアップします。あなたの会話を 1 文たりとも削除・消去・上書きすることはありません。ですので、本記事の後半で「あるセッションが見えなくなった」とあっても、そのほとんどは「別の引き出しに分けられた」だけであり、「データが消えた」わけではありません——本当に心配なときは、症状対照表 と 自分の目でファイルが残っていることを確認する を直接ご覧ください。

動作原理(一言版)

これを 2 つの引き出し + 自動バックアップ と考えてください。

  • デフォルトでは、公式セッションは openai の引き出しに、サードパーティのセッションは custom の引き出しにあり、互いに見えません。
  • スイッチは 公式も custom の引き出しを使うように させ、2 つの引き出しを 1 つの共有リストに統合します。
  • 既存の公式の古いセッション も一緒に共有の引き出しへ「移す」ことを選べます(この操作を 移行 と呼びます。任意で、能動的にチェックを入れる必要があります)。そして いかなる移動の前にも、まずコピーをバックアップ するので、プロセス全体が 可逆 です。
  • 認証はまったく影響を受けません——公式サブスクリプションは引き続きあなたの ChatGPT ログインを使い、引き続き公式バックエンドを経由します。変わるのはセッションの分類ラベルだけです。

完全な仕組み(何が注入されるのか、なぜ可逆なのか、移行 / 復元がどうやってデータ消失を防ぐのか)は、後述の コア・メンタルモデル と巻末の 応用原理付録 をご覧ください。

使い方(クイック)

  1. 有効化: 設定 → 一般 → Codex アプリ拡張 → 「Codex セッション履歴を統一」をオン → ダイアログで「既存の公式セッション履歴も移行する」にチェックを入れるか決める(以前 の公式セッションも統一リストに合流させたいならチェックを入れる。今後だけ統一したいならチェックを入れない)→ 確定。詳しくは 有効化したとき何が起きるか を参照。
  2. 無効化: 同じスイッチをオフにする → ダイアログで「バックアップから正確に復元する」のチェックを保持(デフォルトでチェック済み)→ 確定すれば、移行した公式セッションを正確に公式リストへ戻せます。詳しくは 無効化したとき何が起きるか を参照。
  3. セッションが消えた気がする? 慌てずに 症状対照表 へ進んで症状から原因を特定し、自分の目で確認 セクションのコマンドで、ファイルがすべて残っていることを自分の目で確かめてください。

コア・メンタルモデル: 2 つの引き出し + 自動バックアップ

この機能を理解するには、引き出し と バックアップ の 2 つだけ覚えれば十分です。

引き出し: Codex はどうやってセッションを分類するか

Codex セッションを 1 つ開くたびに、Codex はセッションファイルの先頭に model_provider というラベルを記録し、「このセッションはどのプロバイダーで話したか」を示します。Codex の セッション再開 / 履歴リストは、現在アクティブなこのラベルで正確にフィルタリングされます——「今あなたが使っているプロバイダー」と同じラベルのセッションだけが表示されます。

  • 公式サブスクリプション(ChatGPT ログイン / OpenAI API Key)のセッションのラベルは、内蔵の openai です。
  • CC Switch が管理するすべてのサードパーティプロバイダーは、一律にラベル custom を使います。

そのためデフォルトでは、公式セッションとサードパーティセッションは生まれつき互いに見えません——2 つの異なる引き出しにあるからです。これは Codex 自身の設計 であり、CC Switch が何かをなくしたわけではありません。

text
デフォルト状態(統一スイッチをオンにしていない):
   ┌──────────────────────┐     ┌──────────────────────────────────┐
   │  openai の引き出し   │     │  custom の引き出し               │
   │  (公式セッション)  │     │  (サードパーティのセッション)  │
   └──────────────────────┘     └──────────────────────────────────┘
       ▲                            ▲
     公式のときは                 サードパーティのときは
     こちらだけ表示               こちらだけ表示

   (2 つの引き出しは互いに見えない)

「Codex セッション履歴を統一」スイッチがすることは、公式サブスクリプションも custom ラベルで動作させ、2 つの引き出しを 1 つに統合することです。その結果、公式セッションとサードパーティセッションが同じセッション再開リストに表示されます。注意してほしいのは、認証は変わらない ということです——あなたの公式サブスクリプションは引き続き ChatGPT ログインを使い、引き続き公式バックエンドを経由します。変わるのはセッションの「分類ラベル」が openai から custom になることだけです。

text
統一スイッチをオンにした後:
   ┌────────────────────────────────────────────────┐
   │              custom 共有引き出し               │
   │  公式セッション + サードパーティのセッション  │
   │     (同じ履歴 / 再開リストに表示される)      │
   └────────────────────────────────────────────────┘

バックアップ: ラベルを変更する前に必ずコピーを取る

「引き出しの統合」では、一部の公式セッションのラベルを openai から custom に変更する必要があります(この操作を 移行 と呼び、これは 任意で、あなたが能動的にチェックを入れる必要があります)。そして どの書き換えの前にも、CC Switch はまず元ファイルをそのままコピー して、ここに保存します。

text
~/.cc-switch/backups/codex-official-history-unify-v1/<時間スタンプ>/

このバックアップが、後の「バックアップから正確に復元する」ための唯一の拠り所です。これによってプロセス全体が 可逆 になります——いつでもスイッチをオフにして、移行した公式セッションを正確に openai の引き出しへ戻せます。

この 2 つの言葉——引き出し(セッションは分類が変わるだけ)、バックアップ(変更前に必ずコピー)——を覚えておけば、以降の内容はすべて簡単に理解できます。


有効化したとき何が起きるか: ステップ別解説

Step 1: スイッチを見つける

text
設定 → 一般 → Codex アプリ拡張

「Codex アプリ拡張」のセクションには 2 行のスイッチがあり、2 行目(青い履歴アイコン)が本ガイドの主役です。

Codex セッション履歴を統一

その下には説明文があります(逐語)。

オンにすると、公式サブスクリプションも共有の custom プロバイダー ID で動作し、公式とサードパーティのセッションが同じ履歴リストに表示されます。既存の公式セッションの移行も選択できます(移行前に自動バックアップ)。オフにする際はバックアップから復元できます。注意:プロバイダーをまたいで古いセッションを再開すると、encrypted_content の推論内容を相手のバックエンドが復号できず、再開に失敗する場合があります。

注意: この説明文には、すでに 3 つのことが予告されています——同じリストに表示される、移行を選べて自動バックアップされる、プロバイダーをまたいだ再開は「失敗する場合がある」。ここでの「再開に失敗する」は 続けられない、新しいターンを生成できない という意味であり、「記録が消える」ではありません。これこそ、この後で重点的に解きほぐす核心的な誤解です。

Step 2: スイッチをオフからオンに切り替える → 確認ダイアログが表示される

スイッチをオンに切り替えると、CC Switch は すぐには保存せず、まず確認ダイアログを表示します。ダイアログの文言は次のとおりです(逐語)。

  • タイトル: Codex セッション履歴を統一

  • 本文:

    オンにすると、公式サブスクリプションとサードパーティが同じセッション履歴リストを共有します。注意:プロバイダーをまたいで古いセッションを再開すると、encrypted_content を相手のバックエンドが復号できず失敗する場合があります。

    既存の公式セッション履歴を共有リストへ移行することもできます(移行前に ~/.cc-switch/backups へ自動バックアップされ、オフにする際に復元を選択できます)。

  • チェックボックス: 既存の公式セッション履歴も移行する

  • 確認ボタン: 理解しました、オンにする

  • キャンセルボタン: キャンセル

このチェックボックスはデフォルトでオフです。 これは重要な分岐点です。

あなたの選択 効果 この時点でデータはどこにあるか
チェックしない(デフォルト) ラベルを切り替えるだけ。オンにした後に新規作成された公式セッションだけ が custom の共有引き出しに入る あなたが オンにする前 の公式の古いセッションは、ラベルが openai のまま、その場で動かず、引き続き ~/.codex/sessions/ にある
チェックする ラベルの切り替えに加えて、既存の公式の古いセッション も openai の引き出しから custom の引き出しへ移行する 古いセッションは コピーしてバックアップ された後、ラベルが custom に書き換えられる。元データはバックアップで保護される

「以前の公式セッションも統一リストに表示したい」なら、必ずこのチェックボックスを能動的にオンにしてください。 さもないと、下の対照表の「シナリオ A」に遭遇します——古いセッションが「消えた」ように見えますが、実際は元の引き出しに残っているだけです。

「キャンセル」を押すか、ダイアログの外側をクリックすると、スイッチはそのままオフ状態に戻り、何も起きません。
「理解しました、オンにする」を押すと、スイッチはオンとして保存され、CC Switch はバックグラウンドで設定をディスクに書き込みます(移行にチェックを入れていれば、移行を実行します)。

Step 3(移行にチェックを入れた場合のみ): 移行はどう実行されるか + データの安全性

「既存の公式セッション履歴も移行する」にチェックを入れた場合、CC Switch はあなたの公式の古いセッションに対して、次の一連の流れを実行します。

text
公式(openai ラベル)の各セッションファイルについて:
   ① まず元ファイルをそのままバックアップディレクトリへコピー          ← データの一次保険ができる
   ② 「一時ファイルに書く → まるごと置換」という原子的な方法で、
      先頭行 session_meta 内の model_provider を
      "openai" から "custom" へ変更するだけ               ← 会話本文は 1 バイトも触らない
   ③ インデックス DB state_5.sqlite も同じトランザクション内でラベルを変更
  • バックアップの場所: ~/.cc-switch/backups/codex-official-history-unify-v1/<時間スタンプ>/。移行のたびに、タイムスタンプ付きの「世代ディレクトリ」を生成し、その中に jsonl/(セッションのコピー)、state/(インデックス DB のコピー)、meta.json(この移行がどの Codex ディレクトリに属するかの記録)が含まれます。
  • 変更するもの: model_provider というフィールドの値だけ。あなたの会話内容、推論内容、すべての本文は そのまま保持 されます。
  • 削除するもの: 何も削除しません。バックアップは「コピー」、書き換えは「同一ファイルの原子的な置換」であり、全工程でセッションやインデックスを削除する操作は一切ありません。ファイルはいかなる時点でも完全です(古い内容か新しい内容かのどちらかであり、空や中途半端になることは決してありません)。

移行が成功すると、これらの公式の古いセッションが統一リストに表示されます。この時点でのあなたのデータ: ① 元のコピーがバックアップディレクトリにある。② アクティブファイルは分類ラベルが変わっただけで、内容は無傷。

注意: 有効化と移行そのものは 成功通知を表示しません。移行は保存時にバックエンドが付随的に実行するもので、UI 上ではスイッチがオン状態になったのが見えるだけです。ですので「移行成功のダイアログが見えなかった」のは正常であり、失敗を意味しません。


無効化したとき何が起きるか: ステップ別解説

Step 1: スイッチをオンからオフに切り替える → バックアップを探索 → 確認ダイアログが表示される

無効化のとき、CC Switch はまず 一瞬かけて移行バックアップの有無を探索 し、それから確認ダイアログを表示します(そのため無効化のダイアログは少しだけ遅延しますが、これは正常です)。文言は次のとおりです(逐語)。

  • タイトル: セッション履歴の統一をオフにする

  • 本文:

    オフにすると、公式サブスクリプションとサードパーティはそれぞれ独立した履歴リストに戻ります。オン期間中に作成されたセッションは提供元を判別できないため、サードパーティの履歴に残り、公式サブスクリプションからは見えなくなります。

  • チェックボックス(条件付き表示): オンにした際に移行した公式セッションを公式履歴へ復元する(バックアップから正確に復元)

  • 確認ボタン: オフにする

  • キャンセルボタン: キャンセル

ポイント: 本文が言っているのは「公式サブスクリプションからは 見えなくなる」——見えなくなる であり、削除される ではありません。オン期間中に新たに話したセッションは、引き続き custom の引き出しに完全な形で残っており、オフにした後で公式側から見えなくなるだけです。

この復元チェックボックスはデフォルトでオンです。 つまりデフォルトの動作は「オフにすると同時に、移行した公式セッションを公式履歴へ正確に復元する」です。チェックを保持したまま「オフにする」を押すだけで構いません。

チェックボックスが 表示されない 場合は、復元が必要なバックアップがないとシステムが判断したことを意味します(移行に一度もチェックを入れていない、またはバックアップを探索できない)——この場合、あなたの公式の古いセッションは一度も変更されていないので、スイッチをオフにすれば自然と openai の引き出しに戻ります。

Step 2: 復元はどう実行されるか(バックアップ台帳に従って正確に戻す)

チェックを保持して「オフにする」を押すと、CC Switch の復元フローは次のようになります。

text
① まず現在の状態を独立した復元バックアップディレクトリへもう一度コピー
   ~/.cc-switch/backups/codex-official-history-unify-restore-v1/<時間スタンプ>/
   (復元自体もまずバックアップするので、復元でもデータは失われない)
② すべての移行バックアップ世代を走査し、「当初のラベルが openai」のセッション id を集めて「台帳」を作る
③ 【台帳に含まれ、かつ現在もまだ custom】のセッションだけ、ラベルを "openai" に戻す

③ のステップの 二重条件 に注意してください——台帳に含まれていること(当初確かに公式から移行されたものだと証明できる)に加えて、現在もまだ custom であること(あなたが手動で変更していないことを示す)。両方の条件を満たして初めて戻します。これにより、復元は正確であり、かつ誤って手を加えることもありません。

この時点でのあなたのデータ: 戻された公式セッションはラベルが openai に変わり、再び公式リストに表示されます。同時に、移行バックアップと復元バックアップの 2 つのコピーがどちらもディスク上に残っています。

Step 3: 通知を見て、結果を確認する

「オフにする + 復元にチェック」というパスだけが結果通知を表示します。表示され得る通知(逐語)。

表示される通知 意味
バックアップから公式セッション履歴を復元しました(セッションファイル {{files}} 件、インデックス {{rows}} 行) 復元成功。{{files}} / {{rows}} の部分には実際の数字が表示される
現在の Codex ディレクトリに復元可能な移行バックアップはありません 復元できる内容がない(データが消えたわけではない。対照表シナリオ E を参照)
統一セッション履歴が再度有効化されたため、復元をスキップしました 復元のキュー待ち中にスイッチを再びオンにしたため、システムが復元を自発的に取りやめた(対照表シナリオ F を参照)
公式セッション履歴の復元に失敗しました。もう一度お試しください 復元の途中でエラー。もう一度試せばよく、データは破壊されていない
保存に失敗しました。もう一度お試しください オフにするステップの保存そのものが失敗。この場合 復元は決して起動されず、スイッチは元の位置に戻る

気の利いた安全設計: 「スイッチをオフにする」ステップの保存が失敗した場合、CC Switch は 復元を決して実行しません。さもないと「スイッチはまだオン、しかしセッションは openai バケットに戻された」という矛盾状態が生じてしまいます。保存失敗時、スイッチは 自動で元の位置に戻る ので、「オフに見えるのに実は保存されていない」という偽の状態に取り残されることはありません。


「会話が消えた?」症状対照表

以下の 6 つのシナリオは、ユーザーが最も「セッションが消えた」と誤解しやすいケースです。どれも真相は: データは無傷で、引き出しが変わったか一時的に見えないだけ。 まずこの表で症状から原因を特定し、その後で下の詳細説明を読んでください。

シナリオ あなたが見るもの データの真相 一言での解決法
A 移行にチェックなし 公式の古いセッションが統一リストにない すべて存在、openai ラベルのまま 移行にチェックを入れて再度オンにする、またはスイッチをオフにする
B プロバイダーをまたいだ再開が失敗 続けられない / エラー ファイルは無傷、暗号文がバックエンドをまたいで復号できないだけ 元のプロバイダーで再開する。内容だけ見るなら jsonl を直接読む
C ルーティング接管 / 注入が拒否 移行も復元もされない 移行が安全にスキップされ、ファイルは未変更 接管を終了 → 再起動して再試行。またはスイッチを直接オフにする
D 復元後、新セッションが公式に戻らない オン期間中の新セッションが公式にない custom の引き出しにある、設計上動かさない サードパーティプロバイダーに切り替えれば見える
E 「復元可能なバックアップなし」と通知 復元が「失敗」 通常はそもそも移行していない、セッションは元の引き出しにある スイッチをオフにすれば公式セッションが自動で再表示
F 「スイッチが再度有効化、復元スキップ」と通知 復元が拒否 データの矛盾を防止、何も変更していない まずスイッチを完全にオフにしてから復元する

シナリオ A: スイッチをオンにしたが移行にチェックを入れなかった → 公式の古いセッションが「消えた」

現象: 統一スイッチをオンにしたが、有効化ダイアログの「既存の公式セッション履歴も移行する」にチェックを入れなかった(デフォルトでチェックなし)。オンにした後で見ると、以前の公式の古いセッションがすべてリストにないように見える。

真相: データは 100% すべて存在し、1 行も動いていません。スイッチは「オンにした後に新規作成された」公式セッションにのみ効きます。あなたが オンにする前 の公式の古いセッションはラベルが openai のままで、そっくりそのまま ~/.codex/sessions/ に横たわっています。今あなたがアクティブにしているのは custom の引き出しなので、openai の引き出しに残った古いセッションが見えないのは当然です——これが「消えたように見える」理由のすべてです。

どうするか(いずれか):

  1. スイッチを再度オンにするときに「既存の公式セッション履歴も移行する」にチェックを入れ、古いセッションを custom の引き出しへ移せば、すぐに統一リストに表示されます(書き換え前に自動バックアップ)。
  2. または単に統一スイッチをオフにする と、公式は再び openai の引き出しで動作し、古いセッションがその場で再表示されます。

シナリオ B: プロバイダーをまたいで古いセッションを再開して失敗 → 「このセッションが壊れた / 消えた」と思う

現象: 統一した後、リストに「別のプロバイダー」で話した古いセッションが見える。今のプロバイダーに切り替えて「再開」を押すと、エラーになったり繋がらなかったりする。

真相: セッションファイルは完全に無傷で、失われたのはデータではなく「バックエンドをまたいだ復号能力」です。Codex セッションには暗号化された推論内容 encrypted_content が保存されており、この暗号文は、それを生成したバックエンドだけが復号できます。B プロバイダーで A プロバイダーが生成したセッションを再開しようとすると、B は A の暗号文を解けない → 再開失敗。これは 上流の Codex の設計上の制約(by design) であり、CC Switch がファイルに手を加えたかどうかとは無関係です。セッション内の文字内容はいつでも読めます。

これは本記事全体で 唯一「本当に問題が起きたように見える」実在の例外 です——ただし注意してください: これは 再開できない(新しいターンを生成できない) だけであり、元ファイルは依然として完全に存在し、会話の文字はいつでも読めます。

どうするか:

  • 「このセッションを最初に作成したプロバイダー」で再開すれば、正常に復号でき、繋がります。
  • 履歴の内容だけ見たくて、続ける必要がない場合は、そのセッションの .jsonl ファイルを直接読んでください(巻末にコマンドあり)。
  • 経験則: プロバイダーをまたぐ場合は「新規セッションを始める」のが向いており、古いセッションはできるだけ元のプロバイダーで再開してください。

シナリオ C: スイッチをオンにし移行にもチェックを入れたが、移行が静かにスキップされた → 「移行がセッションをなくした」と思う

現象: オンにして移行にチェックを入れたのに、公式の古いセッションは統一リストに入らず、スイッチをオフにして復元しようとしても「復元できるものがない」と通知される(または無効化ダイアログに復元チェックボックスがそもそも現れない。シナリオ E を参照)。あなたは、移行の過程でセッションをなくしたのではと疑います。

真相: 移行はそもそも 実行されていない ので、なくすことも不可能です——あなたのセッションは 1 文字も変更されていません。CC Switch には移行前に安全ゲートがあります: Codex の live 設定(~/.codex/config.toml)が、この時点で 本当に 共有の custom 引き出しへルーティングされているかを確認し、本当にルーティングされている場合だけ移行します。以下の 2 つのケースでは「まだ統一されていない」と判定され(内部の理由コード live_not_unified)、移行を自発的にスキップし、あなたのスイッチと移行の意思は保持し、条件が満たされてから移行します。

  • ルーティング接管中: CC Switch のローカルルーティングが live 設定を接管しており、接管中の live には統一ルーティングのマークが付いていません。
  • 注入が拒否された: あなたの config.toml にすでに手動指定の model_provider があるか、形態の異なる [model_providers.custom] テーブルが既に存在する(サードパーティのアドレスが付いている可能性がある)。公式トラフィックを誤ってサードパーティバックエンドへルーティングするのを避けるため、CC Switch は注入も移行もしないことを選びます。

移行のスキップ = どのセッションファイルにも触れない。移行していない=動かしていない、消えようがない。 これは「安全な先送り」であり、「失敗してデータが消えた」ではありません。

どうするか:

  • ルーティング接管を終了 → CC Switch を再起動: 起動時に自動で移行を再試行します(あなたの移行の意思はずっと保持されています)。
  • ~/.codex/config.toml を確認: 手動で書いた競合するルーティングがあれば、競合を整理してからスイッチをオンにします。
  • どうしても手間をかけたくない場合は、スイッチをオフにすれば、公式セッションは引き続き openai の引き出しで正常に表示され、まったく無傷です。

シナリオ D: スイッチをオフにして復元したが、「オン期間中に新たに話したセッション」が公式に戻らない → 「新セッションが消えた」と思う

現象: 統一をオンにしている間、公式でさらにいくつかの新セッションを話した。後でスイッチをオフにし、復元にチェックを入れた。復元が終わると、その数本の新セッションが公式の引き出しに戻っていない。

真相: これは 意図的な 設計で、新セッションはちゃんと custom の引き出しにあり、見えるし続けられます。復元の拠り所は「移行時のバックアップ台帳」です——当初 openai の引き出しから移行されてきたセッションだけ がバックアップに記録されており、正確に openai へ戻されます。あなたが オン期間中に新規作成した セッションはどのバックアップ台帳にもありません。しかも統一後は公式もサードパーティも custom ラベルを使うので、CC Switch はこの新セッションが公式で話したものかサードパーティで話したものか判別できません。サードパーティのセッションを公式履歴に誤って押し込まないため、プロダクトの決定として、これらの新セッションは一律に custom(サードパーティ)の履歴に残し、決して自動で動かしません。無効化ダイアログの文言もこれを明示しています——「オン期間中に作成されたセッションは提供元を判別できないため、サードパーティの履歴に残ります」。

どうするか:

  • 任意のサードパーティプロバイダー(custom の引き出し)に切り替えれば、履歴リストでこれらのセッションが見えます。
  • 内容を見たいなら .jsonl を直接読み、再開したいならシナリオ B のルール(それを生成した元のバックエンドに戻る)に従ってください。
  • もし ある 1 本 を手動で公式に戻したい場合: 現在は自動ボタンはありません(方向を誤判定するのを避けるため、あえて作っていません)。上級ユーザーは、そのファイルを 先にバックアップ したうえで、.jsonl の 1 行目 session_meta 内の model_provider を custom から openai に手動で戻せます(上級操作です。変更前に必ずコピーを取ってください)。

シナリオ E: 復元時に「現在の Codex ディレクトリに復元可能な移行バックアップはありません」と通知 → 「復元失敗 = データが消えた」と思う

現象: スイッチをオフにするときに復元にチェックを入れたら、「現在の Codex ディレクトリに復元可能な移行バックアップはありません」と通知が出た。あなたは慌てます: 復元すら失敗した、データは完全に消えたのでは?

真相: 「復元できるものがない」≠「データが消えた」。むしろ逆で、通常は そもそも復元すべき移行が存在しない からです。よくある原因:

  • 当初「既存の公式セッションを移行する」にチェックを入れていない: 移行していない以上、移行バックアップもなく、戻すべきセッションもありません。あなたの公式の古いセッションはずっと openai の引き出しにあり、スイッチをオフにすれば直接再表示されます(シナリオ A と同じ)。(この場合、無効化ダイアログは復元チェックボックスを そもそも表示しない こともあります——システムがバックアップを一切探索できないためです。)
  • すでに一度復元済み: セッションラベルはすべて openai に戻っており、もう一度押しても「まだ custom の対象がない」のは当然です——これは 冪等保護であり、失敗ではありません。
  • Codex ディレクトリを切り替えた: 復元は 現在の ディレクトリに属するバックアップ台帳しか認識しないので、ディレクトリを変えると旧ディレクトリの台帳が見つかりません。ディレクトリを戻せば解決します。

この 3 つのケースでは、どのセッションも削除されていません。

どうするか: 巻末のコマンドで ~/.codex/sessions/ 内のセッションファイル総数を数え、ファイルがすべて残っていることを確認してください。次に ~/.cc-switch/backups/ に codex-official-history-unify-v1 ディレクトリがあるかを見てください——もしこのディレクトリすらなければ、あなたは一度も移行を起動しておらず、セッションはずっと元の引き出しにある、ということです。

シナリオ F: 復元が拒否され、「統一セッション履歴が再度有効化されたため、復元をスキップしました」と通知

現象: スイッチをオフにする → 復元にチェック → 手が速くて、すぐにスイッチを再びオンにした。すると「統一セッション履歴が再度有効化されたため、復元をスキップしました」と通知が出た。

真相: これはデータを「矛盾」状態にしてしまうのを防ぐ防護であり、セッションは同じく消えていません。復元の動作は「セッションラベルを custom から openai へ戻す」ことですが、この時点でスイッチが再びオンになっていると、live 設定は custom へルーティングしています——一方で履歴を openai へ戻し、一方で新セッションを custom に落とせば、セッションが人為的に 2 つに引き裂かれてしまいます。そのため CC Switch は「スイッチが再びオンになった」のを検知すると、この復元を自発的に取りやめ、何も変更しません。セッションは現状を維持し、削除も破壊もありません。

どうするか: 本当に復元したいなら、まずスイッチを安定してオフにし(すぐにオンにし直さない)、それから「オフにする + 復元にチェック」を実行してください。統一を保ちたいなら、復元せず、セッションを custom の共有引き出しに残して通常どおり使ってください。

大原則: CC Switch の統一 / 移行 / 復元は、全工程でセッションの 1 つのラベルフィールドだけを変更し、しかも毎回書き換える前に自動でバックアップします。あなたの会話を削除することはありません。見えない ≠ 消えた——別の引き出しを見るか、下のコマンドで自分の目で確かめてください。


自分の目で確認: セッションファイルはディスク上に残っている(最重要セクション)

文字をいくら重ねるより、自分の目で見るのが一番です。以下に 実際のパス(CC Switch のソースコードから取得)と、異なる OS でセッションファイル・バックアップディレクトリを見る方法を示します。全工程は読み取りのみで変更なし。ぜひ一度ご自身で試してみてください。

最も簡単な方法: ファイルマネージャーで直接開く(コマンドライン完全不要)

  • macOS(Finder): Cmd + Shift + G を押して ~/.codex/sessions を貼り付けて Enter すれば、たくさんの .jsonl セッションファイルとその更新時刻が見えます。バックアップディレクトリは ~/.cc-switch/backups を貼り付けます。
  • Windows(エクスプローラー): アドレスバーに %USERPROFILE%\.codex\sessions を貼り付けて Enter すれば、セッションフォルダとその中の .jsonl が見えます。バックアップディレクトリは %USERPROFILE%\.cc-switch\backups を貼り付けます。

ここで一連の .jsonl ファイルが見えれば、それがセッションデータが無傷でディスク上にある証拠です。 ファイル数や更新時刻は、どんな文章よりも直感的です。

あなたのセッション / 履歴ファイルはどこにあるのか

内容 実際のパス 説明
セッション本文(コア) ~/.codex/sessions/(日付別サブディレクトリを含む、再帰的) セッション 1 つにつき 1 つの .jsonl テキストファイル。これがあなたの会話内容
アーカイブ済みセッション ~/.codex/archived_sessions/ 同じく .jsonl
セッションインデックス DB ~/.codex/state_5.sqlite threads テーブルの model_provider 列が「引き出しラベル」。これこそ、セッション再開リストが実際に読み取る分類のソース
移行バックアップ(移行をオンにすると自動生成) ~/.cc-switch/backups/codex-official-history-unify-v1/<時間スタンプ>/ jsonl/、state/、meta.json を含む
復元バックアップ(復元を押すと自動生成) ~/.cc-switch/backups/codex-official-history-unify-restore-v1/<時間スタンプ>/ 復元前の安全なコピー

注意: CC Switch で Codex ディレクトリを変更した場合や、config.toml で sqlite_home を設定している場合は、上記の ~/.codex をあなたの実際のディレクトリに置き換えてください。以下の ~ = あなたのユーザーホームディレクトリ。

macOS / Linux コマンド

1. セッションファイル総数を数える(これこそ「消えていない」確固たる証拠)

bash
# セッションファイルの総数を数える —— この数が想定どおりなら、データはすべて残っている
find ~/.codex/sessions ~/.codex/archived_sessions -name '*.jsonl' 2>/dev/null | wc -l

# 最近更新されたセッションファイル上位 10 件を見る
find ~/.codex/sessions -name '*.jsonl' 2>/dev/null -print0 \
  | xargs -0 ls -lt 2>/dev/null | head -10

2. (補助)各「引き出し」にそれぞれ何個のセッションがあるか見る

bash
# 公式の引き出し(openai)のセッションファイル数
grep -rlE '"model_provider"[[:space:]]*:[[:space:]]*"openai"' ~/.codex/sessions 2>/dev/null | wc -l

# 統一の引き出し(custom)のセッションファイル数
grep -rlE '"model_provider"[[:space:]]*:[[:space:]]*"custom"' ~/.codex/sessions 2>/dev/null | wc -l

# 各ラベルの分布をひと目で確認
grep -rhoE '"model_provider"[[:space:]]*:[[:space:]]*"[^"]*"' ~/.codex/sessions 2>/dev/null | sort | uniq -c

重要なヒント、このステップに驚かないでください: 初期バージョンの Codex は .jsonl に model_provider フィールドを書き込みません。これらの古い公式セッションは上記の grep では 数えられません が、インデックス DB state_5.sqlite では依然として openai に分類されており、セッション再開リストではちゃんと見えます。ですので 「セッションが消えていない」かの判断はステップ 1 のファイル総数を基準にしてください——バケット別 grep は分類を理解する補助に過ぎず、数えた結果がファイル総数より少ないのは まったく正常 であり、決して「ひとまとまり消えた」ことを意味しません。

3. (応用)インデックス DB state_5.sqlite を見る——セッション再開リストが実際に読む分類

bash
# sqlite3 がインストール済みであること;未インストールならスキップ可
sqlite3 ~/.codex/state_5.sqlite \
  "SELECT COALESCE(model_provider,'<空>'), COUNT(*) FROM threads GROUP BY 1;"

この threads テーブルこそ、Codex のセッション再開リストが実際に読み取る分類のソースであり、openai の行数 ≈ あなたの公式の引き出しで見えるセッション数です。ステップ 2 の jsonl grep とは数が合わないことがあります——その理由は、上述の「古いセッションは jsonl フィールドを書き込まないが、インデックス DB では依然として openai」だからです。両者が合わないのは異常ではありません。

4. あるセッションの内容を直接読む(会話の文字が残っていることを確認)

bash
# <ファイル名> を、上の ls で表示された .jsonl のパスに置き換える
python3 -m json.tool < "<ファイル名>.jsonl" 2>/dev/null | head -50

# またはエディタで直接開いて見る(プレーンテキスト)
open -e "<ファイル名>.jsonl"      # macOS

5. CC Switch のバックアップディレクトリを見る(移行 / 復元の前に必ずコピーを残した証拠)

bash
ls -la ~/.cc-switch/backups/codex-official-history-unify-v1/ 2>/dev/null
ls -la ~/.cc-switch/backups/codex-official-history-unify-restore-v1/ 2>/dev/null

Windows コマンド(PowerShell)

セッションディレクトリは通常 C:\Users\<あなたのユーザー名>\.codex\ にあり、バックアップは C:\Users\<あなたのユーザー名>\.cc-switch\backups\ にあります。

powershell
# 1. セッションファイルの総数(「消えていない」ことの動かぬ証拠)
(Get-ChildItem "$env:USERPROFILE\.codex\sessions","$env:USERPROFILE\.codex\archived_sessions" -Recurse -Filter *.jsonl -ErrorAction SilentlyContinue).Count

# 2. 最近更新されたセッション上位 10 件
Get-ChildItem "$env:USERPROFILE\.codex\sessions" -Recurse -Filter *.jsonl |
  Sort-Object LastWriteTime -Descending | Select-Object -First 10 FullName,LastWriteTime

# 3. (補助)公式(openai) / 統一(custom) の引き出しにそれぞれ何件のセッションファイルがあるか
(Get-ChildItem "$env:USERPROFILE\.codex\sessions" -Recurse -Filter *.jsonl |
  Select-String -Pattern 'model_provider"\s*:\s*"openai"' -List).Count
(Get-ChildItem "$env:USERPROFILE\.codex\sessions" -Recurse -Filter *.jsonl |
  Select-String -Pattern 'model_provider"\s*:\s*"custom"' -List).Count

# 4. バックアップディレクトリを見る
Get-ChildItem "$env:USERPROFILE\.cc-switch\backups\codex-official-history-unify-v1" -ErrorAction SilentlyContinue
Get-ChildItem "$env:USERPROFILE\.cc-switch\backups\codex-official-history-unify-restore-v1" -ErrorAction SilentlyContinue

同じく注意: ステップ 3 の grep の数がファイル総数より 少なくなる のは正常です(古いセッションはこのフィールドを書き込まないため)。「セッションが消えていない」の判断は、ステップ 1 の ファイル総数 を基準にしてください。


応用原理付録(仕組みを本当に理解したい人向け)

1. バケット分け機構(引き出しの本質)

Codex のセッション再開 / 履歴リストは、現在アクティブな model_provider id で 厳密な文字列フィルタリング を行います。セッションファイル .jsonl の 1 行目 は type:"session_meta" のレコードで、その payload.model_provider がそのセッションの属する引き出しです(grep -rl はファイル内にそのラベルが 1 回でも出現すればそのファイルをカウントするので、行ごとに解析する必要はありません。旧バージョンでこのフィールドを書き込んでいないセッションは数えられません)。セッション再開リストを実際に駆動するのはインデックス DB state_5.sqlite の threads.model_provider 列です。公式サブスクリプションは config.toml に明示的な model_provider がないとき、内蔵のデフォルト id openai に入ります。CC Switch のすべてのサードパーティプロバイダーは一律に custom を使います。

2. スイッチがすること(注入、live にのみ存在)

オンにすると、CC Switch は公式 live config.toml に次の内容を注入します。

toml
model_provider = "custom"

[model_providers.custom]
name = "OpenAI"
requires_openai_auth = true
supports_websockets = true
wire_api = "responses"

各フィールドには役割があります。requires_openai_auth = true は認証を引き続き auth.json 内の ChatGPT ログインで行わせ、base_url 未指定時は公式 Codex バックエンドへフォールバックさせます。name = "OpenAI" は Codex の公式機能ゲート(web search、リモート圧縮など)を引き続きヒットさせます。supports_websockets = true は custom エントリでデフォルトに失われる能力を補います。wire_api = "responses" は公式の responses プロトコルを使います。正味の効果は: 認証は変わらず、バケット名が変わるだけ。

重要な不変条件: この注入は live config.toml にのみ存在でき、決してデータベースの保存設定には書き込まれません。 公式プロバイダーから切り替えて離れ、live をデータベースへ書き戻すとき、CC Switch はこの注入を正確に剥離します(形態が注入物と完全に一致するときだけ剥離し、サードパーティがカスタムした custom テーブルはそのまま保持します)。だからこそ「スイッチをオフにする + 一度切り替える」だけで live を完全に復元でき、データベースには常にあなた本来のクリーンな公式設定が保たれます——これがスイッチ全体の可逆性の礎です。

3. 注入の 2 つの拒否ゲート(シナリオ C に対応)

  • config.toml に明示的な model_provider がすでにある → ユーザーのルーティングを上書きしない。
  • 形態の異なる [model_providers.custom] テーブルがすでに存在する(サードパーティの base_url が付いている可能性がある)→ 注入を拒否、さもないと ChatGPT OAuth トラフィックを誤ったバックエンドへルーティングしてしまう。

注入を拒否したとき live は統一されず、移行ゲート(live の model_provider が trim 後に custom と等しいかを確認)が live_not_unified と判定 → 移行をスキップし、意思を保持し、次回起動の再試行時に行います。これは「安全な先送り」であり、「失敗してデータが消えた」ではありません。

4. セッションの三分類(移行 / 復元の境界を決める)

  • A 類: オン時に移行した既存の公式セッション——バックアップが台帳であり、正確に openai へ復元可能。
  • B 類: オン期間中に新規作成——どのバックアップにもなく、公式 / サードパーティを判別不能、決して自動で動かさない(custom に残す)。
  • C 類: オン前の純粋なサードパーティ履歴——絶対に触れない。

5. 移行 / 復元の安全性(データが本当に削除されることはない、その保証はどこから来るか)

4 層の設計が共同で保証します: 正常・異常のあらゆるパス において、元のセッションデータが本当に削除されることはありません。

  • フィールドだけ変更、本文には触れない: 移行 / 復元はセッションメタデータ内の model_provider の値を openai と custom の間で切り替えるだけで、会話内容、response_item、encrypted_content はすべてそのまま保持します。
  • 書き換え前に必ずコピーをバックアップ: jsonl はファイルコピー、state DB は SQLite の完全なコピーで、タイムスタンプ付きの世代ディレクトリに保存します。移行バックアップは codex-official-history-unify-v1/ に、復元バックアップは独立した codex-official-history-unify-restore-v1/ にあり、台帳を純粋に保つため両者は分けられています。
  • 移すだけ削除しない + 原子書き込み: すべての jsonl 書き換えは「一時ファイル + 全体置換」を経由し、state DB はトランザクション化された UPDATE を経由し、全工程でセッションやインデックスを削除する操作は一切ありません。ファイルはいかなる時点でも完全です。
  • 悲観的スキップ + 冪等で再試行可能: バケットが不一致のとき(live_not_unified)は移行しないことを選びます。一つのプロセスロックが移行と復元を直列化し、「起動時の再試行 / 保存後のバックグラウンドタスク / 無効化時の復元」が同じ一群のファイルを並行して双方向に書き換えるのを防ぎます。完了マークは Codex ディレクトリに紐づけて条件付きで書き込み、移行漏れを防ぎます。復元は「台帳にある + 現在もまだ custom」の二重条件を使い、誤変更を防ぎます。復元スキャンはすべてのバックアップ世代の和集合を取り、何度もスイッチを切り替えた後でも初期に移行したセッションを復元できます。重複した復元は nothing_to_restore を返しますが、これは冪等保護であり失敗ではありません。

6. バックエンドをまたいだ encrypted_content(シナリオ B に対応)

セッション内の推論暗号文は、それを生成したバックエンドだけが復号でき、上流の Codex は by design でバックエンドをまたいだ復号をサポートしません。これが「再開失敗」の根本原因であり、ファイルの完全性とは無関係です——セッション .jsonl は完全にディスク上に横たわり、encrypted_content も無傷です。元のプロバイダーに戻して再開するか、新規セッションを始めれば、どちらも正常です。


参考リンク


最後に一言: あなたが見た「セッションが消えた / 再開失敗」は、本質的には セッションが別の履歴リスト(引き出し)に移されたか、相手のバックエンドが古い推論内容を復号できない ことであり、ファイルは常にそっくりそのまま ~/.codex/sessions/(および state_5.sqlite)に横たわっています。スイッチをオフにするとき「バックアップから復元する」にチェックを入れれば、移行した公式セッションを正確に公式リストへ戻せます。たとえ復元しなくても、元の .jsonl ファイルと ~/.cc-switch/backups/codex-official-history-unify-*/ 配下のバックアップコピーはどちらも残っています——データが本当に失われることは決してありません。


Guides Codex Unified Session History Guide Zh (`docs/guides/codex-unified-session-history-guide-zh.md`)

统一 Codex 会话历史:功能介绍与使用攻略(CC Switch)

适用版本:CC Switch v3.16.x 及以上。本文根据当前代码整理,命令与路径均可亲手验证;示例使用去敏数据,不包含真实会话内容或 API Key。

这个功能是什么

「统一 Codex 会话历史」是 CC Switch v3.16.x 为 Codex 新增的一个开关。它的位置在 设置 → 通用 → 「Codex 应用增强」分组里("Codex 应用增强"是这个分组的标题,开关本身叫"统一 Codex 会话历史")。开启后,官方订阅(ChatGPT 登录 / OpenAI API Key)的会话,会和 CC Switch 管理的所有第三方供应商会话,出现在同一个历史 / 续聊列表里——不再被分隔在两个互相看不见的列表中。

它解决什么问题

Codex 自己按"供应商标签"(一个叫 model_provider 的字段)给会话分类,而且续聊 / 历史列表只显示和你当前激活的供应商同标签的会话。于是会话天然被分进两个"抽屉":

  • 官方订阅的会话,归在 Codex 内建的 openai 标签下;
  • CC Switch 管理的所有第三方供应商,归在 custom 标签下。

两个抽屉互相看不见。如果你经常在官方与第三方之间切换,就会遇到这种割裂:"刚才用官方聊的会话,切到第三方后在历史列表里找不到了"——它其实没丢,只是被分到了另一个抽屉。这种割裂既容易让人误以为会话丢失,也不方便把所有会话放在一处统一回顾、续聊。

这个开关就是为了消除这种割裂:让官方订阅也以 custom 标签运行,于是官方与第三方会话合并进同一个列表,找起来、续起来都在一处。

✅ 一个贯穿全文的重要前提,请先记住:这个功能(统一 / 迁移 / 还原)全程只改写会话记录里那一个归类标签 model_provider,而且每次改写前都会自动把原文件备份一份。它不会删除、清空或覆盖你的任何一句对话。所以本文后面若提到"某些会话看不到了",几乎都是"被分到了另一个抽屉",而不是"数据没了"——真担心时,直接看 症状对照表 与 亲手验证文件还在。

工作原理(一句话版)

把它想成 两个抽屉 + 自动备份:

  • 默认时,官方会话在 openai 抽屉、第三方会话在 custom 抽屉,互不可见;
  • 开关让官方也改用 custom 抽屉,于是两个抽屉合并成一个共享列表;
  • 你可以选择把现有的官方老会话也一并"搬"进共享抽屉(这一步叫迁移,可选、需主动勾选),而任何搬动前都会先复制一份备份,所以整个过程可逆;
  • 认证完全不受影响——官方订阅照常用你的 ChatGPT 登录、照常走官方后端,变的只是会话的归类标签。

完整机制(注入了什么、为什么可逆、迁移/还原如何保证不丢数据)见下文 核心心智模型 与文末 进阶原理附录。

如何使用(速览)

  1. 开启:设置 → 通用 → Codex 应用增强 → 打开「统一 Codex 会话历史」→ 在弹窗里决定是否勾选"同时迁入现有官方会话历史"(想让以前的官方会话也并进统一列表,就勾上;只想从现在起统一,就不勾)→ 确认。详见 开启时会发生什么。
  2. 关闭:关掉同一开关 → 弹窗里保持勾选"按备份精确还原"(默认就勾着)→ 确认,即可把当初迁入的官方会话精确翻回官方列表。详见 关闭时会发生什么。
  3. 感觉会话丢了? 别慌,跳到 症状对照表 按症状定位,并用 亲手验证 一节的命令亲眼确认文件都在。

核心心智模型:两个抽屉 + 自动备份

要理解这个功能,你只需要记住两件事:抽屉和备份。

抽屉:Codex 怎么给会话分类

你每开一个 Codex 会话,Codex 会在会话文件头部记一个标签 model_provider,标记"这条会话是用哪个供应商聊的"。Codex 的续聊 / 历史列表是按当前激活的这个标签精确过滤的——只显示和"你现在这个供应商"同标签的会话。

  • 官方订阅(ChatGPT 登录 / OpenAI API Key)的会话,标签是内建的 openai。
  • CC Switch 管理的所有第三方供应商,统一用标签 custom。

所以默认情况下,官方会话和第三方会话天生互相看不见——它们在两个不同的抽屉里。这是 Codex 自身的设计,不是 CC Switch 弄丢了什么。

text
默认状态(没开统一开关):

   ┌─────────────────┐        ┌─────────────────┐
   │   openai 抽屉    │        │   custom 抽屉    │
   │ (官方订阅会话)  │        │ (第三方供应商会话)│
   └─────────────────┘        └─────────────────┘
         ▲                            ▲
   用官方时只看到这边            用第三方时只看到这边
   (两个抽屉互相看不见)

「统一 Codex 会话历史」开关做的事,就是让官方订阅也以 custom 标签运行,把两个抽屉合并成一个,于是官方会话和第三方会话出现在同一个续聊列表里。注意:认证没变——你的官方订阅照常用你的 ChatGPT 登录、照常走官方后端,只是会话的"归类标签"从 openai 变成了 custom。

text
开启统一开关后:

   ┌─────────────────────────────────────────┐
   │            custom 共享抽屉                │
   │   官方订阅会话  +  第三方供应商会话         │
   │   (出现在同一个历史 / 续聊列表里)          │
   └─────────────────────────────────────────┘

备份:每次改标签前都先复制一份

"合并抽屉"需要把一部分官方会话的标签从 openai 改成 custom(这一步叫迁移,且是可选的、需要你主动勾选)。而任何一次改写之前,CC Switch 都会先把原文件原封不动地复制一份到这里:

text
~/.cc-switch/backups/codex-official-history-unify-v1/<时间戳>/

这份备份,就是日后"按备份精确还原"的唯一依据。它让整个过程变得可逆:你随时可以关掉开关,把当初迁进来的官方会话精确地翻回 openai 抽屉。

记住这两个词——抽屉(会话只是换了归类)、备份(改前必先复制)——后面所有内容你都能轻松理解。


开启时会发生什么:分步说明

第 1 步:找到开关

text
设置 → 通用 → Codex 应用增强

在"Codex 应用增强"这个区块里有两行开关,第二行(蓝色历史图标)就是本攻略的主角:

统一 Codex 会话历史

它下方有一段说明文字(逐字):

开启后,官方订阅将以共享的 custom 供应商标识运行,官方与第三方会话出现在同一历史列表中,并可选择把现有官方会话一并迁入(迁移前自动备份)。关闭开关时可按备份恢复迁入的会话。注意:跨供应商继续旧会话时,对方后端可能无法解密会话中的 encrypted_content 推理内容,导致继续失败

注意:这一句说明里已经预告了三件事——会出现在同一列表、可选迁入并自动备份、跨供应商续聊"可能继续失败"。这里的"继续失败"指的是续不上、生成不了新回合,不是"记录丢失"。这正是后面要重点拆解的核心误解。

第 2 步:把开关从关拨到开 → 弹出确认窗

一旦你把开关拨到开,CC Switch 不会立刻保存,而是先弹出一个确认窗口。窗口文案如下(逐字):

  • 标题:统一 Codex 会话历史

  • 正文:

    开启后,官方订阅与第三方将共用同一个会话历史列表。注意:跨供应商继续旧会话时,可能因对方后端无法解密 encrypted_content 推理内容而失败。

    可选择同时把现有官方会话历史迁入共享列表(迁移前自动备份到 ~/.cc-switch/backups,关闭开关时可选择恢复)。

  • 复选框:同时迁入现有官方会话历史

  • 确认按钮:我已了解,继续开启

  • 取消按钮:取消

这个复选框默认是不勾选的。 这是一个重要的分岔点:

你的选择 效果 此刻你的数据在哪
不勾(默认) 只切换标识。只有开启之后新建的官方会话才会落进 custom 共享抽屉 你开启前的官方老会话,标签仍是 openai,原地未动,仍在 ~/.codex/sessions/
勾上 除了切换标识,还会把现有的官方老会话也从 openai 抽屉迁进 custom 抽屉 老会话被复制备份后,标签改写为 custom;原始数据有备份兜底

如果你希望"以前的官方会话也出现在统一列表里",必须主动勾选这个复选框。 否则你会遇到下面对照表里的"场景 A"——老会话看起来"不见了",其实只是留在原抽屉里。

点"取消"或点窗口外面:开关直接弹回关闭状态,什么都没发生。
点"我已了解,继续开启":开关保存为开启,CC Switch 在后台落盘配置(如果勾了迁移,就执行迁移)。

第 3 步(仅当勾了迁移):迁移如何执行 + 数据安全

如果你勾了"同时迁入现有官方会话历史",CC Switch 会对你的官方老会话做这套流程:

text
对每个官方(openai 标签)会话文件:
   ① 先把原文件原样复制一份到备份目录          ← 数据有了第一道保险
   ② 用「写临时文件 → 整体替换」的原子方式,
      只把头部那行 session_meta 里的 model_provider
      从 "openai" 改成 "custom"               ← 对话正文一个字节都不动
   ③ 索引数据库 state_5.sqlite 同步在一个事务里把标签改过来
  • 备份位置:~/.cc-switch/backups/codex-official-history-unify-v1/<时间戳>/,每次迁移生成一个带时间戳的"代际目录",内含 jsonl/(会话副本)、state/(索引库副本)、meta.json(记录这次迁移属于哪个 Codex 目录)。
  • 改的是什么:只有 model_provider 这一个字段值。你的对话内容、推理内容、所有正文原样保留。
  • 删的是什么:什么都没删。备份是"复制",改写是"原子替换同一个文件",全程没有任何删除会话或索引的动作。文件在任何时刻都是完整的(要么是旧内容、要么是新内容,绝不会是空或半截)。

迁移成功后,这些官方老会话就出现在统一列表里了。此刻你的数据:① 原始副本在备份目录;② 活动文件里只有归类标签变了,内容完好。

注意:开启与迁移本身不会弹成功提示。迁移是后端在保存时顺带跑的,UI 上你只会看到开关变成了打开状态。所以"没看到迁移成功的弹窗"是正常的,不代表失败。


关闭时会发生什么:分步说明

第 1 步:把开关从开拨到关 → 探测备份 → 弹出确认窗

关闭时,CC Switch 会先花一瞬间探测有没有迁移备份,然后弹出确认窗口(所以关闭弹窗会有一点点延迟,属正常)。文案如下(逐字):

  • 标题:关闭统一会话历史

  • 正文:

    关闭后,官方订阅与第三方将恢复各自独立的会话历史列表。开启期间产生的会话因无法区分来源,将留在第三方历史中,官方订阅将看不到它们。

  • 复选框(条件显示):把开启时迁入的官方会话还原回官方历史(按备份精确还原)

  • 确认按钮:关闭

  • 取消按钮:取消

划重点:正文说的是"官方订阅将看不到它们"——是看不到,不是删除。开启期间你新聊的会话仍然完整地在 custom 抽屉里,只是关闭后官方那一侧看不到而已。

这个还原复选框默认是勾选的。 也就是说,默认行为就是"关闭的同时,把当初迁入的官方会话精确还原回官方历史"。你只要保持勾选、点"关闭"即可。

如果复选框没有出现,说明系统判断当前没有需要还原的备份(要么你从没勾过迁移、要么探测不到备份)——这种情况下你的官方老会话从没被改动过,关掉开关它们自己就回到 openai 抽屉了。

第 2 步:还原如何执行(按备份账本精确翻回)

如果你保持勾选并点"关闭",CC Switch 的还原流程是这样的:

text
① 先把当前现场再复制一份到独立的还原备份目录
   ~/.cc-switch/backups/codex-official-history-unify-restore-v1/<时间戳>/
   (还原本身也先备份,所以还原也不会丢数据)
② 翻遍所有迁移备份代际,找出"当初标签是 openai"的会话 id,组成一份"账本"
③ 只对【既在账本里、当前又仍是 custom】的会话,把标签改回 "openai"

注意第 ③ 步的双重条件——既要在账本里(证明它当初确实是官方迁来的),又要当前仍是 custom(说明你没手动改过它)。两个条件都满足才翻回。这保证了还原既精确又不会误伤。

此刻你的数据:被迁回的官方会话标签改回 openai,重新出现在官方列表;同时迁移备份和还原备份两份副本都还在硬盘上。

第 3 步:看提示,确认结果

只有"关闭 + 勾选还原"这条路径会弹结果提示。可能看到的提示(逐字):

你看到的提示 含义
已按备份还原官方会话历史({{files}} 个会话文件、{{rows}} 条索引记录) 还原成功。{{files}} / {{rows}} 处会显示实际数字
当前 Codex 目录没有可恢复的迁移备份 没有可还原的内容(不等于数据丢了,详见对照表场景 E)
统一会话历史开关已重新开启,已跳过还原 还原排队期间你又把开关打开了,系统主动放弃还原(详见对照表场景 F)
还原官方会话历史失败,请重试 还原过程报错,重试即可,数据未被破坏
保存失败,请重试 关闭这一步保存本身就失败了;此时绝不会触发还原,开关弹回原位

一个贴心的安全设计:如果"关闭开关"这一步保存失败,CC Switch 绝不会去执行还原。否则就会出现"开关还开着、会话却被翻回 openai 桶"的撕裂状态。保存失败时开关会自动弹回原来的位置,你不会停留在一个"看起来已关、实则没保存"的假状态里。


"我感觉会话丢了?"症状对照表

下面六个场景,是用户最容易误以为"会话丢了"的情形。每一个的真相都是:数据完好,只是换了抽屉或暂时看不到。 先用这张表按症状定位,再看下面的详细说明。

场景 你看到的 数据真相 一句话解法
A 没勾迁移 官方老会话不在统一列表 全在,仍带 openai 标签 重开并勾迁移,或关开关
B 跨供应商续聊失败 续不上 / 报错 文件完好,只是密文跨后端解不开 回原供应商续;只看内容直接读 jsonl
C 路由接管 / 注入被拒 没迁也没还原 迁移被安全跳过,文件没动 退出接管 → 重启重试;或直接关开关
D 还原后新会话没回官方 开启期间新会话不在官方 在 custom 抽屉,设计上不动 切第三方供应商即可见
E 提示"没有可恢复备份" 还原"失败" 通常压根没迁移过,会话在原抽屉 关开关官方会话自动复现
F 提示"开关已重新开启,跳过还原" 还原被拒 防数据撕裂,啥也没改 先彻底关开关再还原

场景 A:开了开关但没勾迁移 → 官方老会话"不见了"

现象:你开了统一开关,但开启弹窗里那个"同时迁入现有官方会话历史"没勾(它默认就不勾)。开启后一看,以前的官方老会话好像都不在列表里了。

真相:数据 100% 都在,一行都没动。开关只对"开启之后新建"的官方会话生效,你开启前的官方老会话标签仍是 openai,原封不动地躺在 ~/.codex/sessions/ 里。你现在激活的是 custom 抽屉,自然看不到留在 openai 抽屉里的老会话——这就是"看起来消失"的全部原因。

怎么办(任选其一):

  1. 重新开启开关时勾上"同时迁入现有官方会话历史",把老会话换到 custom 抽屉,它们立刻出现在统一列表(改写前自动备份)。
  2. 或者干脆关掉统一开关,官方重新以 openai 抽屉运行,老会话原地复现。

场景 B:跨供应商续聊旧会话失败 → 以为"这条会话坏了 / 没了"

现象:统一之后列表里能看到一条用"另一家供应商"聊出来的旧会话,你切到现在的供应商点"继续",结果报错或接不上。

真相:会话文件完好无损,丢的不是数据,是"跨后端解密能力"。Codex 会话里保存了一段加密的推理内容 encrypted_content,这段密文只有当初生成它的那个后端能解密。你用 B 供应商去续 A 供应商生成的会话,B 解不开 A 的密文 → 续聊失败。这是上游 Codex 的设计限制(by design),与 CC Switch 是否动过文件无关。会话里的文字内容你随时能读到。

这是整篇攻略里唯一一个"看起来真出了问题"的真实例外——但请注意:它只是无法续聊(生成不了新回合),原始文件依然完整存在,对话文字随时可读。

怎么办:

  • 用"当初创建这条会话的那个供应商"去续聊,就能正常解密、接上。
  • 只想看历史内容、不必继续?直接读那条会话的 .jsonl 文件(文末有命令)。
  • 经验法则:跨供应商更适合"开新会话",老会话尽量回原供应商续。

场景 C:开了开关也勾了迁移,但迁移被静默跳过 → 以为"迁移把会话弄丢了"

现象:你开启并勾了迁移,但官方老会话既没进统一列表、关开关想还原也提示没东西可还原(或者关闭弹窗里压根没出现还原复选框,参见场景 E)。你怀疑迁移过程中把会话搞丢了。

真相:迁移根本没执行,所以也不可能弄丢——你的会话一个字都没被改。CC Switch 在迁移前有一道安全闸门:它会检查 Codex 的 live 配置(~/.codex/config.toml)此刻是否真的路由到了共享 custom 抽屉,只有真路由过去了才迁移。以下两种情况会判定"还没统一"(内部原因码 live_not_unified),于是主动跳过迁移、保留你的开关和迁移意愿、等条件满足后再迁:

  • 路由接管期间:CC Switch 的本地路由接管了 live 配置,接管期的 live 不带统一路由标记。
  • 注入被拒:你的 config.toml 已有手工指定的 model_provider,或已存在一张形态不同的 [model_providers.custom] 表(可能带第三方地址)。为避免把官方流量错误路由到第三方后端,CC Switch 宁可不注入、不迁移。

跳过迁移 = 不碰任何会话文件。没迁,等于没动,谈不上丢。 这是"安全延后",不是"失败丢数据"。

怎么办:

  • 退出路由接管 → 重启 CC Switch:启动时会自动重试迁移(你的迁移意愿一直保留着)。
  • 检查 ~/.codex/config.toml:若有你手工写的冲突路由,整理掉冲突后再开开关。
  • 实在不想折腾:直接关开关,官方会话仍以 openai 抽屉正常显示,毫发无损。

场景 D:关了开关并还原,但"开启期间新聊的会话"没回官方 → 以为"新会话丢了"

现象:你开启统一期间,用官方又聊了几条新会话。后来关开关、勾了还原,还原完发现那几条新会话没回到官方抽屉。

真相:这是有意为之的设计,新会话好端端在 custom 抽屉里,能看见、能续。还原的依据是"迁移时的备份账本"——只有当初从 openai 抽屉迁进来的会话,备份里有据可查,才会被精确翻回 openai。你开启期间新建的会话不在任何备份账本里;而且统一之后官方和第三方都用 custom 标签,CC Switch 无法分辨这条新会话到底是官方聊的还是第三方聊的。为了不把第三方会话误塞进官方历史,产品决策是:这些新会话一律留在 custom(第三方)历史里,绝不自动搬动。关闭弹窗的文案也明示了这一点——"开启期间产生的会话因无法区分来源,将留在第三方历史中"。

怎么办:

  • 切到任意一个第三方供应商(custom 抽屉),就能在历史列表里看到这些会话。
  • 想看内容直接读 .jsonl;想续聊遵循场景 B 的规则(回到当初生成它的后端)。
  • 如果你确实想把某一条手动归回官方:目前没有自动按钮(刻意不做,避免误判方向)。进阶用户可在先备份该文件后,手动把它 .jsonl 第一行 session_meta 里的 model_provider 从 custom 改回 openai(属高阶操作,改前务必复制一份)。

场景 E:还原提示"当前 Codex 目录没有可恢复的迁移备份" → 以为"还原失败 = 数据没了"

现象:关开关时勾了还原,结果弹出提示"当前 Codex 目录没有可恢复的迁移备份"。你慌了:还原都失败了,是不是数据彻底没了?

真相:"没有可还原的东西"≠"数据丢了"。恰恰相反,通常是因为根本没有需要还原的迁移。常见原因:

  • 你当初没勾过"迁入现有官方会话":既然没迁移,自然没有迁移备份、也没有需要翻回去的会话。你的官方老会话一直在 openai 抽屉,关开关后直接复现(同场景 A)。(这种情况下,关闭弹窗甚至可能根本不显示还原复选框——因为系统探测不到任何备份。)
  • 已经还原过一遍了:会话标签已全部翻回 openai,再点一次自然"没有仍是 custom 的目标可还原"——这是幂等保护,不是失败。
  • 切换过 Codex 目录:还原只认属于当前目录的备份账本,换了目录就找不到旧目录的账本,把目录切回去即可。

这三种情况下,没有任何会话被删除。

怎么办:用文末命令统计 ~/.codex/sessions/ 里的会话文件总数,确认文件都在;再看 ~/.cc-switch/backups/ 里有没有 codex-official-history-unify-v1 目录——如果连这个目录都没有,说明你从没触发过迁移,会话一直在原抽屉。

场景 F:还原被拒,提示"统一会话历史开关已重新开启,已跳过还原"

现象:关开关 → 勾还原 → 你手很快,紧接着又把开关重新打开了,然后看到提示"统一会话历史开关已重新开启,已跳过还原"。

真相:这是一道防护,防止把数据弄成"撕裂"状态,会话同样没丢。还原的动作是"把会话标签从 custom 翻回 openai",但如果此刻开关又开着,live 配置正路由到 custom——一边把历史翻回 openai、一边新会话往 custom 落,会话会被人为撕成两半。所以 CC Switch 检测到"开关又开了",主动放弃这次还原、什么都不改。会话维持现状,没有任何删除或破坏。

怎么办:想真正还原,就先把开关稳定地关掉(别再立刻打开),再执行关闭 + 勾还原;想保持统一,就别还原,让会话留在 custom 共享抽屉正常使用。

总原则:CC Switch 的统一 / 迁移 / 还原全程只改会话的一个标签字段,并且每次改写前都自动备份。它不会删你的对话。看不见 ≠ 丢了——换个抽屉看,或用下面的命令亲眼确认。


亲手验证:你的会话文件还在硬盘上(最重要的一节)

文字再多,不如亲眼看见。下面给出真实路径(取自 CC Switch 源码)和在不同系统下查看会话文件、备份目录的方法。全程只读不改,强烈建议你亲手试一遍。

最简单的方式:用文件管理器直接打开(完全不用命令行)

  • macOS(Finder):按 Cmd + Shift + G,粘贴 ~/.codex/sessions 回车,就能看到一堆 .jsonl 会话文件和它们的修改时间;备份目录粘贴 ~/.cc-switch/backups。
  • Windows(文件资源管理器):在地址栏粘贴 %USERPROFILE%\.codex\sessions 回车,就能看到会话文件夹和里面的 .jsonl;备份目录粘贴 %USERPROFILE%\.cc-switch\backups。

只要你能在这里看到一批 .jsonl 文件,就证明会话数据完好无损地在硬盘上。 文件数量、修改时间,比任何文字都直观。

你的会话 / 历史文件到底在哪

内容 真实路径 说明
会话正文(核心) ~/.codex/sessions/(含按日期分的子目录,递归) 每个会话一个 .jsonl 文本文件,这就是你的对话内容
归档会话 ~/.codex/archived_sessions/ 同为 .jsonl
会话索引数据库 ~/.codex/state_5.sqlite threads 表的 model_provider 列就是"抽屉标签",它才是续聊列表真正读取的归类来源
迁移备份(开启迁移时自动产生) ~/.cc-switch/backups/codex-official-history-unify-v1/<时间戳>/ 内含 jsonl/、state/、meta.json
还原备份(点还原时自动产生) ~/.cc-switch/backups/codex-official-history-unify-restore-v1/<时间戳>/ 还原前的安全副本

注意:如果你在 CC Switch 里改过 Codex 目录,或在 config.toml 里设了 sqlite_home,请把上面的 ~/.codex 换成你的实际目录。下文 ~ = 你的用户主目录。

macOS / Linux 命令

1. 数会话文件总数(这才是"没丢"的硬证据)

bash
# 统计会话文件总数 —— 只要这个数字符合你的预期,数据就都在
find ~/.codex/sessions ~/.codex/archived_sessions -name '*.jsonl' 2>/dev/null | wc -l

# 看最近修改的 10 个会话文件
find ~/.codex/sessions -name '*.jsonl' 2>/dev/null -print0 \
  | xargs -0 ls -lt 2>/dev/null | head -10

2. (辅助)看每个"抽屉"各有多少会话

bash
# 官方抽屉(openai)会话文件数
grep -rlE '"model_provider"[[:space:]]*:[[:space:]]*"openai"' ~/.codex/sessions 2>/dev/null | wc -l

# 统一抽屉(custom)会话文件数
grep -rlE '"model_provider"[[:space:]]*:[[:space:]]*"custom"' ~/.codex/sessions 2>/dev/null | wc -l

# 看各标签分布一目了然
grep -rhoE '"model_provider"[[:space:]]*:[[:space:]]*"[^"]*"' ~/.codex/sessions 2>/dev/null | sort | uniq -c

重要提示,别被这一步吓到:早期版本的 Codex 不在 .jsonl 里写 model_provider 字段,这些旧官方会话用上面的 grep 是数不到的,但它们在索引库 state_5.sqlite 里仍然归类为 openai、续聊列表照样能看到。所以判断"会话没丢"请以第 1 步的文件总数为准——分桶 grep 只是帮你理解归类,数出来比文件总数少完全正常,绝不代表"丢了一批"。

3. (进阶)查索引库 state_5.sqlite——续聊列表真正读的归类

bash
# 需要已安装 sqlite3;没装可跳过
sqlite3 ~/.codex/state_5.sqlite \
  "SELECT COALESCE(model_provider,'<空>'), COUNT(*) FROM threads GROUP BY 1;"

这张 threads 表才是 Codex 续聊列表真正读取的归类来源,openai 行数 ≈ 你官方抽屉里能看到的会话数。它和第 2 步的 jsonl grep 可能对不上数——原因就是上面说的"旧会话不写 jsonl 字段,但索引库里仍是 openai"。两边对不上不是异常。

4. 直接读某条会话的内容(确认对话文字还在)

bash
# 把 <文件名> 换成上面 ls 列出的某个 .jsonl 路径
python3 -m json.tool < "<文件名>.jsonl" 2>/dev/null | head -50

# 或者直接用编辑器打开看(纯文本)
open -e "<文件名>.jsonl"      # macOS

5. 看 CC Switch 的备份目录(证明迁移 / 还原前都留了副本)

bash
ls -la ~/.cc-switch/backups/codex-official-history-unify-v1/ 2>/dev/null
ls -la ~/.cc-switch/backups/codex-official-history-unify-restore-v1/ 2>/dev/null

Windows 命令(PowerShell)

会话目录通常在 C:\Users\<你的用户名>\.codex\,备份在 C:\Users\<你的用户名>\.cc-switch\backups\。

powershell
# 1. 会话文件总数("没丢"的硬证据)
(Get-ChildItem "$env:USERPROFILE\.codex\sessions","$env:USERPROFILE\.codex\archived_sessions" -Recurse -Filter *.jsonl -ErrorAction SilentlyContinue).Count

# 2. 最近修改的 10 个会话
Get-ChildItem "$env:USERPROFILE\.codex\sessions" -Recurse -Filter *.jsonl |
  Sort-Object LastWriteTime -Descending | Select-Object -First 10 FullName,LastWriteTime

# 3. (辅助)官方(openai) / 统一(custom) 抽屉各多少会话文件
(Get-ChildItem "$env:USERPROFILE\.codex\sessions" -Recurse -Filter *.jsonl |
  Select-String -Pattern 'model_provider"\s*:\s*"openai"' -List).Count
(Get-ChildItem "$env:USERPROFILE\.codex\sessions" -Recurse -Filter *.jsonl |
  Select-String -Pattern 'model_provider"\s*:\s*"custom"' -List).Count

# 4. 看备份目录
Get-ChildItem "$env:USERPROFILE\.cc-switch\backups\codex-official-history-unify-v1" -ErrorAction SilentlyContinue
Get-ChildItem "$env:USERPROFILE\.cc-switch\backups\codex-official-history-unify-restore-v1" -ErrorAction SilentlyContinue

同样提醒:第 3 步的 grep 数会少于文件总数属正常(旧会话不写该字段),请以第 1 步的文件总数作为"会话没丢"的判断依据。


进阶原理附录(给想真正搞懂机制的用户)

1. 分桶机制(抽屉的本质)

Codex 的续聊 / 历史列表按当前激活的 model_provider id 精确字符串过滤。会话文件 .jsonl 的第一行是一条 type:"session_meta" 记录,其 payload.model_provider 即该会话所属抽屉(grep -rl 只要文件里出现一次该标签就计入该文件,因此无需逐行解析;旧版本未写该字段的会话则数不到)。真正驱动续聊列表的是索引库 state_5.sqlite 的 threads.model_provider 列。官方订阅在 config.toml 没有显式 model_provider 时落进内建默认 id openai;CC Switch 的所有第三方供应商统一用 custom。

2. 开关做的事(注入,只活在 live)

开启后,CC Switch 对官方 live config.toml 注入如下内容:

toml
model_provider = "custom"

[model_providers.custom]
name = "OpenAI"
requires_openai_auth = true
supports_websockets = true
wire_api = "responses"

每个字段都有作用:requires_openai_auth = true 让认证继续走 auth.json 里的 ChatGPT 登录、base_url 缺省回落官方 Codex 后端;name = "OpenAI" 让 Codex 的官方特性门控(web search、远程压缩等)继续命中;supports_websockets = true 补回 custom 条目默认丢失的能力;wire_api = "responses" 用官方 responses 协议。净效果是:认证没变,只是桶名变了。

关键不变量:这段注入只能存在于 live config.toml,绝不写进数据库的存储配置。 切换离开官方供应商、把 live 回写数据库时,CC Switch 会把这段注入精确剥离(只在形态与注入产物完全一致时才剥,第三方自定义的 custom 表原样保留)。正因如此,"关掉开关 + 切换一次"就能彻底还原 live,数据库里始终是你原本干净的官方配置——这是整个开关可逆性的基石。

3. 注入的两道拒绝闸(对应场景 C)

  • config.toml 已有显式 model_provider → 不覆盖用户路由;
  • 已存在形态不同的 [model_providers.custom] 表(可能带第三方 base_url)→ 拒绝注入,否则会把 ChatGPT OAuth 流量路由到错误后端。

拒绝注入时 live 不统一,迁移闸门(检查 live 的 model_provider 是否 trim 后等于 custom)判定 live_not_unified → 跳过迁移、保留意愿、等下次启动重试时再做。这是"安全延后",不是"失败丢数据"。

4. 会话三分类(决定迁移 / 还原边界)

  • A 类:开启时迁入的存量官方会话——备份即账本,可精确还原回 openai;
  • B 类:开启期间新建——不在任何备份、官方 / 第三方不可分,永不自动搬动(留 custom);
  • C 类:开启前的纯第三方历史——绝不触碰。

5. 迁移 / 还原的安全性(数据不会被真正删除,保障来自哪里)

四层设计共同保证:在正常与异常的所有路径下,原始会话数据都不会被真正删除。

  • 只改字段,不动正文:迁移 / 还原只把会话元数据里的 model_provider 值在 openai 与 custom 之间切换,对话内容、response_item、encrypted_content 一律原样保留。
  • 改写前必先复制备份:jsonl 用文件复制、state DB 用 SQLite 完整副本,存进时间戳代际目录。迁移备份在 codex-official-history-unify-v1/,还原备份在独立的 codex-official-history-unify-restore-v1/,两者分开以保持账本纯净。
  • 只移不删 + 原子写:所有 jsonl 改写走"临时文件 + 整体替换",state DB 走事务化 UPDATE,全程没有任何删除会话或索引的动作。文件在任一时刻都是完整的。
  • 悲观跳过 + 幂等可重试:桶不一致时(live_not_unified)宁可不迁;一把进程锁串行化迁移与还原,避免"启动重试 / 保存后台任务 / 关闭还原"并发对同批文件双向改写;完成标记按 Codex 目录绑定、条件写入,防漏迁;还原用"在账本 + 当前仍 custom"双重条件,防误改。还原扫描全部备份代际取并集,多次开关循环后仍能还原早期迁入的会话;重复还原返回 nothing_to_restore,是幂等保护而非失败。

6. 跨后端 encrypted_content(对应场景 B)

会话内的推理密文只能被生成它的后端解密,上游 Codex by design 不支持跨后端解密。这是"续聊失败"的根因,与文件完整性无关——会话 .jsonl 完整躺在磁盘上、encrypted_content 也完好无损。换回原供应商续聊,或开新会话,都正常。


参考链接


给你的最后一句话:你看到的"会话不见了 / 续聊失败",本质是会话被换到了另一个历史列表(抽屉)里、或对方后端无法解密旧推理内容,文件始终原封不动地躺在 ~/.codex/sessions/(及 state_5.sqlite)里。关闭开关时勾选"按备份还原"即可把当初迁入的官方会话精确翻回官方列表;即便不还原,原始 .jsonl 文件和 ~/.cc-switch/backups/codex-official-history-unify-*/ 下的备份副本也都在——数据绝不会真正丢失。


Add an "Import to CC Switch" Button to Your Site: Integration Guide for Site Owners

中文 | English | 日本語

If you run a site, CC Switch lets your users import your provider into Claude Code, Codex and other agent apps with one click.

Applies to CC Switch v4.0.10 and later. Behavior marked "since v4.0.10" works differently on earlier versions; the differences are listed in "Compatibility with older versions" at the end. This guide is based on the current code. All domains and keys in the examples are fake.

Who this is for

You run an API service (a relay, an aggregator or a self-hosted gateway all count) and want your users to click one button in your dashboard to add your endpoint, key, models and balance query to CC Switch, without filling in a form by hand.

This is done with a ccswitch:// deep link. Once CC Switch is installed, clicking a ccswitch://... link in the browser launches CC Switch and opens an import confirmation dialog. The user checks it and clicks "Import".

The Deep Link Protocol page in the user manual is the parameter reference. This guide covers the decisions a site owner actually has to make: how to generate the link, what it can carry, what gets rejected, and how to show users their balance right after import.

Quickest path

Is your site built on New API or Sub2API? Both already have an "Import to CC Switch" button in their key list, so it works out of the box with no development needed. The difference is the balance: New API links carry no usage query script, so users don't see a balance on the card after import; Sub2API links do. Follow this guide if you want to add the balance, include your icon, or support more apps.

Most site owners only need to do three things. Reading the sections below in order is enough:

  1. Read "Key points", then "The minimal link", "Supported apps" and "Common parameters" under "Provider links", and decide which apps to generate links for and how to write the endpoint and format. You can fill in the form in the online generator to produce a link, click it on your own computer, and see what the confirmation dialog looks like.
  2. If you want users to see their balance after import, read "Show the balance right after import: usage query scripts". NewAPI / OneAPI and Sub2API style sites have ready-made scripts you can copy as is.
  3. Read "Code for generating links" and "Putting the link behind a button": the backend generates the link per user, and the frontend shows the button.

The collapsed sections (embedded config, the summary of rejected links, MCP / prompts / Skills) can be expanded when you need them.

Key points

  1. Generate links per user. An API key is required when importing a provider, and a link without a key fails to import. So the "one-click import" button belongs in the user's dashboard after login, and your backend builds the link with that user's own key. Don't put it on a public page. See "Putting the link behind a button" for how to build the button.
  2. Declare your API format with apiFormat. Values are anthropic, openai_chat, openai_responses and gemini_native; which ones each app supports is listed below. Without it, the app's default format is used: Anthropic Messages for Claude Code, OpenAI Responses for Codex and Grok Build, and OpenAI Chat Completions for OpenCode / OpenClaw / Hermes / Pi.
  3. Set model names only when needed. If your relay serves genuine Claude models, leave all Claude Code models empty and Claude Code uses its built-in model list. Only non-native models such as DeepSeek or Kimi need model, haikuModel, sonnetModel and opusModel. OpenCode, OpenClaw and Hermes take their model list from model, so without it there are no models to choose from. Pi requires it.
  4. Include a usage query script if you want users to see their balance. Since v4.0.10, a link with usageScript enables it by default. To stay compatible with older versions, also set usageEnabled=true. The script can only request HTTPS endpoints with the same origin as the provider endpoint; details below.
  5. The user decides whether to "switch after import". The confirmation dialog has a switch for it, and enabled in the link only sets its initial value. You usually don't need to set it.
  6. URL-encode Base64 parameters again. Build the link with URLSearchParams or an equivalent function, not by concatenating strings by hand.
text
ccswitch://v1/import?resource=<type>&<params>...
  • v1 is the protocol version and /import is a fixed path. Getting either wrong gets the link rejected.
  • resource is one of provider, mcp, prompt and skill.
  • Parameter names are case-sensitive and use camelCase: apiKey, usageScript, not api_key.

Encoding rules

There are two layers of encoding, and the order matters:

  1. Parameters that carry a whole block of content, such as config, usageScript and content, are first encoded as Base64 from their UTF-8 text. Both standard and URL-safe Base64 are accepted, and the trailing = is optional.
  2. When building the link, every parameter value is then URL-encoded (application/x-www-form-urlencoded rules). The + in standard Base64 must become %2B, otherwise it is decoded as a space. CC Switch tries to turn spaces back into +, but don't rely on that.

URLSearchParams does step 2 for you. Forgetting this step is the most common mistake in hand-written links.

Boolean parameters take true / false. Any other value is treated as if the parameter were missing.

  1. The browser asks whether to open CC Switch. Once the user agrees, CC Switch comes up (it starts first if it isn't running).
  2. CC Switch opens the import confirmation dialog, showing everything in the link: the endpoint, the masked key, the models, the embedded config, and the full usage query script. Suspicious content is highlighted in yellow, for example endpoints pointing at localhost or a private network, environment variables that change how processes load code (NODE_OPTIONS, LD_PRELOAD and the like), and MCP servers that run a whole command line through a shell.
  3. After the user clicks "Import":
    • Provider: added to the provider list of the target app. The bottom of the dialog has a switch whose initial value comes from enabled in the link, and the user can change it:
      • Claude Code, Codex, Gemini CLI, Grok Build: the switch is "Switch to this provider after import", off by default. When it is on, the dialog warns that "client requests will go to the endpoint above".
      • OpenCode, OpenClaw, Hermes, Pi: these apps can hold several providers at once. The switch is "Add to the config after import" (for Pi, "Enable in Pi after import"), on by default. When it is off, the provider is only saved in CC Switch's list.
    • MCP: written immediately into the config file of every app listed in apps.
    • Prompt: added to the prompt list. The dialog has an "Enable after import" switch whose initial value comes from enabled in the link. When it is on, it replaces the app's current prompt file, and the previously enabled prompt is disabled.
    • Skill: what gets added is a Skill repository. The user still has to go to the "Skills" page and choose which Skills to install.

A few details site owners tend to trip over:

  • The link can only be triggered by a user click. Most browsers block an automatic redirect to ccswitch:// on page load.
  • CC Switch handles one link at a time. If the user clicks a new link before finishing the previous one, only the newest one is kept. Don't design "one button that fires several links in a row". Give providers, MCP and prompts a button each and let the user click them one by one.
  • Clicking the same provider link twice imports two copies. The provider ID is generated from the name plus a timestamp, with no deduplication.
  • A web page cannot reliably tell whether the user has CC Switch installed. Put a hint and a download link next to the button; see "Putting the link behind a button" for the wording.
text
ccswitch://v1/import?resource=provider&app=claude&name=Example%20AI&endpoint=https%3A%2F%2Fapi.example.com&apiKey=sk-xxxx

The only required items are app, name, the endpoint and the key (the last two can be URL parameters or go in the embedded config). Pi additionally requires model.

Supported apps

app App Default format Allowed apiFormat What config can carry
claude Claude Code anthropic All four {"env": {...}}, all variables in env are kept
codex Codex openai_responses openai_responses, openai_chat, anthropic All or part of a config.toml, see below
gemini Gemini CLI gemini_native Only gemini_native The three keys GEMINI_API_KEY, GOOGLE_GEMINI_BASE_URL and GEMINI_MODEL; anything else is ignored
grokbuild Grok Build openai_responses openai_responses, openai_chat, anthropic One [model."<name>"] table, see below
opencode OpenCode openai_chat All four Only the endpoint and key
openclaw OpenClaw openai_chat All four Only the endpoint and key
hermes Hermes openai_chat openai_chat, openai_responses, anthropic Only the endpoint and key
pi Pi openai_chat All four Only the endpoint and key

Deep link import of providers is not yet supported for Claude Desktop or MiniMax Code; such links are rejected.

apiFormat lands in different places depending on the app:

  • Claude Code, Codex, Grok Build: these three clients only speak their own native format (Anthropic for Claude Code, Responses for the other two). With a non-native format, the imported card carries a "Needs routing" tag, and when the user switches to it, local routing has to be on so CC Switch can convert the request format.
  • OpenCode, OpenClaw, Hermes, Pi: these clients support several formats themselves. CC Switch maps apiFormat to the protocol field in their config (npm for OpenCode, api for OpenClaw / Pi, api_mode for Hermes), and the client calls your API in that format directly, without local routing.

Write the endpoint following the convention of the chosen format: for the Anthropic format in Claude Code, leave out /v1 (e.g. https://api.example.com); the two OpenAI formats usually include /v1. For OpenCode, OpenClaw, Hermes and Pi, the endpoint is the base URL of each one's SDK, and they don't build paths the same way: for the same Anthropic format, the OpenCode endpoint in CC Switch's built-in presets includes /v1, while Hermes and Pi don't. Generate a separate link for each app, and use the endpoint form you have actually tested to work in that app.

Common parameters

Parameter Description
name Display name, required
endpoint API endpoint. Several can be separated by commas: the first is the primary endpoint, and the rest are added to the provider's endpoint list ("API Endpoint Management") for the user to speed-test and switch between
apiKey API key. When it is both a URL parameter and in config, the URL parameter wins
apiFormat API format, see the table above. Without it, the app's default format is used
model Default model. Leave it empty for Claude Code with genuine Claude models; Codex uses gpt-5-codex and Grok Build uses grok-4.5 when it is missing; required for Pi
haikuModel / sonnetModel / opusModel Claude Code only: the real model names behind the three model aliases, needed only for non-native models
homepage Website. Inferred from the endpoint when missing (with the api. prefix removed)
icon Name of a CC Switch built-in icon. Only lowercase letters, digits and . _ - are allowed; anything else is dropped. An unknown name shows the first letter of the provider name. Leave it out if there is no built-in icon for your brand
iconUrl URL of your own icon image, see "Adding your own icon" below. Falls back to icon if the download fails
notes Notes, shown on the provider card
enabled Initial value of the switch-after-import / add-after-import switch in the confirmation dialog; the user can change it. You usually don't need to set it
config + configFormat Embedded config, Base64. configFormat is json (default) or toml

configUrl (remote config) is not implemented yet. Links that carry this parameter are rejected outright.

Adding your own icon: iconUrl

If CC Switch has no built-in icon for your brand, give an image URL with iconUrl. As soon as the confirmation dialog opens, CC Switch downloads the image and shows it at the top. After import it becomes the card icon, with nothing more for the user to click.

The image is redrawn as a 96×96 PNG and stored in CC Switch, and the URL is not fetched again after that. If you change your icon later, users who already imported won't get the new one.

The URL and the image must meet all of the conditions below. If any one fails, the dialog shows no error; the icon falls back to the built-in icon named by icon, or to the first letter of the provider name if there is no icon:

  • It starts with https://, the host is a domain name (not an IP), the port is the default one, and there is no username or password. A malformed URL is dropped when the link is parsed, and the rest of the link imports as usual.
  • It is publicly accessible: CC Switch downloads it without cookies or Referer, and does not go through the user's system proxy. URLs that require login or have hotlink protection will fail.
  • The domain must resolve to a public address. Anything pointing at a private network or localhost is never downloaded.
  • The download finishes within 5 seconds and follows at most 3 redirects, and every redirect target must also meet these conditions.
  • It is no larger than 256 KB.
  • The Content-Type response header is one of image/png, image/jpeg, image/webp or image/svg+xml, and matches the actual file format. Generic types such as application/octet-stream don't work.
  • Bitmap width and height are no more than 4096 pixels.

Suggestions for the image itself:

  • Use a square image. A square image with opaque corners fills the whole icon frame; a logo with transparent corners is shrunk to the center with padding around it, matching the look of the built-in icons.
  • SVG is displayed only as an image: scripts inside it don't run, and external fonts and images it references aren't loaded. Convert text to paths.
  • Every user requests this URL once each time they open the confirmation dialog. Serving it from a CDN is fine.

Claude Code: embedded environment variables

Expand if you need extra environment variables (custom request headers, timeouts, etc.)

Sites that need extra environment variables (custom request headers, timeouts, turning off experimental features, etc.) put them in config:

json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://api.example.com",
    "ANTHROPIC_AUTH_TOKEN": "sk-xxxx",
    "ANTHROPIC_MODEL": "example-sonnet",
    "API_TIMEOUT_MS": "600000",
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
  }
}

Variables in env are kept as they are. For the endpoint, key and model names, the URL parameters win if they are also set. The confirmation dialog lists every variable, with sensitive values masked.

Codex: embedded config.toml

Only needed for extra settings such as wire_api, request headers or reasoning effort. Expand to see which keys are accepted and which forms are rejected

Two forms:

  • configFormat=json, with content {"auth": {"OPENAI_API_KEY": "sk-xxxx"}, "config": "<config.toml contents>"};
  • configFormat=toml, with the config.toml contents directly.

CC Switch does not copy the whole file into the user's ~/.codex/config.toml. It only takes the parts that belong to this provider:

  • The selected [model_providers.] table: the one model_provider points to; without model_provider, the file may contain only one such table. These keys are taken from the table: name, base_url, wire_api, requires_openai_auth, experimental_bearer_token, model_catalog_url, capabilities, query_params, http_headers, request_max_retries, stream_max_retries, stream_idle_timeout_ms, websocket_connect_timeout_ms, supports_websockets, supports_standalone_web_search.
  • Top-level model fields: model, review_model, model_reasoning_effort, plan_mode_reasoning_effort, disable_response_storage, web_search, model_context_window, model_auto_compact_token_limit, model_supports_reasoning_summaries, model_verbosity, plus the subagent models in [agents] and the memory model in [memories].

Nothing else is taken: [features], [tools], MCP, sandbox, notify, other provider tables and so on are the user's own global settings.

After import, the table is renamed to custom (all Codex providers managed by CC Switch are written to [model_providers.custom]), and base_url and experimental_bearer_token use the merged endpoint and key. model_catalog_url must have the same origin as the provider endpoint, otherwise the import is rejected.

Forms that are rejected: a table containing auth (makes Codex run a command to get the key), aws, gateway_oauth (reads cloud credentials on the machine), or env_http_headers (reads environment variables). env_key is dropped; the key must be given by the link itself. A link that only has env_key and no key is rejected.

Example (configFormat=toml):

toml
model_provider = "example"
model = "example-coder"
model_reasoning_effort = "high"

[model_providers.example]
name = "Example AI"
base_url = "https://api.example.com/v1"
wire_api = "responses"
http_headers = { "X-Client" = "cc-switch" }
stream_idle_timeout_ms = 300000

Grok Build: embedded model table

Only needed for extra settings such as the context window or sampling parameters

Same forms as Codex ({"config": "<config.toml contents>"} or configFormat=toml).

Only the [model."<name>"] table that [models] default points to is imported. Without default, the file may contain only one table; several tables without default are rejected. A Grok Build provider in CC Switch maps to exactly one model table, so importing several models from one link is not supported.

The table keeps the display name, description, api_backend, context_window, max_completion_tokens, sampling and retry parameters, reasoning effort fields and so on. The endpoint, key and model name come from the link parameters (URL parameters first). If the table has no api_backend or context_window, defaults are filled in.

Links whose table contains auth_provider, env_http_headers or mtls_cert_dir are rejected. env_key is handled the same way as in Codex.

Expand when the confirmation dialog shows an error, and look up the cause by the error text

Situation Error in the confirmation dialog (original text, excerpt)
No key API key is required
No endpoint Endpoint is required
Endpoint is not http / https Invalid URL scheme for 'endpoint[0]'
Unsupported app value Invalid provider app type
Invalid apiFormat value Unsupported apiFormat
The app doesn't support that apiFormat is not supported for app
Pi without a model Pi providers need a model
The name, endpoint, key or model for OpenCode / OpenClaw / Hermes / Pi contains syntax the client would expand (see below) uses syntax that … would expand
configUrl is present 'configUrl' is not supported yet
Base64 can't be decoded config 参数 Base64 解码失败 (Base64 decoding of the config parameter failed)
Codex / Grok gives the key only through env_key supplies its API key indirectly
Codex table contains auth or similar cannot be imported from a link
Codex catalog URL has a different origin from the provider endpoint model_catalog_url
Grok has several tables but no default several [model.*] tables

OpenCode, OpenClaw, Hermes and Pi expand certain syntax when reading their config: in Pi, a key starting with ! is run as a command, and $NAME / ${NAME} are replaced with environment variables; in OpenCode, {env:…} reads an environment variable and {file:…} reads a local file; in OpenClaw and Hermes, ${…} reads an environment variable. All of these are rejected when importing from a link. Your key and endpoint are plain literal values, so they are not affected.

Show the balance right after import: usage query scripts

The CC Switch provider card can show a balance or plan usage, and the data comes from a usage query script. Put the script in the link and users see it right after import.

What a script looks like

A script is a JavaScript expression that returns an object with request (what request to send) and extractor (how to pull the numbers out of the response):

javascript
({
  request: {
    url: "{{baseUrl}}/user/balance",
    method: "GET",
    headers: {
      "Authorization": "Bearer {{apiKey}}"
    }
  },
  extractor: function (response) {
    return {
      remaining: response.balance,
      unit: "USD"
    };
  }
})

Before running it, CC Switch replaces the placeholders in the script with actual values:

Placeholder Replaced with
{{apiKey}} usageApiKey; the provider's API key if not given
{{baseUrl}} usageBaseUrl; the provider's primary endpoint (trailing / removed) if not given
{{accessToken}} usageAccessToken
{{userId}} usageUserId

Note that {{baseUrl}} is the provider endpoint as is. If it includes /v1, the result is https://api.example.com/v1/user/balance. If your balance endpoint is not under /v1, just write the full URL in the script, as long as it has the same origin as the endpoint.

extractor receives the parsed response JSON and returns an object, or an array of objects (for several plans). All fields are optional:

Field Type Description
remaining number Remaining quota
used number Used
total number Total quota
unit string Unit, such as USD, CNY, or a count unit like "times"
planName string Plan name
isValid boolean Whether the key is valid; when false, the card shows it as invalid
invalidMessage string Reason it is invalid
extra string Additional note

Runtime limits

The script is untrusted input, and CC Switch puts hard limits on it:

  • It runs in a QuickJS sandbox with no fetch, files, network or any other capability. The script only "describes the request" and "parses the response"; CC Switch sends the request on its behalf.
  • Each query sends only one request, so you can't log in first and then query.
  • The request must be HTTPS and have the same origin as {{baseUrl}} (same domain, same port). Requests to a different origin are rejected. If your balance endpoint is on another domain (for example the dashboard is at console.example.com and the API at api.example.com), point usageBaseUrl at the dashboard domain.
  • The response must be JSON.
  • CC Switch sends the request directly from the user's computer, not through a browser, so your balance endpoint doesn't need CORS. The endpoint must accept API key authentication. If it can only be queried with a login session or a system access token, put the token in the link with usageAccessToken (see the NewAPI section below).
  • Script execution is limited to 5 seconds and 16 MiB of memory; the HTTP request times out after 10 seconds.

Enabled or not

How the link is written After import
usageScript present, no usageEnabled Enabled (since v4.0.10; not enabled on earlier versions)
usageScript present, usageEnabled=true Enabled
usageScript present, usageEnabled=false Not enabled; the user can turn it on in the app
No script Not enabled

The confirmation dialog shows the full script and an "Enabled" / "Disabled" tag.

usageAutoInterval sets the automatic query interval in minutes. 0 or leaving it out means no scheduled queries. Don't make it too short: every user will hit your endpoint at that rate.

NewAPI / OneAPI style sites

The balance endpoint on these sites uses a system access token and a user ID, not the API key. Include usageAccessToken and usageUserId in the link:

javascript
({
  request: {
    url: "{{baseUrl}}/api/user/self",
    method: "GET",
    headers: {
      "Authorization": "Bearer {{accessToken}}",
      "New-Api-User": "{{userId}}"
    }
  },
  extractor: function (response) {
    if (response.success && response.data) {
      return {
        planName: response.data.group,
        remaining: response.data.quota / 500000,
        used: response.data.used_quota / 500000,
        unit: "USD"
      };
    }
    return { isValid: false, invalidMessage: response.message };
  }
})

500000 is NewAPI's default quota conversion ratio. If you changed it, use your own value. A system access token has more power than an API key, so only put it in links generated after the user has logged in.

Sub2API style sites

Sub2API ships a GET /v1/usage endpoint meant for CC Switch. It authenticates with the API key, so no usageAccessToken is needed. Its top-level fields are exactly the isValid, planName, remaining and unit that CC Switch understands, so the script is mostly a direct copy:

javascript
({
  request: {
    url: "{{baseUrl}}".replace(/\/+$/, "").replace(/\/v1$/, "") + "/v1/usage",
    method: "GET",
    headers: {
      "Authorization": "Bearer {{apiKey}}",
      "User-Agent": "cc-switch/1.0"
    }
  },
  extractor: function (response) {
    var quota = response.quota || {};
    var result = {
      isValid: response.isValid !== false,
      unit: response.unit || quota.unit || "USD"
    };
    if (typeof response.planName === "string") result.planName = response.planName;
    if (typeof response.remaining === "number" && response.remaining >= 0) {
      result.remaining = response.remaining;
    }
    if (quota.limit > 0) {
      result.used = quota.used;
      result.total = quota.limit;
    }
    if (!result.isValid) {
      result.invalidMessage = response.status
        ? String(response.status)
        : "Query failed";
    }
    return result;
  },
})
  • Codex and Grok Build provider endpoints include /v1; Claude Code's don't. The script strips a trailing /v1 before appending the path, so it works for every app and you don't need usageBaseUrl.
  • remaining is present in all three cases: wallet balance (planName is Sub2API's wallet balance label), a subscription group (planName is the group name, and remaining is whichever of the daily / weekly / monthly limits has the least left), and a key with its own total quota (with quota.used and quota.limit as well). When a subscription group has no limits at all, remaining is -1, meaning unlimited, and the script doesn't show that number.
  • The response also has rate_limits (the key's 5-hour / 1-day / 7-day windows) and subscription (the group's daily / weekly / monthly usage and limits). To show these on separate lines on the card, have extractor return an array with one element per line.
  • This script is identical to the Sub2API template under "Configure usage query" in the CC Switch app (since v4.0.10), so users adding your site by hand can pick it with one click too.
  • The link generated by the "Import to CC Switch" button in the Sub2API admin panel comes with its own query script. It uses ?. and ??, which CC Switch can run, but it shows -1 when a subscription group is unlimited.

Not closely related to an API service. Expand if you also distribute companion tools

These three types have little to do with your API service, but some sites also distribute companion tools, so here are the key points.

MCP (resource=mcp)

  • apps is required, comma-separated: claude, codex, gemini, grokbuild, opencode, hermes, pi, mcode. openclaw is ignored.
  • config is a Base64 {"mcpServers": {"": {...}}}. One link can carry several servers.
  • If the user already has a server with the same ID, only the new apps are checked for it; its config is not overwritten by the link. Use a different ID if you want to update the config.
  • Importing writes to the client config files right away. The enabled parameter currently has no effect.

Prompt (resource=prompt)

  • app is one of claude, codex, gemini, grokbuild, opencode, pi, mcode. In CC Switch, openclaw and hermes are handled by the workspace editor and memory management, so distributing prompts to them via deep link is not recommended.
  • name and content (Base64 Markdown) are required; description is optional.
  • enabled is the initial value of the "Enable after import" switch in the confirmation dialog. Enabling replaces the user's current prompt file (such as CLAUDE.md) with this content, so usually don't set it.

Skill (resource=skill)

  • repo is required, in the form owner/name, and must be a public GitHub repository; branch defaults to main.
  • What gets added is the repository; users still choose which Skills to install themselves. The directory parameter is currently ignored.

Backend (Node.js)

javascript
function b64(text) {
  return Buffer.from(text, "utf8").toString("base64");
}

const usageScript = `({
  request: {
    url: "{{baseUrl}}/user/balance",
    method: "GET",
    headers: { "Authorization": "Bearer {{apiKey}}" }
  },
  extractor: function (r) {
    return { remaining: r.balance, unit: "USD" };
  }
})`;

function claudeImportLink(user) {
  const params = new URLSearchParams({
    resource: "provider",
    app: "claude",
    name: "Example AI",
    endpoint: "https://api.example.com",
    apiKey: user.apiKey,
    // Leave all models empty when serving genuine Claude models; only set
    // model / haikuModel / sonnetModel / opusModel for non-native models like DeepSeek or Kimi
    homepage: "https://example.com",
    // If there is no built-in icon for your brand, give your own icon URL; see "Adding your own icon"
    iconUrl: "https://example.com/static/logo.png",
    usageScript: b64(usageScript),
    usageEnabled: "true",
  });
  return `ccswitch://v1/import?${params}`;
}

A link for OpenCode in the Anthropic format only changes app and apiFormat, and adds the model:

javascript
const params = new URLSearchParams({
  resource: "provider",
  app: "opencode",
  name: "Example AI",
  endpoint: "https://api.example.com/v1",
  apiKey: user.apiKey,
  apiFormat: "anthropic",
  model: "claude-sonnet-5-5",
});

Backend (Python)

python
import base64
from urllib.parse import urlencode

def b64(text: str) -> str:
    return base64.b64encode(text.encode("utf-8")).decode("ascii")

codex_toml = """\
model_provider = "example"
model = "example-coder"

[model_providers.example]
name = "Example AI"
base_url = "https://api.example.com/v1"
wire_api = "responses"
"""

def codex_import_link(api_key: str) -> str:
    params = {
        "resource": "provider",
        "app": "codex",
        "name": "Example AI",
        "apiKey": api_key,
        "configFormat": "toml",
        "config": b64(codex_toml),
    }
    return "ccswitch://v1/import?" + urlencode(params)

By default urlencode turns spaces into + and + into %2B, which matches how CC Switch parses links.

Generating in the browser

The browser's btoa doesn't handle non-ASCII characters such as Chinese, so convert to UTF-8 first:

javascript
function b64(text) {
  const bytes = new TextEncoder().encode(text);
  let binary = "";
  bytes.forEach((b) => (binary += String.fromCharCode(b)));
  return btoa(binary);
}

If you can generate the link on the backend, do it there. It's better if the key never passes through frontend JavaScript.

Recommended flow:

  1. The button itself carries no link. When the user clicks it, the frontend asks your backend for this user's link.
  2. The backend checks that the user is logged in, generates the link with this user's own key (using the generator function from the previous section) and returns it.
  3. Once the frontend has the link, it runs window.location.href = link. The browser asks whether to open CC Switch, and after the user agrees, the import confirmation dialog opens.

This way the link never appears in the page source and is generated only once, when the user actually clicks the button.

Using Node.js (Express) as an example. claudeImportLink is the generator function from the previous section; write codexImportLink the same way:

javascript
const builders = {
  claude: claudeImportLink,
  codex: codexImportLink,
};

app.post("/api/ccswitch-link", requireLogin, (req, res) => {
  const build = builders[req.body.app];
  if (!build) return res.status(400).json({ error: "unsupported app" });
  // The response contains the user's key: don't cache it, and keep it out of logs
  res.set("Cache-Control", "no-store");
  res.json({ link: build(req.user) });
});

Use POST, not GET: GET requests may be prefetched or cached by the browser, or show up in access logs with their parameters.

Frontend: button and hint

html
<button type="button" onclick="importToCcSwitch('claude')">Import to Claude Code</button>
<button type="button" onclick="importToCcSwitch('codex')">Import to Codex</button>
<p class="hint">
  Your browser will ask whether to open CC Switch. Choose "Open". Nothing happened? CC Switch may not be installed yet:
  <a href="https://ccswitch.io" target="_blank" rel="noopener">download CC Switch</a>, install it, then click again.
</p>

<script>
  async function importToCcSwitch(app) {
    const res = await fetch("/api/ccswitch-link", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ app }),
    });
    if (!res.ok) {
      alert("Failed to generate the import link. Please try again later.");
      return;
    }
    const { link } = await res.json();
    window.location.href = link;
  }
</script>

Notes:

  • Redirect right after the click. Browsers only allow launching an external app when it is triggered by a user click, and some browsers stop treating it as click-triggered if too much time passes after the click. Your endpoint should respond within a second or two. Don't show another confirmation dialog after getting the link and make the user click again.
  • One link imports into one app only. If you support several apps, give each app its own button, or let the user pick the client first and then click a single "Import" button. The endpoint and format may differ per app; see "Supported apps".
  • When CC Switch isn't installed, the browser usually shows nothing, and the web page can't reliably detect it. So keep the hint next to the button visible at all times instead of waiting for a detection result.
  • Clicking the same button twice imports two copies. After the user clicks once, you can change the button to "Sent to CC Switch" or disable it for a few seconds.

Security and privacy

  • A link with a key is as good as the key itself. A link written directly into a button's href appears in the page source and may be read by browser extensions. Following "Putting the link behind a button", where the link is requested from the backend only when the user clicks, avoids this. Only generate it on pages behind login. Never put it on public pages, in mass emails or in community announcements, and keep it out of your access logs and third-party analytics.
  • Keep links as short as possible. With a long full config, the command line passed to CC Switch on Windows has a limit of about 32,000 characters, and longer links won't open.
  • CC Switch applies allowlist filtering and prominent warnings to link content; it does not vouch for you to the user. Users see every item shown in the confirmation dialog. Don't put anything unrelated to your service in there, or users will stop trusting the button.

Debugging

  1. First click the link on your own computer, check that every item in the confirmation dialog is what you expect, then import, switch, and send a message.
  2. If the confirmation dialog shows an error, the message is the cause. Check it against "Rejected links" above.
  3. Import succeeded but no balance shows: open "Configure usage query" on the provider card and click "Test script" to see the error. The most common causes are a request URL with a different origin, a balance endpoint that doesn't return JSON, and wrong fields in extractor.
  4. Import succeeded but requests fail after switching: most likely the API format is wrong (see "Supported apps") or the model name is wrong.
  5. The iconUrl icon doesn't show: download failures don't produce an error; the reason is in the CC Switch log (~/.cc-switch/logs/cc-switch.log, search for Skipped deep link icon). The most common causes are a wrong Content-Type, an image over 256 KB, or a URL that requires login or has hotlink protection. Check the response headers with curl -I.

Compatibility with older versions

Not all of your users have upgraded to the latest version. These behaviors differ on older versions:

Behavior v4.0.10 and later v3.19.0 – v4.0.9
Script present, no usageEnabled Enabled Not enabled
config.toml embedded for Codex Provider table and model fields taken per the allowlist Only the endpoint, key and model name are taken; the rest is dropped and the config is rebuilt from a fixed template
Model table embedded for Grok Build Fields of the selected table are taken Only the endpoint, key and model name are taken
Clicking a link while CC Switch isn't running The confirmation dialog opens after startup Occasionally lost; the user has to click again
apiFormat Mapped per app Ignored; the default format is always used
app=pi Supported Import rejected
iconUrl Downloaded and used as the card icon Ignored; shows icon or the first letter of the name
Switch / enable after import A switch in the confirmation dialog, with enabled as its initial value Follows enabled in the link directly; OpenCode / OpenClaw / Hermes always write to the app config

To get consistent behavior across versions: set usageEnabled=true explicitly for the usage query, and for Codex / Grok Build put the key information (endpoint, key, model) in URL parameters too, not only in config. If your API is not the app's default format, cards imported on older versions will have the wrong format; you can add a hint next to the button asking users to upgrade CC Switch.


サイトに「CC Switch にワンクリックでインポート」ボタンを置く:サイト運営者向け連携ガイド

中文 | English | 日本語

サイト運営者であれば、CC Switch を通じて、ユーザーがあなたのプロバイダーを Claude Code や Codex などの Agent アプリにワンクリックで取り込めるようにできます。

対象バージョン:CC Switch v4.0.10 以降。本文中で「v4.0.10 以降」と記した動作は、それより前のバージョンでは異なります。違いは末尾の「旧バージョンとの互換性」を参照してください。本記事は現在のコードをもとに整理しており、例に出てくるドメインと Key はすべて架空のものです。

この記事の対象読者

API サービス(中継サービス、集約プラットフォーム、自前のゲートウェイなど)を運営していて、ユーザーがコンソールでボタンを 1 回押すだけで、エンドポイント、Key、モデル、それに残高の照会までまとめて CC Switch に追加できるようにしたい方を想定しています。ユーザーが手でフォームを埋める必要はなくなります。

これは ccswitch:// ディープリンクで実現します。ユーザーのシステムに CC Switch がインストールされていれば、ブラウザで ccswitch://... のリンクを押すと CC Switch が起動してインポート確認ダイアログが開き、ユーザーが内容を確かめて「インポート」を押します。

ユーザーマニュアルの ディープリンクプロトコル はパラメーターの早見表です。この記事では、サイト運営者が実際に決める必要のあること——リンクの生成方法、何を含められるか、何が拒否されるか、インポート直後に残高を表示させる方法——を説明します。

最短ルート

サイトを New API または Sub2API で構築していますか? どちらも Key 一覧に「CC Switch へのインポート」ボタンが最初から付いているので、自分で開発しなくてもそのまま使えます。違いは残高です。New API のリンクには使用量クエリスクリプトが含まれないため、インポート後のカードに残高は表示されません。Sub2API のリンクには含まれています。残高を表示したい、自社アイコンを付けたい、対応アプリを増やしたいといった場合は、この記事に沿って手を加えてください。

ほとんどのサイト運営者がやることは 3 つだけです。以下の節を順に読めば足ります。

  1. 「まず要点」を読み、続いて「プロバイダーリンク」の「最小構成のリンク」「対応アプリ」「よく使うパラメーター」を読んで、どのアプリ向けにリンクを生成するか、エンドポイントと形式をどう書くかを決めます。まず オンライン生成ツール のフォームに入力してリンクを 1 本作り、自分のパソコンで押して確認ダイアログの見た目を確かめておくとよいでしょう。
  2. インポート後に残高を表示したい場合は「使用量クエリスクリプト」を読みます。NewAPI / OneAPI 系、Sub2API 系のサイトには既成のスクリプトがあるので、そのまま写せば済みます。
  3. 「リンクを生成するコード」と「リンクをボタンに載せる」を読みます。バックエンドでユーザーごとにリンクを生成し、フロントエンドにボタンを置きます。

折りたたんである節(同梱する設定の原文、拒否されるリンクのまとめ、MCP / プロンプト / Skill)は、必要になったときに開いてください。

まず要点

  1. リンクはユーザーごとに生成します。プロバイダーのインポートでは API Key が必須で、Key のないリンクはインポートに失敗します。そのため「ワンクリックインポート」ボタンはユーザーがログインした後のコンソールに置き、バックエンドがそのユーザー自身の Key でリンクを組み立てるようにしてください。公開ページには置かないでください。ボタンの作り方は「リンクをボタンに載せる」を参照してください。
  2. apiFormat で API の形式を宣言します。値は anthropic、openai_chat、openai_responses、gemini_native のいずれかで、アプリごとの対応状況は後述します。省略するとアプリのデフォルト形式になります。Claude Code は Anthropic Messages、Codex と Grok Build は OpenAI Responses、OpenCode / OpenClaw / Hermes / Pi は OpenAI Chat Completions です。
  3. モデル名は必要なときだけ書きます。中継サービスが純正の Claude モデルを提供している場合、Claude Code のモデルはすべて空欄にしてください。Claude Code は内蔵のモデル一覧を使います。DeepSeek や Kimi のようなネイティブでないモデルの場合にだけ、model、haikuModel、sonnetModel、opusModel を書きます。OpenCode、OpenClaw、Hermes のモデル一覧は model から作られるため、書かないと選べるモデルがありません。Pi では必須です。
  4. ユーザーに残高を見せたいなら、使用量クエリスクリプトを付けます。v4.0.10 以降は usageScript を付けるだけでデフォルトで有効になります。旧バージョンとも互換にしたい場合は、あわせて usageEnabled=true を書いてください。スクリプトがリクエストできるのは、プロバイダーのエンドポイントと同一オリジンの HTTPS API だけです。詳しくは後述します。
  5. 「インポート後すぐに切り替えるか」はユーザーが決めます。確認ダイアログにそのスイッチがあり、リンクの enabled はスイッチの初期値にすぎません。通常は書かなくて構いません。
  6. Base64 のパラメーターはさらに URL エスケープします。リンクは URLSearchParams などの同等の関数で組み立て、文字列を手で連結しないでください。

リンクの構造

text
ccswitch://v1/import?resource=<種類>&<パラメーター>...
  • v1 はプロトコルのバージョン、/import は固定のパスで、どちらも間違えると拒否されます。
  • resource は provider(プロバイダー)、mcp、prompt(プロンプト)、skill の 4 つのいずれかです。
  • パラメーター名は大文字と小文字を区別し、キャメルケースで書きます。api_key ではなく apiKey、usageScript です。

エンコード規則

エンコードは 2 段階で、順番を逆にしてはいけません。

  1. config、usageScript、content のような「ひとまとまりの内容」を渡すパラメーターは、まず UTF-8 テキストを Base64 エンコードします。標準の Base64 と URL-safe Base64 のどちらも受け付け、末尾の = はあってもなくても構いません。
  2. リンクに組み込むときに、すべてのパラメーター値をもう一度 URL エスケープします(application/x-www-form-urlencoded の規則)。標準 Base64 に含まれる + は必ず %2B にしてください。そうしないとスペースとして解釈されます。CC Switch はスペースを + に戻そうとしますが、それに頼らないでください。

URLSearchParams は手順 2 を自動で行います。リンクを手書きするときに最も多い間違いが、この手順の抜けです。

真偽値のパラメーターは true / false で書きます。それ以外の書き方は、書かなかったものとして扱われます。

ユーザーがリンクをクリックした後

  1. ブラウザが「CC Switch を開きますか」と確認し、ユーザーが許可すると CC Switch が起動します(起動していなければまず起動します)。
  2. CC Switch がインポート確認ダイアログを開き、リンクの内容をすべて表示します。エンドポイント、マスクされた Key、モデル、同梱された設定の原文、使用量クエリスクリプトの全文です。疑わしい内容は黄色で強調して警告します。たとえばローカルや社内ネットワークを指すアドレス、プロセスの読み込み動作を変えられる環境変数(NODE_OPTIONS、LD_PRELOAD など)、シェルでコマンド全体を実行する MCP などです。
  3. ユーザーが「インポート」を押すと、次のようになります。
    • プロバイダー:対応するアプリのプロバイダー一覧に追加されます。確認ダイアログの下部にスイッチが 1 つあり、初期値はリンクの enabled から取られ、ユーザーが変更できます。
      • Claude Code、Codex、Gemini CLI、Grok Build:スイッチは「インポート後にこのプロバイダーへ切り替える」で、デフォルトはオフです。オンにすると、確認ダイアログに「クライアントのリクエストは上記のエンドポイントに送られます」という注意が表示されます。
      • OpenCode、OpenClaw、Hermes、Pi:これらのアプリは複数のプロバイダーを同時に置けるため、スイッチは「インポート後に <アプリ名> の設定へ追加する」(Pi では「インポート後に Pi で有効にする」)で、デフォルトはオンです。オフにすると CC Switch の一覧に保存されるだけになります。
    • MCP:apps に挙げた各アプリの設定ファイルにすぐ書き込まれます。
    • プロンプト:プロンプト一覧に追加されます。確認ダイアログに「インポート後に有効にする」スイッチがあり、初期値はリンクの enabled から取られます。オンにすると、そのアプリの現在のプロンプトファイルが置き換えられ、それまで有効だったプロンプトは無効になります。
    • Skill:追加されるのは Skill リポジトリです。ユーザーはさらに「Skills」ページで、どの Skill をインストールするかを選ぶ必要があります。

サイト運営者がつまずきやすい細かな点:

  • リンクはユーザーのクリックでしか起動できません。ページ読み込み時に ccswitch:// へ自動で遷移させると、ほとんどのブラウザでブロックされます。
  • CC Switch が一度に処理するリンクは 1 本だけです。前のリンクをユーザーが処理し終える前に新しいリンクが押されると、最新の 1 本だけが残ります。「1 つのボタンで複数のリンクを続けて起動する」設計にはせず、プロバイダー、MCP、プロンプトにそれぞれボタンを用意して、ユーザーに順に押してもらってください。
  • 同じプロバイダーリンクを 2 回押すと 2 件インポートされます。プロバイダー ID は名前とタイムスタンプから生成され、重複は除かれません。
  • Web ページからは、ユーザーが CC Switch をインストールしているかどうかを確実には判定できません。ボタンの横に案内文とダウンロード先を添えてください。書き方は「リンクをボタンに載せる」を参照してください。

プロバイダーリンク

最小構成のリンク

text
ccswitch://v1/import?resource=provider&app=claude&name=Example%20AI&endpoint=https%3A%2F%2Fapi.example.com&apiKey=sk-xxxx

必須なのは app、name、それにエンドポイントと Key だけです(エンドポイントと Key は URL パラメーターに書いても、同梱する config に書いても構いません)。Pi ではこれに加えて model が必須です。

対応アプリ

app アプリ デフォルト形式 指定できる apiFormat config に含められるもの
claude Claude Code anthropic 4 種類すべて {"env": {...}}。env 内の変数はすべて保持
codex Codex openai_responses openai_responses、openai_chat、anthropic config.toml の全体または一部。後述
gemini Gemini CLI gemini_native gemini_native のみ GEMINI_API_KEY、GOOGLE_GEMINI_BASE_URL、GEMINI_MODEL の 3 キー。ほかは無視
grokbuild Grok Build openai_responses openai_responses、openai_chat、anthropic [model."<名前>"] テーブル 1 つ。後述
opencode OpenCode openai_chat 4 種類すべて エンドポイントと Key のみ取得
openclaw OpenClaw openai_chat 4 種類すべて エンドポイントと Key のみ取得
hermes Hermes openai_chat openai_chat、openai_responses、anthropic エンドポイントと Key のみ取得
pi Pi openai_chat 4 種類すべて エンドポイントと Key のみ取得

Claude Desktop、MiniMax Code のプロバイダーは現在ディープリンクでのインポートに対応しておらず、リンクは拒否されます。

apiFormat が反映される場所はアプリによって異なります。

  • Claude Code、Codex、Grok Build:この 3 つのクライアントは自分のネイティブ形式しか話しません(Claude Code は Anthropic、残りの 2 つは Responses)。ネイティブでない形式を書くと、インポートされたカードに「ルーティングが必要」マークが付き、ユーザーが切り替えるときにはローカルルーティングを有効にして、CC Switch にリクエスト形式を変換させる必要があります。
  • OpenCode、OpenClaw、Hermes、Pi:これらのクライアントは自身で複数の形式に対応しているため、CC Switch は apiFormat を各クライアントの設定のプロトコル欄(OpenCode の npm、OpenClaw / Pi の api、Hermes の api_mode)に換算します。クライアントはその形式で直接あなたの API にリクエストし、ローカルルーティングは経由しません。

エンドポイントは選んだ形式の慣例に従って書きます。Anthropic 形式は Claude Code では /v1 を付けず(例:https://api.example.com)、OpenAI の 2 形式は通常 /v1 を付けます。OpenCode、OpenClaw、Hermes、Pi のエンドポイントはそれぞれの SDK の base URL で、パスの組み立て方は統一されていません。同じ Anthropic 形式でも、CC Switch の内蔵プリセットでは OpenCode のエンドポイントに /v1 が付き、Hermes と Pi には付きません。アプリごとに別々のリンクを生成し、エンドポイントはそのアプリで実際に通ることを確かめた書き方にしてください。

よく使うパラメーター

パラメーター 説明
name 表示名。必須
endpoint API エンドポイント。半角カンマ区切りで複数指定でき、最初が主エンドポイント、残りはエンドポイント候補に追加され、ユーザーが速度テストして切り替えられます
apiKey API Key。URL パラメーターと config の両方にある場合は URL パラメーターが優先
apiFormat API の形式。上の表を参照。省略時はアプリのデフォルト形式
model デフォルトモデル。Claude Code で純正の Claude モデルを使う場合は空欄。Codex は省略すると gpt-5-codex、Grok Build は省略すると grok-4.5 を使用。Pi は必須
haikuModel / sonnetModel / opusModel Claude Code のみ:3 段階のモデルエイリアスに対応する実際のモデル名。ネイティブでないモデルの場合にだけ必要
homepage 公式サイト。省略時はエンドポイントから推定(api. の接頭辞を除く)
icon CC Switch 内蔵アイコンの名前。英小文字・数字と . _ - のみ使用でき、それ以外の書き方は捨てられます。知らない名前の場合は名前の頭文字を表示。自社ブランドの内蔵アイコンがなければ書く必要はありません
iconUrl 自社アイコン画像の URL。後述の「自社アイコンを付ける」を参照。ダウンロードに失敗した場合は icon に戻ります
notes メモ。プロバイダーカードに表示されます
enabled 確認ダイアログの「インポート後に切り替える / 追加する」スイッチの初期値。ユーザーが変更できます。通常は書かなくて構いません
config + configFormat 同梱する設定の原文(Base64)。configFormat は json(デフォルト)または toml

configUrl(リモート設定)はまだ実装されておらず、このパラメーターを含むリンクはそのまま拒否されます。

自社アイコンを付ける:iconUrl

CC Switch の内蔵アイコンに自社ブランドがない場合は、iconUrl で画像の URL を指定します。確認ダイアログが開いた時点で CC Switch がその画像をダウンロードして上部に表示し、インポート後はそれがカードのアイコンになります。ユーザーが追加で何かを押す必要はありません。

画像は 96×96 の PNG に描き直して CC Switch に保存され、以後その URL にはアクセスしません。後でアイコンを変えても、すでにインポートしたユーザーには反映されません。

URL と画像は以下の条件を満たす必要があります。1 つでも満たさない場合、確認ダイアログはエラーを出さず、アイコンは icon で指定した内蔵アイコンに戻り、icon もなければ名前の頭文字が表示されます。

  • https:// で始まり、ホストがドメイン名(IP は不可)、デフォルトポート、アカウントやパスワードを含まないこと。形の正しくない URL はリンクの解析時に捨てられ、リンクのそれ以外の部分は通常どおりインポートされます。
  • 公開アクセスできること:CC Switch はダウンロード時に Cookie と Referer を付けず、ユーザーのシステムプロキシも使いません。ログインが必要な URL や、ホットリンク防止を有効にした URL は失敗します。
  • ドメインの解決先がパブリックアドレスであること。社内ネットワークやローカルを指すものは一切ダウンロードしません。
  • 5 秒以内にダウンロードが終わること。リダイレクトは最大 3 回までたどり、リダイレクト先もそれぞれ上記の条件を満たす必要があります。
  • 256 KB 以下であること。
  • レスポンスヘッダーの Content-Type が image/png、image/jpeg、image/webp、image/svg+xml のいずれかで、ファイルの実際の形式と一致していること。application/octet-stream のような汎用の型は不可です。
  • ビットマップの幅と高さが 4096 ピクセル以下であること。

画像そのものについての推奨:

  • 正方形の画像を使ってください。四隅が不透明な正方形の画像はアイコン枠いっぱいに表示されます。四隅が透明なロゴは中央に縮小され、周囲に余白ができて、内蔵アイコンと同じ見た目になります。
  • SVG は画像としてのみ表示され、中のスクリプトは実行されず、参照する外部フォントや画像も読み込まれません。文字はパスに変換してください。
  • ユーザーが確認ダイアログを開くたびにこの URL へ 1 回リクエストが来ます。CDN に置けば十分です。

Claude Code:環境変数を同梱する

追加の環境変数(カスタムリクエストヘッダー、タイムアウトなど)が必要な場合に開く

追加の環境変数(カスタムリクエストヘッダー、タイムアウト、実験的機能の無効化など)が必要なサイトは、それらを config に入れます。

json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://api.example.com",
    "ANTHROPIC_AUTH_TOKEN": "sk-xxxx",
    "ANTHROPIC_MODEL": "example-sonnet",
    "API_TIMEOUT_MS": "600000",
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
  }
}

env 内の変数はそのまま保持されます。エンドポイント、Key、モデル名については、URL パラメーターにも書かれていれば URL パラメーターが優先されます。確認ダイアログには変数が 1 つずつ表示され、機密性のある値はマスクされます。

Codex:config.toml を同梱する

wire_api、リクエストヘッダー、推論レベルなどの追加設定を含めたい場合にだけ必要です。開くと、受け付けるキーと拒否される書き方を確認できます

書き方は 2 通りです。

  • configFormat=json で、内容を {"auth": {"OPENAI_API_KEY": "sk-xxxx"}, "config": "<config.toml のテキスト>"} にする。
  • configFormat=toml で、内容を config.toml の原文そのものにする。

CC Switch はファイル全体をユーザーの ~/.codex/config.toml にそのまま持ち込むことはせず、このプロバイダーに属する部分だけを受け取ります。

  • 選ばれた [model_providers.] テーブル:model_provider が指しているテーブルです。model_provider を書かない場合、ファイル内のテーブルは 1 つだけでなければなりません。テーブルからは次のキーを受け取ります:name、base_url、wire_api、requires_openai_auth、experimental_bearer_token、model_catalog_url、capabilities、query_params、http_headers、request_max_retries、stream_max_retries、stream_idle_timeout_ms、websocket_connect_timeout_ms、supports_websockets、supports_standalone_web_search。
  • トップレベルのモデル関連フィールド:model、review_model、model_reasoning_effort、plan_mode_reasoning_effort、disable_response_storage、web_search、model_context_window、model_auto_compact_token_limit、model_supports_reasoning_summaries、model_verbosity、それに [agents] のサブエージェント用モデルと [memories] のメモリー用モデル。

それ以外は一切受け取りません。[features]、[tools]、MCP、sandbox、notify、ほかのプロバイダーテーブルなどは、ユーザー自身のグローバル設定だからです。

インポート後、テーブル名は一律 custom に変わり(CC Switch が管理する Codex プロバイダーはすべて [model_providers.custom] に書かれます)、base_url と experimental_bearer_token にはマージ後のエンドポイントと Key が使われます。model_catalog_url はプロバイダーのエンドポイントと同一オリジンでなければならず、そうでなければインポートは拒否されます。

拒否される書き方:テーブルに auth(Codex にコマンドを実行させて Key を取得する)、aws、gateway_oauth(ローカルのクラウド認証情報を読む)、env_http_headers(環境変数を読む)が含まれるもの。env_key は捨てられるので、Key は必ずリンク自体で渡してください。env_key だけを書いて Key を渡していないリンクは拒否されます。

例(configFormat=toml):

toml
model_provider = "example"
model = "example-coder"
model_reasoning_effort = "high"

[model_providers.example]
name = "Example AI"
base_url = "https://api.example.com/v1"
wire_api = "responses"
http_headers = { "X-Client" = "cc-switch" }
stream_idle_timeout_ms = 300000

Grok Build:モデルテーブルを 1 つ同梱する

コンテキストウィンドウ、サンプリングパラメーターなどの追加設定を含めたい場合にだけ必要です

書き方は Codex と同じです({"config": "<config.toml のテキスト>"}、または configFormat=toml)。

インポートされるのは [models] default が指す [model."<名前>"] テーブルだけです。default を書かない場合、ファイル内のテーブルは 1 つだけでなければならず、テーブルが複数あるのに default がない場合は拒否されます。CC Switch では 1 つの Grok Build プロバイダーが 1 つのモデルテーブルに対応するため、1 本のリンクで複数のモデルをインポートすることはできません。

テーブルからは表示名、description、api_backend、context_window、max_completion_tokens、サンプリングとリトライのパラメーター、推論レベル関連のフィールドなどを保持します。エンドポイント、Key、モデル名にはリンクのパラメーターを使います(URL パラメーターが優先)。テーブルに api_backend、context_window がない場合はデフォルト値を補います。

テーブルに auth_provider、env_http_headers、mtls_cert_dir を含むリンクは拒否されます。env_key の扱いは Codex と同じです。

拒否されるリンクのまとめ

確認ダイアログでエラーが出たときに開き、エラーの原文から原因を調べる

状況 確認ダイアログのエラー(英語の原文、抜粋)
Key がない API key is required
エンドポイントがない Endpoint is required
エンドポイントが http / https でない Invalid URL scheme for 'endpoint[0]'
app に対応していない値を書いた Invalid provider app type
apiFormat の値が正しくない Unsupported apiFormat
そのアプリがこの apiFormat に対応していない is not supported for app
Pi でモデルを書いていない Pi providers need a model
OpenCode / OpenClaw / Hermes / Pi の名前、エンドポイント、Key、モデルに、クライアントが展開する書き方が含まれる(下記参照) uses syntax that … would expand
configUrl を含む 'configUrl' is not supported yet
Base64 をデコードできない config 参数 Base64 解码失败(config パラメーターの Base64 デコードに失敗)
Codex / Grok で env_key だけで Key を渡している supplies its API key indirectly
Codex のテーブルに auth などがある cannot be imported from a link
Codex のモデル目録の URL がプロバイダーのエンドポイントと同一オリジンでない model_catalog_url
Grok でテーブルが複数あるのに default がない several [model.*] tables

OpenCode、OpenClaw、Hermes、Pi は、設定を読むときに特定の書き方を展開します。Pi では Key が ! で始まるとコマンドとして実行され、$NAME / ${NAME} は環境変数に置き換えられます。OpenCode の {env:…} は環境変数を、{file:…} はローカルのファイルを読みます。OpenClaw と Hermes の ${…} は環境変数を読みます。リンクからのインポートでは、これらの書き方はすべて拒否されます。あなたの Key とエンドポイントはもともとリテラル値なので、影響はありません。

インポート直後に残高を表示する:使用量クエリスクリプト

CC Switch のプロバイダーカードには残高やプランの使用量を表示でき、そのデータは使用量クエリスクリプトから取得します。スクリプトをリンクに入れておけば、ユーザーはインポートした直後から残高を確認できます。

スクリプトの形

スクリプトは JavaScript の式で、request(どんなリクエストを送るか)と extractor(レスポンスからどう値を取り出すか)を持つオブジェクトを返します。

javascript
({
  request: {
    url: "{{baseUrl}}/user/balance",
    method: "GET",
    headers: {
      "Authorization": "Bearer {{apiKey}}"
    }
  },
  extractor: function (response) {
    return {
      remaining: response.balance,
      unit: "USD"
    };
  }
})

実行前に、CC Switch はスクリプト中のプレースホルダーを実際の値に置き換えます。

プレースホルダー 置き換え後
{{apiKey}} usageApiKey。指定がなければプロバイダーの API Key
{{baseUrl}} usageBaseUrl。指定がなければプロバイダーの主エンドポイント(末尾の / を除く)
{{accessToken}} usageAccessToken
{{userId}} usageUserId

{{baseUrl}} はプロバイダーのエンドポイントそのままである点に注意してください。/v1 が付いていれば、組み立てた結果は https://api.example.com/v1/user/balance になります。残高 API が /v1 の下にない場合は、スクリプトに完全な URL を直接書いて構いません。エンドポイントと同一オリジンでありさえすれば大丈夫です。

extractor が受け取るのはパース済みのレスポンス JSON で、オブジェクト 1 つ、またはオブジェクトの配列(プランが複数ある場合)を返します。フィールドはすべて任意です。

フィールド 型 説明
remaining 数値 残りの額
used 数値 使用済み
total 数値 総額
unit 文字列 単位。例:USD、CNY、回
planName 文字列 プラン名
isValid 真偽値 Key が有効かどうか。false のときカードに無効と表示
invalidMessage 文字列 無効の理由
extra 文字列 補足説明

実行時の制限

スクリプトは信頼できない入力として扱われ、CC Switch はハードな制限をかけています。

  • QuickJS のサンドボックス内で動き、fetch、ファイル、ネットワークなどの機能は一切ありません。スクリプト自体は「リクエストの記述」と「レスポンスの解析」だけを担い、リクエストは CC Switch が代わりに送ります。
  • 1 回の照会で送るリクエストは 1 つだけです。先にログインしてから照会する、といったことはできません。
  • リクエストは HTTPS で、かつ {{baseUrl}} と同一オリジン(同じドメイン、同じポート)でなければなりません。オリジンが異なるリクエストは拒否されます。残高 API が別のドメインにある場合(たとえばコンソールが console.example.com、API が api.example.com)は、usageBaseUrl でコンソールのドメインを指してください。
  • レスポンスは JSON でなければなりません。
  • リクエストはブラウザを経由せず、CC Switch がユーザーのパソコンから直接送るため、残高 API に CORS の設定は不要です。API は API Key で認証できる必要があります。ログイン状態やシステムアクセストークンでしか照会できない場合は、usageAccessToken でトークンをリンクに含めてください(下の NewAPI の節を参照)。
  • スクリプトの実行時間の上限は 5 秒、メモリの上限は 16 MiB、HTTP リクエストのタイムアウトは 10 秒です。

有効になるかどうか

リンクの書き方 インポート後
usageScript あり、usageEnabled なし 有効(v4.0.10 以降。それより前のバージョンでは無効)
usageScript あり、usageEnabled=true 有効
usageScript あり、usageEnabled=false 無効。ユーザーがアプリ内で手動でオンにできます
スクリプトなし 無効

確認ダイアログには、スクリプトの本文全体と「有効 / 無効」の表示が出ます。

usageAutoInterval は自動照会の間隔(分)です。0 または省略すると定期的な照会は行いません。短くしすぎないでください。すべてのユーザーがこの頻度であなたの API を叩くことになります。

NewAPI / OneAPI 系のサイト

この種のサイトの残高 API は、API Key ではなくシステムアクセストークンとユーザー ID を使います。リンクには usageAccessToken と usageUserId を含めてください。

javascript
({
  request: {
    url: "{{baseUrl}}/api/user/self",
    method: "GET",
    headers: {
      "Authorization": "Bearer {{accessToken}}",
      "New-Api-User": "{{userId}}"
    }
  },
  extractor: function (response) {
    if (response.success && response.data) {
      return {
        planName: response.data.group,
        remaining: response.data.quota / 500000,
        used: response.data.used_quota / 500000,
        unit: "USD"
      };
    }
    return { isValid: false, invalidMessage: response.message };
  }
})

500000 は NewAPI のデフォルトのクォータ換算比率です。変更している場合は自分の値に合わせてください。システムアクセストークンは API Key より権限が大きいので、ユーザー本人がログインした後に生成するリンクにだけ入れてください。

Sub2API 系のサイト

Sub2API には CC Switch 向けの GET /v1/usage API が最初から用意されており、API Key で認証するため usageAccessToken は不要です。返されるトップレベルのフィールドは、CC Switch が理解する isValid、planName、remaining、unit そのものなので、スクリプトはほぼそのまま写せます。

javascript
({
  request: {
    url: "{{baseUrl}}".replace(/\/+$/, "").replace(/\/v1$/, "") + "/v1/usage",
    method: "GET",
    headers: {
      "Authorization": "Bearer {{apiKey}}",
      "User-Agent": "cc-switch/1.0"
    }
  },
  extractor: function (response) {
    var quota = response.quota || {};
    var result = {
      isValid: response.isValid !== false,
      unit: response.unit || quota.unit || "USD"
    };
    if (typeof response.planName === "string") result.planName = response.planName;
    if (typeof response.remaining === "number" && response.remaining >= 0) {
      result.remaining = response.remaining;
    }
    if (quota.limit > 0) {
      result.used = quota.used;
      result.total = quota.limit;
    }
    if (!result.isValid) {
      result.invalidMessage = response.status
        ? String(response.status)
        : "照会に失敗しました";
    }
    return result;
  },
})
  • Codex、Grok Build のプロバイダーのエンドポイントには /v1 が付き、Claude Code のものには付きません。スクリプトは先に末尾の /v1 を取り除いてから組み立てるので、どのアプリでも共通に使え、usageBaseUrl を書く必要はありません。
  • 3 つのケースいずれでも remaining があります。ウォレット残高(planName はウォレット残高を示す名前)、サブスクリプショングループ(planName はグループ名で、日 / 週 / 月の上限のうち残りが最も少ないものを取る)、Key に個別の総額上限を設定した場合(このときは quota.used と quota.limit も返る)です。サブスクリプショングループに上限が一切設定されていない場合、remaining は -1 で無制限を意味し、スクリプトはこの値を表示しません。
  • レスポンスには rate_limits(Key の 5 時間 / 1 日 / 7 日のウィンドウ)と subscription(グループの日 / 週 / 月の使用量と上限)も含まれます。カードに行を分けて表示したい場合は、extractor から配列を返し、要素ごとに 1 行にできます。
  • このスクリプトは、CC Switch のアプリ内「利用状況を設定」にある Sub2API テンプレート(v4.0.10 以降)とまったく同じです。ユーザーがあなたのサイトを手動で追加するときも、ワンクリックで選べます。
  • Sub2API の管理画面にある「CC Switch へのインポート」ボタンが生成するリンクには独自の照会スクリプトが含まれています。?. と ?? を使った書き方で、CC Switch でも動作しますが、サブスクリプショングループが無制限の場合は -1 と表示されます。

MCP・プロンプト・Skill のリンク

API サービスとはあまり関係がありません。関連ツールもあわせて配布する場合に開いてください

この 3 種類は API サービスとはあまり関係がありませんが、関連ツールをあわせて配布するサイトもあるので、要点だけ簡単に挙げておきます。

MCP(resource=mcp)

  • apps は必須で、カンマ区切りです:claude、codex、gemini、grokbuild、opencode、hermes、pi、mcode。openclaw は無視されます。
  • config は {"mcpServers": {"": {...}}} を Base64 にしたもので、1 本のリンクに複数のサーバーを含められます。
  • ユーザーがすでに同じ ID のサーバーを持っている場合は、そのサーバーに新しいアプリのチェックが付くだけで、設定内容はリンクで上書きされません。設定を更新したい場合は別の ID にしてください。
  • インポートと同時にクライアントの設定ファイルへ書き込まれます。enabled パラメーターは現在効果がありません。

プロンプト(resource=prompt)

  • app は claude、codex、gemini、grokbuild、opencode、pi、mcode のいずれかです。openclaw、hermes は CC Switch ではワークスペースエディターとメモリー管理が担当しているため、ディープリンクでプロンプトを配布することはお勧めしません。
  • name、content(Base64 にした Markdown)は必須、description は任意です。
  • enabled は確認ダイアログの「インポート後に有効にする」スイッチの初期値です。有効にすると、この内容でユーザーの現在のプロンプトファイル(CLAUDE.md など)が置き換えられるため、通常は書かないでください。

Skill(resource=skill)

  • repo は必須で、形式は owner/name、GitHub 上の公開リポジトリでなければなりません。branch のデフォルトは main です。
  • 追加されるのはリポジトリで、どの Skill をインストールするかはユーザーが自分で選びます。directory パラメーターは現在無視されます。

リンクを生成するコード

バックエンド(Node.js)

javascript
function b64(text) {
  return Buffer.from(text, "utf8").toString("base64");
}

const usageScript = `({
  request: {
    url: "{{baseUrl}}/user/balance",
    method: "GET",
    headers: { "Authorization": "Bearer {{apiKey}}" }
  },
  extractor: function (r) {
    return { remaining: r.balance, unit: "USD" };
  }
})`;

function claudeImportLink(user) {
  const params = new URLSearchParams({
    resource: "provider",
    app: "claude",
    name: "Example AI",
    endpoint: "https://api.example.com",
    apiKey: user.apiKey,
    // 純正の Claude モデルを提供する場合、モデルはすべて空欄。DeepSeek、Kimi などネイティブでないモデルのときだけ次を書く:
    // model / haikuModel / sonnetModel / opusModel
    homepage: "https://example.com",
    // 内蔵アイコンに自社ブランドがない場合は自社アイコンの URL を指定する。「自社アイコンを付ける」を参照
    iconUrl: "https://example.com/static/logo.png",
    usageScript: b64(usageScript),
    usageEnabled: "true",
  });
  return `ccswitch://v1/import?${params}`;
}

OpenCode 向けに Anthropic 形式のリンクを生成する場合は、app と apiFormat を変えてモデルを加えるだけです。

javascript
const params = new URLSearchParams({
  resource: "provider",
  app: "opencode",
  name: "Example AI",
  endpoint: "https://api.example.com/v1",
  apiKey: user.apiKey,
  apiFormat: "anthropic",
  model: "claude-sonnet-5-5",
});

バックエンド(Python)

python
import base64
from urllib.parse import urlencode

def b64(text: str) -> str:
    return base64.b64encode(text.encode("utf-8")).decode("ascii")

codex_toml = """\
model_provider = "example"
model = "example-coder"

[model_providers.example]
name = "Example AI"
base_url = "https://api.example.com/v1"
wire_api = "responses"
"""

def codex_import_link(api_key: str) -> str:
    params = {
        "resource": "provider",
        "app": "codex",
        "name": "Example AI",
        "apiKey": api_key,
        "configFormat": "toml",
        "config": b64(codex_toml),
    }
    return "ccswitch://v1/import?" + urlencode(params)

urlencode はデフォルトでスペースを + に、+ を %2B に変換し、CC Switch の解析規則と一致します。

ブラウザで生成する

ブラウザの btoa は中国語などの非 ASCII 文字に対応していないため、先に UTF-8 に変換します。

javascript
function b64(text) {
  const bytes = new TextEncoder().encode(text);
  let binary = "";
  bytes.forEach((b) => (binary += String.fromCharCode(b)));
  return btoa(binary);
}

バックエンドで生成できるならバックエンドで生成してください。Key がフロントエンドの JavaScript を経由しないほうが安全です。

リンクをボタンに載せる

推奨する流れ:

  1. ボタン自体にはリンクを持たせません。ユーザーがクリックしたら、フロントエンドがバックエンドにそのユーザーのリンクを要求します。
  2. バックエンドはユーザーがログイン済みであることを確認し、そのユーザー自身の Key でリンクを生成して返します(前の節の生成関数を使います)。
  3. フロントエンドはリンクを受け取ったら window.location.href = link を実行します。ブラウザが CC Switch を開くかどうかを確認し、ユーザーが許可するとインポート確認ダイアログが開きます。

こうすればリンクがページのソースに書き込まれることはなく、ユーザーが実際にボタンを押したときに 1 回だけ生成されます。

バックエンド:ユーザーごとにリンクを返す

Node.js(Express)の例です。claudeImportLink は前の節の生成関数で、codexImportLink は同じ書き方で別に用意します。

javascript
const builders = {
  claude: claudeImportLink,
  codex: codexImportLink,
};

app.post("/api/ccswitch-link", requireLogin, (req, res) => {
  const build = builders[req.body.app];
  if (!build) return res.status(400).json({ error: "unsupported app" });
  // レスポンスにユーザーの Key が含まれる:キャッシュさせず、ログにも出さない
  res.set("Cache-Control", "no-store");
  res.json({ link: build(req.user) });
});

GET ではなく POST を使ってください。GET リクエストはブラウザに先読みされたり、キャッシュされたり、パラメーター付きでアクセスログに残ったりすることがあります。

フロントエンド:ボタンと案内文

html
<button type="button" onclick="importToCcSwitch('claude')">Claude Code にインポート</button>
<button type="button" onclick="importToCcSwitch('codex')">Codex にインポート</button>
<p class="hint">
  ブラウザが CC Switch を開くかどうか確認するので、「開く」を選んでください。押しても何も起きない場合は、まだインストールされていない可能性があります。
  <a href="https://ccswitch.io" target="_blank" rel="noopener">CC Switch をダウンロード</a>してインストールしてから、もう一度押してください。
</p>

<script>
  async function importToCcSwitch(app) {
    const res = await fetch("/api/ccswitch-link", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ app }),
    });
    if (!res.ok) {
      alert("インポート用リンクの生成に失敗しました。しばらくしてからもう一度お試しください");
      return;
    }
    const { link } = await res.json();
    window.location.href = link;
  }
</script>

補足:

  • 遷移はクリックの直後に行ってください。ブラウザが外部アプリの起動を許可するのはユーザーのクリックによるものだけで、クリックから時間が空きすぎるとクリックによる起動とみなさなくなるブラウザもあります。API は 1〜2 秒以内に返すようにし、リンクを受け取った後にさらに確認ダイアログを出してもう一度押させる、といったことはしないでください。
  • 1 本のリンクでインポートできるのは 1 つのアプリだけです。複数のアプリに対応する場合は、アプリごとにボタンを置くか、先にユーザーにクライアントを選んでもらってから同じ「インポート」ボタンを押してもらいます。アプリごとにエンドポイントや形式が異なることがあります。「対応アプリ」を参照してください。
  • CC Switch がインストールされていないとき、ブラウザは通常何も表示しません。Web ページからも確実には判定できません。そのため、ボタンの横の案内文は判定結果を待たずに常に表示しておいてください。
  • 同じボタンを 2 回押すと 2 件インポートされます。ユーザーが 1 回押した後は、ボタンの表示を「CC Switch に送信済み」に変えるか、数秒間無効にしておくとよいでしょう。

セキュリティとプライバシー

  • Key を含むリンクは Key そのものと同じです。ボタンの href に直接書いたリンクはページのソースに現れ、ブラウザの拡張機能に読まれる可能性があります。「リンクをボタンに載せる」のやり方に従い、ユーザーがクリックしたときに初めてバックエンドへリンクを要求すれば、これを避けられます。リンクはユーザーがログインした後のページでだけ生成し、公開ページ、一斉配信メール、コミュニティのお知らせなどには載せないでください。アクセスログやサードパーティの解析ツールにも残さないようにしてください。
  • リンクは短いほど良いです。config 全体が長い場合、Windows では CC Switch に渡すコマンドラインに約 3.2 万文字の上限があり、長すぎるリンクは開けません。
  • CC Switch がリンクの内容に対して行うのはホワイトリストによるフィルタリングと目立つ警告表示であり、ユーザーに代わって内容を保証するものではありません。確認ダイアログに表示される項目はすべてユーザーの目に入ります。あなたのサービスと関係のないものを入れないでください。ユーザーがこのボタンを信用しなくなります。

デバッグ

  1. まず自分のパソコンで一通り押してみて、確認ダイアログの各項目が想定どおりかを確かめ、インポート、切り替え、メッセージの送信まで行います。
  2. 確認ダイアログにエラーが表示された場合は、そのエラーメッセージが原因です。上の「拒否されるリンクのまとめ」と照らし合わせて調べてください。
  3. インポートには成功したが残高が表示されない場合:プロバイダーカードで「利用状況を設定」を開き、「スクリプトをテスト」を押してどんなエラーが出るか確認します。よくある原因は、リクエスト先のオリジンが異なる、残高 API が JSON を返していない、extractor で取り出すフィールドを間違えている、のいずれかです。
  4. インポートには成功したが、切り替えた後にリクエストが失敗する場合:たいていは API の形式が合っていない(「対応アプリ」を参照)か、モデル名が間違っています。
  5. iconUrl のアイコンが表示されない場合:ダウンロードに失敗してもエラーにはならず、原因は CC Switch のログ(~/.cc-switch/logs/cc-switch.log、Skipped deep link icon で検索)に記録されます。よくある原因は Content-Type が正しくない、画像が 256 KB を超えている、URL にログインが必要かホットリンク防止が有効になっている、のいずれかです。curl -I でレスポンスヘッダーを確認してください。

旧バージョンとの互換性

ユーザー全員が最新版に更新しているとは限りません。以下の動作は旧バージョンでは異なります。

動作 v4.0.10 以降 v3.19.0 – v4.0.9
スクリプトあり、usageEnabled なし 有効 無効
Codex に同梱する config.toml ホワイトリストに従ってプロバイダーテーブルとモデルフィールドを受け取る エンドポイント、Key、モデル名だけを取り出し、残りは捨てて固定テンプレートで組み直す
Grok Build に同梱するモデルテーブル 選ばれたテーブルのフィールドを受け取る エンドポイント、Key、モデル名だけを取り出す
CC Switch が起動していないときにリンクを押す 起動後に確認ダイアログが開く まれに取りこぼし、もう一度押す必要がある
apiFormat アプリごとに換算 無視し、常にデフォルト形式を使う
app=pi 対応 インポートを拒否
iconUrl ダウンロードしてカードのアイコンにする 無視し、icon または名前の頭文字を表示
「インポート後に切り替える / 有効にする」 確認ダイアログのスイッチで、enabled は初期値 リンクの enabled どおりにそのまま実行。OpenCode / OpenClaw / Hermes は常にアプリの設定へ書き込む

どのバージョンでも同じ動作にしたい場合は、使用量クエリに usageEnabled=true を明示し、Codex / Grok Build の重要な情報(エンドポイント、Key、モデル)は config だけに入れず URL パラメーターにも書いてください。あなたの API がアプリのデフォルト形式でない場合、旧バージョンでインポートしたカードは形式が正しくなくなるので、ボタンの横で CC Switch の更新を促すとよいでしょう。


在你的网站上放「一键导入 CC Switch」按钮:站长接入指南

中文 | English | 日本語

如果你是站长,可以通过 CC Switch 让你的用户一键把你的供应商导入到 Claude Code、Codex 等 Agent 应用中使用。

适用版本:CC Switch v4.0.10 及以上。文中标了「v4.0.10 起」的行为在更早的版本上不同,差异见文末「兼容旧版本」。本文根据当前代码整理,示例里的域名和 Key 都是假的。

这篇写给谁

你运营一个 API 服务(中转站、聚合平台、自建网关都算),想让用户在你的控制台点一下按钮,就把你的地址、Key、模型,以及余额查询,一起加进 CC Switch,不用再手动填表。

这件事靠 ccswitch:// 深链接完成。用户的系统装了 CC Switch 之后,浏览器点到 ccswitch://... 链接会唤起 CC Switch,弹出导入确认框,用户核对后点「导入」。

用户手册里的 深度链接协议 是参数速查表;这篇讲站长真正要做的决定:链接怎么生成、哪些东西能带、哪些会被拒绝、怎么让用户导入后直接看到余额。

最快路径

你的站是用 New API 或 Sub2API 搭的?两者的 Key 列表里都自带「导入到 CC Switch」按钮,开箱即用,不用自己开发。区别在余额:New API 的链接不带用量查询脚本,用户导入后卡片上看不到余额;Sub2API 的链接带。想补上余额、带上你的图标,或者支持更多应用,再按这篇改。

大多数站长只要做三件事,按顺序读下面几节就够了:

  1. 读「先看结论」,再读「供应商链接」里的「最小的一条」「支持哪些应用」「常用参数」,定下给哪些应用生成链接、地址和格式怎么写。可以先在 在线生成器 里填表单生成一条,在自己电脑上点一下,看看确认框长什么样。
  2. 想让用户导入后看到余额,读「用量查询脚本」。NewAPI / OneAPI、Sub2API 系的站有现成脚本,照抄即可。
  3. 读「生成链接的代码」和「把链接放到按钮上」:后端按用户生成链接,前端放按钮。

折叠起来的几节(附带配置原文、会被拒绝的链接汇总、MCP / 提示词 / Skill)用到时再展开。

先看结论

  1. 链接要按用户生成。导入供应商时 API Key 是必填的,没有 Key 的链接会导入失败。所以「一键导入」按钮应该放在用户登录后的控制台里,由你的后端用这个用户自己的 Key 拼出链接,不要放在公开页面上。按钮怎么做见「把链接放到按钮上」。
  2. 用 apiFormat 声明你的接口格式。取值 anthropic、openai_chat、openai_responses、gemini_native,各应用支持哪几种见下文。不写时按应用的默认格式:Claude Code 是 Anthropic Messages,Codex 和 Grok Build 是 OpenAI Responses,OpenCode / OpenClaw / Hermes / Pi 是 OpenAI Chat Completions。
  3. 模型名按需写。中转站提供的是原版 Claude 模型时,Claude Code 的模型全部留空,Claude Code 会用自带的模型列表;只有 DeepSeek、Kimi 这类非原生模型才需要把 model、haikuModel、sonnetModel、opusModel 写上。OpenCode、OpenClaw、Hermes 的模型列表来自 model,不写就没有可选的模型;Pi 必须写。
  4. 想让用户看到余额,就带上用量查询脚本。v4.0.10 起,带了 usageScript 就默认启用;想兼容旧版本,同时写上 usageEnabled=true。脚本只能请求与供应商地址同源的 HTTPS 接口,详见下文。
  5. 「导入后立即切换」由用户决定。确认框里有这个开关,链接里的 enabled 只是开关的初始值。一般不用写。
  6. Base64 参数要再做 URL 转义。用 URLSearchParams 或等价函数拼链接,不要手工拼字符串。

链接的结构

text
ccswitch://v1/import?resource=<类型>&<参数>...
  • v1 是协议版本,/import 是固定路径,写错都会被拒绝。
  • resource 取 provider(供应商)、mcp、prompt(提示词)、skill 四者之一。
  • 参数名区分大小写,用驼峰:apiKey、usageScript,不是 api_key。

编码规则

有两层编码,顺序不能反:

  1. config、usageScript、content 这类「整段内容」的参数,先把 UTF-8 文本做 Base64 编码。标准 Base64 和 URL-safe Base64 都认,末尾的 = 可有可无。
  2. 拼进链接时,所有参数值再做一次 URL 转义(application/x-www-form-urlencoded 规则)。标准 Base64 里的 + 必须转成 %2B,否则会被解成空格。CC Switch 会尝试把空格还原成 +,但别依赖它。

URLSearchParams 会自动完成第 2 步。手写链接时最常见的错误就是漏了这一步。

布尔参数写 true / false,其他写法会被当成没写。

用户点了链接之后

  1. 浏览器询问「是否打开 CC Switch」,用户同意后 CC Switch 被唤起(没开着的话会先启动)。
  2. CC Switch 弹出导入确认框,展示链接里的全部内容:地址、打码后的 Key、模型、附带的配置原文、用量查询脚本全文。可疑的内容会标黄提示,例如指向本机或内网的地址、能改变进程加载行为的环境变量(NODE_OPTIONS、LD_PRELOAD 之类)、用 shell 执行整段命令的 MCP。
  3. 用户点「导入」后:
    • 供应商:加进对应应用的供应商列表。确认框底部有一个开关,初始值取链接里的 enabled,用户可以改:
      • Claude Code、Codex、Gemini CLI、Grok Build:开关是「导入后立即切换到这个供应商」,默认关闭。打开时确认框会提示「客户端请求会改发到上面的地址」。
      • OpenCode、OpenClaw、Hermes、Pi:这些应用可以同时放多个供应商,开关是「导入后立即添加到应用配置」(Pi 叫「启用」),默认打开;关掉则只保存在 CC Switch 的列表里。
    • MCP:立即写进 apps 里列出的每个应用的配置文件。
    • 提示词:加进提示词列表。确认框里有「导入后立即启用」开关,初始值取链接里的 enabled;打开时会替换这个应用当前的提示词文件,原来启用的提示词被停用。
    • Skill:添加的是 Skill 仓库,用户还要到「Skills」页选择安装哪些。

几个站长容易踩到的细节:

  • 链接只能由用户点击触发。页面加载时自动跳转 ccswitch:// 会被大多数浏览器拦下。
  • CC Switch 一次只处理一条链接;用户还没处理完上一条时又点了新的,只保留最新那条。不要设计成「一个按钮连续触发多条链接」,供应商、MCP、提示词各给一个按钮,让用户依次点。
  • 同一条供应商链接点两次会导入两份。供应商 ID 由名称加时间戳生成,不做去重。
  • 网页无法可靠地判断用户是否装了 CC Switch。按钮旁边写一句提示并附上下载地址,写法见「把链接放到按钮上」。

供应商链接

最小的一条

text
ccswitch://v1/import?resource=provider&app=claude&name=Example%20AI&endpoint=https%3A%2F%2Fapi.example.com&apiKey=sk-xxxx

必填的只有 app、name,以及地址和 Key(可以写在 URL 参数里,也可以写在附带的 config 里)。Pi 另外必须写 model。

支持哪些应用

app 应用 默认格式 可选的 apiFormat config 能带什么
claude Claude Code anthropic 四种都可以 {"env": {...}},env 里的变量全部保留
codex Codex openai_responses openai_responses、openai_chat、anthropic 整份或部分 config.toml,见下文
gemini Gemini CLI gemini_native 只有 gemini_native GEMINI_API_KEY、GOOGLE_GEMINI_BASE_URL、GEMINI_MODEL 三个键,其他忽略
grokbuild Grok Build openai_responses openai_responses、openai_chat、anthropic 一张 [model."<名称>"] 表,见下文
opencode OpenCode openai_chat 四种都可以 只取地址和 Key
openclaw OpenClaw openai_chat 四种都可以 只取地址和 Key
hermes Hermes openai_chat openai_chat、openai_responses、anthropic 只取地址和 Key
pi Pi openai_chat 四种都可以 只取地址和 Key

Claude Desktop、MiniMax Code 的供应商暂不支持深链接导入,链接会被拒绝。

apiFormat 在不同应用里落到不同的地方:

  • Claude Code、Codex、Grok Build:这三个客户端只会说自己的原生格式(Claude Code 是 Anthropic,另两个是 Responses)。写了非原生格式,导入的卡片会带「需要路由」标记,用户切过去时要开启本地路由,由 CC Switch 转换请求格式。
  • OpenCode、OpenClaw、Hermes、Pi:这些客户端自己支持多种格式,CC Switch 把 apiFormat 换算成它们配置里的协议字段(OpenCode 的 npm、OpenClaw / Pi 的 api、Hermes 的 api_mode),客户端直接用这种格式请求你的接口,不经过本地路由。

地址按所选格式的惯例写:Anthropic 格式在 Claude Code 里不带 /v1(如 https://api.example.com),OpenAI 两种格式一般带 /v1。OpenCode、OpenClaw、Hermes、Pi 的地址是各自 SDK 的 base URL,拼路径的方式不统一:同样是 Anthropic 格式,CC Switch 内置预设里 OpenCode 的地址带 /v1,Hermes 和 Pi 的不带。请为每个应用分别生成链接,地址以你在该应用里实测能通的写法为准。

常用参数

参数 说明
name 显示名,必填
endpoint 接口地址。可以用英文逗号分隔多个,第一个是主地址,其余加进「端点候选」供用户测速切换
apiKey API Key。URL 参数和 config 里都有时,以 URL 参数为准
apiFormat 接口格式,见上表。不写用应用的默认格式
model 默认模型。Claude Code 用原版 Claude 模型时留空;Codex 不写会用 gpt-5-codex,Grok Build 不写会用 grok-4.5;Pi 必填
haikuModel / sonnetModel / opusModel 仅 Claude Code:三档模型别名对应的真实模型名,非原生模型才需要
homepage 官网。不写时从地址推断(去掉 api. 前缀)
icon CC Switch 内置图标的名字,只能是小写字母、数字和 . _ -,其他写法会被丢掉;不认识的名字显示名称首字母。你的品牌没有内置图标时不用写
iconUrl 你自己的图标图片地址,见下文「带上你的图标」。下载失败时退回 icon
notes 备注,显示在供应商卡片上
enabled 确认框里「导入后立即切换 / 添加」开关的初始值,用户可以改。一般不用写
config + configFormat 附带配置原文,Base64。configFormat 取 json(默认)或 toml

configUrl(远程配置)还没实现,带了这个参数的链接会被直接拒绝。

带上你的图标:iconUrl

CC Switch 内置图标里没有你的品牌时,用 iconUrl 给一个图片地址。确认框一打开,CC Switch 就下载这张图并显示在顶部,用户导入后它就是卡片图标,不需要用户再点什么。

图片会被重新画成 96×96 的 PNG 存进 CC Switch,之后不再访问这个地址。你以后换了图标,已经导入的用户不会跟着变。

地址和图片要满足下面的条件,任何一条不满足,确认框不报错,图标退回 icon 指定的内置图标,没写 icon 就显示名称首字母:

  • https:// 开头,主机是域名(不能是 IP),默认端口,不带账号密码。形状不对的地址在解析链接时就被丢掉,链接其余部分照常导入。
  • 公开可访问:CC Switch 下载时不带 Cookie 和 Referer,也不走用户的系统代理。需要登录、开了防盗链的地址都会失败。
  • 域名解析到的地址必须是公网地址,指向内网、本机的一律不下载。
  • 5 秒内下载完,最多跟 3 次重定向,每次重定向的目标也要满足上面这些条件。
  • 不超过 256 KB。
  • 响应头 Content-Type 是 image/png、image/jpeg、image/webp 或 image/svg+xml 之一,并且和文件实际格式一致。application/octet-stream 之类的通用类型不行。
  • 位图宽高不超过 4096 像素。

图片本身的建议:

  • 用方形图。四角不透明的方图会铺满整个图标框;四角透明的 logo 会缩到中间,四周留白,和内置图标的样子一致。
  • SVG 只当图片显示,里面的脚本不执行,引用的外部字体、图片也不加载,文字请转成路径。
  • 每个用户打开确认框时都会请求一次这个地址,放在 CDN 上即可。

Claude Code:附带环境变量

需要额外环境变量(自定义请求头、超时等)时展开

需要额外环境变量的站(自定义请求头、超时、关闭实验特性等),把它们放进 config:

json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://api.example.com",
    "ANTHROPIC_AUTH_TOKEN": "sk-xxxx",
    "ANTHROPIC_MODEL": "example-sonnet",
    "API_TIMEOUT_MS": "600000",
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
  }
}

env 里的变量原样保留;地址、Key、模型名这几个,URL 参数里也写了的话以 URL 参数为准。确认框会把每个变量列出来,敏感值打码。

Codex:附带 config.toml

只有要带 wire_api、请求头、推理强度等额外设置时才需要,展开看收哪些键、拒绝哪些写法

两种写法:

  • configFormat=json,内容是 {"auth": {"OPENAI_API_KEY": "sk-xxxx"}, "config": "<config.toml 原文>"};
  • configFormat=toml,内容直接是 config.toml 原文。

CC Switch 不会把整份文件照搬进用户的 ~/.codex/config.toml,只收属于这个供应商的部分:

  • 选中的那张 [model_providers.] 表:model_provider 指向的那张;没写 model_provider 时文件里只能有一张。表里收这些键:name、base_url、wire_api、requires_openai_auth、experimental_bearer_token、model_catalog_url、capabilities、query_params、http_headers、request_max_retries、stream_max_retries、stream_idle_timeout_ms、websocket_connect_timeout_ms、supports_websockets、supports_standalone_web_search。
  • 顶层的模型相关字段:model、review_model、model_reasoning_effort、plan_mode_reasoning_effort、disable_response_storage、web_search、model_context_window、model_auto_compact_token_limit、model_supports_reasoning_summaries、model_verbosity,以及 [agents] 的子代理模型、[memories] 的记忆模型。

其他的一律不收:[features]、[tools]、MCP、sandbox、notify、其他供应商表等,这些是用户自己的全局设置。

导入后表名统一改成 custom(CC Switch 管理的 Codex 供应商都写在 [model_providers.custom]),base_url 和 experimental_bearer_token 用合并后的地址和 Key。model_catalog_url 必须与供应商地址同源,否则拒绝导入。

会被拒绝的写法:表里带 auth(让 Codex 执行命令取 Key)、aws、gateway_oauth(读本机云凭据)、env_http_headers(读环境变量)。env_key 会被丢掉,Key 一定要由链接自己给出;只写了 env_key、没给 Key 的链接会被拒绝。

示例(configFormat=toml):

toml
model_provider = "example"
model = "example-coder"
model_reasoning_effort = "high"

[model_providers.example]
name = "Example AI"
base_url = "https://api.example.com/v1"
wire_api = "responses"
http_headers = { "X-Client" = "cc-switch" }
stream_idle_timeout_ms = 300000

Grok Build:附带一张模型表

只有要带上下文窗口、采样参数等额外设置时才需要

写法同 Codex({"config": "<config.toml 原文>"} 或 configFormat=toml)。

只导入 [models] default 指向的那张 [model."<名称>"] 表;没写 default 时文件里只能有一张表,有多张又没写 default 会被拒绝。CC Switch 里一个 Grok Build 供应商只对应一张模型表,所以一条链接导入多个模型不支持。

表里保留显示名、description、api_backend、context_window、max_completion_tokens、采样和重试参数、推理强度相关字段等;地址、Key、模型名用链接参数(URL 参数优先)。表里没写 api_backend、context_window 时补默认值。

表里带 auth_provider、env_http_headers、mtls_cert_dir 的链接会被拒绝;env_key 处理同 Codex。

会被拒绝的链接,汇总

确认框报错时展开,按报错原文查原因

情况 确认框里的报错(英文原文,节选)
没给 Key API key is required
没给地址 Endpoint is required
地址不是 http / https Invalid URL scheme for 'endpoint[0]'
app 写成了不支持的值 Invalid provider app type
apiFormat 取值不对 Unsupported apiFormat
应用不支持这种 apiFormat is not supported for app
Pi 没写模型 Pi providers need a model
OpenCode / OpenClaw / Hermes / Pi 的名称、地址、Key、模型里带了会被客户端展开的写法(见下) uses syntax that … would expand
带了 configUrl 'configUrl' is not supported yet
Base64 解不开 config 参数 Base64 解码失败
Codex / Grok 只靠 env_key 给 Key supplies its API key indirectly
Codex 表里有 auth 等 cannot be imported from a link
Codex 目录地址与供应商地址不同源 model_catalog_url
Grok 有多张表但没写 default several [model.*] tables

OpenCode、OpenClaw、Hermes、Pi 读配置时会展开某些写法:Pi 的 Key 以 ! 开头会被当成命令执行,$NAME / ${NAME} 换成环境变量;OpenCode 的 {env:…} 读环境变量、{file:…} 读本机文件;OpenClaw、Hermes 的 ${…} 读环境变量。从链接导入时,这些写法一律拒绝。你的 Key 和地址本来就是字面值,不受影响。

让用户导入后直接看到余额:用量查询脚本

CC Switch 的供应商卡片可以显示余额或套餐用量,数据来自一段用量查询脚本。你把脚本放进链接,用户导入后就能直接看到。

脚本长什么样

脚本是一段 JavaScript 表达式,返回一个对象,包含 request(发什么请求)和 extractor(怎么从响应里取数):

javascript
({
  request: {
    url: "{{baseUrl}}/user/balance",
    method: "GET",
    headers: {
      "Authorization": "Bearer {{apiKey}}"
    }
  },
  extractor: function (response) {
    return {
      remaining: response.balance,
      unit: "USD"
    };
  }
})

运行前,CC Switch 会把脚本里的占位符替换成实际值:

占位符 替换成
{{apiKey}} usageApiKey;没给时用供应商的 API Key
{{baseUrl}} usageBaseUrl;没给时用供应商的主地址(去掉末尾 /)
{{accessToken}} usageAccessToken
{{userId}} usageUserId

注意 {{baseUrl}} 是供应商地址原样,如果它带了 /v1,拼出来就是 https://api.example.com/v1/user/balance。余额接口不在 /v1 下时,直接在脚本里写完整的 URL 即可,只要和地址同源。

extractor 收到的是解析后的响应 JSON,返回一个对象或对象数组(多个套餐时),字段都可选:

字段 类型 说明
remaining 数字 剩余额度
used 数字 已用
total 数字 总额度
unit 字符串 单位,如 USD、CNY、次
planName 字符串 套餐名
isValid 布尔 Key 是否有效;false 时卡片显示失效
invalidMessage 字符串 失效原因
extra 字符串 附加说明

运行限制

脚本是不可信输入,CC Switch 对它有硬限制:

  • 跑在 QuickJS 沙箱里,没有 fetch、文件、网络等任何能力;脚本本身只负责「描述请求」和「解析响应」,请求由 CC Switch 代发。
  • 每次查询只发一个请求,不能先登录再查询。
  • 请求必须是 HTTPS,且与 {{baseUrl}} 同源(同域名、同端口)。不同源的请求会被拒绝。余额接口在另一个域名时(比如控制台在 console.example.com,API 在 api.example.com),用 usageBaseUrl 指向控制台域名。
  • 响应必须是 JSON。
  • 请求由 CC Switch 从用户电脑上直接发出,不经过浏览器,你的余额接口不需要配置 CORS。接口要能用 API Key 认证;只能用登录态或系统访问令牌查询时,用 usageAccessToken 把令牌带进链接(见下面 NewAPI 一节)。
  • 脚本执行时间上限 5 秒,内存上限 16 MiB;HTTP 请求超时 10 秒。

启用与否

链接写法 导入后
带 usageScript,不写 usageEnabled 启用(v4.0.10 起;更早的版本不启用)
带 usageScript,usageEnabled=true 启用
带 usageScript,usageEnabled=false 不启用,用户可以在应用里手动打开
不带脚本 不启用

确认框会完整显示脚本正文和「已启用 / 未启用」标记。

usageAutoInterval 设自动查询间隔(分钟),0 或不写表示不定时查询。别设得太短,每个用户都会按这个频率打你的接口。

NewAPI / OneAPI 系的站

这类站的余额接口用的是系统访问令牌和用户 ID,不是 API Key。链接里带上 usageAccessToken 和 usageUserId:

javascript
({
  request: {
    url: "{{baseUrl}}/api/user/self",
    method: "GET",
    headers: {
      "Authorization": "Bearer {{accessToken}}",
      "New-Api-User": "{{userId}}"
    }
  },
  extractor: function (response) {
    if (response.success && response.data) {
      return {
        planName: response.data.group,
        remaining: response.data.quota / 500000,
        used: response.data.used_quota / 500000,
        unit: "USD"
      };
    }
    return { isValid: false, invalidMessage: response.message };
  }
})

500000 是 NewAPI 默认的额度换算比例,你改过的话按自己的值写。系统访问令牌的权限比 API Key 大,只在用户本人登录后生成的链接里放。

Sub2API 系的站

Sub2API 自带给 CC Switch 用的 GET /v1/usage 接口,用 API Key 认证,不需要 usageAccessToken。返回的顶层字段就是 CC Switch 认的 isValid、planName、remaining、unit,脚本基本照搬:

javascript
({
  request: {
    url: "{{baseUrl}}".replace(/\/+$/, "").replace(/\/v1$/, "") + "/v1/usage",
    method: "GET",
    headers: {
      "Authorization": "Bearer {{apiKey}}",
      "User-Agent": "cc-switch/1.0"
    }
  },
  extractor: function (response) {
    var quota = response.quota || {};
    var result = {
      isValid: response.isValid !== false,
      unit: response.unit || quota.unit || "USD"
    };
    if (typeof response.planName === "string") result.planName = response.planName;
    if (typeof response.remaining === "number" && response.remaining >= 0) {
      result.remaining = response.remaining;
    }
    if (quota.limit > 0) {
      result.used = quota.used;
      result.total = quota.limit;
    }
    if (!result.isValid) {
      result.invalidMessage = response.status
        ? String(response.status)
        : "查询失败";
    }
    return result;
  },
})
  • Codex、Grok Build 的供应商地址带 /v1,Claude Code 的不带。脚本先去掉末尾的 /v1 再拼接,所以各个应用通用,不用写 usageBaseUrl。
  • 三种情况都有 remaining:钱包余额(planName 是「钱包余额」)、订阅分组(planName 是分组名,取日 / 周 / 月限额里剩得最少的那个)、Key 单独设了总额度(另有 quota.used 和 quota.limit)。订阅分组没设任何限额时 remaining 是 -1,表示不限量,脚本不显示这个数。
  • 响应里还有 rate_limits(Key 的 5 小时 / 1 天 / 7 天窗口)和 subscription(分组的日 / 周 / 月用量和限额)。想在卡片上分行显示,可以让 extractor 返回数组,每个元素一行。
  • 这份脚本和 CC Switch 应用内「配置用量查询」的 Sub2API 模板(v4.0.10 起)完全一样,用户手动添加你的站时也能一键选用。
  • Sub2API 后台「导入到 CC Switch」按钮生成的链接自带一份查询脚本,用了 ?. 和 ?? 写法,CC Switch 也能运行,但订阅分组不限量时会显示 -1。

MCP、提示词、Skill 链接

和 API 服务关系不大,顺带分发配套工具时展开

这三类和你的 API 服务关系不大,但有的站会顺带分发配套工具,简单列一下要点。

MCP(resource=mcp)

  • apps 必填,逗号分隔:claude、codex、gemini、grokbuild、opencode、hermes、pi、mcode。openclaw 会被忽略。
  • config 是 Base64 的 {"mcpServers": {"": {...}}},一条链接可以带多个服务器。
  • 用户已经有同 ID 的服务器时,只会给它勾上新的应用,配置内容不会被链接覆盖。想更新配置请换一个 ID。
  • 导入即写入客户端配置文件。enabled 参数目前不起作用。

提示词(resource=prompt)

  • app 取 claude、codex、gemini、grokbuild、opencode、pi、mcode。openclaw、hermes 在 CC Switch 里由工作区编辑器和记忆管理负责,不建议用深链接分发提示词。
  • name、content(Base64 的 Markdown)必填,description 可选。
  • enabled 是确认框里「导入后立即启用」开关的初始值。启用会用这段内容替换用户当前的提示词文件(如 CLAUDE.md),一般不要写。

Skill(resource=skill)

  • repo 必填,格式 owner/name,必须是 GitHub 上的公开仓库;branch 默认 main。
  • 添加的是仓库,用户还要自己选择安装哪些 Skill。directory 参数目前会被忽略。

生成链接的代码

后端(Node.js)

javascript
function b64(text) {
  return Buffer.from(text, "utf8").toString("base64");
}

const usageScript = `({
  request: {
    url: "{{baseUrl}}/user/balance",
    method: "GET",
    headers: { "Authorization": "Bearer {{apiKey}}" }
  },
  extractor: function (r) {
    return { remaining: r.balance, unit: "USD" };
  }
})`;

function claudeImportLink(user) {
  const params = new URLSearchParams({
    resource: "provider",
    app: "claude",
    name: "Example AI",
    endpoint: "https://api.example.com",
    apiKey: user.apiKey,
    // 提供原版 Claude 模型时模型全部留空;DeepSeek、Kimi 这类非原生模型才写
    // model / haikuModel / sonnetModel / opusModel
    homepage: "https://example.com",
    // 内置图标里没有你的品牌时,给一个自己的图标地址,见「带上你的图标」
    iconUrl: "https://example.com/static/logo.png",
    usageScript: b64(usageScript),
    usageEnabled: "true",
  });
  return `ccswitch://v1/import?${params}`;
}

给 OpenCode 生成一条 Anthropic 格式的链接,只是换 app 和 apiFormat,再带上模型:

javascript
const params = new URLSearchParams({
  resource: "provider",
  app: "opencode",
  name: "Example AI",
  endpoint: "https://api.example.com/v1",
  apiKey: user.apiKey,
  apiFormat: "anthropic",
  model: "claude-sonnet-5-5",
});

后端(Python)

python
import base64
from urllib.parse import urlencode

def b64(text: str) -> str:
    return base64.b64encode(text.encode("utf-8")).decode("ascii")

codex_toml = """\
model_provider = "example"
model = "example-coder"

[model_providers.example]
name = "Example AI"
base_url = "https://api.example.com/v1"
wire_api = "responses"
"""

def codex_import_link(api_key: str) -> str:
    params = {
        "resource": "provider",
        "app": "codex",
        "name": "Example AI",
        "apiKey": api_key,
        "configFormat": "toml",
        "config": b64(codex_toml),
    }
    return "ccswitch://v1/import?" + urlencode(params)

urlencode 默认把空格转成 +、把 + 转成 %2B,和 CC Switch 的解析规则一致。

浏览器里生成

浏览器的 btoa 不支持中文等非 ASCII 字符,要先转 UTF-8:

javascript
function b64(text) {
  const bytes = new TextEncoder().encode(text);
  let binary = "";
  bytes.forEach((b) => (binary += String.fromCharCode(b)));
  return btoa(binary);
}

能在后端生成就在后端生成,Key 不经过前端 JavaScript 更好。

把链接放到按钮上

推荐的流程:

  1. 按钮本身不带链接。用户点击时,前端向你的后端请求这个用户的链接。
  2. 后端确认用户已登录,用这个用户自己的 Key 生成链接返回(用上一节的生成函数)。
  3. 前端拿到链接后执行 window.location.href = link。浏览器询问是否打开 CC Switch,用户同意后弹出导入确认框。

这样链接不会写进页面源码,只在用户真的点了按钮时生成一次。

后端:按用户返回链接

以 Node.js(Express)为例。claudeImportLink 是上一节的生成函数,codexImportLink 照同样的写法另写一个:

javascript
const builders = {
  claude: claudeImportLink,
  codex: codexImportLink,
};

app.post("/api/ccswitch-link", requireLogin, (req, res) => {
  const build = builders[req.body.app];
  if (!build) return res.status(400).json({ error: "unsupported app" });
  // 响应里有用户的 Key:不缓存,也别打进日志
  res.set("Cache-Control", "no-store");
  res.json({ link: build(req.user) });
});

用 POST,不用 GET:GET 请求可能被浏览器预取、被缓存,或者带着参数出现在访问日志里。

前端:按钮和提示

html
<button type="button" onclick="importToCcSwitch('claude')">导入到 Claude Code</button>
<button type="button" onclick="importToCcSwitch('codex')">导入到 Codex</button>
<p class="hint">
  浏览器会先询问是否打开 CC Switch,请选「打开」。点了没有任何反应?可能还没安装,
  先<a href="https://ccswitch.io" target="_blank" rel="noopener">下载 CC Switch</a>,装好后再点一次。
</p>

<script>
  async function importToCcSwitch(app) {
    const res = await fetch("/api/ccswitch-link", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ app }),
    });
    if (!res.ok) {
      alert("生成导入链接失败,请稍后再试");
      return;
    }
    const { link } = await res.json();
    window.location.href = link;
  }
</script>

几点说明:

  • 跳转要紧跟着点击。浏览器只放行用户点击触发的外部应用唤起,有的浏览器在点击后隔得太久就不再算作点击触发。接口应在一两秒内返回;不要在拿到链接后再弹一个确认框,让用户再点一次。
  • 一条链接只导入到一个应用。同时支持几个应用时,每个应用放一个按钮,或者先让用户选择客户端,再点同一个「导入」按钮。每个应用的地址和格式可能不同,见「支持哪些应用」。
  • 没装 CC Switch 时浏览器通常什么都不提示,网页也无法可靠地判断。所以按钮旁边的那句提示要一直显示,不要等检测结果。
  • 同一个按钮被点两次会导入两份。用户点完一次后,可以把按钮改成「已发送到 CC Switch」,或者暂时禁用几秒。

安全与隐私

  • 带 Key 的链接等同于 Key 本身。直接写进按钮 href 的链接会出现在页面源码里,可能被浏览器插件读到;按「把链接放到按钮上」的做法,在用户点击时才向后端要链接,可以避免这一点。只在用户登录后的页面生成,不要写进公开页面、邮件群发或社群公告;不要让它进入你的访问日志和第三方统计。
  • 链接越短越好。整份 config 很长时,Windows 下传给 CC Switch 的命令行有约 3.2 万字符的上限,超长的链接打不开。
  • CC Switch 对链接内容做的是白名单过滤和醒目提示,不是替用户背书。确认框显示的每一项用户都能看到,别在里面放和你的服务无关的东西,用户会因此不信任这个按钮。

调试

  1. 先在自己电脑上点一遍,看确认框里的每一项是否符合预期,再导入、切换、发一条消息。
  2. 确认框直接报错时,错误信息就是原因,对照上面「会被拒绝的链接」排查。
  3. 导入成功但余额不显示:在供应商卡片上打开「配置用量查询」,点「测试脚本」看报什么错。最常见的是请求地址不同源、余额接口返回的不是 JSON、extractor 里取错了字段。
  4. 导入成功但切过去后请求失败:多半是接口格式不对(见「支持哪些应用」),或模型名不对。
  5. iconUrl 的图标没显示:下载失败不会报错,原因写在 CC Switch 的日志里(~/.cc-switch/logs/cc-switch.log,搜 Skipped deep link icon)。最常见的是 Content-Type 不对、图片超过 256 KB、地址要登录或开了防盗链,用 curl -I 看一下响应头。

兼容旧版本

你的用户不一定都升级到了最新版。下面这些行为在旧版本上不同:

行为 v4.0.10 起 v3.19.0 – v4.0.9
带脚本、不写 usageEnabled 启用 不启用
Codex 附带的 config.toml 按白名单收下供应商表和模型字段 只取地址、Key 和模型名,其余丢弃,按固定模板重建
Grok Build 附带的模型表 收下选中表的字段 只取地址、Key 和模型名
CC Switch 没开着时点链接 启动后弹出确认框 偶尔丢失,要再点一次
apiFormat 按应用换算 忽略,一律用默认格式
app=pi 支持 拒绝导入
iconUrl 下载并作为卡片图标 忽略,显示 icon 或名称首字母
「导入后立即切换 / 启用」 确认框里的开关,enabled 是初始值 直接按链接的 enabled 执行;OpenCode / OpenClaw / Hermes 总是写进应用配置

想让各个版本表现一致:用量查询显式写 usageEnabled=true;Codex / Grok Build 的关键信息(地址、Key、模型)同时写进 URL 参数,不要只放在 config 里。你的接口不是应用的默认格式时,旧版本导入的卡片格式会不对,可以在按钮旁提示用户升级 CC Switch。


Release Notes V3.10.0 En (`docs/release-notes/v3.10.0-en.md`)

CC Switch v3.10.0

OpenCode Support, Global Proxy, Claude Rectifier & Multi-App Experience Enhancements

中文版 → | 日本語版 →


Overview

CC Switch v3.10.0 introduces OpenCode support, becoming the fourth managed CLI application.
This release also brings global proxy settings, Claude Rectifier (thinking signature fixer), enhanced health checks, per-provider configuration, and many other important features, along with comprehensive improvements to multi-app workflows and terminal experience.

Release Date: 2026-01-21


Highlights

  • OpenCode Support: Full management of providers, MCP servers, and Skills with auto-import on first launch
  • Global Proxy: Configure a unified proxy for all outbound network requests
  • Claude Rectifier: Thinking signature fixer for better compatibility with third-party APIs
  • Enhanced Health Checks: Configurable prompts and CLI-compatible request format
  • Per-Provider Config: Persistent provider-specific configuration support
  • App Visibility Control: Freely show/hide apps with synchronized tray menu updates
  • Terminal Improvements: Provider-specific terminal buttons, fnm path support, cross-platform safe launch
  • WSL Tool Detection: Detect tool versions in WSL environment with security hardening

Main Features

OpenCode Support (New Fourth App)

  • Complete OpenCode provider management: add, edit, switch, delete
  • MCP server management: unified architecture with Claude/Codex/Gemini
  • Skills support: OpenCode can also use Skills functionality
  • Auto-import on first launch: automatically imports existing OpenCode configuration when detected
  • Full internationalization: Chinese/English/Japanese support (#695)

Global Proxy

  • Configure a unified proxy for all outbound network requests (#596, thanks @yovinchen)
  • Supports HTTP/HTTPS proxy protocols
  • Suitable for network environments requiring proxy access to external APIs

Claude Rectifier (Thinking Signature Fixer)

  • Automatically fixes Claude API thinking signatures (#595, thanks @yovinchen)
  • Resolves incompatible thinking block formats returned by some third-party API gateways
  • Can be enabled/disabled in Advanced Settings

Enhanced Health Checks

  • Configurable custom prompts for streaming health checks (#623, thanks @yovinchen)
  • Supports CLI-compatible request format for better simulation of real usage scenarios
  • Improves fault detection accuracy

Per-Provider Config

  • Support for saving configuration separately for each provider (#663, thanks @yovinchen)
  • Persistent configuration: provider-specific settings retained after restart
  • Suitable for scenarios where different providers require different configurations

App Visibility Control

  • Freely show/hide any app (Gemini hidden by default)
  • Tray menu automatically syncs visibility settings
  • Hidden apps won't appear in the main interface or tray menu

Takeover Compact Mode

  • Automatically uses compact layout when 3 or more visible apps are displayed
  • Optimizes space utilization in multi-app scenarios

Terminal Improvements

  • Provider-specific terminal button: one-click to use current provider in terminal (#564, thanks @kkkman22)
  • fnm path support: automatically recognizes Node.js paths managed by fnm
  • Cross-platform safe launch: improved terminal launch logic for Windows/macOS/Linux

WSL Tool Detection

  • Detect tool versions in WSL environment (#627, thanks @yovinchen)
  • Added security hardening to prevent command injection risks

Skills Preset Enhancements

  • Added baoyu-skills preset repository
  • Automatically supplements missing default repositories for out-of-the-box experience

Experience Improvements

  • Keyboard shortcuts: Press ESC to quickly return/close panels (#670, thanks @xxk8)
  • Simplified proxy logs: cleaner and more readable output (#585, thanks @yovinchen)
  • Pricing editor UX: unified FullScreenPanel style
  • Advanced settings layout: Rectifier section moved below Failover for better logical flow
  • OpenRouter compatibility mode: disabled by default, UI toggle hidden (reduces clutter)

Bug Fixes

Proxy & Failover

  • Immediately switch to P1 when auto-failover is enabled (instead of waiting for next request)

Provider Management

  • Fixed stale data when reopening provider edit dialog after save (#654, thanks @YangYongAn)
  • Fixed baseUrl and apiKey state not resetting when switching presets
  • Fixed endpoint auto-selection state not persisting (#611, thanks @yovinchen)
  • Automatically apply default color when icon color is not set
  • Support multi-endpoint import (#597, thanks @yovinchen)
  • Prefer GOOGLE_GEMINI_BASE_URL over GEMINI_BASE_URL

MCP

  • Skip cmd /c wrapper for WSL target paths (#592, thanks @cxyfer)

Usage Templates

  • Added variable hints, fixed validation issues (#628, thanks @YangYongAn)
  • Prevent configuration leakage between providers
  • Usage block offset automatically adapts to action button width (#613, thanks @yovinchen)

Gemini

  • Convert timeout parameters to Gemini CLI format (#580, thanks @cxyfer)

UI

  • Fixed Select dropdown rendering issues in FullScreenPanel

Notes & Considerations

  • OpenCode is a newly supported app: OpenCode CLI must be installed first to use related features.
  • Global proxy affects all outbound requests: including usage queries, health checks, and other network operations.
  • Rectifier is experimental: can be disabled in Advanced Settings if issues occur.

Special Thanks

Thanks to @yovinchen @YangYongAn @cxyfer @xxk8 @kkkman22 @Shuimo03 for their contributions to this release!
Thanks to @libukai for designing the elegant failover-related UI!


Download & Installation

Visit Releases to download the appropriate version.

System Requirements

System Minimum Version Architecture
Windows Windows 10 or later x64
macOS macOS 10.15 (Catalina) or later Intel (x64) / Apple Silicon (arm64)
Linux See table below x64

Windows

File Description
CC-Switch-v3.10.0-Windows.msi Recommended - MSI installer with auto-update
CC-Switch-v3.10.0-Windows-Portable.zip Portable version, extract and run, no registry write

macOS

File Description
CC-Switch-v3.10.0-macOS.zip Recommended - Extract and drag to Applications, Universal Binary
CC-Switch-v3.10.0-macOS.tar.gz For Homebrew installation and auto-update

Note: Since the author doesn't have an Apple Developer account, you may see an "unidentified developer" warning on first launch. Please close it, then go to "System Settings" → "Privacy & Security" → click "Open Anyway", and it will open normally afterwards.

Homebrew (macOS)

bash
brew tap farion1231/ccswitch
brew install --cask cc-switch

Update:

bash
brew upgrade --cask cc-switch

Linux

Distribution Recommended Format Installation Method
Ubuntu / Debian / Linux Mint / Pop!_OS .deb sudo dpkg -i CC-Switch-*.deb or sudo apt install ./CC-Switch-*.deb
Fedora / RHEL / CentOS / Rocky Linux .rpm sudo rpm -i CC-Switch-*.rpm or sudo dnf install ./CC-Switch-*.rpm
openSUSE .rpm sudo zypper install ./CC-Switch-*.rpm
Arch Linux / Manjaro .AppImage Add execute permission and run directly, or use AUR
Other distributions / Unsure .AppImage chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage

Release Notes V3.10.0 Ja (`docs/release-notes/v3.10.0-ja.md`)

CC Switch v3.10.0

OpenCode サポート、グローバルプロキシ、Claude Rectifier とマルチアプリ体験の強化

中文版 → | English →


概要

CC Switch v3.10.0 では OpenCode サポートが追加され、4番目の管理対象 CLI アプリケーションとなりました。
また、グローバルプロキシ設定、Claude Rectifier(thinking 署名修正機能)、ヘルスチェックの強化、プロバイダー別設定など、多くの重要な機能が追加され、マルチアプリワークフローとターミナル体験が全面的に改善されました。

リリース日: 2026-01-21


ハイライト

  • OpenCode サポート:プロバイダー、MCP サーバー、Skills の完全管理、初回起動時の自動インポート
  • グローバルプロキシ:すべての送信ネットワークリクエストに統一プロキシを設定
  • Claude Rectifier:thinking 署名修正機能、サードパーティ API との互換性向上
  • ヘルスチェック強化:カスタムプロンプト設定、CLI 互換リクエスト形式
  • プロバイダー別設定:プロバイダー固有の設定の永続化をサポート
  • アプリ表示制御:アプリの表示/非表示を自由に設定、トレイメニューと同期
  • ターミナル改善:プロバイダー専用ターミナルボタン、fnm パスサポート、クロスプラットフォーム安全起動
  • WSL ツール検出:WSL 環境でのツールバージョン検出とセキュリティ強化

主な機能

OpenCode サポート(新しい4番目のアプリ)

  • 完全な OpenCode プロバイダー管理:追加、編集、切り替え、削除
  • MCP サーバー管理:Claude/Codex/Gemini と統一されたアーキテクチャ
  • Skills サポート:OpenCode でも Skills 機能を使用可能
  • 初回起動時の自動インポート:既存の OpenCode 設定を検出すると自動的にインポート
  • 完全な国際化:中国語/英語/日本語サポート (#695)

グローバルプロキシ

  • すべての送信ネットワークリクエストに統一プロキシを設定 (#596、@yovinchen に感謝)
  • HTTP/HTTPS プロキシプロトコルをサポート
  • 外部 API へのプロキシアクセスが必要なネットワーク環境に適用

Claude Rectifier(Thinking 署名修正機能)

  • Claude API の thinking 署名を自動修正 (#595、@yovinchen に感謝)
  • 一部のサードパーティ API ゲートウェイが返す互換性のない thinking ブロック形式を解決
  • 詳細設定で有効/無効を切り替え可能

ヘルスチェック強化

  • ストリーミングヘルスチェック用のカスタムプロンプトを設定可能 (#623、@yovinchen に感謝)
  • CLI 互換リクエスト形式をサポートし、実際の使用シナリオをより良くシミュレート
  • 障害検出の精度を向上

プロバイダー別設定

  • 各プロバイダーごとに設定を個別に保存可能 (#663、@yovinchen に感謝)
  • 設定の永続化:再起動後もプロバイダー固有の設定を保持
  • 異なるプロバイダーに異なる設定が必要なシナリオに適用

アプリ表示制御

  • 任意のアプリを自由に表示/非表示(Gemini はデフォルトで非表示)
  • トレイメニューは表示設定と自動的に同期
  • 非表示のアプリはメインインターフェースとトレイメニューに表示されない

Takeover コンパクトモード

  • 3つ以上の表示アプリがある場合、自動的にコンパクトレイアウトを使用
  • マルチアプリシナリオでのスペース利用を最適化

ターミナル改善

  • プロバイダー専用ターミナルボタン:ワンクリックでターミナルで現在のプロバイダーを使用 (#564、@kkkman22 に感謝)
  • fnm パスサポート:fnm で管理された Node.js パスを自動認識
  • クロスプラットフォーム安全起動:Windows/macOS/Linux のターミナル起動ロジックを改善

WSL ツール検出

  • WSL 環境でツールバージョンを検出 (#627、@yovinchen に感謝)
  • コマンドインジェクションリスクを防ぐためのセキュリティ強化を追加

Skills プリセット強化

  • baoyu-skills プリセットリポジトリを追加
  • 不足しているデフォルトリポジトリを自動補完し、すぐに使える状態を確保

体験の改善

  • キーボードショートカット:ESC を押してパネルをすばやく戻る/閉じる (#670、@xxk8 に感謝)
  • プロキシログの簡素化:より明確で読みやすい出力 (#585、@yovinchen に感謝)
  • 価格エディター UX:統一された FullScreenPanel スタイル
  • 詳細設定レイアウト:Rectifier セクションを Failover の下に移動し、論理的な流れを改善
  • OpenRouter 互換モード:デフォルトで無効、UI トグルを非表示(煩雑さを軽減)

バグ修正

プロキシとフェイルオーバー

  • 自動フェイルオーバーが有効な場合、すぐに P1 に切り替え(次のリクエストを待たずに)

プロバイダー管理

  • 保存後にプロバイダー編集ダイアログを再度開いたときにデータが古い問題を修正 (#654、@YangYongAn に感謝)
  • プリセット切り替え時に baseUrl と apiKey の状態がリセットされない問題を修正
  • エンドポイント自動選択状態が永続化されない問題を修正 (#611、@yovinchen に感謝)
  • アイコンカラーが設定されていない場合、デフォルトカラーを自動適用

ディープリンク

  • マルチエンドポイントインポートをサポート (#597、@yovinchen に感謝)
  • GEMINI_BASE_URL より GOOGLE_GEMINI_BASE_URL を優先

MCP

  • WSL ターゲットパスの cmd /c ラッパーをスキップ (#592、@cxyfer に感謝)

使用量テンプレート

  • 変数ヒントを追加、検証の問題を修正 (#628、@YangYongAn に感謝)
  • プロバイダー間での設定漏洩を防止
  • 使用量ブロックのオフセットがアクションボタンの幅に自動適応 (#613、@yovinchen に感謝)

Gemini

  • タイムアウトパラメータを Gemini CLI 形式に変換 (#580、@cxyfer に感謝)

UI

  • FullScreenPanel での Select ドロップダウンのレンダリング問題を修正

注意事項

  • OpenCode は新しくサポートされたアプリです:関連機能を使用するには、まず OpenCode CLI をインストールする必要があります。
  • グローバルプロキシはすべての送信リクエストに影響します:使用量クエリ、ヘルスチェックなどのネットワーク操作を含みます。
  • Rectifier は実験的機能です:問題が発生した場合は、詳細設定で無効にできます。

特別な感謝

@yovinchen @YangYongAn @cxyfer @xxk8 @kkkman22 @Shuimo03 の皆様、このリリースへの貢献に感謝します!
@libukai 様、エレガントなフェイルオーバー関連 UI のデザインに感謝します!


ダウンロードとインストール

Releases から適切なバージョンをダウンロードしてください。

システム要件

システム 最小バージョン アーキテクチャ
Windows Windows 10 以降 x64
macOS macOS 10.15 (Catalina) 以降 Intel (x64) / Apple Silicon (arm64)
Linux 下表参照 x64

Windows

ファイル 説明
CC-Switch-v3.10.0-Windows.msi 推奨 - MSI インストーラー、自動更新対応
CC-Switch-v3.10.0-Windows-Portable.zip ポータブル版、解凍して実行、レジストリ書き込みなし

macOS

ファイル 説明
CC-Switch-v3.10.0-macOS.zip 推奨 - 解凍して Applications にドラッグ、Universal Binary
CC-Switch-v3.10.0-macOS.tar.gz Homebrew インストールと自動更新用

注意:作者が Apple Developer アカウントを持っていないため、初回起動時に「開発元を確認できません」という警告が表示される場合があります。一度閉じてから、「システム設定」→「プライバシーとセキュリティ」→「このまま開く」をクリックすると、その後は正常に開けます。

Homebrew (macOS)

bash
brew tap farion1231/ccswitch
brew install --cask cc-switch

更新:

bash
brew upgrade --cask cc-switch

Linux

ディストリビューション 推奨形式 インストール方法
Ubuntu / Debian / Linux Mint / Pop!_OS .deb sudo dpkg -i CC-Switch-*.deb または sudo apt install ./CC-Switch-*.deb
Fedora / RHEL / CentOS / Rocky Linux .rpm sudo rpm -i CC-Switch-*.rpm または sudo dnf install ./CC-Switch-*.rpm
openSUSE .rpm sudo zypper install ./CC-Switch-*.rpm
Arch Linux / Manjaro .AppImage 実行権限を追加して直接実行、または AUR を使用
その他のディストリビューション / 不明 .AppImage chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage

Release Notes V3.10.0 Zh (`docs/release-notes/v3.10.0-zh.md`)

CC Switch v3.10.0

OpenCode 支持、全局代理、Claude Rectifier 与多应用体验增强

English → | 日本語版 →


概览

CC Switch v3.10.0 新增 OpenCode 支持,成为第四个受管理的 CLI 应用。
同时带来全局代理设置、Claude Rectifier(thinking 签名修正器)、健康检查增强、按供应商配置等多项重要功能,并对多应用工作流与终端体验做了全面改进。

发布日期:2026-01-21


重点内容

  • OpenCode 支持:供应商、MCP 服务器、Skills 全面管理,首次启动自动导入
  • 全局代理:为出站网络请求统一配置代理
  • Claude Rectifier:thinking 签名修正器,兼容更多第三方 API
  • 健康检查增强:可配置提示词、CLI 兼容请求
  • 按供应商配置:支持供应商特定配置的持久化
  • 应用可见性控制:自由显示/隐藏应用,托盘菜单同步更新
  • 终端改进:供应商专属终端按钮、fnm 路径支持、跨平台安全启动
  • WSL 工具检测:在 WSL 环境检测工具版本,并增加安全加固

主要功能

OpenCode 支持(新增第四应用)

  • 完整的 OpenCode 供应商管理:新增、编辑、切换、删除
  • MCP 服务器管理:与 Claude/Codex/Gemini 统一架构
  • Skills 支持:OpenCode 也可使用 Skills 功能
  • 首次启动自动导入:检测到已有 OpenCode 配置时自动导入
  • 完整国际化:中/英/日三语支持(#695)

全局代理(Global Proxy)

  • 为所有出站网络请求配置统一代理(#596,感谢 @yovinchen)
  • 支持 HTTP/HTTPS 代理协议
  • 适用于需要代理访问外部 API 的网络环境

Claude Rectifier(Thinking 签名修正器)

  • 自动修正 Claude API 的 thinking 签名(#595,感谢 @yovinchen)
  • 解决部分第三方 API 网关返回的 thinking 块格式不兼容问题
  • 在高级设置中可开启/关闭

健康检查增强

  • 可配置自定义提示词(prompt)用于流式健康检查(#623,感谢 @yovinchen)
  • 支持 CLI 兼容请求格式,更好地模拟真实使用场景
  • 提升故障检测的准确性

按供应商配置(Per-Provider Config)

  • 支持为每个供应商单独保存配置(#663,感谢 @yovinchen)
  • 配置持久化:重启后保留供应商专属设置
  • 适用于不同供应商需要不同配置的场景

应用可见性控制

  • 自由显示/隐藏任意应用(Gemini 默认隐藏)
  • 托盘菜单自动同步可见性设置
  • 隐藏的应用不会出现在主界面和托盘菜单中

Takeover Compact Mode

  • 当显示 3 个及以上可见应用时,自动使用紧凑布局
  • 优化多应用场景下的空间利用

终端改进

  • 供应商专属终端按钮:一键在终端中使用当前供应商(#564,感谢 @kkkman22)
  • fnm 路径支持:自动识别 fnm 管理的 Node.js 路径
  • 跨平台安全启动:改进 Windows/macOS/Linux 的终端启动逻辑

WSL 工具检测

  • 在 WSL 环境中检测工具版本(#627,感谢 @yovinchen)
  • 增加安全加固,防止命令注入风险

Skills 预设增强

  • 新增 baoyu-skills 预设仓库
  • 自动补充缺失的默认仓库,确保开箱即用

体验优化

  • 键盘快捷键:按 ESC 快速返回/关闭面板(#670,感谢 @xxk8)
  • 代理日志简化:输出更清晰易读(#585,感谢 @yovinchen)
  • 定价编辑器 UX:统一使用 FullScreenPanel 风格
  • 高级设置布局:Rectifier 区块移至 Failover 下方,逻辑更顺畅
  • OpenRouter 兼容模式:默认禁用,UI 开关隐藏(减少干扰)

Bug 修复

代理与故障切换

  • 启用自动故障切换时立即切换到 P1(而非等待下次请求)

供应商管理

  • 修复供应商编辑对话框保存后重新打开时数据过时的问题(#654,感谢 @YangYongAn)
  • 修复切换预设时 baseUrl 和 apiKey 状态未重置的问题
  • 修复端点自动选择状态未持久化的问题(#611,感谢 @yovinchen)
  • 未设置图标颜色时自动应用默认颜色

深链接

  • 支持多端点导入(#597,感谢 @yovinchen)
  • 优先使用 GOOGLE_GEMINI_BASE_URL 而非 GEMINI_BASE_URL

MCP

  • WSL 目标路径跳过 cmd /c 包裹(#592,感谢 @cxyfer)

用量模板

  • 新增变量提示,修复验证问题(#628,感谢 @YangYongAn)
  • 防止配置在供应商之间泄漏
  • 用量区块偏移量根据操作按钮宽度自动适应(#613,感谢 @yovinchen)

Gemini

  • 超时参数转换为 Gemini CLI 格式(#580,感谢 @cxyfer)

UI

  • 修复 FullScreenPanel 中 Select 下拉框渲染问题

说明与注意事项

  • OpenCode 为新支持的应用:需要先安装 OpenCode CLI 才能使用相关功能。
  • 全局代理会影响所有出站请求:包括用量查询、健康检查等网络操作。
  • Rectifier 功能为实验性:如遇问题可在高级设置中关闭。

特别感谢

感谢 @yovinchen @YangYongAn @cxyfer @xxk8 @kkkman22 @Shuimo03 为本版本做出的贡献!
感谢 @libukai 设计的故障转移相关 UI,非常优雅!


下载与安装

访问 Releases 下载对应版本。

系统要求

系统 最低版本 架构
Windows Windows 10 及以上 x64
macOS macOS 10.15 (Catalina) 及以上 Intel (x64) / Apple Silicon (arm64)
Linux 见下表 x64

Windows

文件 说明
CC-Switch-v3.10.0-Windows.msi 推荐 - MSI 安装包,支持自动更新
CC-Switch-v3.10.0-Windows-Portable.zip 便携版,解压即用,不写入注册表

macOS

文件 说明
CC-Switch-v3.10.0-macOS.zip 推荐 - 解压后拖入 Applications 即可,Universal Binary
CC-Switch-v3.10.0-macOS.tar.gz 用于 Homebrew 安装和自动更新

注意:由于作者没有苹果开发者账号,首次打开可能出现"未知开发者"警告,请先关闭,然后前往"系统设置" → "隐私与安全性" → 点击"仍要打开",之后便可以正常打开

Homebrew(macOS)

bash
brew tap farion1231/ccswitch
brew install --cask cc-switch

更新:

bash
brew upgrade --cask cc-switch

Linux

发行版 推荐格式 安装方式
Ubuntu / Debian / Linux Mint / Pop!_OS .deb sudo dpkg -i CC-Switch-*.deb 或 sudo apt install ./CC-Switch-*.deb
Fedora / RHEL / CentOS / Rocky Linux .rpm sudo rpm -i CC-Switch-*.rpm 或 sudo dnf install ./CC-Switch-*.rpm
openSUSE .rpm sudo zypper install ./CC-Switch-*.rpm
Arch Linux / Manjaro .AppImage 添加执行权限后直接运行,或使用 AUR
其他发行版 / 不确定 .AppImage chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage

Release Notes V3.11.0 En (`docs/release-notes/v3.11.0-en.md`)

CC Switch v3.11.0

OpenClaw Support, Session Manager, Backup Management & 50+ Improvements

中文版 → | 日本語版 →


Overview

CC Switch v3.11.0 is a major update that adds full management support for OpenClaw as the fifth application, introduces a new Session Manager and Backup Management feature. Additionally, Oh My OpenCode (OMO) integration, the partial key-field merging architecture upgrade for provider switching, settings page refactoring, and many other improvements make the overall experience more polished.

Release Date: 2026-02-26

Update Scale: 147 commits | 274 files changed | +32,179 / -5,467 lines


Highlights

  • OpenClaw Support: Fifth managed application with 13 provider presets, Env/Tools/AgentsDefaults config editors, and Workspace file management
  • Session Manager: Browse conversation history across all five apps with table-of-contents navigation and in-session search
  • Backup Management: Independent backup panel with configurable policies, periodic backups, and pre-migration auto-backup
  • Oh My OpenCode Integration: Full OMO config management with OMO Slim lightweight mode support
  • Partial Key-Field Merging (⚠️ Breaking Change): Provider switching now only replaces provider-related fields, preserving all other settings; the "Common Config Snippet" feature has been removed
  • Settings Page Refactoring: 5-tab layout with ~40% code reduction
  • 6 New Provider Presets: AWS Bedrock, SSAI Code, CrazyRouter, AICoding, and more
  • Thinking Budget Rectifier: Fine-grained thinking budget control
  • Theme Switch Animation: Circular reveal transition animation
  • WebDAV Auto Sync: Automatic sync with large file protection

Main Features

OpenClaw Support (New Fifth App)

Full management support for OpenClaw, the fifth managed application following Claude Code, Codex, Gemini CLI, and OpenCode.

  • Provider Management: Add, edit, switch, and delete OpenClaw providers with 13 built-in presets
  • Config Editors: Three dedicated panels for Env (environment variables), Tools, and AgentsDefaults
  • Workspace Panel: HEARTBEAT/BOOTSTRAP/BOOT file management and daily memory
  • Additive Overlay Mode: Support config overlay instead of overwrite
  • Default Model Button: One-click to fill recommended models; auto-register suggested models to allowlist when adding providers
  • Brand & Interaction: Dedicated brand icon, fade-in/fade-out transition animation when switching apps
  • Deep Link Support: Import OpenClaw provider configurations via URL
  • Full Internationalization: Complete Chinese/English/Japanese support

Session Manager

A brand-new session manager to browse and search conversation history.

  • Browse conversation history across Claude Code, Codex, Gemini CLI, OpenCode, and OpenClaw (#867, thanks @TinsFox)
  • Table-of-contents navigation and in-session search
  • Auto-filter by current app when entering the session page
  • Parallel directory scanning + head-tail JSONL reading for optimized loading performance

Backup Management

An independent backup management panel for better data safety.

  • Configurable backup policy: maximum backup count and auto-cleanup rules
  • Hourly automatic backup timer during runtime
  • Auto-backup before database schema migrations with backfill warning
  • Support backup rename and deletion (with confirmation dialog)
  • Backup filenames use local time for better clarity

Oh My OpenCode (OMO) Integration

Full Oh My OpenCode config file management.

  • Agent model selection, category configuration, and recommended model fill (#972, thanks @yovinchen)
  • Improved agent model selection UX with lowercase key fix (#1004, thanks @yovinchen)
  • OMO Slim lightweight mode support
  • OMO ↔ OMO Slim mutual exclusion (enforced at database level)

Workspace

  • Full-text search across daily memory files, sorted by date
  • Clickable directory paths for quick file location access

Toolbar

  • AppSwitcher auto-collapses to compact mode based on available width
  • Smooth transition animation for compact mode toggle

Settings

  • First-use confirmation dialogs for proxy and usage features to prevent accidental operations
  • New enableLocalProxy switch to control proxy UI visibility on home page
  • More granular local environment checks: CLI tool version detection (#870, thanks @kv-chiu), Volta path detection (#969, thanks @myjustify)

Provider Presets

  • AWS Bedrock: Support for AKSK and API Key authentication modes (#1047, thanks @keithyt06)
  • SSAI Code: Partner preset across all five apps
  • CrazyRouter: Partner preset with dedicated icon
  • AICoding: Partner preset with i18n promotion text
  • Updated domestic model provider presets to latest versions
  • Renamed Qwen Coder to Bailian (#965, thanks @zhu-jl18)

Other New Features

  • Thinking Budget Rectifier: Fine-grained thinking budget allocation control (#1005, thanks @yovinchen)
  • WebDAV Auto Sync: Automatic sync with large file protection (#923, thanks @clx20000410; #1043, thanks @SaladDay)
  • Theme Switch Animation: Circular reveal transition for a smoother visual experience (#905, thanks @funnytime75)
  • Claude Config Editor Quick Toggles: Quick toggle switches for common settings (#1012, thanks @JIA-ss)
  • Dynamic Endpoint Hint: Context-aware hint text based on API format selection (#860, thanks @zhu-jl18)
  • Usage Dashboard Enhancement: Auto-refresh control and robust formatting (#942, thanks @yovinchen)
  • New Pricing Data: claude-opus-4-6 and gpt-5.3-codex (#943, thanks @yovinchen)
  • Silent Startup Optimization: Silent startup option only shown when launch-on-startup is enabled

Architecture Improvements

Partial Key-Field Merging (⚠️ Breaking Change)

Provider switching now uses partial key-field merging instead of full config overwrite (#1098).

Before: Switching providers overwrote the entire settings_config to the live config file. This meant that any non-provider settings the user manually added to the live file (plugins, MCP config, permissions, etc.) would be lost on every switch. To work around this, previous versions offered a "Common Config Snippet" feature that let users define shared config to be merged on every switch.

After: Switching providers now only replaces provider-related key-values (API keys, endpoints, models, etc.), leaving all other settings intact. The "Common Config Snippet" feature is therefore no longer needed and has been removed.

Impact & Migration:

  • If you didn't use Common Config Snippets, this change is fully transparent — switching just works better now
  • If you used Common Config Snippets to preserve custom settings (MCP config, permissions, etc.), those settings are now automatically preserved during switches — no action needed
  • If you used Common Config Snippets for other purposes (e.g., injecting extra config on every switch), please manually add those settings to your live config file after upgrading

This refactoring removed 6 frontend files (3 components + 3 hooks) and ~150 lines of backend dead code.

Manual Import Replaces Auto-Import

Startup no longer auto-imports external configurations. Users now click "Import Current Config" manually, preventing accidental data overwrites.

OmoVariant Parameterization

Eliminated ~250 lines of duplicated code in the OMO module via OmoVariant struct parameterization.

OMO Common Config Removal

Removed the two-layer merge system, reducing ~1,733 lines of code and simplifying the architecture.

ProviderForm Decomposition

Reduced ProviderForm component from 2,227 lines to 1,526 lines by extracting 5 independent modules (opencodeFormUtils, useOmoModelSource, useOpencodeFormState, useOmoDraftState, useOpenclawFormState), significantly improving maintainability.

Shared MCP/Skills Components

Extracted AppCountBar, AppToggleGroup, and ListItemRow shared components to reduce duplication across MCP and Skills panels (#897, thanks @PeanutSplash).

Settings Page Refactoring

Refactored settings page to a 5-tab layout (General | Proxy | Advanced | Usage | About), reducing SettingsPage code from ~716 to ~426 lines.

Other Improvements

  • Unified terminal selection via global settings with WezTerm support added
  • Updated Claude model references from 4.5 to 4.6

Bug Fixes

Critical Fixes

  • Windows Home Dir Regression: Restored default home directory resolution to prevent providers/settings "disappearing" when HOME env var differs from the real user profile directory in Git/MSYS environments
  • Linux White Screen: Disabled WebKitGTK hardware acceleration on AMD GPUs (Cezanne/Radeon Vega) to prevent blank screen on startup (#986, thanks @ThendCN)
  • OpenAI Beta Parameter: Stopped appending ?beta=true to /v1/chat/completions endpoints, fixing request failures for Nvidia and other apiFormat="openai_chat" providers (#1052, thanks @jnorthrup)
  • Health Check Auth: Health check now respects provider's auth_mode setting, preventing failures for proxy services that only support Bearer authentication (#824, thanks @Jassy930)

Provider Preset Fixes

  • Fixed OpenClaw /v1 prefix causing double path (/v1/v1/messages)
  • Corrected Opus pricing ($15/$75 → $5/$25) and upgraded to 4.6
  • Unified AIGoCode URL to https://api.aigocode.com across all apps
  • Removed outdated partner status from Zhipu GLM presets
  • Restored API Key input visibility when creating new Claude providers
  • Hide quick toggles for non-active providers, show context-aware JSON editor hints

OMO Fixes

  • Added missing omo-slim category checks across add/form/mutation paths
  • Fixed OMO Slim query cache invalidation after provider mutations
  • Synced OMO agent/category recommended models with upstream sources
  • Added toast feedback for "Fill Recommended" button silent failures
  • Removed last-provider deletion restriction for OMO/OMO Slim
  • Reject saving OpenCode providers without configured models (#932, thanks @yovinchen)

OpenClaw Fixes

  • Fixed 25 missing i18n keys, replaced key={index} with stable IDs, added deep link additive merge, and other code review issues
  • Enhanced EnvPanel robustness (NaN guards, entry key names instead of array indices)
  • Merged duplicate i18n keys to restore provider form translations

Platform Fixes

  • Windows silent startup window flicker (#901, thanks @funnytime75)
  • Title bar dark mode theme following (#903, thanks @funnytime75)
  • Windows Skills path separator matching (#868, thanks @stmoonar)
  • WSL helper functions conditional compilation

UI Fixes

  • Toolbar height clipping causing AppSwitcher to be obscured
  • Show update badge instead of green checkmark when newer version available
  • Session Manager button only visible for Claude/Codex apps
  • Unified SQL import/export card dark mode styling (#1067, thanks @SaladDay)

Other Fixes

  • Replaced hardcoded Chinese strings in Session Manager with i18n keys
  • Fixed Skill documentation URL branch and path resolution (#977, thanks @yovinchen)
  • Added missing OpenCode install.sh installation path detection (#988, thanks @zhu-jl18)
  • Fixed Skill ZIP symlink resolution (#1040, thanks @yovinchen)
  • Added missing OpenCode checkbox in MCP add/edit form (#1026, thanks @yovinchen)
  • Removed auto-import side effect from useProvidersQuery queryFn

Performance

  • Parallel directory scanning + head-tail JSONL reading for session panel, significantly improving session list loading speed
  • Removed unnecessary TanStack Query cache overhead for Tauri local IPC calls

Documentation

  • Sponsor updates: SSSAiCode, Crazyrouter, AICoding, Right Code, MiniMax
  • Added user manual documentation (#979, thanks @yovinchen)

Notes & Considerations

  • OpenClaw is a newly supported app: OpenClaw CLI must be installed first to use related features.
  • ⚠️ Common Config Snippet feature has been removed: Since provider switching now uses partial key-field merging (only replacing API keys, endpoints, models, etc.), user's other settings are automatically preserved, making Common Config Snippets unnecessary. See the "Architecture Improvements" section above for migration details.
  • Auto-import changed to manual: External configurations are no longer auto-imported on startup. Click "Import Current Config" manually when needed.
  • OMO and OMO Slim are mutually exclusive: Only one can be active at a time. Switching to one automatically disables the other.
  • Backup is enabled by default: Automatic hourly backup during runtime. Adjust the policy in the Backup panel.

Special Thanks

Thanks to all contributors for their contributions to this release!

@TinsFox @keithyt06 @kv-chiu @SaladDay @jnorthrup @JIA-ss @clx20000410 @ThendCN @yovinchen @zhu-jl18 @myjustify @funnytime75 @PeanutSplash @Jassy930 @stmoonar


Download & Installation

Visit Releases to download the appropriate version.

System Requirements

System Minimum Version Architecture
Windows Windows 10 or later x64
macOS macOS 10.15 (Catalina) or later Intel (x64) / Apple Silicon (arm64)
Linux See table below x64

Windows

File Description
CC-Switch-v3.11.0-Windows.msi Recommended - MSI installer with auto-update
CC-Switch-v3.11.0-Windows-Portable.zip Portable version, extract and run, no registry write

macOS

File Description
CC-Switch-v3.11.0-macOS.zip Recommended - Extract and drag to Applications, Universal Binary
CC-Switch-v3.11.0-macOS.tar.gz For Homebrew installation and auto-update

Note: Since the author doesn't have an Apple Developer account, you may see an "unidentified developer" warning on first launch. Please close it, then go to "System Settings" → "Privacy & Security" → click "Open Anyway", and it will open normally afterwards.

Homebrew (macOS)

bash
brew tap farion1231/ccswitch
brew install --cask cc-switch

Update:

bash
brew upgrade --cask cc-switch

Linux

Distribution Recommended Format Installation Method
Ubuntu / Debian / Linux Mint / Pop!_OS .deb sudo dpkg -i CC-Switch-*.deb or sudo apt install ./CC-Switch-*.deb
Fedora / RHEL / CentOS / Rocky Linux .rpm sudo rpm -i CC-Switch-*.rpm or sudo dnf install ./CC-Switch-*.rpm
openSUSE .rpm sudo zypper install ./CC-Switch-*.rpm
Arch Linux / Manjaro .AppImage Add execute permission and run directly, or use AUR
Other distributions / Unsure .AppImage chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage

Release Notes V3.11.0 Ja (`docs/release-notes/v3.11.0-ja.md`)

CC Switch v3.11.0

OpenClaw サポート、セッションマネージャー、バックアップ管理と 50 以上の改善

中文版 → | English →


概要

CC Switch v3.11.0 は大規模なアップデートです。5番目のアプリケーション OpenClaw の完全管理サポートを追加し、新しいセッションマネージャーとバックアップ管理機能を導入しました。さらに、Oh My OpenCode (OMO) 統合、プロバイダー切り替えの部分キーフィールドマージアーキテクチャアップグレード、設定ページのリファクタリングなど、多数の改善により全体的な体験がさらに向上しました。

リリース日: 2026-02-26

更新規模: 147 commits | 274 files changed | +32,179 / -5,467 lines


ハイライト

  • OpenClaw サポート: 5番目の管理対象アプリ、13 のプロバイダープリセット、Env/Tools/AgentsDefaults 設定エディター、Workspace ファイル管理
  • セッションマネージャー: 5つのアプリの会話履歴を閲覧、目次ナビゲーションとセッション内検索
  • バックアップ管理: 独立バックアップパネル、設定可能なポリシー、定期バックアップ、マイグレーション前自動バックアップ
  • Oh My OpenCode 統合: 完全な OMO 設定管理、OMO Slim 軽量モードサポート
  • 部分キーフィールドマージ(⚠️ 破壊的変更): プロバイダー切り替え時にプロバイダー関連フィールドのみ置換し、その他の設定を保持;「共通設定スニペット」機能は削除されました
  • 設定ページリファクタリング: 5タブレイアウト、コード量約 40% 削減
  • 6つの新プロバイダープリセット: AWS Bedrock、SSAI Code、CrazyRouter、AICoding など
  • Thinking Budget Rectifier: より精密な thinking budget 制御
  • テーマ切り替えアニメーション: 円形リビール遷移アニメーション
  • WebDAV 自動同期: 自動同期と大容量ファイル保護

主な機能

OpenClaw サポート(新しい5番目のアプリ)

Claude Code、Codex、Gemini CLI、OpenCode に続く5番目の管理対象アプリケーションとして OpenClaw の完全管理サポートを追加しました。

  • プロバイダー管理: OpenClaw プロバイダーの追加、編集、切り替え、削除、13 の内蔵プリセット
  • 設定エディター: Env(環境変数)、Tools(ツール)、AgentsDefaults(エージェントデフォルト)の3つの専用パネル
  • Workspace パネル: HEARTBEAT/BOOTSTRAP/BOOT ファイル管理とデイリーメモリ
  • Additive オーバーレイモード: 上書きではなく設定の重ね合わせをサポート
  • デフォルトモデルボタン: ワンクリックで推奨モデルを入力、プロバイダー追加時に候補モデルを allowlist に自動登録
  • ブランドとインタラクション: 専用ブランドアイコン、アプリ切り替えフェード遷移アニメーション
  • ディープリンクサポート: URL 経由で OpenClaw プロバイダー設定をインポート
  • 完全な国際化: 中/英/日 三言語完全対応

セッションマネージャー

会話履歴を閲覧・検索できる新しいセッションマネージャーです。

  • Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw の5つのアプリの会話履歴を閲覧(#867、@TinsFox に感謝)
  • 目次ナビゲーションとセッション内検索
  • セッションページに入ると現在のアプリで自動フィルター
  • 並列ディレクトリスキャン + ヘッドテール JSONL 読み取りで読み込みパフォーマンスを最適化

バックアップ管理

データの安全性を高める独立バックアップ管理パネルです。

  • 設定可能なバックアップポリシー: 最大バックアップ数、自動クリーンアップルール
  • ランタイム中の1時間ごとの定期自動バックアップ
  • データベースマイグレーション前の自動バックアップ、バックフィル警告プロンプト
  • バックアップのリネームと削除をサポート(確認ダイアログ付き)
  • バックアップファイル名にローカルタイムを使用、より直感的に

Oh My OpenCode (OMO) 統合

完全な Oh My OpenCode 設定ファイル管理です。

  • エージェントモデル選択、カテゴリ設定、推奨モデル入力(#972、@yovinchen に感謝)
  • エージェントモデル選択 UX の改善、lowercase key 問題の修正(#1004、@yovinchen に感謝)
  • OMO Slim 軽量モードサポート
  • OMO と OMO Slim の相互排他(データベースレベルで一貫性を保証)

ワークスペース

  • デイリーメモリファイルの全文検索、日付順ソート
  • ディレクトリパスがクリック可能に、ファイル位置をすばやく開く

ツールバー

  • AppSwitcher がウィンドウ幅に応じて自動的にコンパクトモードに折りたたみ
  • コンパクトモード切り替えのスムーズ遷移アニメーション

設定

  • プロキシと使用量機能に初回使用確認ダイアログを追加、誤操作を防止
  • enableLocalProxy スイッチを追加、ホーム画面のプロキシ UI 表示を制御
  • より詳細なローカル環境チェック: CLI ツールバージョン検出(#870、@kv-chiu に感謝)、Volta パス検出(#969、@myjustify に感謝)

プロバイダープリセット

  • AWS Bedrock: AKSK と API Key の2種類の認証方式をサポート(#1047、@keithyt06 に感謝)
  • SSAI Code: パートナープリセット、5アプリ対応
  • CrazyRouter: パートナープリセットと専用アイコン
  • AICoding: パートナープリセットとプロモーションテキスト
  • 国内モデルプロバイダープリセットを最新版に更新
  • Qwen Coder を百炼 (Bailian) にリネーム(#965、@zhu-jl18 に感謝)

その他の新機能

  • Thinking Budget Rectifier: より精密な thinking budget 制御(#1005、@yovinchen に感謝)
  • WebDAV 自動同期: 自動同期設定と大容量ファイル保護(#923、@clx20000410 に感謝;#1043、@SaladDay に感謝)
  • テーマ切り替えアニメーション: 円形リビール遷移アニメーション(#905、@funnytime75 に感謝)
  • Claude 設定エディタークイックトグル: よく使う設定項目のクイック切り替え(#1012、@JIA-ss に感謝)
  • 動的エンドポイントヒント: API フォーマット選択に基づく動的ヒントテキスト(#860、@zhu-jl18 に感謝)
  • 使用量ダッシュボード強化: 自動更新、堅牢なフォーマット(#942、@yovinchen に感謝)
  • 新しい価格データ: claude-opus-4-6 と gpt-5.3-codex(#943、@yovinchen に感謝)
  • サイレント起動の最適化: サイレント起動オプションは自動起動が有効な場合のみ表示

アーキテクチャ改善

部分キーフィールドマージ(⚠️ 破壊的変更)

プロバイダー切り替えを完全な設定上書きから部分キーフィールドマージ戦略に変更しました(#1098)。

変更前: プロバイダーを切り替えると、settings_config 全体がライブ設定ファイルに上書きされていました。つまり、ユーザーがライブファイルに手動で追加した非プロバイダー設定(プラグイン設定、MCP 設定、権限設定など)は、切り替えのたびに失われていました。この問題を補うため、以前のバージョンでは「共通設定スニペット」機能を提供し、毎回の切り替え時にマージされる共通設定を定義できました。

変更後: プロバイダー切り替え時に、プロバイダー関連のキー値(API キー、エンドポイント、モデルなど)のみが置換され、その他の設定はそのまま保持されます。そのため「共通設定スニペット」機能は不要となり、削除されました。

影響と移行:

  • 共通設定スニペットを使用していなかった場合、この変更は完全に透過的で、切り替え体験が向上するだけです
  • カスタム設定(MCP 設定、権限など)を保持するために共通設定スニペットを使用していた場合、それらの設定は切り替え時に自動的に保持されるようになり、追加の操作は不要です
  • 共通設定スニペットを他の目的(切り替え時に追加設定を注入するなど)で使用していた場合は、アップグレード後にライブ設定ファイルに手動で設定を追加してください

このリファクタリングにより、フロントエンドファイル 6 つ(コンポーネント 3 つ + hooks 3 つ)と約 150 行のバックエンドデッドコードを削除しました。

手動インポートに変更

起動時の自動インポートを廃止し、手動の「現在の設定をインポート」ボタンに変更。意図しないユーザーデータの上書きを防止します。

OmoVariant パラメータ化

OmoVariant 構造体によるパラメータ化で、OMO モジュールの約250行の重複コードを削除しました。

OMO 共通設定の削除

2層マージシステムを削除し、約1,733行のコードを削減、アーキテクチャを簡素化しました。

ProviderForm 分割

ProviderForm コンポーネントを2,227行から1,526行に削減し、5つの独立モジュール(opencodeFormUtils、useOmoModelSource、useOpencodeFormState、useOmoDraftState、useOpenclawFormState)に分離。保守性が大幅に向上しました。

MCP/Skills 共有コンポーネント

AppCountBar、AppToggleGroup、ListItemRow などの共有コンポーネントを抽出し、MCP と Skills パネルの重複コードを削減(#897、@PeanutSplash に感謝)。

設定ページリファクタリング

設定ページを5タブレイアウト(一般 | プロキシ | 詳細 | 使用量 | 情報)にリファクタリング。SettingsPage のコードを約716行から約426行に削減しました。

その他の改善

  • ターミナル統一: グローバル設定でターミナル選択を統一、WezTerm サポートを追加
  • Claude モデル参照を 4.5 から 4.6 に更新

バグ修正

重大な修正

  • Windows ホームディレクトリ回帰: デフォルトのホームディレクトリ解決を復元し、Git/MSYS 環境でのデータベースパス変更によるデータ「消失」を防止
  • Linux 白画面: AMD GPU の WebKitGTK ハードウェアアクセラレーションを無効化し、一部の Linux システムの起動白画面問題を解決(#986、@ThendCN に感謝)
  • OpenAI Beta パラメータ: /v1/chat/completions に ?beta=true を追加しないように修正、Nvidia など OpenAI Chat 形式を使用するプロバイダーのリクエスト失敗を修正(#1052、@jnorthrup に感謝)
  • ヘルスチェック認証: プロバイダーの auth_mode 設定を尊重し、Bearer 認証のみをサポートするプロキシサービスのヘルスチェック失敗を回避(#824、@Jassy930 に感謝)

プロバイダープリセット修正

  • OpenClaw /v1 プレフィックスの二重パス問題を修正
  • Opus 価格修正($15/$75 → $5/$25)と 4.6 へのアップグレード
  • AIGoCode URL を https://api.aigocode.com に統一
  • Zhipu GLM の古いパートナーステータスを削除
  • 新規 Claude プロバイダー作成時の API Key 入力フィールドの表示を復元
  • 非アクティブプロバイダーのクイックトグルを非表示、コンテキスト対応の JSON エディターヒントを表示

OMO 修正

  • omo-slim カテゴリチェックの補完(add/form/mutation パス)
  • OMO Slim プロバイダー変更後のクエリキャッシュ無効化を修正
  • OMO agent/category 推奨モデルをアップストリームソースと同期
  • 「推奨を入力」ボタン失敗時の toast フィードバックを追加
  • OMO/OMO Slim の最後のプロバイダー削除制限を撤廃
  • OpenCode でモデル未設定時の保存を拒否(#932、@yovinchen に感謝)

OpenClaw 修正

  • 25個の欠落 i18n キー、key={index} を安定 ID に置換、ディープリンク additive マージなどのコードレビュー問題を修正
  • EnvPanel 堅牢性強化(NaN ガード、配列インデックスではなくエントリーキー名を使用)
  • i18n 重複キーのマージ、プロバイダーフォーム翻訳を復元

プラットフォーム修正

  • Windows サイレント起動時のウィンドウフラッシュ(#901、@funnytime75 に感謝)
  • タイトルバーのダークモード追従(#903、@funnytime75 に感謝)
  • Windows の Skills パスセパレーターマッチング(#868、@stmoonar に感謝)
  • WSL ヘルパー関数の条件付きコンパイル

UI 修正

  • ツールバーの高さクリッピングによる AppSwitcher の遮蔽を修正
  • 新バージョンがある場合、緑のチェックマークではなく更新バッジを表示
  • セッションマネージャーボタンを Claude/Codex アプリでのみ表示
  • SQL インポート/エクスポートカードのダークモードスタイルを統一(#1067、@SaladDay に感謝)

その他の修正

  • セッションマネージャーのハードコードされた中国語文字列を i18n キーに置換
  • Skill ドキュメント URL のブランチとパスを修正(#977、@yovinchen に感謝)
  • OpenCode install.sh インストールパス検出の補完(#988、@zhu-jl18 に感謝)
  • Skill ZIP シンボリックリンク解決の修正(#1040、@yovinchen に感謝)
  • MCP フォームに OpenCode チェックボックスを追加(#1026、@yovinchen に感謝)
  • useProvidersQuery の自動インポート副作用を削除

パフォーマンス最適化

  • セッションパネルの並列ディレクトリスキャン + ヘッドテール JSONL 読み取りで、セッションリスト読み込み速度を大幅向上
  • Tauri ローカル IPC の不要な query cache を削除し、メモリ使用量を削減

ドキュメント

  • スポンサー更新: SSSAiCode、Crazyrouter、AICoding、Right Code、MiniMax
  • ユーザーマニュアルを追加(#979、@yovinchen に感謝)

注意事項

  • OpenClaw は新しくサポートされたアプリです: 関連機能を使用するには、先に OpenClaw CLI をインストールする必要があります。
  • ⚠️ 共通設定スニペット機能は削除されました: プロバイダー切り替えが部分キーフィールドマージ(API キー、エンドポイント、モデルなどのみ置換)に変更されたため、ユーザーのその他の設定は自動的に保持され、共通設定スニペットは不要になりました。移行の詳細は上記「アーキテクチャ改善」セクションを参照してください。
  • 自動インポートは手動に変更されました: 起動時に外部設定を自動インポートしなくなりました。必要に応じて「現在の設定をインポート」を手動でクリックしてください。
  • OMO と OMO Slim は相互排他: 同時に一つだけ有効にできます。切り替え時にもう一方は自動的に無効になります。
  • バックアップ機能はデフォルトで有効: ランタイム中に1時間ごとに自動バックアップします。バックアップパネルでポリシーを調整できます。

特別な感謝

以下のコントリビューターの皆様、このリリースへの貢献に感謝します!

@TinsFox @keithyt06 @kv-chiu @SaladDay @jnorthrup @JIA-ss @clx20000410 @ThendCN @yovinchen @zhu-jl18 @myjustify @funnytime75 @PeanutSplash @Jassy930 @stmoonar


ダウンロードとインストール

Releases から適切なバージョンをダウンロードしてください。

システム要件

システム 最小バージョン アーキテクチャ
Windows Windows 10 以降 x64
macOS macOS 10.15 (Catalina) 以降 Intel (x64) / Apple Silicon (arm64)
Linux 下表参照 x64

Windows

ファイル 説明
CC-Switch-v3.11.0-Windows.msi 推奨 - MSI インストーラー、自動更新対応
CC-Switch-v3.11.0-Windows-Portable.zip ポータブル版、解凍して実行、レジストリ書き込みなし

macOS

ファイル 説明
CC-Switch-v3.11.0-macOS.zip 推奨 - 解凍して Applications にドラッグ、Universal Binary
CC-Switch-v3.11.0-macOS.tar.gz Homebrew インストールと自動更新用

注意: 作者が Apple Developer アカウントを持っていないため、初回起動時に「開発元を確認できません」という警告が表示される場合があります。一度閉じてから、「システム設定」→「プライバシーとセキュリティ」→「このまま開く」をクリックすると、その後は正常に開けます。

Homebrew (macOS)

bash
brew tap farion1231/ccswitch
brew install --cask cc-switch

更新:

bash
brew upgrade --cask cc-switch

Linux

ディストリビューション 推奨形式 インストール方法
Ubuntu / Debian / Linux Mint / Pop!_OS .deb sudo dpkg -i CC-Switch-*.deb または sudo apt install ./CC-Switch-*.deb
Fedora / RHEL / CentOS / Rocky Linux .rpm sudo rpm -i CC-Switch-*.rpm または sudo dnf install ./CC-Switch-*.rpm
openSUSE .rpm sudo zypper install ./CC-Switch-*.rpm
Arch Linux / Manjaro .AppImage 実行権限を追加して直接実行、または AUR を使用
その他のディストリビューション / 不明 .AppImage chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage

Release Notes V3.11.0 Zh (`docs/release-notes/v3.11.0-zh.md`)

CC Switch v3.11.0

OpenClaw 支持、会话管理器、备份管理与 50+ 项改进

English → | 日本語版 →


概览

CC Switch v3.11.0 是一次大规模更新,新增第五个应用 OpenClaw 的完整管理支持,同时带来全新的会话管理器和备份管理功能。此外,Oh My OpenCode (OMO) 集成、供应商切换的部分键值合并架构升级、设置页面重构等多项改进使整体体验更加完善。

发布日期:2026-02-26

更新规模:147 commits | 274 files changed | +32,179 / -5,467 lines


重点内容

  • OpenClaw 支持:第五个受管理应用,含 13 个供应商预设、Env/Tools/AgentsDefaults 配置编辑器、Workspace 文件管理
  • 会话管理器:浏览五个应用的历史会话,支持目录导航和会话内搜索
  • 备份管理:独立备份面板,可配置策略、定时备份、迁移前自动备份
  • Oh My OpenCode 集成:完整 OMO 配置管理,支持 OMO Slim 轻量模式
  • 部分键值合并(⚠️ 破坏性变更):供应商切换改为仅替换供应商相关字段,保留用户的其余设置;"通用配置片段"功能因此移除
  • 设置页面重构:5 标签页布局,代码量减少约 40%
  • 6 组新供应商预设:AWS Bedrock、SSAI Code、CrazyRouter、AICoding 等
  • Thinking Budget Rectifier:代理矫正器,更精细的 thinking budget 控制
  • 主题切换动画:圆形揭示过渡动画,视觉体验升级
  • WebDAV 自动同步:支持自动同步与大文件防护

主要功能

OpenClaw 支持(新增第五应用)

CC Switch 新增对 OpenClaw 的完整管理支持,这是继 Claude Code、Codex、Gemini CLI、OpenCode 之后的第五个受管理应用。

  • 供应商管理:新增、编辑、切换、删除 OpenClaw 供应商,含 13 个内置预设
  • 配置编辑器:Env(环境变量)、Tools(工具)、AgentsDefaults(代理默认值)三个专属配置面板
  • Workspace 面板:支持 HEARTBEAT/BOOTSTRAP/BOOT 文件管理及每日记忆
  • Additive 叠加模式:支持配置叠加而非覆盖
  • 默认模型按钮:一键填充推荐模型,添加供应商时自动将建议模型注册到 allowlist
  • 品牌与交互:专属品牌图标、应用切换淡入淡出过渡动画
  • 深链接支持:通过 URL 导入 OpenClaw 供应商配置
  • 完整国际化:中/英/日三语全面支持

会话管理器 Sessions

全新的会话管理器,帮助你浏览和检索历史会话记录。

  • 支持浏览 Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw 五个应用的历史会话(#867,感谢 @TinsFox)
  • 目录导航和会话内搜索
  • 进入会话页面时默认过滤为当前应用,快速定位
  • 并行目录扫描 + 头尾 JSONL 读取,优化加载性能

备份管理 Backup

独立的备份管理面板,让数据安全更有保障。

  • 可配置备份策略:最大备份数量、自动清理规则
  • 运行时每小时定期自动备份
  • 数据库迁移前自动备份,带回填警告提示
  • 支持备份重命名和删除(含确认对话框)
  • 备份文件名使用本地时间,更直观

Oh My OpenCode (OMO) 集成

完整的 Oh My OpenCode 配置文件管理。

  • Agent 模型选择、Category 配置、推荐模型填充(#972,感谢 @yovinchen)
  • 改进 Agent 模型选择 UX,修复 lowercase key 问题(#1004,感谢 @yovinchen)
  • OMO Slim 轻量模式支持
  • OMO 与 OMO Slim 互斥切换(数据库层级强制保证一致性)

工作空间 Workspace

  • 每日记忆文件全文搜索,按日期排序
  • 目录路径可点击跳转,快速打开文件位置

工具栏 Toolbar

  • AppSwitcher 根据窗口宽度自动折叠为紧凑模式
  • 紧凑模式切换平滑过渡动画

设置 Settings

  • 代理和用量功能新增首次使用确认对话框,避免误操作
  • 新增 enableLocalProxy 开关,控制主页代理 UI 显示
  • 更精细的本地环境检查:CLI 工具版本检测(#870,感谢 @kv-chiu)、Volta 路径检测(#969,感谢 @myjustify)

供应商预设 Preset

  • AWS Bedrock:支持 AKSK 和 API Key 两种认证方式(#1047,感谢 @keithyt06)
  • SSAI Code:合作伙伴预设,覆盖五端
  • CrazyRouter:合作伙伴预设及专属图标
  • AICoding:合作伙伴预设及推广文案
  • 更新国内模型供应商预设至最新版本
  • Qwen Coder 重命名为百炼 (Bailian)(#965,感谢 @zhu-jl18)

其他新功能

  • Thinking Budget Rectifier:代理矫正器,更精细地控制 thinking budget 分配(#1005,感谢 @yovinchen)
  • WebDAV 自动同步:支持自动同步配置,并增加大文件防护(#923,感谢 @clx20000410;#1043,感谢 @SaladDay)
  • 主题切换动画:圆形揭示过渡动画,视觉体验更流畅(#905,感谢 @funnytime75)
  • Claude 配置编辑器快速开关:快速切换常用配置项(#1012,感谢 @JIA-ss)
  • 动态端点提示:根据 API 格式选择动态显示端点提示文本(#860,感谢 @zhu-jl18)
  • 用量仪表盘增强:自动刷新、更强健的数据格式化(#942,感谢 @yovinchen)
  • 新增定价数据:claude-opus-4-6 和 gpt-5.3-codex(#943,感谢 @yovinchen)
  • 静默启动优化:静默启动选项仅在开机启动开启时显示

架构改进

部分键值合并(⚠️ 破坏性变更)

供应商切换从全量配置覆写改为部分键值合并策略(#1098)。

变更前:切换供应商时,整个 settings_config 会覆写到 live 配置文件。这意味着用户在 live 文件中手动添加的非供应商设置(插件配置、MCP 配置、权限设置等)会在每次切换时丢失。为了弥补这个问题,之前版本提供了"通用配置片段"功能,让用户定义每次切换时都会合并的公共配置。

变更后:切换供应商时,仅替换供应商相关的键值(API Key、端点、模型等),用户的其余设置完整保留。因此"通用配置片段"功能不再需要,已被移除。

影响与迁移:

  • 如果你之前没有使用通用配置片段功能,此变更对你完全透明,切换体验只会更好
  • 如果你之前使用了通用配置片段功能来保留自定义设置(如 MCP 配置、权限等),升级后这些设置会在切换时自动保留,无需额外操作
  • 如果你利用通用配置片段做其他用途(如在切换时注入额外配置),请在升级后手动将这些配置写入 live 配置文件中

此次重构删除了 6 个前端文件(3 个组件 + 3 个 hooks)、约 150 行后端死代码。

手动导入替代自动导入

启动时不再自动导入外部配置,改为手动点击"导入当前配置"按钮,避免意外覆盖用户数据。

OMO Variant 参数化

通过 `OmoVaria