내장 anthropic 프로바이더는 shunt의 기본 목적지입니다: 일치하는 라우트가 없는 모델은 모두
api.anthropic.com으로 변경 없이 전달됩니다(server.default_provider로 설정 가능).
이는 kind = "anthropic" 프로바이더입니다 — 업스트림이 이미 Anthropic Messages API를 사용하므로,
shunt는 변환 없이 요청을 패스스루하고 어떤 자격 증명을 업스트림으로 보낼지만 결정합니다.
요청 필드 하나만은 예외입니다. shunt가 다른 프로바이더용으로 생성한 signature를 담은 thinking
블록은 요청을 전달하기 전에 제거되며(Responses·Gemini·Cursor 경로가 각각 하나씩 생성합니다 —
블록이 형식을 갖추려면 이 필드가 필요하기 때문입니다), 그 결과 아무것도 남지 않은 assistant 턴도
함께 제거됩니다. Anthropic은 이 필드를 복호화하므로 자신이 발급하지 않은 값은 거부하며, 그대로
전달하면 요청이 실패합니다. Anthropic이 발급한 signature는 shunt에게 불투명하므로 절대 건드리지
않습니다. 이 제거는 대화 이력을 확인하지 않으므로 매핑된 프로바이더를 사용한 세션에만 국한되지
않습니다 — signature가 아예 없는 thinking 블록도 함께 제거됩니다. shunt의 Responses 경로가
업스트림에서 signature를 받지 못했을 때 그런 블록을 만들고, Anthropic은 어느 쪽이든 검증할 수 없는
signature를 가진 thinking 블록을 거부하기 때문입니다.
서드파티 Anthropic 계열 프로바이더 — api.anthropic.com이 아니고 claude_oauth 풀도 아닌
kind = "anthropic" 업스트림(MiniMax, Kimi, Zhipu 등) — 는 Anthropic이 발급하지 않은
signature를 thinking 블록에 붙일 수 있습니다. shunt는 스트리밍 여부와 관계없이 클라이언트로 가는 응답에서 이
signature를 프로바이더 base_url(끝의 / 제거)의 다이제스트를 담은 자체 envelope로 감쌉니다. URL 자체는 담지 않으므로 URL과 거기 포함된 자격 증명은 클라이언트에 노출되지 않습니다. 다만 다이제스트는 솔트 없는 고정값이라 추측을 확인하는 데 쓰일 수 있습니다. 잘 알려진 엔드포인트나 그 안에 넣은 약한 자격 증명처럼 base_url 전체를 추측할 수 있다면, 그 추측이 맞는지 다이제스트와 대조해 확인할 수 있습니다. 이후 턴이 같은 base_url의
프로바이더로 돌아가면 shunt가 envelope를 풀어 원래 signature를 바이트 그대로 전달하므로, 그
프로바이더의 extended thinking 연속 호출은 계속 동작합니다. Anthropic을 포함한 다른 곳으로 보내면
envelope는 shunt가 생성한 값으로 취급되어 위와 같이 블록이 제거됩니다. 따라서 서드파티 Anthropic
계열 프로바이더와 Anthropic 사이를 오가면 요청이 실패하는 대신 그 프로바이더의 thinking 블록이
제거되고, 같은 프로바이더로 돌아가면 다시 복원됩니다. api.anthropic.com과 claude_oauth 풀의
응답은 절대 감싸지 않습니다.
| 인증 모드 | 자격 증명 | 사용 사례 |
|---|---|---|
passthrough (기본값) |
호출자 본인의 x-api-key / Authorization |
투명 프록시 — 각 클라이언트가 자신의 키나 OAuth 토큰을 가져옴 |
api_key |
env 변수에서 읽는 서버 측 키 | 운영자 소유의 API 키 하나로 모든 요청을 다시 키잉 |
claude_oauth |
shunt가 관리하는 하나 이상의 Claude 구독 계정 | 풀링과 쿼터 인지 로테이션을 통해 Claude 구독을 사용 |
빠른 시작
코딩 에이전트가 대신 구성하도록 하세요 — shunt add는 내장된 설정 블루프린트를 출력합니다
(오프라인·읽기 전용이며, 구성은 에이전트가 편집하고 이 명령은 절대 편집하지 않습니다):
shunt add upstream anthropic --print | claude또는 아래의 수동 단계를 따르세요.
업스트림 구성
anthropic은 내장입니다 — 구성이 전혀 없어도 shunt는 라우팅되지 않은 모델을 이미 passthrough로
그쪽에 전달합니다. 명시적으로 선언하려면(순서가 있는 페일오버를 위해서, 또는 인증을 바꾸기 위해서)
kind = "anthropic", base_url = "https://api.anthropic.com", auth = "passthrough"를 제공하는
프리셋을 사용하세요:
[[upstreams]]
name = "anthropic"
provider = "anthropic"명시적으로 지정한 필드는 프리셋 기본값을 오버라이드합니다. 레거시 [providers.anthropic] 테이블 형식도
계속 지원됩니다 — 다만 한 파일에서 [[upstreams]]와 [providers.*]를 섞지 마세요.
패스스루 (기본값)
더 구성할 것이 없습니다: shunt는 클라이언트 본인의 x-api-key 또는 Authorization 헤더를
전달합니다. 서버 측 시크릿은 구성에 들어가지 않습니다. 클라이언트가 어떤 자격 증명을 보내야 하는지는
Claude Code 연결에서 다룹니다.
서버 측 API 키
호출자가 키를 가져오리라 믿는 대신 운영자 소유의 키를 주입하세요:
[[upstreams]]
name = "anthropic"
provider = "anthropic"
auth = { mode = "api_key", env = "ANTHROPIC_API_KEY", header = "x_api_key" }서버 측 자격 증명을 주입한다면, 루프백 밖으로 노출하기 전에
[server.auth]로 게이트웨이를 보호하세요.
Claude 구독 계정 (claude_oauth)
갱신 가능한 shunt 관리 계정을 한 번 만든 다음, 업스트림을 그 계정으로 한정하세요:
shunt login claude --name primary --mode oauth[[upstreams]]
name = "anthropic"
provider = "anthropic"
auth = { mode = "claude_oauth", account = "primary" }shunt login claude에는 세 가지 모드가 있습니다: --mode oauth는 shunt 자체의 갱신 가능한 OAuth
플로우를 실행하고(권장), --mode import는 현재 Claude Code 로그인을 복사하며, --mode setup-token은
1년짜리 추론 전용 토큰을 생성합니다. account(그리고 accounts)를 생략하면 shunt가 관리하는 계정
스토어 전체를 스캔합니다 — 스토어에 계정이 여러 개 있으면 이는 세션 고정성과 쿼터 인지 로테이션을 갖춘
부하 분산 풀이 됩니다. 전체 풀링 동작 — 명시적 계정 항목, 계정별 임계값, [server.pool] 튜닝,
페일오버 — 은 Anthropic 멀티 계정에 문서화되어 있습니다.
모델 & 라우팅
기본 프로바이더이므로 anthropic에는 라우트가 필요 없습니다 — 다른 곳에 매핑하지 않은 것은 모두
여기로 옵니다. 순서가 있는 페일오버 체인 안에서 모델을 명시적으로 고정하려면:
[[models]]
id = "claude-sonnet-5"
display_name = "Claude Sonnet 5"
[models.upstream_model]
anthropic = "claude-sonnet-5"맵의 키는 프리셋 id가 아니라 [[upstreams]].name입니다.
auto_include_builtin_models = true(기본값)이면, GET /v1/models는 server.default_provider가
Anthropic 종류일 때 먼저 그쪽의 실시간 모델 목록을 시도합니다. 그렇지 않으면 shunt의 내장 Claude 카탈로그
스냅샷으로 폴백합니다 — 모델 디스커버리를 참고하세요.
자동 모드 분류기
Claude Code를 자동 모드로 실행하면, 워크스페이스를 벗어나거나 네트워크를 건드리는 모든 동작은
권한 분류기를 거칩니다 — 대기 중인 동작에 대한 안전성 판정을 모델에게 묻는, 시스템 프롬프트가
따로 붙은 별도의 Messages 요청입니다. 이 요청은 구독 OAuth 자격 증명에서 api.anthropic.com이
확인하는 Claude Code identity 블록을 빠뜨리며, CLAUDE_CODE_ATTRIBUTION_HEADER=0일 때 mod의
$.model.complete 같은 사이드 쿼리도 마찬가지입니다. shunt는 auto-mode 분류기와, 허용된 마커가
없는 모든 Claude Code 요청(x-claude-code-session-id, claude-cli/ user agent 또는 x-app: cli로 식별)에
identity를 복원합니다. 이 복원은 나가는 bearer가 구독 OAuth 토큰일 때만 적용되고, 업스트림이 확인하지
않는 count_tokens에는 적용되지 않으며, 빈 x-claude-code-session-id는 Claude Code로 보지 않습니다.
다른 클라이언트와 API 키 요청에는 이 복원을 적용하지 않습니다. 이 복원이 막아주는 실패는
429 문제 해결 항목에 설명되어 있습니다.
분류기는 기본적으로 세션의 모델을 쓰지 않습니다. Claude Code 2.1.226에서 측정한 바로는, 서버가
모델을 지정해 주면 그것을, 아니면 Sonnet 티어 별칭을, 그마저도 없으면 세션 자신의 모델을
씁니다 — ANTHROPIC_DEFAULT_SONNET_MODEL이 분류기까지 옮기는 이유이며, 와이어에서 확인했습니다.
이는 배포된 클라이언트에서 읽어낸 내용이라 계약이 아니라 측정한 버전에 대한 설명입니다.
classifier_model을 설정하면 세션 자신의 턴이 어떤 모델로 도는지는 그대로 둔 채, 게이트웨이 쪽에서
분류기 요청만 특정 모델에 고정할 수 있습니다:
[providers.anthropic]
kind = "anthropic"
base_url = "https://api.anthropic.com"
classifier_model = "claude-sonnet-5"이 키는 kind = "anthropic" 프로바이더에서만 받으며, 해당 프로바이더 안에서의 모델 리맵이지
다른 프로바이더로 가는 라우트가 아닙니다. 분류기 요청은 stop_sequences에 의존합니다. shunt의
Responses 변환이 이 필드를 떨어뜨리던 시절에는, Sonnet 별칭을 통해 Codex 업스트림을 가리키게 했더니
분류기가 첫 단계를 재시도했고 권한 확인마다 5~7초가 더 걸렸습니다. 지금은 shunt가
Responses 경로에서 stop_sequences를 에뮬레이션하므로 그 실패는
더 이상 해당되지 않지만, 이 키는 그대로 프로바이더 내부 리맵입니다. 키를 설정하지 않으면(기본값)
분류기는 클라이언트가 요청한 모델을 그대로 씁니다.
게이트웨이 로그인 배포에서는 대신 관리형 설정으로 별칭을 클라이언트에 내려보낼 수 있습니다:
[server.gateway.policies.cli.env]
ANTHROPIC_DEFAULT_SONNET_MODEL = "claude-sonnet-5"같은 방식으로 분류기를 옮기지만, 분류기만이 아니라 세션 전체에서 sonnet이 가리키는 대상이
바뀝니다 — 그리고 availableModels 목록을 설정했다면 그 id가 목록에도 있어야 합니다.
검증
shunt check # -> config ok
shunt run
curl -sS http://127.0.0.1:3001/v1/models그런 다음 최소 요청을 하나 보내세요(passthrough에서는 본인의 자격 증명을 포함하고,
claude_oauth에서는 생략합니다):
curl -sS http://127.0.0.1:3001/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H 'anthropic-version: 2023-06-01' \
-H 'content-type: application/json' \
-d '{"model":"claude-sonnet-5","max_tokens":16,"messages":[{"role":"user","content":"Reply with OK."}]}'관련 문서
- Anthropic 멀티 계정 — 계정 풀, 쿼터 인지 선택,
[server.pool] - 관리자 & 원격 프로비저닝 — 브라우저에서 계정 프로비저닝
- 구성 레퍼런스 — 모든 계정 키