Mcp Remote Ssh について
Mcp Remote Ssh は、AI エージェントがリモート SSH を利用するための MCP サーバーです。永続セッション、コマンド実行、SFTP、ポート転送、記録、応答のシークレット除去を備えています。
主な機能
- 01永続 SSH セッション
- 02構造化された出力と終了コード
- 03SFTP ファイル転送
- 04SSH ポート転送
- 05シークレット注入と出力の除去
- 06任意のセッション記録
活用シーン
- 01リモートホストでのコマンド実行
- 02SFTP によるファイル転送
- 03応答に値を出さずにリモート認証情報を使用
- 04デバッグ用の SSH 操作記録
MCP 対応
SSH 接続、コマンド、シェル、シークレット管理、セッション記録、SFTP、ポート転送のツールを MCP クライアントに提供します。ローカルの環境ファイルから読み込んだ値はツール応答から除去されます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
20掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| host | string | はい | リモートサーバーのホスト名または IP アドレス。 |
| key_path | string | いいえ | SSH 秘密鍵ファイルのパス。パスワード認証の場合は空欄にします。 |
| password | string | いいえ | 認証用パスワード。鍵認証の場合は空欄にします。 |
| port | integer | いいえ | SSH ポート(デフォルト:22)。 |
| timeout | integer | いいえ | 接続タイムアウト(秒)(デフォルト:60)。 |
| username | string | いいえ | SSH ユーザー名(デフォルト:root)。 |
詳細
mcp-remote-ssh
AI エージェントに完全な SSH アクセスを提供する MCP サーバーです。永続セッション、構造化されたコマンド出力、SFTP ファイル転送、ポートフォワーディング、セッションのトランスクリプト記録、そして出力の自動マスキング機能を備えた、秘密情報を安全に扱う環境変数の注入に対応しています。
これが必要な理由
ほかの SSH MCP サーバーには、パスワード認証、永続セッション、SFTP、ポートフォワーディング、構造化された終了コードのいずれかが欠けています。このサーバーはそのすべてに対応し、さらに、AI エージェントに認証情報を決して見せない、MCP レベルで唯一の秘密情報管理機能を備えています。
環境変数を安全に扱う
問題: AI エージェントがリモートサーバーで API トークン、パスワード、キーを使う場合、一般的な方法では LLM のコンテキストウィンドウに秘密情報が露出します。エージェントが秘密情報のファイルを読み取ると、その内容が会話に含まれてしまうか、echo $TOKEN を実行して出力から値を確認してしまいます。
解決策: ssh_load_env_file は、マシン上のローカルファイルから秘密情報を読み取り、リモート SSH セッションに注入し、出力の自動マスキング対象として登録します。AI エージェントは変数を自由に使用できます。ツールの応答はすべて、LLM に届く前にマスキングされます。
# Agent calls this -- file is read from YOUR machine, not the remote host
ssh_load_env_file(session_id="abc", file_path="~/.secrets/prod.env")
→ "Loaded 3 variables from local:~/.secrets/prod.env: API_TOKEN, DB_PASS, SECRET_KEY"
# Agent tries to echo the value -- redacted automatically
ssh_execute(session_id="abc", command="echo $API_TOKEN")
→ {"stdout": "***\n", "exit_code": 0}
# Agent dumps the environment -- all secret values scrubbed
ssh_execute(session_id="abc", command="env | grep API_TOKEN")
→ {"stdout": "API_TOKEN=***\n", "exit_code": 0}
# Agent reads a file containing a secret -- also redacted
ssh_read_remote_file(session_id="abc", remote_path="/etc/app/config")
→ "db_password=***\ndb_host=localhost\n"
# Normal commands work perfectly -- no over-redaction
ssh_execute(session_id="abc", command="uname -a")
→ {"stdout": "Linux server 6.1.0 ...", "exit_code": 0}
仕組み
┌─────────┐ ┌──────────────────────────────┐ ┌─────────────┐
│ LLM │ ←─JSON─ │ MCP Server (your machine) │ ──SSH─→ │ Remote Host │
│ (Agent) │ │ │ │ │
└─────────┘ │ 1. Reads ~/.secrets/prod.env│ └─────────────┘
│ 2. Parses KEY=VALUE pairs │
│ 3. Stores values in memory │
│ 4. Injects into SSH session │
│ 5. Redacts ALL tool output │
└──────────────────────────────┘
- ローカルファイルの読み取り — env ファイルはマシン上に保存され、リモートホストには置かれません
- シェル組み込みコマンドによる注入 —
read -r VAR <<< 'value' && export VARを使用します(プロセスツリーに露出しません) - 標準入力経由の exec 注入 —
ssh_executeは標準入力経由で秘密情報を bash ラッパーに渡すため、/proc/*/cmdlineには表示されません - 自動マスキング — LLM に届く前に、すべてのツール応答(
ssh_execute、ssh_shell_send、ssh_shell_read、ssh_read_remote_file)をマスキングします - 長い文字列を優先して照合 — 部分一致による破損を防ぎます(例:
abc123をabcより先に置換します)
セキュリティ上の特性
| 脅威 | 軽減されるか | 方法 |
|---|---|---|
| LLM のコンテキストウィンドウ内の秘密情報 | はい | 出力のマスキングにより値を *** に置換します |
| リモートプロセスツリー内の秘密情報(シェル) | はい | シェル組み込みコマンド(read/export)はフォークしません |
| リモートプロセスツリー内の秘密情報(exec) | はい | 秘密情報は標準入力経由で渡され、/proc/*/cmdline には表示されません |
LLM が env ファイルに対して cat を試す | 該当なし | ファイルはローカルにのみ存在し、リモートにはありません |
LLM が echo $VAR を試す | はい | 出力がマスキングされます |
| エンコード/変換された秘密情報(base64) | いいえ | リテラル一致のみがマスキングされます |
| 初回 SSH 接続時の MITM | 許容 | AutoAddPolicy を使用しています。以下の注記を参照してください |
ホストキーのポリシー
このサーバーは Paramiko の AutoAddPolicy を使用しており、未知のホストキーは確認なしで受け入れられます。これは、ホストが一時的な QE/ラボ環境(Beaker、クラウドインスタンス、CI マシンなど)で意図された動作です。トレードオフは次のとおりです。
- 利点: 新しくプロビジョニングされたマシンに、手間なく接続できます
- 欠点: 未知のホストへの初回接続時に MITM の脆弱性があります
信頼できないネットワークを利用する場合は、VPN または事前配布されたホストキーを使用する SSH バスティオンを経由した接続を検討してください。厳格な環境向けに、今後のリリースで host_key_policy パラメーターが追加される可能性があります。
env ファイルの形式
標準の .env 形式です。
# Comments are ignored
API_TOKEN=your-secret-token
DB_PASSWORD="quoted values work"
SECRET_KEY='single quotes too'
export ALSO_WORKS=yes
セッショントランスクリプト
記録はデフォルトでオフです。エージェントが実際に実行した内容の監査ログが必要な場合は、セッションごとに有効にしてください。バグの再現やテストキャンペーンに役立ちます。
# Start recording on connect
ssh_connect(host="lab.example.com", username="root", password="...", record=True)
# Or toggle later
ssh_start_recording(session_id="a1b2c3d4")
ssh_execute(session_id="a1b2c3d4", command="uname -a")
ssh_get_transcript(session_id="a1b2c3d4")
→ {"recording": true, "total_entries": 2, "transcript": "[12:01:02] --- connect: lab.example.com ---\n[12:01:05] $ uname -a\nLinux ...\n[exit 0]"}
ssh_save_transcript(session_id="a1b2c3d4", path="/tmp/lab-session.log")
ssh_stop_recording(session_id="a1b2c3d4")
- 実行/sudo の出力とシェルの送受信 I/O は、記録前に秘密情報がマスキングされます
- セッションを閉じると、メモリ上のトランスクリプトは破棄されます。先に
ssh_save_transcriptまたはssh_get_transcriptを実行してください
インストール
uvx mcp-remote-ssh # or: pip install mcp-remote-ssh
設定
{
"mcpServers": {
"remote-ssh": {
"command": "uvx",
"args": ["mcp-remote-ssh"]
}
}
}
ツール(24)
接続
| ツール | 説明 |
|---|---|
ssh_connect | パスワード、キー、またはエージェント認証で接続します。record=True を指定すると、すぐにトランスクリプトの記録を開始します。session_id を返します |
ssh_list_sessions | アクティブなセッションを一覧表示します |
ssh_close_session | セッションを閉じて、リソースを解放します |
実行
| ツール | 説明 |
|---|---|
ssh_execute | コマンドを実行し、{stdout, stderr, exit_code} を返します |
ssh_sudo_execute | sudo 権限で実行します |
インタラクティブシェル
| ツール | 説明 |
|---|---|
ssh_shell_open | 永続的なシェルを開きます(作業ディレクトリ、環境変数、プロセスを保持します) |
ssh_shell_send | テキストを送信します(任意で Enter キーも送信できます) |
ssh_shell_read | 現在の出力バッファーを読み取ります |
ssh_shell_send_control | Ctrl+C、Ctrl+D などを送信します |
ssh_shell_wait | パターンが現れるか、出力が安定するまで待機します |
シークレット管理
| ツール | 説明 |
|---|---|
ssh_load_env_file | ローカルの環境変数ファイルからシークレットを読み込みます。値が LLM に返されることはありません |
ssh_clear_secrets | マスキング用レジストリをクリアします(値が再び表示されるようになります) |
トランスクリプト
| ツール | 説明 |
|---|---|
ssh_start_recording | このセッションの execute/sudo/シェルの入出力の記録を開始します |
ssh_stop_recording | 記録を停止します。トランスクリプトはセッションが閉じられるまで利用できます |
ssh_get_transcript | トランスクリプトをテキストまたは JSONL として返します(last_n は任意です) |
ssh_save_transcript | トランスクリプトを MCP ホスト上のローカルファイルに書き込みます |
SFTP
| ツール | 説明 |
|---|---|
ssh_upload_file | ローカルファイルをリモートホストにアップロードします |
ssh_download_file | リモートファイルをローカルマシンにダウンロードします |
ssh_read_remote_file | リモートのテキストファイルを読み取ります |
ssh_write_remote_file | リモートファイルに書き込み/追記します |
ssh_list_remote_dir | メタデータとともにディレクトリを一覧表示します |
ポートフォワーディング
| ツール | 説明 |
|---|---|
ssh_forward_port | SSH トンネルを作成します(ローカル → リモート) |
ssh_list_forwards | アクティブなトンネルを一覧表示します |
ssh_close_forward | トンネルを閉じます |
クイックスタート
ssh_connect(host="server.example.com", username="admin", password="secret", record=True)
→ {"session_id": "a1b2c3d4", "connected": true, "recording": true}
ssh_load_env_file(session_id="a1b2c3d4", file_path="~/.secrets/prod.env")
→ "Loaded 2 variables: API_TOKEN, DB_PASS"
ssh_execute(session_id="a1b2c3d4", command="curl -H \"Authorization: Bearer $API_TOKEN\" https://api.example.com")
→ {"stdout": "{\"status\": \"ok\"}", "exit_code": 0} # token used but never visible
ssh_shell_open(session_id="a1b2c3d4")
ssh_shell_send(session_id="a1b2c3d4", data="cd /opt && make -j$(nproc)")
ssh_shell_wait(session_id="a1b2c3d4", pattern="$ ", timeout=600)
ssh_upload_file(session_id="a1b2c3d4", local_path="config.yaml", remote_path="/etc/app/config.yaml")
ssh_forward_port(session_id="a1b2c3d4", remote_port=5432, local_port=15432)
設計
Paramiko(SSH)と FastMCP(MCP プロトコル)を基盤にしています。
ssh_executeはexec_command()を使用し、終了コードを含む明確な構造化出力を返します- シークレットが読み込まれている場合、
ssh_executeは標準入力経由でbashラッパーにエクスポート設定を渡し、実際のコマンドをexecします。シークレットがプロセスツリーに現れることはありません ssh_shell_*はinvoke_shell()を使用して、永続的なインタラクティブセッションを実現します- Paramiko のブロッキング呼び出しはすべて
run_in_executorで実行し、非同期性を維持します - シェルは、
shell_readによるポーリング用に 500KB のローリングバッファーを保持します - シークレットのマスキングでは、すべての出力経路で文字列を長いものから順に置換します
- セッショントランスクリプトはメモリー上に保持され、既定では無効です。また、セッションを閉じると破棄されます
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。