프로바이더는 이름 → 구성 맵입니다. 새 업스트림은 그저 또 하나의 [providers.<name>] 테이블일 뿐이며 — 코드 변경은 없습니다. 어댑터 종류는 다음과 같습니다:
kind = "anthropic"— 업스트림이 Anthropic Messages API를 사용합니다. shunt는 요청을 패스스루하며, 필요하면 다른 API 키를 주입합니다.kind = "responses"— 업스트림이 OpenAI Responses API를 사용합니다. shunt는 Anthropic Messages ⇄ Responses를 스트리밍 포함하여 변환합니다.kind = "cursor"— 네이티브 Cursor 어댑터입니다. shunt는 Cursor의 ConnectRPC/protobuf AgentService를 Anthropic Messages API로 브리지하며, 스트리밍·추론·네이티브 도구 호출·인라인 이미지를 포함합니다. 내장cursor프로바이더가 사용합니다.kind = "gemini"— 네이티브 Google Code AssistgenerateContent어댑터입니다.kind = "antigravity"— HTTP를 통해 Google Antigravity 백엔드에 연결합니다.kind = "antigravity_cli"— 더 이상 사용되지 않습니다. 로컬 AntigravityagyCLI를 호출합니다.
내장 프로바이더
| 이름 | 종류 | 인증 | 백엔드 |
|---|---|---|---|
anthropic |
anthropic |
passthrough |
api.anthropic.com — 호출자 본인의 자격 증명을 전달 |
openai |
responses |
api_key (OPENAI_API_KEY) |
api.openai.com/v1 |
codex |
responses |
chatgpt_oauth |
chatgpt.com/backend-api — ~/.codex/auth.json 재사용 |
xai |
responses |
api_key (XAI_API_KEY) |
api.x.ai/v1 — xAI 개발자 API |
grok |
responses |
xai_oauth |
cli-chat-proxy.grok.com/v1 — shunt login xai를 통한 SuperGrok / X Premium+ 구독, 또는 ~/.shunt/accounts/xai/의 이름 있는 로그인을 풀로 묶음(shunt login xai --name) |
cursor |
cursor |
cursor_oauth |
api2.cursor.sh — ~/.shunt/cursor-auth.json 재사용 (shunt login cursor) |
gemini |
gemini |
google_oauth |
cloudcode-pa.googleapis.com — ~/.gemini/oauth_creds.json 재사용 |
antigravity |
antigravity |
antigravity_oauth |
daily-cloudcode-pa.googleapis.com — ~/.shunt/antigravity-auth.json 재사용 (shunt login antigravity) |
antigravity-cli |
antigravity_cli |
none |
더 이상 사용되지 않습니다. 로컬 agy CLI — 서브프로세스를 통해 동일한 백엔드 |
각 이름은 전체 설정을 설명하는 해당 프로바이더의 전용 페이지로 연결됩니다. shunt add upstream <name>은 모든 내장 프로바이더의 단계별 블루프린트를 출력합니다. 이를 코딩 에이전트에 파이프로 전달하면(shunt add upstream codex --print | claude) 에이전트가 구성을 연결하도록 할 수 있습니다. CLI 레퍼런스를 참고하세요.
gemini 프로바이더의 도구 선언은 antigravity 프로바이더와 동일한 스키마 조정을 거칩니다. 두 전송이 하나의 Gemini 어댑터를
공유하므로, Antigravity 프로바이더 페이지의 어댑터가 전달하는 것에서 설명한 튜플 접기와 타입
없는 요소 폴백이 gemini 라우트에도 적용됩니다.
antigravity 프로바이더 (Google Antigravity)
antigravity 프로바이더는 HTTP를 통해 Google Antigravity 백엔드에 도달합니다. shunt login antigravity로 인증하세요 —
Antigravity 자체의 OAuth 클라이언트를 사용하는 Google authorization-code 플로우이며, Gemini CLI 로그인으로는 결코 가질 수 없는
두 개의 스코프(cclog, experimentsandconfigs)를 요청합니다. 따라서 두 자격 증명은 어느 방향으로도 서로 대체할 수 없습니다.
로그인 과정에서 Code Assist 프로젝트도 함께 해석하며, 처음 사용하는 계정은 onboardUser로 프로비저닝하므로 요청 앞에서
별도의 디스커버리가 일어나지 않습니다.
각 로컬 별칭을 정확한 Antigravity 모델 슬러그에 매핑하세요:
[[models]]
id = "claude-gemini-3.6-flash-via-antigravity"
display_name = "[AGY ] Gemini-3.6-Flash"
[[routes]]
model = "claude-gemini-3.6-flash-via-antigravity"
provider = "antigravity"
upstream_model = "gemini-3.6-flash-medium"Antigravity는 Gemini 모델을 effort가 id에 담긴 형태로 게시하며, 접미사가 없는 슬러그는 제공하지
않습니다. 형태는 두 가지입니다 — -low / -medium / -high 접미사, 또는 effort를 요청 필드로 받는
단일 -tiered id. 계정이 어느 형태를 받는지는 시간이 지나며 바뀌므로, shunt는 계정 자신의 카탈로그를
읽어 실제로 게시된 id를 고릅니다. 접미사가 없는 gemini-* id는 effort나 요청에서, 그것도 없으면
medium으로 등급이 정해지고, 계정이 더 이상 게시하지 않는 접미사는 그대로 보내는 대신 다시 해석됩니다.
어느 표기든 동작합니다.
전체 설정 — 로그인과 스코프, 프로젝트 디스커버리, 모델 슬러그, thinking, 어댑터가 전달하는 것 — 은 전용 Antigravity 프로바이더 페이지를 참고하세요.
더 이상 사용되지 않는 antigravity_cli 전송
antigravity-cli 경로는 요청마다 agy CLI 서브프로세스를 하나씩 에이전트 모드로 실행합니다. agy는 자신의 도구 호출을
스스로 해결하므로 이 어댑터는 tool_use 블록을 반환할 수 없고, 도구 호출을 요구하는 요청은 거부됩니다. 비어 있지 않은
tools 배열 또는 any/tool인 tool_choice는 이 제약을 명시한 400 invalid_request_error로 거부됩니다. 예전에는
이런 요청이 조용히 버려지고 stop_reason: "end_turn"인 텍스트 전용 200이 반환됐는데, 이는 에이전트 호출자가 활용할 수
없는 응답이며 tool_choice: {"type": "any"}를 정면으로 위반하면서도 성공으로 보고하는 것이었습니다. 도구 호출을 강제하지
않는 두 가지 형태는 예외입니다. tools가 함께 있어도 tool_choice: {"type": "none"}은 예외이고, 도구가 없는
tool_choice: {"type": "auto"}도 많은 클라이언트가 매 요청에 직렬화하는 Anthropic SDK 기본값이므로 예외입니다. 빈
tools: []도 도구 요청이 아닙니다. 도구 루프를 직접 구동해야 하는 클라이언트는 도구를 전달하는 antigravity 또는
gemini 프로바이더를 사용하세요.
전달되지 못한 send_message 핸드오프는 완료된 턴을 실패시키지 않습니다. print 모드는 send_message를 포함한 agy의
전체 대화형 도구 목록을 노출하지만 인박스를 등록하지 않습니다. 서브에이전트 형태의 프롬프트(“결과를 메인 에이전트에게
보고하라”)만으로도 모델은 답변을 main, team-lead, user에게 넘기려 하고, 호출은 실패하며 agy는 — 답변이 이미
스트리밍된 뒤에 — recipient "<name>" not found 오류로 실행을 ERROR로 표시합니다. shunt는 어시스턴트 텍스트가
스트리밍된 경우 그 턴을 정상 종료(end_turn, HTTP 200)하고, 아무것도 스트리밍되지 않았으면 답변이 전달되지 못한
메시지 안에만 존재했던 것이므로 계속 실패로 처리합니다. 그 밖의 뒤늦은 실패는 여전히 SSE error로 턴을 끝냅니다.
이는 업스트림 오류 문자열에 기댄 호환성 처리이며, 저장소의 docs/notes/agy-print-mode-tool-surface.md를 참고하세요.
비대화형 실행에서는 권한 프롬프트에 응답할 수 없으므로, agy는 --dangerously-skip-permissions로, 그리고 기본적으로
--sandbox와 함께 실행됩니다. 그러므로 이 프로바이더는 shunt를 실행하는 사용자 권한의 임의 코드 실행으로 취급하세요.
두 가지 설정이 이를 제한합니다. sandbox(기본값 true)는 --sandbox를 전달하며, 실제로 에이전트를 가두는 것은 이
설정입니다 — 끄면 제한 없는 셸 접근이 남습니다. workspace_roots(기본값은 비어 있음)는 에이전트가 시작할 수 있는
위치만 결정합니다. 해석 순서는 SHUNT_AGY_WORKSPACE, 그다음 요청의 시스템 프롬프트에 있는 Working directory: 줄,
그다음 게이트웨이 자신의 디렉터리입니다. 시스템 프롬프트는 클라이언트가 제어하는 텍스트이므로, 거기서 찾은 경로는 구성된
루트 중 하나 안으로 정규화될 때만 인정됩니다. 루트를 하나도 구성하지 않으면 프롬프트에서 유래한 경로는 무시됩니다.
[providers.antigravity-cli]
kind = "antigravity_cli"
base_url = "http://localhost"
auth = "none"
# 요청 내용이 에이전트를 가리킬 수 있는 저장소.
workspace_roots = ["/Users/you/repos"]
# sandbox = false # 에이전트에 제한 없는 터미널 접근이 필요한 경우에만workspace_roots는 감옥이 아닙니다. sandbox = false이면 허용된 루트에서 시작한 에이전트도 프롬프트의 다른 곳에 적힌
경로를 대상으로 동작할 수 있습니다.
shunt는 sandbox = false가 루프백이 아닌 bind와 결합되면 기동을 거부하며, 기동 시점에 바인드된 리스너를 기준으로 요청
단위로도 이를 강제합니다. 핫 리로드는 리스너를 옮길 수 없으므로, 루프백 bind를 다시 읽어들여도 공개 리스너가 살아 있는
동안에는 샌드박스를 끌 수 없습니다. 샌드박스를 켜 두거나, 루프백 바인드로 다시 기동하세요. 신뢰할 수 없는 클라이언트에게
루프백이 아닌 바인드로 이 프로바이더를 노출하지 마세요.
세 번째 설정인 profile_dir은 항목마다 자기 HOME을 줍니다. agy는 크리덴셜을 포함한 상태 트리 전체를 HOME으로
해석하므로, 설정하지 않으면 모든 항목이 게이트웨이 호스트의 단일 ambient ~/.gemini 프로필을 공유하고 결국 한 Google
계정만 서비스합니다. 항목별로 디렉터리를 지정하면 각자 자기 계정에 로그인하고 여러 계정을 동시에 풀링할 수 있습니다.
디렉터리는 필요할 때 생성되고 절대 경로로 정규화되며, 맨 앞의 ~는 확장됩니다. 각 디렉터리마다 agy 로그인을 한 번씩
해 줘야 합니다. 이 설정을 쓴 항목에 한해 자식 프로세스의 GOOGLE_* / GEMINI_* 환경 변수가 제거되므로, 호스트의 설정이
어느 계정 — 그리고 누구의 청구서 — 이 요청을 처리할지 조용히 바꿔 버릴 수 없습니다. 지정하지 않으면(기본값) 기존 동작
그대로입니다. 정렬 업스트림([[upstreams]])에서도 같은 설정을 쓸 수 있습니다.
이런 설정이 전혀 필요 없는 위의 네이티브 antigravity HTTP 프로바이더를 사용하는 편이 좋습니다. 이 절은 요약본입니다 —
모델/effort 행렬을 비롯한 전체 문서는 영문 가이드의
The deprecated antigravity-cli transport에 있습니다.
codex 프로바이더 (ChatGPT 구독)
Codex CLI로 한 번 로그인하면, shunt가 ~/.codex/auth.json을 읽고 자동 갱신합니다:
codex login파일이 없거나 만료되면, shunt는 codex login을 실행하라는 authentication_error를 반환합니다.
전체 설정 — 인증 파일 처리, 모델 선택, 노력, 컨텍스트 크기 조정 — 은 전용 ChatGPT / Codex 가이드를 참고하세요.
cursor 프로바이더 (Cursor 구독)
내장 cursor 프로바이더는 Cursor 자체의 ConnectRPC/protobuf AgentService를 통해 Cursor 구독에 도달합니다. kind = "cursor" 네이티브 어댑터가 이를 Anthropic Messages로, 그리고 그 반대로 변환하며 스트리밍, 추론, 네이티브 도구 호출, 인라인 이미지를 지원합니다.
shunt login cursor로 한 번 로그인한 뒤 cursor:default, cursor-plan:default, cursor-ask:default 같은 cursor:* 모델 id를 라우팅하세요. 프로바이더는 기본으로 시드되므로 구성 테이블은 필요하지 않습니다.
전체 설정 — 로그인, 에이전트 모드, 와이어 모델 id, 어댑터 기능, 오버라이드 — 은 전용 Cursor 프로바이더 페이지를 참고하세요.
xai / grok 프로바이더 (Grok)
두 개의 내장 프로바이더가 xAI의 Grok 모델에 도달하며, 자격 증명으로 갈립니다: grok은
OAuth를 통해 사용자의 SuperGrok / X Premium+ 구독을 사용하고(shunt login xai, 토큰당 과금 없음),
xai는 측정된 개발자 API에 대해 XAI_API_KEY를 사용합니다. 구독 bearer와 API 키는 서로 교체할 수
없습니다 — 각각은 자신의 프로바이더에서만 동작합니다.
전체 설정 — 로그인, 두 프로바이더 블록, 모델 슬러그, 옵트인 노력 다이얼, 자격 관련 함정 — 은 전용 xAI / Grok 가이드를 참고하세요.
여러 SuperGrok 계정을 풀로 묶으려면 각 계정을 shunt login xai --name <name>으로 로그인하세요. 자세한 내용은 xAI / Grok 페이지를 참고하세요.
Anthropic 호환 백엔드 추가
대부분의 서드파티 “Claude Code를 X와 함께 쓰기” 게이트웨이는 Anthropic-Messages 호환입니다: kind = "anthropic"에 auth = "api_key"이며, base_url과 키 env 변수만 다릅니다. 바로 사용할 수 있는 base(각 프로바이더는 전체 설정을 설명하는 전용 페이지로 연결됨):
| 프로바이더 | base_url |
예시 모델 ID |
|---|---|---|
| Kimi (Moonshot) | https://api.moonshot.ai/anthropic |
kimi-k3[1m], kimi-k2.7-code |
| Kimi Code(구독, OAuth) | https://api.kimi.com/coding |
구독이 노출하는 모델 ID 사용 |
| DeepSeek | https://api.deepseek.com/anthropic |
deepseek-v4-pro, deepseek-v4-flash |
| Z.ai (GLM) | https://api.z.ai/api/anthropic |
glm-5.2, glm-4.7 |
| Zhipu (GLM 중국) | https://open.bigmodel.cn/api/anthropic |
glm-5.3, glm-5.3-flash |
| MiniMax | https://api.minimax.io/anthropic |
MiniMax 문서 참고 |
| MiniMax 중국 | https://api.minimax.cn/anthropic |
MiniMax-M3 |
| OpenCode Zen | https://opencode.ai/zen |
claude-fable-5-1, gpt-6-astra — 큐레이션된 크로스 벤더 카탈로그 (x-api-key 읽음) |
| Mimo (Xiaomi) | https://api.xiaomimimo.com/anthropic |
mimo-v2.5-pro — Mimo 문서 참고 |
| OpenRouter | https://openrouter.ai/api |
anthropic/claude-opus-4.8 |
| Vercel AI Gateway | https://ai-gateway.vercel.sh |
anthropic/claude-opus-4.8(x_api_key를 받아들임) |
이 표에 없는 프로바이더의 경우 shunt add upstream <docs-url>은 프로바이더 자체 문서를 바탕으로 코딩 에이전트가 구성을 연결하도록 안내하는 리서치 블루프린트를 출력합니다(shunt add upstream https://docs.example.com --print | claude).
위 표의 행은 하나만 빼고 모두 auth = "api_key"를 사용합니다. Kimi Code는 예외입니다 — 바로 위 행의 종량제 Moonshot API와는 별개의, 구독 결제 방식 Kimi 서비스로, 호스트가 다르고 API 키 대신 OAuth를 사용합니다. 전용 내장 프리셋 kimi-code(kind = "anthropic", base_url = "https://api.kimi.com/coding", auth = "kimi_oauth")가 제공되므로, 순서가 있는 [[upstreams]] 형식에서 provider = "kimi-code"만 지정하면 되고 수동 [providers.*] 테이블은 필요 없습니다. 이제 로그인된 계정만 있으면 됩니다:
shunt login kimi --name <account-name> # RFC 8628 디바이스 플로우 -> ~/.shunt/accounts/kimi/<account-name>.json# shunt.toml — Kimi Code 구독으로 라우팅
[[upstreams]]
name = "kimi-code"
provider = "kimi-code"
auth = { mode = "kimi_oauth", account = "<account-name>" }
# [[upstreams]]를 선언하면 내장 프로바이더 집합이 대체되므로, 끝에
# anthropic 패스스루를 남겨두어야 합니다 — 이것이 없으면 기본
# server.default_provider를 `shunt check`가 거부합니다. 이는 `shunt init`이
# 추가하는 것과 동일한 항목입니다.
[[upstreams]]
name = "anthropic"
provider = "anthropic"
[[routes]]
model = "<model-id-your-subscription-exposes>"
provider = "kimi-code"kimi_oauth는 claude_oauth/chatgpt_oauth처럼 풀링을 지원합니다 — account 대신 accounts = [...]를 사용해 저장된 여러 Kimi 계정으로 부하를 분산할 수 있습니다. 전체 안내는 Kimi → Kimi Code (OAuth 구독)를 참고하세요.
예를 들어, Kimi(Moonshot)의 모델을 shunt를 통해 라우팅하려면:
[providers.kimi]
kind = "anthropic"
base_url = "https://api.moonshot.ai/anthropic"
auth = "api_key"
api_key_env = "MOONSHOT_API_KEY"
[[routes]]
model = "kimi-k3[1m]"
provider = "kimi"
[[routes]]
model = "kimi-k2.7-code"
provider = "kimi"그런 다음 export MOONSHOT_API_KEY=…를 실행하고, Claude Code를 shunt에 연결한 뒤, kimi-k3[1m]를 선택하세요(ANTHROPIC_CUSTOM_MODEL_OPTION 또는 ANTHROPIC_MODEL을 통해). shunt check를 실행하여 검증하세요 — 라우트의 알 수 없는 프로바이더, 누락된 api_key_env, 잘못된 base_url을 보고합니다.
모든 프로바이더 키(kind, auth, api_key_header, count_tokens 등)는 구성 레퍼런스에 문서화되어 있습니다.
서브에이전트 플러그인
pleaseai/shunt 마켓플레이스는 각 프로바이더의 모델에 고정된, 미리 만들어진 Claude Code 서브에이전트를 제공합니다 — 모델당 하나의 에이전트. 플러그인을 설치한 뒤, 모델을 @로 멘션하거나 CLAUDE_CODE_SUBAGENT_MODEL을 설정하세요. 각 에이전트의 model: 프론트매터는 그 서브에이전트만 우회시키며, 메인 세션은 Claude에 머뭅니다.
| 플러그인 | 모델 (에이전트당 하나) | 프로바이더 |
|---|---|---|
shunt-codex |
gpt-6-sol, gpt-6-luna, gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna |
codex (ChatGPT 구독) |
shunt-xai |
grok-4.6, grok-4.5, grok-build-0.1 |
xai (API 키) 또는 grok (구독) |
shunt-kimi |
kimi-k3[1m], kimi-k2.7-code |
kimi |
shunt-deepseek |
deepseek-v4-pro, deepseek-v4-flash |
deepseek |
shunt-zai |
glm-5.2, glm-4.7 |
zai |
shunt-minimax |
MiniMax-M3[1m] |
minimax |
shunt-mimo |
mimo-v2.5-pro |
mimo |
/plugin marketplace add pleaseai/shunt
/plugin install shunt-xai@shunt각 플러그인은 여전히 shunt.toml에서 해당 프로바이더가 라우팅되어야 하고(위 섹션 참고) 일치하는 자격 증명이 내보내져야 합니다 — 플러그인 자체의 README가 정확한 라우트와 env 변수를 나열합니다. grok 모델은 두 xAI 프로바이더 중 어느 쪽으로도 제공할 수 있습니다: xai(API 키, 토큰당 과금) 또는 grok(shunt login xai를 통한 SuperGrok / X Premium+ 구독; 티어로 게이트됨 — 403 시 xai로 폴백).