Claude DesktopでsshHostCommandsからSSH接続を作る手順
sshHostCommandsにコマンドを書くと、Claude Desktopが出力されたホストをSSH接続として保存して接続します。書き方、出力の形、ホストの差し替え、チーム配布、止め忘れの課金までを扱います。
sshHostCommands は、リモートマシンをコマンドで都合よく作る社内ツールを持つ人向けの設定です。~/.claude/settings.json にコマンドを書くと、Claude Desktopのコード タブの環境セレクターに「Create Dev box」のような項目が増えます。選ぶとDesktopが手元でコマンドを実行し、出力されたホストをSSH接続として保存して、そのまま接続します。
要件はClaude Desktop v3.6556.0以降で、macOSまたはLinux、Claudeアカウントでのサインインです。Windowsとサードパーティプロバイダー経由の利用では使えません。
設定の最小形
次の例は「Dev box」という接続を1つ足します。acme-dev create は自前のツールの代わりに置いた架空のコマンドです。
{
"sshHostCommands": [
{
"id": "devbox",
"name": "Dev box",
"command": "acme-dev create",
"startDirectory": "~/project"
}
]
}ファイルがなければ作り、すでに設定があるなら同じ階層にキーを足します。編集後にDesktopを再起動する必要はありません。1エントリが1接続で、持てるホストは同時に1つです。2台を並べたいときはエントリを2つ書きます。
各フィールドの意味
| フィールド | 必須 | 内容 |
|---|---|---|
id | 必須必須 | 内容英数字と . _ - で64文字まで、先頭は英数字 |
name | 必須必須 | 内容セレクターに出る名前。1行200文字まで |
command | 必須必須 | 内容プログラムと引数 |
sshIdentityFile | 必須任意 | 内容秘密鍵のパス。省略するとSSH設定かSSHエージェントを使う |
startDirectory | 必須任意 | 内容リモートの既定フォルダー。/ か ~/ で始めるか、~ だけにする |
id は設計上いちばん重いフィールドです。Desktopは接続のホストをこの id の下に保存します。あとから変えると接続はホストなしの状態からやり直しになり、古いマシンは動いたまま残ります。sshHostCommands と sshConfigs の間でも重複させないでください。
コマンドの書き方には制約が多い
Desktopはシェルも端末も通さず、プログラムを直接起動します。そのため次の点で、普段のターミナルとは勝手が違います。
- プログラムは名前か
/から始まるフルパスで書きます。名前だけの場合、ログインシェルがエクスポートするPATHから探します。./acme-dev、~で始まるパス、シェルのエイリアスや関数は使えません - 引数に使えるのは、空白、英数字、
+,-./:=@_~だけです。単語の先頭を~にもできません - クォート、パイプ、変数、
?や&を含むURLが必要なら、スクリプトに書いて、その絶対パスをcommandに入れます。スクリプトには実行権限と#!行が要ります。macOSでは、ドキュメント、デスクトップ、ダウンロードの各フォルダーに置くとmacOSに止められることがあるため避けます - プログラムには入力も端末も渡りません。ブラウザやプロンプトでサインインさせる種類のツールは、先にターミナルでサインインしておき、期限が切れたらやり直します
- 環境変数はDesktopの起動時に読まれます。変えたらDesktopを終了して開き直します
- 10分たっても終わらないプログラムはDesktopが止めます。進行中のメッセージの横の「Cancel」でも止められます
出力はホストだけにする
コマンドは終了コード0で終わり、標準出力にホストだけを出す必要があります。形は2つです。
- 1行:
hostまたはuser@host。ポートを指定するならJSON形式にします - JSONオブジェクト1つ:
sshHostが必須で、数値のsshPortと、エントリの値を上書きするstartDirectoryが任意
たとえば {"sshHost": "dev@devbox-1234.example.com", "sshPort": 2222} が有効な出力です。事前に自分で確かめるには、入力なしで標準出力をファイルに落とします。
acme-dev create < /dev/null > host.txthost.txt にホストだけが入っていれば合格です。ただしこのテストでもツールはマシンを実際に作るため、確認後はツール側で削除してください。
ツールが進捗メッセージなどを先に出力してしまうなら、ホストだけを出すラッパースクリプトで包みます。次のスクリプトは、ツールの最終行だけを出力します。ツールが失敗したときは同じ終了コードで抜けるので、Desktopが失敗として報告できます。
#!/bin/bash
out=$(mktemp) || exit
trap 'rm -f "$out"' EXIT
acme-dev create > "$out" || exit
tail -n 1 "$out"コマンドが失敗したときは、Desktopのメッセージにある「View details」で、標準エラー出力の最終行を確認できます。
初回接続で聞かれること
新しいホストに初めて接続するときは、2つの確認が出ます。
- ホストキー: OpenSSHの既定の検査なら、フィンガープリントを見て接続するか選びます。この確認を省きたければ、ホストを出力する前に、マシンを作った時点でツールが知っている鍵を
~/.ssh/known_hostsに追記させます。22以外のポートなら、その行は[host]:portで始めます。ツールがホスト名を使い回すなら、古い鍵の行も消してください - フォルダー: そこを開いてよいかという信頼の確認
ホストキーの検査は有効にして、known_hosts を残してください。StrictHostKeyChecking が no か accept-new で、かつ UserKnownHostsFile が /dev/null か none だと、鍵がどこにも記録されません。ツールがホスト名を使い回すと、別のマシンに繋がっても警告が出ない状態になります。
ホストを差し替える
ホストが保存されると、セレクターの「Create Dev box」は「Replace Dev box's host」に変わります。見当たらないときは「More」の中を探します。マシンが消えたときや新しいマシンにしたいときに選ぶと、Desktopがコマンドをもう一度実行し、以降の新規セッションは新しいホストに向きます。
- 新しいホストを保存した直後の10分間は、この項目がグレーになります。マシンの起動に時間がかかるためで、その間、新規セッション画面は接続を試し続けます
- 古いホストのセッションは、古いホストに残ります。Desktopはその接続を、自分で足し戻さない限り繋ぎ直しません。続きをやるなら、セッションを開いて「Add SSH connection」を選びます。古いホストが入力済みで出るので、別の接続として保存します
コマンドが実行されるのは、接続を作るときとホストを差し替えるときだけです。接続のたびに毎回実行されるわけではありません。
止めたマシンは自動では消えない
この設定でいちばん費用に響くのは、次の点です。Desktopはマシンを止めも消しもしません。ツールで削除するまで、次のマシンは動き続けて、課金も続く可能性があります。
- 差し替えて古くなったホスト
- ファイルからエントリを消した、または
idを変えたあとに残ったホスト - コマンドが作ったのに、Desktopがホストを保存できなかったマシン
3つ目の例は、コマンドの失敗やタイムアウト、出力されたホストを使えない場合(ほかの接続がすでに使っている、組織が許可していない)です。実行中にキャンセルしたり、エントリを消したり、command や id を書き換えたり、Desktopを終了したりした場合も同じです。
運用上は、ツール側に「一覧」と「削除」のコマンドを持っておき、差し替えのたびに古いマシンを片付ける習慣にしておくのが安全です。接続中のタスクがSSH切断後にどうなるかは、別の話としてSSHタスクが切断後も続く条件にまとめています。
チームに配る
チームに接続を配るには、デスクトップアプリ自身のデバイス管理ポリシーではなく、Claude Codeの管理設定ファイルかMDMポリシーに sshHostCommands を書きます。各ユーザーのコンピューターに置く形で、配られた項目はユーザー自身の項目と並んで表示されます。アプリにはどちらの項目も編集・削除する手段がありません。
次の管理設定は、Dev boxという接続を配り、ユーザー自身のエントリを止めています。strictPluginOnlyCustomization に hooks を入れる指定で、ユーザー、プロジェクト、ローカルの各設定にあるClaude Codeのフックも止まります。
{
"sshHostCommands": [
{
"id": "acme-devbox",
"name": "Dev box",
"command": "/usr/local/bin/acme-dev create"
}
],
"strictPluginOnlyCustomization": ["hooks"]
}配る前に決めておくことは次の通りです。
- キーを置く場所: Claude Code用のMDMポリシーキーがすでにあるなら、そこに入れます。なければ管理設定ファイルです。既定ではポリシーがファイルより優先され、その場合はファイル側のエントリをDesktopは無視します。サーバー管理設定を使う組織でも、このキーはコンピューター上に置いてください。サーバー管理設定とプロジェクト、ローカルの設定にあるキーは読まれません
id: ユーザー自身のエントリが同じidなら、配った側だけが動きます。sshConfigsなど別の種類のSSH接続と重なると、配ったエントリはグレーになります。ユーザーが選びにくいidにします- プログラム: フルパスで指定します。名前だけだと、各ユーザー自身の
PATHから探されます。プログラムは各ユーザーの権限で、そのログインシェルの環境変数を持って動きます - ユーザー自身のエントリ: Desktopは、プログラムを動かす点がフックと同じなので、フックと同じ扱いにします。配ったエントリだけにしたいなら、
strictPluginOnlyCustomizationにhooksを足します。allowManagedHooksOnlyをtrueにする方法もありますが、止まる範囲が広がります - すべてのエントリを止める: 配ったものを含めて止めるなら、管理設定で
disableAllHooksを設定します。disableDesktopLocalSessionsを設定したときや、許可ホストが空のsshHostAllowlistを設定したときも、セレクターに「Create」「Replace」の項目は出ません sshHostAllowlistとの併用: Desktopはコマンドの実行後に、出力されたホスト名を検査します。許可リストに合わないマシンはすでに作られているので、削除はユーザーが自分でツールを使って行います。パターンは出力されるホスト名に一致させ、user@はパターンに入れません。接続のたびに解決後のHostNameも一致する必要があります。許可リスト側の設計はsshHostAllowlistの記事にあります
配ったあとは、テスト用のコンピューターでDesktopを再起動し、環境セレクターの「SSH」の下(または1行だけの「SSH」)を見ます。「Create」項目が出るか、ホバーで理由が出るグレーの項目になっていれば、読み込みには成功しています。
固定の接続先をそのまま配るなら sshConfigs のほうが単純です。違いは、接続先が決まっているか、毎回コマンドで作るかです。固定接続の配布はsshConfigsの記事にまとめています。
項目が出ない、グレーのときの切り分け
セレクターに「Create」や「Replace」が出ないのは、次のような場合です。
項目が出ないときの確認順
- QmacOSまたはLinuxで、Claudeアカウントにサインインしていますか?答えがWindowsやサードパーティプロバイダーでは使えません。接続はSSH接続として自分で追加します答えがはい
次の確認に進みます。
- Q`~/.claude/settings.json` は正しいJSONで、キーの綴りも合っていますか?答えがJSONかスキーマの誤りです。プロジェクトの設定に書いたものも読まれないので、ユーザー設定に移します答えがはい
次の確認に進みます。
- Q管理者はローカルセッションとSSHセッションを許可していますか?答えが管理者に使えるか確認します答えがはい
OpenSSHクライアントを起動できるかも確かめます。
それでも出ない場合
項目がグレーならホバーで理由を読みます。
選べずグレーになっている項目は、ホバーすると理由が出ます。公式が挙げる原因は次の通りです。
- エントリの誤り: メッセージが指すフィールドかコマンドを直します。
idが重複しているなら別のidにします - 設定ファイルの破損: 自分のファイルが壊れていると、管理者が配った項目までグレーになり、ファイル名がメッセージに出ます
- 新しいホスト: 保存から10分たてば差し替えられます
- フックの無効化: 自分のエントリは、自分のフックが動く環境でしか使えません。
disableAllHooksを外すか、管理者に相談します - 設定の読み込み中: 起動の数秒後まで、すべての項目がグレーです。続くなら、claude.aiへの接続を確かめます
設定を書き換えるときの注意
Claude Code v2.1.307より前では、有効な設定ファイルにこのキーを足すEditツールの変更が、Unrecognized field: sshHostCommands で拒否されます。そのため、エディターで直接書いてください。キーを含むファイル自体はClaude Codeに読み込まれます。Desktopでは、ターミナルのClaude Codeではなく、コード タブのClaude Codeのバージョンで判断します。
まとめ
sshHostCommands はホストの作成を手元のツールに任せ、Desktopは出力された1行だけを受け取る仕組みです。成否はコマンド側で決まります。ホストだけを出力するラッパーを用意すること、id を途中で変えないこと、古いマシンを自分で消すこと。この3点を押さえれば、チーム配布まで同じ形で広げられます。