무엇인가
사용량을 보려고 보낸 호출이 사용량을 썼다.
계정별 사용률을 보여 주는 대시보드에서
조회 한 번은 곧 실제 요청 한 번이다.
지금은 Claude Code가 응답마다 써 두는 값을 읽기 때문에,
대화 중인 계정은 호출 없이도 사용률이 바뀐다.
이 대시보드가 붙은 도구가 cct다.
cct는 여러 Claude 구독 계정을 골라 쓰는 셸 지갑이자 사용량 대시보드다.
계정마다 claude setup-token으로 한 번 인증해서 받은 장기 토큰을
로컬 지갑에 등록하고
cct 뒤에 라벨을 붙이면 그 계정으로 Claude Code가 실행된다.
Claude Code를 여러 구독 계정으로 번갈아 써야 할 때 쓰고,
한도를 볼 때는 cct usage나 대시보드를 쓴다.
지갑을 안전하게 옮기면 새 PC에서도
계정마다 브라우저 로그인을 다시 하지 않아도 된다.
macOS, Linux, WSL2(윈도우 안의 리눅스)에서 동작한다.
어떤 계정을 쓸지는 언제나 사람이 고른다.
README에도 이 도구는 프록시도, 자동 라우터도,
로드밸런서도 아니라고 적혀 있다.
왜 만들었나
출발점은 로그인 하나가 막혔을 때를 대비하는 것이었다.
6월 19일 오전에 다른 계정으로 넘어가되,
"웹으로 인증받지않고도 끊임없이 이어질수있게" 해 달라고 적었다.
그날 오후에는 키체인에 등록하는 이유를 묻고 파일 보관을 제안한 뒤,
"env하자. 나 wsl2 쓰는 pc도있어."라는 말로 보관 방식을 정했다.
이름도 같은 날 바뀌었다.
처음 만든 cc 계열 명령은 cc check를 치면 Claude Code가 뜨고
check가 프롬프트로 들어가 버렸다.
"cc 시리즈를 cct로 전부변경하자"고 해서 이름이 cct가 됐다.
어느 PC에서든 클론해서 바로 쓸 수 있도록 공개 리포로 올렸고
README는 한국어와 영어로 작성했다. 첫 커밋은 그날 저녁에 했다.
대시보드는 9월에 귀찮음 때문에 만들었다.
"맨날 cct usage --all 치려니 귀찮아서말이야."
로컬용이어야 하고, 윈도우에서도 같이 볼 수 있어야 한다는 조건을 붙였다.
어떻게 동작하나
셸 스크립트 하나가 지갑을 관리하고 대시보드는 그 스크립트를 호출한다.
첫 커밋은 셸 스크립트 154줄을 포함해 6개 파일, 350줄이었다.
토큰은 권한 600 파일에 보관하고 실행할 때만 주입했다.
6월 말에는 고른 라벨을 셸에 고정하는 활성 프로필을 추가했다.
cct off로 해제하기 전까지는 그냥 claude를 쳐도 같은 계정으로 실행된다.
7월 초에 병합한 풀 리퀘스트 #1이 cct를 휴대용 지갑으로 만들었다.
지갑 쓰기를 원자적이고 권한 600이며 백업되는 잠금으로 묶었고,
macOS와 우분투에서 가짜 픽스처만으로 실행되는 자동 시험을 붙였다.
그 풀 리퀘스트 본문에도 프록시, 데몬, 자동 라우팅은 더하지 않았다고 적혀 있다.
사용량 조회는 7월에 cct usage로 추가됐다.
setup-token에는 user:profile 권한이 없어서
공식 사용량 API(프로그램용 조회 창구)가 403을 돌려준다.
그래서 1토큰짜리 요청을 보내고
응답에 붙어 오는 rate-limit 헤더에서 사용률과 리셋 시각을 읽는다.
조회 한 번이 곧 실제 호출 한 번이다.
대시보드 서버는 의존성 없는 파이썬 파일 하나다.
조회 로직을 다시 짜지 않고 cct를 호출한다.
헤더 해석 규칙과 지갑 잠금을 cct 한 곳에만 두려는 선택이었다.
조회가 곧 소비이므로 첫 구현부터 갱신 정책을 기능으로 넣었다.
서버는 자동 갱신 주기의 하한을 15분으로 강제하고
같은 라벨을 60초 안에 다시 조회하면 429로 거절한다.
계획 문서는 계정 여러 개를 자동 갱신하면
하루에 약 9천 토큰이 든다고 추정했다.
이 수치는 설계 단계에서 낸 추정치다. 기본값은 자동 갱신 끔이다.
9월 말에는 한도에 걸린 이유를 확인하려고 계정별 상세 화면을 추가했다.
"언제 어떻게 사용해서 지금 limit이 걸렸는지 추적을 하고싶은거야."
"계정카드를 클릭해서들어가면 그 계정에대한 상세정보를 볼수있게."
cct가 claude를 실행할 때 라벨을 함께 넘기면,
Claude Code의 SessionStart 훅이 시각과 세션 id, 라벨을 한 줄씩 기록한다.
토큰과 대화 내용은 기록하지 않는다.
README는 2026-10-19 확인 기준으로, 웹·앱·다른 PC에서 쓴 양은 사용률로만 보인다고
적는다.
2026-10-19 확인 기준으로 마지막 커밋인 10월 16일 커밋까지
71개 중 35개에 Claude 공동 작성 표기가 붙어 있다.
발행 카탈로그는 내 역할을 "제품 계약과 설계 판단"으로 적는다.
9월 19일 커밋 메시지는 ChatGPT와 SuperGrok 사용량 칸을 추가하면서
그 토큰을 지갑에 합치는 안은 기각했다고 적는다.
이유는 cct가 Claude 계정 지갑이라는 제품 계약을 지키는 것이었다.
써 보니
남은 사용 흔적으로는 훅 기록과 GitHub 지표가 있다.
훅 기록은 9월 25일 저녁부터 10월 18일 밤까지 462건이고
고유 세션 id는 435개, 기록이 있는 날은 23일이다.
이 수는 SessionStart 훅이 남긴 줄 수다.
라벨이 걸린 셸에서 그냥 실행한 claude와
cct check 조회 세션도 여기에 포함된다.
GitHub 스타는 3개다(다른 계정 2개, 내 계정 1개).
포크와 이슈는 0이다.
최근 14일 동안 클론은 28회(고유 19)였지만
트래픽 API는 누가 클론했는지 알려 주지 않는다.
효용을 평가한 기록은 이슈와 풀 리퀘스트, 세션 원문 검색에서 찾지 못했다.
토큰·비용 분석을 붙인 9월 커밋에는 대화 기록을 전수 스캔한 결과가 적혀 있다.
1,098개 파일, 847MB를 2.9초에 읽고 고유 19,263건을 셌다.
파일 단위로 중복을 지우면 세션 이어쓰기로 복제된 3,142건이
이중으로 잡혀 2배 이상 부풀기 때문에,
메시지 id와 요청 id를 기준으로 전체에서 중복을 지웠다.
실패와 고친 것
실패는 첫날부터 발생했다.
등록한 계정이 정말 그 계정인지부터 확신할 수 없었다.
"아무래도 불안해. 각 계정마다 돌아가면서 테스트해보게."
얼마 뒤 처음 등록한 계정이 잘못 들어간 것 같아서 다시 로그인해 바꿨다.
그날 저녁 첫 커밋의 도움말에는 계정 지문으로 중복을 찾는 fp 명령이 들어 있다.
"7d_reset 같으면 같은 계정"이라는 설명도 붙어 있다.
6월 23일 커밋은 401 오류가 나던 동작을 없앴다.
라벨 없이 cct를 치면 키체인 로그인으로 돌아가던 동작이 원인이었다.
키체인 access token은 약 8시간마다 만료되는데,
세션이 그 경계에 걸치면 갱신이 늦어져 401("Please run /login")로 중단됐다.
진입점을 전부 장기 setup-token으로 통일해서 문제를 풀었다.
9월 25일 저녁에는 넣은 기능을 같은 저녁 안에 지웠다.
계정별 상세 화면을 작업하던 중 에이전트가 낸 진행안에 "조회 주기 자동 조절"이 있었다.
그 계정으로 세션이 돌 때만 5분 간격으로 조회한다는 항목이다.
첫 구현에서 빠진 이 항목을 리뷰어가 명세와 대조하면서 잡아냈고,
19시 17분 커밋이 그 항목을 채웠다. 그다음에는 내 질문이 이어졌다.
19:17 5분 실조회 커밋 (마지막 메시지가 10분 안인 계정만)
19:33 "5분조회 토큰소모량이 어느수준이지?"
19:42 "꼭 호출을통해서 사용량을 집계할수밖에없어?"
19:49 "쉽게말해봐. 토큰을 안쓰고 동일하게 동작할수있다는거야?"
19:58 "그럼 갱신버튼 안눌러도 계속 refresh가 되는상태가되는건가?"
20:03 5분 실조회 삭제, statusline 캐시 읽기로 교체첫 질문에 에이전트는 조회 한 번이 약 60토큰 이하이고
세션이 도는 계정 하나에 시간당 약 700토큰이 든다고 답했다.
한도 계산에서 이 호출에 가중치를 더 줄 수 있고
그 가중치는 공개돼 있지 않다는 단서가 붙었다.
두 번째 질문에 돌아온 답은 statusline이었다.
Claude Code가 응답마다 쓰는 statusline(입력창 아래 상태 줄) 캐시에
세션 id와 사용률이 이미 들어 있었다.
에이전트가 "이걸로 바꿀까요?"라고 물은 뒤 나는 19시 58분에 다시 물었다.
에이전트가 대화 중인 계정은 버튼을 누르지 않아도 계속 새 값으로 바뀐다고 답하고
다시 "바꿀까요?"라고 묻자 9초 뒤 "ㅇㅇ"라고 답했고
20시 03분 커밋이 5분 실조회와 그 설정을 지웠다.
기능을 넣은 지 45분 56초 만이다.
10월 7일 커밋은 재부팅 뒤 대시보드 서버가 크래시루프에 빠진 사고를 고쳤다.
목업용으로 띄웠던 launchd 정의가 남아 있다가 같은 127.0.0.1:8790을 먼저 점유했고
실서버는 Errno 48(주소 사용 중)로 계속 죽었다.
목업 잡을 내리고, 목업 화면과 롤백용 정의까지 지웠다.
롤백용 정의를 남겨 두면 재설치할 때 실수로 같은 사고가 되풀이되기 때문이다.
| 시기 | 실패 | 고친 것 |
|---|---|---|
| 6월 19일 | 설치 스크립트가 전역 ignore 설정을 덮어쓰는 등 결함 11건 | 같은 날 수정, 네트워크 없는 행동 테스트 62개 |
| 6월 말~7월 초 | 자동 시험 초기 설정 | fix(ci) 커밋 6개(GNU stat 우선, ShellCheck 진단 대응 등) |
| 7월 12일 | 웹 기능 차단용 변수가 자동 업데이트까지 끔 | 개별 플래그로 나눔, 테스트 610/610 |
| 9월 25일 | 두 번째 최종 리뷰가 확정한 결함 8건 | 한 커밋으로 수정, 수정별 전용 회귀 테스트 없이 재현 스크립트·기존 스위트로 확인 |
지금 상태
2026-10-19 확인 기준으로 운영 중이다.
그 시점에 대시보드 서버는 launchd로 떠 있고
127.0.0.1:8790이 HTTP 200으로 응답한다.
같은 시점에 열린 이슈는 0이고 git 태그 없이 발행하지 않은 변경 묶음 세 개가 쌓여 있다.
리포는 MIT 라이선스로 GitHub에 공개돼 있다.
커밋 메시지에 남은 한계는 이렇다.
2026-10-19 기준 마지막 커밋인 10월 16일 커밋의 메시지는
대시보드 테스트 하나가 그 커밋 전에도 실패했다고 적는다.
고정해 둔 날짜가 집계 창 밖으로 밀려났기 때문이다.
9월 25일 커밋 메시지는 statusline에 프리미엄 7일 창이 없어 그 창은
마지막 조회 값을 유지한다고 적었다.
같은 메시지는 다른 계정 세션을 동시에 돌릴 때 놓치는 갱신의 빈도를 시험하지 않았다고 했다.