본문으로 건너뛰기

"CCS" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

Claude Code Switcher

· 약 15분

왜 "스위처"가 필요해졌나

Claude Code가 2024년 말 등장한 직후만 해도 사용량 캡은 거의 의식되지 않았어요. 그게 바뀐 건 2025-08-28이에요. Anthropic이 Pro / Max 플랜에 5시간 롤링 윈도우 + 7일 weekly cap 이중 제한을 도입한 날이에요. Max 5x ($100/mo)와 Max 20x ($200/mo)도 weekly 캡에서 자유롭지 않습니다.

cap에 걸리면 두 가지 길이 있습니다.

  1. 그 주가 끝날 때까지 기다립니다
  2. 다른 프로바이더로 옮깁니다. Z.AI의 GLM Coding Plan, Moonshot의 Kimi, OpenRouter의 300개 모델 중 하나, 또는 로컬 Ollama를 선택합니다

옮기는 일 자체는 어렵지 않습니다. Claude Code가 환경변수 두 개(ANTHROPIC_BASE_URLANTHROPIC_AUTH_TOKEN)만 보고 동작하기 때문입니다. 예를 들어 GLM으로 옮기는 방법은 Z.AI 공식 가이드 기준으로 두 줄이면 됩니다.

export ANTHROPIC_BASE_URL="https://api.z.ai/api/anthropic"
export ANTHROPIC_AUTH_TOKEN="..."

다른 프로바이더(Kimi, DeepSeek 등)도 같은 패턴이지만 정확한 Anthropic-호환 엔드포인트 URL은 각 프로바이더 공식 문서에서 직접 확인해야 합니다. 같은 회사라도 OpenAI-호환 엔드포인트(/v1)와 Anthropic-호환 엔드포인트가 다르고, 후자가 잘못 표기된 글이 인터넷에 흔합니다.

문제는 하루에 셋넷씩 갈아타게 되는 순간입니다. 회사 계정, 개인 계정, GLM, 로컬 모델, 임시 OpenRouter를 오가며 매번 셸 변수를 바꾸다 보면, 헷갈려서 회사 계정으로 사이드 프로젝트를 돌리기도 하고 캡이 어디서 깎이는지도 까먹습니다. 이 지점에서 등장한 도구가 **CCS (Claude Code Switcher)**입니다.

CCS 한 줄 요약

@kaitranntt/ccs는 Kai Tran(카이 트란)이 만든 Claude Code용 멀티 프로바이더/멀티 계정 프로필 매니저입니다. MIT 라이선스의 npm 패키지이며, GitHub ★2.2k, 2026-04-29 기준 v7.75.0입니다. 721개 릴리즈와 3,687개 커밋이 쌓일 만큼 개발이 매우 활발합니다.

홈페이지: https://ccs.kaitran.ca/ 저장소: https://github.com/kaitranntt/ccs

자기 소개는 한 문장입니다.

The multi-provider profile and runtime manager for Claude Code and compatible CLIs. — config 파일 갈아엎지 말고, 활성 세션 깨지 않으면서, 몇 초 안에 프로바이더를 옮겨라.

무엇을 지원하나

설치는 한 줄이면 됩니다.

npm install -g @kaitranntt/ccs
# 또는
bun add -g @kaitranntt/ccs

ccs config 한 번 돌려 초기 설정 후, 프로필 단위로 사용합니다.

명령라우팅
ccs기본값: Claude Sonnet 4.6
ccs glmZ.AI GLM-5.1 (API 또는 Coding Plan)
ccs kimiMoonshot Kimi (1M context)
ccs geminiGemini 3 Pro/Flash (OAuth)
ccs codexGPT-5.4 / Codex (OAuth)
ccs ollama로컬 Ollama 모델
ccs work / ccs personal같은 Claude 라도 계정 격리
ccs --target droid glmruntime 자체를 Factory Droid로 바꾸고 모델은 GLM

지원 프로바이더는 점점 늘어 현재 다음을 포함합니다.

  • Claude (Sonnet 4.6, Opus 4.6): 공식
  • GLM-5.1, GLM-5-Turbo, GLM-4.7: Z.AI
  • Kimi K2.5: Moonshot
  • Gemini 3 Pro/Flash: Google (OAuth)
  • GPT-5.4 / Codex: OpenAI (OAuth)
  • Antigravity Pro/Turbo: ccs agy (OAuth)
  • OpenRouter: 300+ 모델 한 번에
  • Ollama, llama.cpp, Novita, Alibaba Coding Plan 등 로컬/OpenAI-호환 모두

어떻게 동작하나

CCS의 핵심은 두 가지 컴포넌트입니다.

첫 번째는 로컬 Anthropic-호환 프록시입니다. GLM/Kimi처럼 이미 Anthropic-호환 엔드포인트를 제공하는 프로바이더는 단순 패스스루로 지나가고, 그렇지 않은 OpenAI-호환 프로바이더(OpenRouter, DeepSeek 등)는 로컬 프록시가 요청과 응답을 변환해 Claude Code가 자기 형식대로 받게 만듭니다.

두 번째는 CLIProxyAPI라는 OAuth 프록시 백엔드입니다. Gemini, Codex, Antigravity처럼 공식 API 키가 없는 OAuth 기반 프로바이더는 이 별도 컴포넌트가 처리하고, 라운드로빈이나 fill-first 같은 토큰 관리 정책도 여기서 돕습니다. 커뮤니티 fork(CLIProxyAPIPlus)도 옵트인으로 쓸 수 있습니다.

활성화는 eval "$(ccs proxy activate)" 같이 셸에 평가시켜 ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN을 그 세션 한정으로 주입하는 방식입니다. 다음 셸이나 다음 디렉토리에서는 다시 깨끗해집니다.

# CCS가 한 번에 처리하는 것
$ ccs glm "이 PR 리뷰해줘"
# 내부적으로:
# 1. ~/.ccs/profiles/glm.settings.json 읽기
# 2. ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic 주입
# 3. ANTHROPIC_AUTH_TOKEN=$GLM_KEY 주입
# 4. claude code 호출

겉으로는 한 줄이지만 안쪽에서 하는 일은 수동 env 셋과 다르지 않고, 그걸 프로필이라는 단위로 캡슐화했을 뿐입니다.

장점은 어디서 나오나

가장 눈에 띄는 건 명령 하나가 프로파일 하나에 대응한다는 점입니다. 회사 Claude, 개인 Claude, GLM, Kimi, 로컬까지 다섯 개를 셸 변수 갈아끼우지 않고 명령 하나로 분리합니다. 여기서 한 발 더 들어가면 멀티 계정 격리가 있습니다. ccs workccs personal이 같은 머신에서 동시에 다른 Claude 세션을 돌릴 수 있고 weekly cap도 따로 깎이므로, 회사 계정으로 사이드 프로젝트를 돌리다 cap을 축내는 사고가 구조적으로 사라집니다.

비용 이야기도 빼놓기 어렵습니다. 공식 페이지는 "Save $500–1000/month with strategic delegation"이라 적는데, 검증은 본인 워크로드에 따라 다릅니다. 다만 무거운 보일러플레이트는 GLM($10–30/mo)으로 돌리고 설계만 Claude Max로 가는 패턴은 실제로 cap 부담을 크게 줄여줍니다.

나머지 장점은 결이 비슷합니다. Z.AI처럼 API 키를 발급해 쓰는 곳, Gemini처럼 OAuth로 가는 곳, 로컬 Ollama까지 같은 명령 표면 위로 올라오고, proxy.routing 설정으로 "긴 컨텍스트는 Kimi, 추론은 Claude, 백그라운드는 GLM" 식의 자동 라우팅도 짤 수 있습니다. config 파일을 손으로 만지지 않고 비주얼 대시보드로 프로필을 추가/수정할 수 있어, 한국에서 GLM Coding Plan처럼 결제/키 발급이 번거로운 프로바이더를 쓸 때 편합니다. 721 릴리즈에 거의 매일 업데이트될 만큼 개발이 활발해 새 프로바이더가 나오면 빠르게 흡수되는 것도 덤입니다.

단점과 주의사항

가장 실질적인 부담은 추상화가 두껍다는 점입니다. 프록시가 두 단계(로컬 + CLIProxyAPI)로 끼어들고 프로바이더마다 라우팅 룰이 따로 사는 탓에, "내 요청이 어디로 갔지?"가 헷갈리는 순간이 생깁니다. 로그(~/.ccs/logs/)를 켜둘 가치가 여기 있습니다. 핵심 기능 일부가 CLIProxyAPI라는 별도 프로젝트에 묶여 있다는 점도 같은 맥락인데, 그쪽 이슈가 CCS 동작에 그대로 옮겨붙을 수 있습니다. 버전 업이 매우 빠른 것(v7.75.0, 721 릴리즈)도 새 프로바이더 흡수에는 좋지만 "내 환경에서 안정적인 v7.x"를 고수하려는 보수적 운영에는 부담이라, lockfile로 고정하는 편이 낫습니다.

쓸모의 경계도 분명합니다. 다른 프로바이더를 안 쓰고 회사/개인 두 계정만 격리하는 경우라면 direnv.envrc 같은 더 가벼운 도구로 충분하고, CCS는 옮겨 다닐 곳이 셋 이상일 때부터 의미가 생깁니다. 그리고 Codex, Antigravity 같은 비공개 OAuth 프로바이더를 우회로 쓰는 것은 각 서비스 이용약관 위반 소지가 있으니, 회사 환경에서는 한 번 확인하는 편이 안전합니다.

한국에서 쓸 때 걸리는 현실적 지점도 둘 있습니다. Z.AI Coding Plan은 분기 결제(분기당 $30–80), Moonshot Kimi는 위안화 결제라 CCS가 결제까지 해결해주지는 않습니다. 또 이 도구가 weekly cap 회피 수단으로 광고되지만, Anthropic 입장에서 "한 사람이 멀티 계정으로 cap을 돌파"하는 패턴이 쌓이면 정책이 다시 조여질 수 있습니다. 도구의 책임은 아니어도 시장 동학은 의식해 둘 만합니다.

한국 커뮤니티 반응

CCS 자체에 대한 긱뉴스(news.hada.io) 단일 글은 (작성 시점 기준) 아직 없지만, CCS 같은 도구가 왜 등장했는지를 보여주는 신호는 긱뉴스에 풍부합니다.

스레드(Threads) 쪽에서는 한국어 사용자들이 비슷한 도구를 다양하게 시도 중이라는 점이 눈에 띕니다. vibe proxy로 Claude Code에 AntiGravity와 GLM을 라이드 매핑하거나, oh-my-opencode(★9K)가 Kimi K2.5와 GLM 5를 메인 오케스트레이터로 튜닝하거나, free-claude-code가 NVIDIA NIM 무료 API로 Claude Code를 무료 운영하는 식입니다. 한국 개발자들이 프록시와 멀티 프로바이더라는 패턴 자체에 적극적으로 베팅하고 있다는 의미이고, CCS는 그 흐름에서 가장 잘 정리된 도구 중 하나입니다.

대안 비교

CCS만 있는 게 아닙니다. 같은 영역에 여러 도구가 경쟁 중입니다.

도구강점약점
CCS (kaitranntt)★2.2kOAuth 프록시 + GUI 대시보드 + 활발한 업데이트추상화 두꺼움, 의존성 복잡
claude-code-router (musistudio)★33.2k시나리오 라우팅(background/think/longContext), 토큰 임계값 자동 전환, JS 플러그인OAuth 미지원
cc-switch (farion1231)(데스크톱)데스크톱 GUI, Claude Code/Codex/OpenCode/Gemini 통합CLI 친화도 낮음
claude-code-switch (foreveryh)(소규모)미니멀, 한 명령으로 Anthropic 모델만 전환Anthropic 외 미지원
OpenCode (opencode.ai)(별도 트리)75+ 프로바이더, 완전 오픈, Claude Code 호환 인터페이스자체 CLI 라 Claude Code 그대로는 아님
DIY (.zshrc 두 줄)의존성 없음, 가장 투명함프로필 3개 넘어가면 관리 불가

API 키 기반 프로바이더가 2개 이내이고 라우팅이 필요하다면 claude-code-router가 어울립니다. 별 수도 가장 많고 시나리오 라우팅이 가장 강합니다. OAuth 프로바이더를 포함한 멀티 계정이라면 이 영역에서 거의 유일한 CCS가 맞습니다. 데스크톱 친화성과 멀티 툴 통합 GUI를 원한다면 cc-switch, Anthropic만 쓰면서 단순함을 우선한다면 DIY 또는 claude-code-switch를 고르면 됩니다.

시나리오: 회사 Team + Enterprise 두 계정만 쓴다면

CCS가 풀려는 문제가 프로바이더 다양화와 OAuth 우회라면, Anthropic만 쓰면서 회사 계정 두 개(Team + Enterprise)만 격리하는 시나리오에는 정확히 그 두 가치가 빠져 있습니다. 이때는 도구 선택이 달라집니다.

이 시나리오의 본질은 두 ANTHROPIC 계정 사이를 빠르고 정확하게 전환하는 한 가지로 줄어듭니다. 다른 프로바이더도, 시나리오 라우팅도, 로컬 모델도 무관합니다.

이 경우라면 direnv가 첫 손에 꼽힙니다. .envrcexport ANTHROPIC_API_KEY=... 한 줄을 두 회사 디렉토리에 각각 두면 cd만으로 키가 자동 로드됩니다. 이 시나리오에서 가장 큰 리스크는 한 회사 코드에 다른 회사 키가 실수로 흘러가는 사고인데, 디렉토리 경계로 그걸 막아주는 게 direnv의 장점입니다.

더 단순하게 가려면 ~/.zshrc에 alias 두 줄이면 됩니다.

alias cct='ANTHROPIC_AUTH_TOKEN=$TEAM_TOKEN claude'
alias cce='ANTHROPIC_AUTH_TOKEN=$ENT_TOKEN claude'

디렉토리에 묶이지 않아 빠른 대신, 지금 어느 회사 컨텍스트인지는 사람이 기억해야 합니다. Anthropic 전용 미니멀 스위처인 claude-code-switch도 CCS보다 가볍고 이 시나리오에 정확히 맞습니다. CCS를 굳이 쓴다면 멀티 계정 모드만(ccs auth create team / ccs auth create ent) 떼어 쓰는 것도 동작은 하지만, 프로바이더 다양화, 프록시, OAuth 같은 95% 기능을 놀리면서 의존성과 복잡도는 그대로 짊어지게 됩니다. 나중에 GLM 같은 외부 프로바이더로 확장할 가능성이 있을 때만 미리 깔아두는 의미가 있습니다.

Enterprise가 SSO를 강제하면 단순 API 키 토글로는 안 되고 OAuth 로그인 사이클이 필요합니다. 이때는 direnv만으로 부족해 CCS의 OAuth 프로필 분리나 Anthropic Console의 organization 스위처를 써야 하는데, SSO 강제에 잦은 전환까지 겹친 경우가 사실상 CCS를 정당화하는 거의 유일한 회사 시나리오입니다. 정리하면 API 키 기반 두 계정에는 direnv로 충분하고, SSO 강제에 잦은 전환이 겹칠 때만 CCS가 값을 하며, 그 밖에는 대체로 과한 도구입니다.

설정/대화는 공유하면서 계정만 분리하고 싶다면

같은 시나리오의 변종입니다. 두 회사 계정을 전환은 하되 슬래시 커맨드, MCP, hooks, CLAUDE.md/대화 히스토리는 한 군데에서 공유하고 싶은 경우인데, 이때는 정답이 다릅니다.

먼저 Claude Code가 무엇을 어디 두는지 알면 답이 나옵니다.

위치무엇계정 종속?
~/.claude/settings.json사용자 설정 (theme, env, hooks 트리거 등)무관
~/.claude/commands/, agents/, skills/커스텀 슬래시 커맨드, 에이전트, 스킬무관
~/.claude/CLAUDE.md글로벌 메모리무관
~/.claude/projects/<path-hash>/*.jsonl대화 히스토리 (프로젝트 경로 기준)무관
OS 키체인 / ANTHROPIC_AUTH_TOKEN인증 토큰종속

핵심은 계정 종속이 토큰 한 가지뿐이라는 점입니다. 토큰만 갈아끼우면 나머지는 자동으로 공유되므로, 답은 direnv로 토큰만 스위칭하는 것입니다. .envrcexport ANTHROPIC_AUTH_TOKEN=... 한 줄만 두고 ~/.claude/는 건드리지 않으면, 슬래시 커맨드, hooks, MCP, 대화가 전부 자동으로 공유됩니다. 반대로 ccs auth create work 같은 CCS의 isolated profile 모드는 정확히 이 공유를 분리하는 기능이라 피해야 합니다. CCS 자체는 써도 되지만 isolation 옵션은 끄고 토큰만 바꾸는 모드로만 씁니다. 여러 머신 사이에서도 공유하고 싶으면 ~/.claude/를 git으로 관리하는 dotfiles가 답인데, settings.json에 토큰이 평문으로 들어가지 않도록 .gitignoresettings.local.json을 등록해 두는 정도만 주의하면 됩니다.

다만 Enterprise 데이터 격리는 짚어둘 필요가 있습니다. Enterprise 플랜 약관에 대화 데이터를 다른 organization 환경과 섞지 못하게 하는 조항이 있을 수 있어서, PII, 고객 데이터, 비공개 코드를 다루는 프로젝트라면 ~/.claude/projects/를 공유하는 것이 회사 보안 정책 위반이 될 수 있습니다. 사내 보안팀에 한 번 확인하는 게 안전하고, 우려가 있으면 프로젝트 디렉토리 자체를 회사별로 분리해 자연히 다른 <path-hash>로 떨어뜨리는 패턴(예: ~/work/team/, ~/work/ent/ 두 루트)이 가장 깔끔합니다.

SSO 강제 환경, 한국 회사 현실에 더 가까운 케이스

위 두 서브섹션은 API 키를 사용자가 직접 발급받을 수 있다는 전제 위에 있습니다. 그런데 국내 대기업, 금융권, 보안 민감 조직 대부분은 그 전제 자체가 깨져 있습니다. Team/Enterprise 플랜에서 SSO를 강제하면 사용자 API 키 발급이 비활성화되고, 인증은 OAuth + IdP MFA 사이클로만 가능합니다. 이 환경에서는 도구 선택이 다시 한 번 달라집니다.

먼저 구조를 짚으면 다음과 같습니다.

  1. claude login → 브라우저 → 회사 IdP 로그인 (SSO + MFA) → Anthropic Console → 토큰 발급
  2. 토큰은 OS 키체인 또는 ~/.claude/.credentials.json에 저장
  3. 토큰은 보통 시간 제한이 있고 (몇 시간~며칠), 만료되면 다시 SSO 사이클
  4. 한 머신의 한 OS 유저는 동시에 한 organization의 세션만 보유 가능

즉 SSO 강제 환경에서 두 회사 organization 사이를 전환하려면 결국 logout, 다른 org로 login, 다시 작업 사이클을 돌아야 합니다. IdP가 매번 MFA를 요구하니 도구가 우회할 수 있는 영역이 아닙니다.

실제로 동작하는 패턴은 현실적 운영 순으로 정리할 수 있습니다. 가장 흔한 사례이자 가장 깔끔한 결론은 organization 하나만 쓰는 것입니다. 회사가 Enterprise 하나를 표준화했고 Team이 레거시/POC였다면 둘 다 유지할 이유가 없으니 회사 IT에 정리를 요청하는 편이 낫습니다. 두 organization이 같은 Anthropic Workspace 안의 서로 다른 workspace라면, admin이 workspace를 분리해 두는 것만으로 organization 전환 없이 claude /switch-workspace 식의 in-session 전환이 가능합니다. 이게 되는지부터 회사 IT에 확인하면 가장 매끄럽습니다.

두 organization이 진짜 별개라면 방법이 무거워집니다. 같은 노트북에 OS 계정 두 개를 만들어 각각 SSO 로그인 상태를 독립으로 두면 키체인과 ~/.claude/가 자연히 분리되지만, 설정/대화 공유가 깨져서 dotfiles를 두 OS 유저 사이에 공유하는 추가 작업이 필요합니다. CCS의 OAuth 프로필 분리(ccs auth create work-team / ccs auth create work-ent)는 이론상 이 시나리오에 정확히 맞지만, 회사 IdP가 OAuth 흐름에 거는 추가 검증(IP 화이트리스트, 디바이스 트러스트, MFA 빈도)에 따라 CCS의 토큰 캐시 방식이 IdP 정책과 충돌할 수 있어 시도 전에는 알기 어렵습니다. 사내 보안팀과 사전 협의를 권합니다. 가장 보수적인 선택은 두 회사용 Dev Container나 VM을 따로 띄워 각각 한 organization으로 로그인하는 것인데, 무겁고 호스트 키체인을 못 쓴다는 대가가 따릅니다.

반대로 SSO 환경에서 동작하지 않는 패턴은 다음과 같습니다.

  • direnv + ANTHROPIC_AUTH_TOKEN 토글: 사용자 API 키 자체가 없으니 토글할 대상이 없습니다.
  • 셸 alias로 토큰 swap: 같은 이유로 동작하지 않습니다.
  • "session 토큰을 추출해서 재사용": 만료가 짧고 IdP가 디바이스 핑거프린팅으로 거부할 가능성이 있습니다. ToS의 회색지대이기도 합니다.
  • 두 organization의 ~/.claude/.credentials.json을 수동으로 백업/복구: 동작은 할 수 있지만 MFA 빈도 정책을 우회하는 모양새가 되어 정책 위반 우려가 있습니다.

한국 회사 현실에 맞는 결론은, SSO 강제면 organization 전환 자체가 비용이 크다는 사실을 인정하고 두 organization을 동시에 자주 오가지 않는 워크플로우를 설계하는 쪽입니다. 오전엔 Team org에서 한 덩어리, 오후엔 Enterprise org에서 다른 덩어리를 처리하는 식의 시간 분할이, 전환을 도구로 매끄럽게 만드는 것보다 운영 부담이 훨씬 적습니다. 도구는 그 다음 문제입니다.

실전 팁

블로그, GitHub 이슈, 도구 README의 패턴을 종합해 한국 환경에서 바로 쓸 만한 것만 모았습니다.

가장 큰 가치는 라우팅 자동화보다 자기 워크플로우에 맞는 모델 분리에서 나옵니다. 설계/아키텍처는 ccs(Claude Sonnet), 보일러플레이트/테스트 정리는 ccs glm, 1M 컨텍스트가 필요한 대규모 리뷰는 ccs kimi, 민감 코드는 로컬 ccs ollama 정도가 무난한 시작점입니다. Claude Sonnet 4.6도 1M 컨텍스트를 지원하지만 토큰 값이 비싸서, 큰 monorepo 전체 리뷰는 ccs kimi 한 번이 훨씬 싸게 먹힙니다. 새 prompt가 안정적인지 확인하는 단계라면 첫 5~10번은 무료인 ccs ollama로 돌려보다 만족스러우면 Claude로 옮기면 됩니다.

회사/개인 계정은 무조건 격리하는 편이 좋습니다(ccs auth create work / ccs auth create personal). weekly cap이 섞이지 않아 둘 다 마음 편히 쓸 수 있습니다. 여기에 더해 Claude Max의 weekly cap이 60% 이상 깎였으면 남은 작업의 70% 정도는 GLM으로 돌리는 룰을 정해두면, cap이 갑자기 끊기는 사고가 사라집니다.

라우팅은 단순하게 시작하는 편이 낫습니다. proxy.routing 시나리오 라우팅을 처음부터 복잡하게 짜면 요청이 어디로 갔는지 못 따라가니, 모델을 직접 지정해 일주일 운용하고 패턴이 보이면 그때 룰을 추가합니다. 기본 CLIProxyAPI가 새 프로바이더를 못 잡으면 옵트인 fork(CLIProxyAPIPlus) 활성화부터 시도해 볼 만합니다.

매번 eval 치기 싫으면 ~/.zshrc에 한 줄을 넣어 영구화합니다.

[[ -s "$HOME/.ccs/init.zsh" ]] && source "$HOME/.ccs/init.zsh"

멀티 계정 사고를 디버깅할 때는 CCS_LOG=debug ccs glm "..." 식으로 한 번 돌려보면 어느 base URL로 갔는지, 어느 토큰을 썼는지 정확히 보이니 로그를 켜두는 게 필수입니다.

한 줄로

CCS는 Claude Code가 환경변수 두 개로 정의되는 도구라는 사실을 그대로 받아들인 도구입니다. 그 두 변수를 프로파일이라는 단위로 정리하고, OAuth 우회와 다중 계정까지 한 명령 표면 위로 올려놓았습니다. weekly cap 시대에 한 프로바이더에만 의지하는 게 부담스러워진 사용자에게 기본기에 가까운 도구가 됐고, 같은 영역에 claude-code-router 같은 더 큰 별 수의 경쟁자도 있습니다. 자기 워크플로우가 옮겨 다닐 곳이 셋 이상인지부터 보고, 그다음에 도구를 고르는 순서가 맞아요.


→ 다음 편: Claude Code Switcher (CCS) 2편: 디렉토리, 설정, 라우팅의 실제 — 사용자 머신의 ~/.ccs/를 직접 들여다보며 instance / shared 격리 모델, config.yaml의 9개 영역, 로컬 프록시의 5단계 변환을 풀어 봅니다.

참고

CCS 설정과 라우팅

· 약 14분

1편의 잔상

Claude Code Switcher (CCS) — 프로바이더 전환, 멀티 계정, 로컬 모델까지 한 명령으로표면의 글이었어요. CCS가 등장했는지, 무엇을 풀고 있는지, 누구에게 언제 맞고 안 맞는지를 다뤘어요. 그 글의 한 단락을 그대로 옮기면 이렇습니다.

CCS는 Claude Code가 환경변수 두 개로 정의되는 도구라는 사실을 그대로 받아들인 도구다. 그 두 변수를 프로파일 이라는 단위로 정리하고, OAuth 우회와 다중 계정까지 한 명령 표면 위로 올려놓았다.

2편은 그 표면 아래를 다룹니다. ~/.ccs/ 한 디렉토리에 무엇이 어떻게 사는지, config.yaml의 어느 키가 무엇을 결정하는지, instance와 shared가 어떻게 갈리는지, 로컬 프록시는 정확히 어떤 변환을 거치는지 살펴봅니다. 1편에서 표 한 줄로만 끝낸 부분을 시스템의 그림으로 풀어 봅니다.

이 글의 모든 디렉토리/키 이름은 사용자 머신의 실제 CCS 설치를 직접 들여다본 결과입니다. 토큰/세션 같은 민감한 값은 보지 않고 구조만 인용합니다.

~/.ccs/ 한 장 지도

CCS가 머신에 자리 잡으면 홈 디렉토리에 ~/.ccs/ 한 폴더가 생깁니다. 그 안의 트리가 사실상 CCS의 운영 모델 전부인데, 진짜 그림은 심볼릭 링크 체인입니다.

~/.claude/ ← 사용자의 기존 Claude Code 글로벌 (canonical)
├── settings.json
├── commands/, skills/, agents/, plugins/
└── projects/

~/.ccs/ ← CCS 영역
├── config.yaml ← 메인 설정 (YAML, 11K 정도)
├── .session-secret ← 세션 비밀 (64B, 절대 공유 금지)
├── .claude/ ← CCS *번들* (ccs.md, ccs-delegation 스킬 등 자체 주입)
├── cliproxy/bin/ ← CLIProxyAPI 바이너리 (자동 다운로드)
├── cache/, completions/, logs/

├── shared/ ← 사용자 정의 공유 영역
│ ├── settings.json → ~/.claude/settings.json (symlink)
│ ├── commands → ~/.claude/commands (symlink)
│ ├── skills → ~/.claude/skills (symlink)
│ ├── agents → ~/.claude/agents (symlink)
│ ├── plugins → ~/.claude/plugins (symlink)
│ └── context-groups/default/projects/ (실 디렉토리)

└── instances/ ← per-account 격리 영역
├── team/ ← 회사 Team account
│ ├── settings.json → ~/.ccs/shared/settings.json (symlink)
│ ├── commands → ~/.ccs/shared/commands (symlink)
│ ├── skills → ~/.ccs/shared/skills (symlink)
│ ├── agents → ~/.ccs/shared/agents (symlink)
│ ├── projects → ~/.ccs/shared/context-groups/default/projects/ (symlink)
│ ├── plugins/, .anthropic/, sessions/, session-env/ ← 실 디렉토리
│ ├── todos/, file-history/, shell-snapshots/, logs/ ← 실
│ ├── backups/, cache/, debug/, image-cache/, paste-cache/, plans/ ← 실
│ └── .claude.json, history.jsonl, .session-stats.json,
│ mcp-needs-auth-cache.json, policy-limits.json, remote-settings.json
└── enterprise/ ← 회사 Enterprise account (구조 동일)

여기서 눈여겨볼 것은 두 가지입니다. 하나는 2단계 symlink 체인입니다. instances/team/settings.json을 따라가면 ~/.ccs/shared/settings.json으로, 다시 ~/.claude/settings.json으로 이어집니다. 사용자의 기존 Claude Code 글로벌 설정이 모든 인스턴스에 자동 반영된다는 뜻이며, 한 번 만든 슬래시 커맨드, 스킬, MCP가 team과 enterprise 양쪽에서 살아 있는 이유도 여기에 있습니다.

다른 하나는 projects/만 체인이 한 단계라는 점입니다. 대화 히스토리는 instances/team/projects에서 ~/.ccs/shared/context-groups/default/projects/(실 디렉토리)까지만 가고 ~/.claude/projects/까지는 이어지지 않습니다. CCS가 자기 context-group 단위로 대화를 모아 사용자의 평소 Claude Code 대화와 자연히 분리해 두는 것으로, 회사 대화가 개인용 Claude Code에 섞이지 않도록 의도한 끊음입니다.

이 2단계 체인이 이중 구조라고 표현했던 것의 실제 메커니즘이며, 1편의 "공유 vs 분리"가 단일 축이 아니라 어느 단위까지 체인을 잇느냐의 문제였다는 뜻입니다. 5~6절에서 이 단위들을 풀어 봅니다.

config.yaml의 9개 영역

설정의 거의 전부는 ~/.ccs/config.yaml 한 파일에 모입니다. JSON이 아니라 YAML인 점이 의외인데, 사람이 손으로 읽고 고치기 좋은 쪽을 택한 것으로 보입니다.

키 구조만 추리면 9개 영역으로 나뉩니다.

version: # 메타
default: # 기본 프로파일

accounts: # *instance 단위* 메타
team:
context_mode: # isolated | shared
context_group: # shared 일 때 그룹 이름
continuity_mode: # 추가 공유 정책
enterprise:
...

profiles: # 프로바이더 프로파일 (glm, kimi, ollama, ...)

cliproxy: # OAuth 프록시 백엔드 설정
backend:
oauth_accounts:
providers:
routing:
strategy: # round-robin / fill-first
session_affinity:
session_affinity_ttl:

proxy: # 로컬 OpenAI-호환 프록시
profile_ports: # 프로파일별 포트 매핑
routing:
longContextThreshold:

cliproxy_server: # 원격/로컬 CLIProxy 서버
remote: { enabled, host, protocol, auth_token }
fallback: { enabled, auto_start }
local: { port, auto_start }

logging: # 로그 회전·보관
preferences: # theme, telemetry, auto_update

websearch: # ★ 8개 fallback 프로바이더
providers:
exa, tavily, brave, searxng, duckduckgo, gemini, opencode, grok

# --- 통합 (Claude Code 외부 도구들) ---
copilot: # GitHub Copilot 라우팅
cursor: # Cursor 통합 (ghost_mode 포함)
channels: # Telegram/Discord/iMessage
thinking: # opus/sonnet/haiku 별 thinking 기본값
global_env: # DISABLE_TELEMETRY 등 전역 env 자동 주입

이 9개를 한 번 훑으면 CCS가 단순 스위처가 아니라 Claude Code 주변의 운영 표면 전체를 흡수해 가고 있다는 인상이 분명해집니다. 12절에서 이 중 안 알려진 부분을 따로 추립니다.

Instance 시스템, symlink와 실 상태의 갈림

instances/<name>/ 디렉토리는 언뜻 보면 Claude Code의 모든 상태를 담은 통 같지만, ls -la로 열어 보면 절반은 shared/로의 symlink이고 나머지 절반만 인스턴스별 실 상태입니다. 둘을 갈라 두면 멘탈 모델이 명확해집니다.

먼저 모든 인스턴스가 공유하는 symlink 항목입니다.

항목가는 곳
settings.json~/.ccs/shared/settings.json~/.claude/settings.json
commands/~/.ccs/shared/commands~/.claude/commands/
skills/~/.ccs/shared/skills~/.claude/skills/
agents/~/.ccs/shared/agents~/.claude/agents/
projects/~/.ccs/shared/context-groups/default/projects/ (한 단계만)

settings.json의 최상위 키 9개는 체인을 따라가 본 결과 다음과 같습니다. 사용자의 기존 ~/.claude/settings.json 스키마 그대로입니다.

alwaysThinkingEnabled
enabledPlugins
env
extraKnownMarketplaces
hooks
permissions
skipAutoPermissionPrompt
skipDangerousModePermissionPrompt
statusLine

다음은 인스턴스별로 격리된 실 상태입니다.

분류항목
인증 (절대 안 섞임).anthropic/ (OAuth), .claude.json (사용자 메타)
세션/실행sessions/, session-env/, shell-snapshots/, history.jsonl
작업 상태todos/, file-history/, plans/ (team만), backups/
로깅/캐시logs/, cache/, debug/, image-cache/, paste-cache/
플러그인plugins/ — 인스턴스별 (claude-hud 같은 설치)
메타/정책policy-limits.json, remote-settings.json, mcp-needs-auth-cache.json, .session-stats.json
외부 통합.omc/ (oh-my-claudecode 상태)

한 가지 눈에 띄는 사실은 이 글의 plan 파일이 instances/team/plans/ccs-hashed-llama.md에 있다는 점입니다(이 항목은 real이고 symlink가 아닙니다). 이 글을 쓰는 동안 사용자의 Claude Code 세션이 team 인스턴스에서 돌고 있었다는 뜻입니다. CCS는 보이지 않게 CLAUDE_CONFIG_DIR 같은 환경변수로 인스턴스 컨텍스트를 끼워 넣습니다.

enterprise 인스턴스는 team보다 가볍게 비어 있는 상태였는데, 활성 사용 중인지 아닌지가 디렉토리 충실도에 그대로 드러납니다. CCS는 인스턴스를 만들 때 symlink와 빈 디렉토리만 만들어 두고, 실제로 사용해야 실 데이터가 채워지는 lazy 모델입니다.

shared/와 context-groups로 1편의 빈칸 메우기

1편의 "설정/대화는 공유하면서 계정만 분리하고 싶다면" 단락의 진짜 답이 여기 있습니다. CCS는 이 시나리오를 shared/라는 별도 영역과 context_mode/context_group 설정으로 정식 지원합니다.

config.yamlaccounts: 섹션:

accounts:
team:
context_mode: isolated # 또는 shared
context_group: default # shared 일 때만 의미
continuity_mode: deeper # 또는 default
enterprise:
context_mode: shared
context_group: default
continuity_mode: deeper

세 키의 역할:

context_mode: isolated | shared는 인스턴스가 자기 디렉토리에만 사는지, 같은 그룹의 다른 인스턴스와 공유하는지를 정합니다. context_groupshared일 때 쓸 그룹 이름이며, ~/.ccs/shared/context-groups/<group>/가 그 그룹의 공유 데이터 자리입니다. continuity_mode: deeper는 공유의 깊이를 정하며, deeper는 더 많은 디렉토리를 공유 대상에 포함합니다.

이 셋을 조합해 보면 1편에서 "공유 vs 분리"라고 단순화한 구도가 사실 세 축의 조합임이 드러납니다.

무엇이 공유 가능하고 무엇이 항상 격리되는가

CCS의 공식 docs는 이 부분을 명시해 두지 않습니다.

CCS only shares workspace context paths (project/session context files). It does not merge or copy authentication credentials between accounts.

docs/session-sharing-technical-analysis.md

요약 표:

분류대상동작
shared (조건부)session-env/shared + deeper 일 때 그룹 안에서 공유
shared (조건부)file-history/동일
shared (조건부)shell-snapshots/동일
shared (조건부)todos/동일
항상 격리.anthropic/ (OAuth)인증은 어떤 모드에서도 인스턴스별
항상 격리인증 토큰 / 자격증명동일
수동 공유commands/, skills/, agents/, plugins/shared/<dir>/에 두면 모든 인스턴스가 사용

인증은 어떤 경우에도 섞이지 않습니다. 한 인스턴스의 OAuth 토큰이 실수로 다른 인스턴스의 요청에 흘러갈 일이 구조적으로 없으므로, 회사 환경에서 가장 큰 사고 가능성을 시스템 자체가 막아 둡니다.

ccs -r (resume)는 현재 활성 lane만 이어가고, ccs <account> -r은 그 인스턴스의 lane만 이어갑니다. 두 인스턴스 모두 다른 continuity 인벤토리를 가질 수 있다는 점을 의식하고 운영해야 합니다.

4가지 진입점: Target Adapter System

ccs가 Claude Code만 호출하는 게 아닙니다. CCS는 runtime 자체를 바꾸는 4가지 바이너리를 노출합니다.

바이너리runtime
ccsClaude Code (기본)
ccsd / ccs-droidFactory Droid
ccsx / ccs-codexCodex CLI (네이티브)
ccsxpCodex CLI + CLIProxy 프로바이더 오버라이드

내부적으로는 각 바이너리가 CCS_INTERNAL_ENTRY_TARGET 환경변수를 세팅한 후 target resolver에 위임합니다. resolver의 우선순위:

  1. CLI 플래그 (--target)
  2. 진입 바이너리 자체
  3. argv[0] 이름 검출
  4. 프로파일별 config
  5. 기본값

이 추상화 덕분에 "Claude Code로 GLM 돌리기"와 "Droid로 GLM 돌리기"가 같은 명령 표면 위에서 가능합니다(ccs glm vs ccs --target droid glm). Codex의 경우 자기 ~/.codex/ 상태를 별도 보존하려고 환경변수만 임시로 덮어쓰는 식으로 신경을 더 씁니다.

로컬 프록시 (127.0.0.1:포트)의 5단계 흐름

ccs glm 같은 OpenAI-호환 프로바이더 명령이 들어오면 다음 5단계를 거칩니다(docs/openai-compatible-providers.md 정리).

  1. 127.0.0.1에서 그 프로파일의 로컬 포트 바인딩 (포트는 proxy.profile_ports에서 할당)
  2. Claude Code가 보내는 Anthropic 형식 /v1/messages 요청 수신
  3. OpenAI chat-completions 형식으로 변환
  4. 업스트림 프로바이더로 포워드
  5. 스트리밍 응답을 다시 Anthropic SSE로 역변환해 Claude Code에 돌려줌

정리하면 Claude Code는 자기가 Anthropic과 이야기하는 줄 알고, 변환은 프록시 한 점에서만 일어나므로 디버깅 지점도 한 곳으로 모입니다.

Anthropic-호환 엔드포인트는 프록시를 우회합니다. https://api.anthropic.com이나 Z.AI의 /api/anthropic으로 가는 요청은 변환이 필요 없어 그냥 직통하고, 이 분기 덕분에 GLM 사용은 추상화 비용이 거의 0입니다.

CLIProxyAPI 서버 자체는 기본적으로 port 8317에서 동작하는데, cliproxy_server.local.port로 바꿀 수 있고 remote.host를 켜면 다른 머신의 CLIProxy를 쓸 수도 있습니다.

시나리오 라우팅 4종

CCS가 수동으로 프로바이더를 명시하지 않아도 자동으로 라우팅하는 4가지 시나리오가 있습니다.

시나리오트리거
background요청이 Haiku를 포함 (가벼운 백그라운드 작업)
thinkAnthropic extended thinking 활성화
longContext토큰 추정치가 임계값 초과 (proxy.routing.longContextThreshold)
webSearchweb_search 툴 호출

config.yamlproxy.routing.longContextThreshold 키가 실제로 있어 임계값을 손으로 조절할 수 있습니다. 자동화의 깊이는 워크로드에 따라 잘 맞기도 하고 헷갈리기도 하므로, 처음부터 라우팅 룰을 복잡하게 짜기보다 한 주 동안 단순하게 운영한 뒤 패턴을 보고 추가하는 편이 낫습니다(1편 팁 7절 참조).

CLIProxy 서브시스템, OAuth 프로바이더의 자리

API 키가 없는 OAuth 기반 프로바이더(Gemini, GitHub Copilot, AWS Kiro 등)는 별도 서브시스템이 책임집니다. ~/.ccs/cliproxy/bin/에 자동 다운로드되는 CLIProxyAPI 바이너리가 그 핵심입니다.

이 서브시스템의 Account manager는 OAuth 토큰의 lifecycle(발급, 갱신, 만료)을 관리하고, Quota manager와 Quota fetcher는 각각 프로바이더별 quota 추적과 자동 failover, 사용량 실시간 동기화를 맡습니다. Auth handler는 Anthropic, Gemini, Copilot, Kiro 등 각 프로바이더의 OAuth 흐름을 처리합니다. Model catalogs에는 프로바이더별 모델 목록과 compatibility 가드가 있으며, codex-plan-compatibility.ts 같은 파일이 plan별로 맞지 않는 모델 조합을 막아 줍니다. Hybrid quota strategy는 round-robin 또는 fill-first(cliproxy.routing.strategy) 방식으로 같은 프로바이더의 여러 OAuth 계정을 어떻게 분산할지 정합니다.

config.yamlcliproxy.oauth_accounts가 등록된 OAuth 계정 목록을 담는데, 이 부분은 토큰을 포함하므로 git에 올리면 안 되는 영역입니다. 다음 11절에서 정리합니다.

파일 관리 실전: symlink가 dotfiles의 답입니다

2절의 symlink 체인을 보고 나면 자연스레 이런 질문이 나옵니다. 내 CCS 환경을 다른 머신에 어떻게 옮기는지, ~/.ccs/를 통째로 git에 넣어도 되는지 궁금해집니다. ~/.ccs/를 versioning하지 않고 ~/.claude/를 versioning해 CCS가 그쪽을 끌어들이게 하면 됩니다.

멘탈 모델: ~/.claude/가 source of truth

체인의 시작점은 ~/.claude/입니다. CCS의 shared/와 instance들은 그쪽으로 가는 포인터일 뿐입니다. 따라서 dotfiles의 운용 원칙은 하나로 압축됩니다. ~/.claude/를 git으로 관리해 두면, 새 머신에 CCS를 설치하더라도 shared/만 같은 symlink로 다시 걸어 모든 인스턴스가 같은 환경을 보게 됩니다.

git에 올리기 좋은 자산 (~/.claude/ 쪽)

~/.claude/commands/, ~/.claude/skills/, ~/.claude/agents/에는 각각 슬래시 커맨드, 스킬, 에이전트 정의가 들어가므로 git에 올리기 좋습니다. 글로벌 메모리인 ~/.claude/CLAUDE.md도 관리 대상입니다. ~/.claude/settings.json은 토큰을 직접 적어 두지 않은 경우에만 포함해야 하며, env 필드에 비밀이 있다면 settings.local.json 패턴으로 분리합니다. 실 디렉토리인 ~/.ccs/shared/context-groups/default/에서는 projects/를 빼고 CCS의 그룹 메타만 versioning하는 식으로 관리합니다.

~/.ccs/.claude/ (CCS 번들)은 npm 패키지 일부라 install 시 자동으로 따라옵니다. 직접 versioning 할 필요 없습니다.

절대 git 금지 (자격증명, 세션, 트랜스크립트)

~/.ccs/config.yaml에는 OAuth 토큰/refresh_token이 있으므로 머신별로 보관하고, 세션 비밀인 ~/.ccs/.session-secret도 제외합니다. ~/.ccs/instances/*/.anthropic/의 Anthropic OAuth와 계정 식별자를 포함한 ~/.ccs/instances/*/.claude.json도 올리면 안 됩니다.

~/.ccs/instances/*/sessions/, session-env/에는 세션과 세션별 env가 있어 토큰 환경변수가 들어갈 가능성이 있습니다. ~/.ccs/instances/*/history.jsonl, file-history/에는 명령과 파일 history가 남아 회사 코드의 흔적이 섞일 수 있습니다. 대화 히스토리 본체~/.ccs/shared/context-groups/*/projects/도 PII나 회사 코드를 포함할 가능성이 있으므로 제외합니다. 바이너리와 휘발성 데이터가 담긴 ~/.ccs/cliproxy/, cache/, logs/, 평소 Claude Code 대화 히스토리인 ~/.claude/projects/도 git에 올리지 않습니다.

새 머신 부트스트랩 4단계

dotfiles가 ~/.claude/만 들고 있다고 할 때 새 머신에서 같은 환경을 만들려면:

  1. dotfiles를 clone해 ~/.claude/를 채웁니다.
  2. npm install -g @kaitranntt/ccs로 CCS를 설치합니다.
  3. ccs config로 초기 ~/.ccs/ 골격을 생성합니다.
  4. symlink를 재구성합니다. ~/.ccs/shared/{commands,skills,agents,plugins,settings.json}~/.claude/의 동명 항목으로 link하며, 한 줄 스크립트로 자동화하기를 권장합니다.
ln -sf ~/.claude/commands ~/.ccs/shared/commands
ln -sf ~/.claude/skills ~/.ccs/shared/skills
ln -sf ~/.claude/agents ~/.ccs/shared/agents
ln -sf ~/.claude/plugins ~/.ccs/shared/plugins
ln -sf ~/.claude/settings.json ~/.ccs/shared/settings.json

이 다섯 줄로 새 머신에서도 1편의 instance들이 평소 환경을 그대로 봅니다. OAuth 인증만 각 인스턴스에서 새로 하면 끝입니다.

격리의 운영 이점

한 인스턴스가 망가져도(plugins/ 깨짐, policy-limits.json 누락 등) 다른 인스턴스는 그대로이므로 단일 장애점이 줄어드는 부수 효과가 있습니다. 인스턴스 단위 백업에는 tar czf team-backup.tgz -C ~/.ccs/instances team을 씁니다. symlink는 그대로 보존하며, 옵션 -h를 추가하면 링크가 가리키는 파일까지 따라가 archive합니다. 복원할 때 같은 dotfiles 환경을 가정하므로 보통은 symlink를 그대로 두는 편이 의미 있습니다.

config.yaml의 비공식 영역들

CCS의 README가 강조하지 않지만 config.yaml 키만 봐도 드러나는, 단순 스위처라기엔 풍부한 통합이 여럿입니다.

가장 눈에 띄는 것은 WebSearch fallback입니다. websearch.providers 아래에 exa, tavily, brave, searxng, duckduckgo, gemini, opencode, grok 여덟 곳이 등록돼 있어, Claude Code의 WebSearch가 Anthropic 밖 8개 프로바이더로 넘어갈 수 있습니다. docs/websearch.md가 별도 문서로 있을 만큼 일급 통합입니다. 외부 에디터/툴 통합도 넓어서, copilot.account_type, rate_limit, model로 GitHub Copilot을 프로바이더 한 슬롯처럼 다루고 cursor.ghost_mode/cursor.port로 Cursor의 ghost-mode까지 건드립니다. channels.selected, channels.unattended를 통해 Telegram, Discord, iMessage로 Claude에게 일을 시키는 통합도 있습니다(1편의 free-claude-code 텔레그램 봇 사례와 같은 결입니다).

세밀한 정책 키도 있습니다. thinking.tier_defaults는 opus, sonnet, haiku별로 thinking 기본 모드를 다르게 잡게 해주고(Opus는 항상 deep thinking, Haiku는 끄는 식), global_env.envDISABLE_BUG_COMMAND, DISABLE_ERROR_REPORTING, DISABLE_TELEMETRY는 보안, 프라이버시에 민감한 회사 환경에서 텔레메트리를 자동으로 꺼줍니다. cliproxy.routing.session_affinitysession_affinity_ttl은 같은 세션을 같은 OAuth 계정으로 sticky하게 묶는 정책입니다. 이런 영역들은 CCS가 단순 스위처에서 운영 플랫폼으로 진화 중이라는 신호입니다.

한 줄로

1편이 CCS의 표면이었다면 2편은 안쪽입니다. 안쪽을 보고 나면 "프로파일로 옮겨 다닌다"는 1편의 단순한 설명이 사실은 instance 격리, shared 공유, OAuth 분리, OpenAI와 Anthropic 사이의 변환, 시나리오 라우팅, 여러 통합 지점이라는 축들로 짜여 있다는 게 보입니다. 추상화가 두껍다는 1편의 단점 평가는 그래서 정확하지만, 그 두께가 풀고 있는 문제도 같이 두껍다는 사실이 디렉토리 한 통에 적나라하게 드러납니다.

다음 편이 있다면 두 갈래 중 하나일 가능성이 커요. proxy.routing 시나리오를 실제 워크로드로 맞춰 보는 실측 운영 글이거나, CCS와 dotfiles, Anthropic Workspaces를 엮는 멀티-머신 계정 운영 글일 거예요. 어느 쪽이 먼저 나올지는 다음 글에서 정할게요.

참고