公式の Deploy Claude Desktop with an LLM gateway ガイドに基づいています — shunt こそが、あなたが接続するゲートウェイです。shunt は Anthropic の Messages API(ストリーミングとツール使用に対応する POST /v1/messages)と、オプションの GET /v1/models を実装しています。これはまさに、Claude Desktop のサードパーティ推論が期待するゲートウェイ契約です。
1. Claude Desktop を shunt へ向ける
Developer → Configure Third-Party Inference… で、Inference provider を Gateway に設定し、Gateway base URL に稼働中の shunt(デフォルトのバインド 127.0.0.1:3001)を設定します。
| Claude Desktop キー | 値 |
|---|---|
inferenceProvider |
gateway |
inferenceGatewayBaseUrl |
http://127.0.0.1:3001(または公開 shunt URL) |
shunt は平文 HTTP を提供します。ループバック以外へデプロイする場合は、ゲートウェイの共有とまったく同じように、前段で TLS を終端するかトンネルを使ってください。
2. 認証方式を選ぶ
Claude Desktop にはいくつかの方式があります。shunt は静的キー(およびその認証情報ヘルパー版)と、shunt 自身がデバイスコードの認可サーバーになる bootstrap サインインにそのまま対応します。外部 IdP の JWT を使う SSO はゲートウェイ側の機能であり、shunt はインバウンドで実装していません。
| Claude Desktop の方式 | shunt 側 | 備考 |
|---|---|---|
静的 API キー(inferenceGatewayApiKey) |
[server.auth] クライアントトークン |
推奨。 |
認証情報ヘルパー(inferenceCredentialHelper) |
[server.auth] クライアントトークンを出力する実行可能ファイル |
ゲートウェイ認証情報をすでに発行している組織向け。 |
Bootstrap サインイン(bootstrapUrl + デバイスコード、inferenceCredentialKind: interactive) |
[server.gateway] ログインと [server.gateway.desktop_bootstrap] |
ユーザーごとに shunt へのサインインは 1 回、デバイスに CLI は不要 — Bootstrap サインインを参照してください。 |
インタラクティブ SSO(inferenceGatewayOidc + inferenceCredentialKind: interactive) |
インバウンドでは未対応 | shunt は外部 IdP の JWT を検証しません — 以下を参照してください。 |
静的 API キー(推奨)
shunt で [server.auth] を有効にし、各ユーザーへクライアントトークンを配布します。
[server.auth]
header = "x-shunt-token" # default
tokens_env = "SHUNT_CLIENT_TOKENS"そのトークンを Claude Desktop の inferenceGatewayApiKey に設定します。shunt は Authorization: Bearer または x-api-key でクライアントトークンを受け付けるため、どちらの Gateway auth scheme でも動作します。
| Claude Desktop キー | 値 |
|---|---|
inferenceGatewayApiKey |
shunt のクライアントトークン |
inferenceGatewayAuthScheme |
bearer(デフォルト)または x-api-key |
[server.auth] がなければ、shunt はインバウンドの認証情報を要求しません(個人用のループバックゲートウェイなら問題ありません)。それでも Claude Desktop はこのフィールドへの入力を要求するため、任意のプレースホルダーを指定してください。
このトークンは GET /v1/models と、注入された認証情報を使う(マッピング/プールされた)モデルをゲートします。パススルーモデルは開いたままで、オペレーター自身のプロバイダー認証情報を運びます。
Bootstrap サインイン(デバイスコード)
Claude Desktop は bootstrap URL から構成を取得し、同じサーバーに対する OAuth デバイスコード grant でユーザーをサインインさせられます(Anthropic の bootstrap ガイド、“Bootstrap server as authorization server (device code)” モード)。shunt はこのモードを提供します。ユーザーは shunt の /device ページでパスワードまたは OIDC IdP により 1 回サインインし、Desktop はその bearer を推論にも再利用します。デバイスに Claude Desktop 以外をインストールする必要はなく、マシンごとにそろえるヘルパースクリプトのパスもありません。
1. ゲートウェイログインを有効にする。 public_url、署名シークレット、静的ユーザーまたは OIDC IdP とともに [server.gateway] を設定します。このモードには、shunt の前段に TLS を備えた実在のホスト名が必要です。Anthropic のガイドは bootstrap エンドポイントを HTTPS として説明しており、パッケージ版の Desktop アプリはレスポンスのキーからループバック URL(127.0.0.1、localhost、[::1])を破棄します。
2. shunt にテンプレートを指定する。
[server.gateway.desktop_bootstrap]
template = "/etc/shunt/claude-desktop-bootstrap.json" # ファイルパスのみファイルは存在する JSON オブジェクトである必要があり、そうでなければ設定のロード(および shunt check)が失敗します。shunt はリクエストごとにファイルを読むため、編集は再起動なしで反映されます。Desktop 自身の JSON エクスポートが書き出すネスト形式の v2、またはフラットな v1 形式で記述してください。shunt はそのまま返します。
{
"$schemaVersion": 2,
"inference": {
"provider": "gateway",
"baseUrl": "https://shunt.example.corp",
"credential": { "kind": "interactive" }
},
"otlp": {
"resourceAttributes": { "user.email": "${user.email}" }
}
}フラットな v1 形式は {"inferenceProvider":"gateway","inferenceGatewayBaseUrl":"https://shunt.example.corp","inferenceCredentialKind":"interactive","otlpResourceAttributes":{"user.email":"${user.email}"}} です。
- ゲートウェイの base URL は shunt の
public_urlにします。bootstrapOidcがない場合、Desktop はbootstrapUrlと origin が同じでないゲートウェイ base URL を破棄します。origin が同じでinteractive認証情報を使うと、Desktop は bootstrap の bearer を推論にも再利用し(1.34493.0 以降は refresh grant で更新もします)、ユーザーのサインインは 1 回で済みます。 - プレースホルダー。 文字列値の中の
${user.email}、${user.sub}、${user.name}は、サインインしたユーザーの値に置き換わります。未知の${...}トークンはそのまま残り、オブジェクトのキーは置換されません。 - 適用したいキーはすべて返してください。 レスポンスのキーがそのまま有効な構成です。テンプレートで省略したキーは MDM から継承されず、未設定になります。
3. シードファイルを配布する。 各ユーザーは Developer → Configure Third-Party Inference… → Import configuration からインポートします。
{
"bootstrapUrl": "https://shunt.example.corp/user/bootstrap",
"trustBootstrapDelivery": true
}bootstrapUrl の origin は public_url の origin と一致させます。Desktop は末尾の /user/bootstrap を取り除いて shunt の OAuth ディスカバリードキュメントを見つけ、デバイスコードログインを実行し、発行された bearer で GET /user/bootstrap を呼び出します。trustBootstrapDelivery は、ローカルファイルで構成されたデバイスに bootstrap レスポンスが base URL、ヘルパー、マーケットプレイスの値を配信するときに Desktop が表示する “Apply settings from your organization?” ダイアログをスキップします。Desktop はこのキーを MDM またはローカルファイルからのみ受け付け、bootstrap レスポンスからは受け付けません。
構成を受け取るユーザー。 対象の判定は [[server.gateway.policies]] を再利用します。policy がなければサインイン済みの全ユーザーが対象で、policy があれば、policy の match.emails に含まれるか、catch-all policy(match なし)がある場合に対象になります。それ以外は 403 を受け取ります。desktop_bootstrap がなければルートは 404 を返します。レスポンスには ETag が付くため、Desktop のバックグラウンド再確認(デフォルトで 10 分ごと)は通常 304 で済みます。
Desktop はレスポンスをメモリ上にのみ保持します。起動時に shunt に到達できない場合、Desktop は縮退したサインイン状態で起動します。これは推論がすでに持っている依存関係と同じです。Desktop のサインアウトはローカルのみで、shunt は失効(revocation)エンドポイントを公開していません。すべてのステータスコードはエンドポイントリファレンスを参照してください。
3. モデルを選択する
shunt は GET /v1/models を提供するため、Claude Desktop は起動時にピッカーを自動検出します。何が表示されるかは 2 つの要素で決まります。
Discovery フィルター。 Claude Desktop の自動 discovery に表示されるのは、Claude と認識できる id、つまり tier 名の id(claude-sonnet-*、claude-opus-*、claude-haiku-*、claude-fable-*)のみです。shunt の組み込みカタログは Anthropic API とリファレンス Claude apps gateway が提供する一覧の上位集合です。14 個すべてが tier 名の id なので、Claude Desktop にはそのすべてが表示されます。これはフォールバック用のスナップショットで、shunt が Anthropic アップストリームに到達できる場合は、その呼び出し元自身の実際の一覧を返します(モデルディスカバリー を参照)。
// GET /v1/models — builtin catalog (auto_include_builtin_models), all tier-named
// (each entry also carries "type": "model", "display_name", "created_at",
// "max_input_tokens", and "max_tokens")
{ "data": [
{ "id": "claude-sonnet-5-5" }, { "id": "claude-opus-5-5" },
{ "id": "claude-fable-5-1" }, { "id": "claude-opus-5" },
{ "id": "claude-sonnet-5" }, { "id": "claude-fable-5" },
{ "id": "claude-opus-4-8" }, { "id": "claude-opus-4-7" },
{ "id": "claude-sonnet-4-6" }, { "id": "claude-opus-4-6" },
{ "id": "claude-opus-4-5-20251101" }, { "id": "claude-haiku-4-5-20251001" },
{ "id": "claude-sonnet-4-5-20250929" }, { "id": "claude-opus-4-1-20250805" }
], "has_more": false,
"first_id": "claude-sonnet-5-5", "last_id": "claude-opus-4-1-20250805" }選定した claude-<slug>-via-<provider> エイリアス(Claude Code で機能するパターン)は Claude Desktop では破棄されます — モデルディスカバリー → Claude Desktop は tier 名の id のみを認識しますを参照してください。
非 Anthropic バックエンドを公開する。 選択肢は 2 つあります。
-
tier 名の id をマッピングする。
[[routes]]のupstream_modelでマッピングすると、Desktop で選択したときにバックエンドへ解決されます。[[routes]] model = "claude-sonnet-5" # a tier-named id Claude Desktop recognizes provider = "codex" upstream_model = "gpt-5.6-sol" # real backend slug -
Desktop 側で discovery を上書きする。 shunt がルーティングする正確な id を、明示的な
inferenceModelsリストに指定します。すべてのエントリが完全な id なら、Claude Desktop は/v1/modelsの呼び出しをスキップします。
4. 検証
クライアントトークンを使って、shunt が discovery と推論に応答することを確認します。
# Discovery — the token gates it when [server.auth] is set
curl -s "$SHUNT_URL/v1/models" -H "Authorization: Bearer $SHUNT_CLIENT_TOKEN" | jq '.data[].id'
# A tier-named id you mapped -> diverted to the backend
curl -s -X POST "$SHUNT_URL/v1/messages" \
-H "Authorization: Bearer $SHUNT_CLIENT_TOKEN" \
-H "anthropic-version: 2023-06-01" -H "content-type: application/json" \
-d '{"model":"claude-sonnet-5","max_tokens":16,"messages":[{"role":"user","content":"hi"}]}'その後 Claude Desktop を開きます。モデルピッカーに tier 名のエントリが表示されるはずです。空の場合は、discovery がフィルターで除外された(tier 名でない id)か、/v1/models に到達できていません。フォールバックとして inferenceModels を明示的に設定してください。