Skip to main content
Glama
perhamm

ssh-mcp-server

by perhamm

ssh-mcp-server

CI npm

SSH 上で動作する MCP サーバー: エージェントがリモートマシン上でコマンドを実行し、鍵・パスワード・sudo はこちら側に留まります。

classfang/ssh-mcp-server の ISC ライセンスでのフォークです。

Русский | English

これは何か

ssh-mcp-server は MCP クライアント(Claude Code、Cursor、Cline)と SSH の間のブリッジです。エージェントがツールを呼び出し、サーバーがマシンに接続して出力を返します。モデルは秘密鍵もパスワードも sudo パスワードも見ることはありません。これらはすべてローカル設定とプロセスの環境変数から読み込まれます。

1 つのサーバーで任意の数のホストを処理できます。ホストは ~/.ssh/config のエイリアスからその場で選択されるため、MCP クライアントの設定に各マシンを書き込む必要はありません。

Related MCP server: ssh-mcp-server

このフォークで追加されたもの

機能

目的

~/.ssh/config からのホストをその場で取得

1 つの MCP で全マシンを管理。エイリアスを connectionName に渡し、最初のアクセス時に接続を確立

ProxyJump

踏み台の背後にあるホストにエイリアスでアクセス可能。ProxyJump チェーンは SSH 設定から解析

環境変数からの sudo

エージェントが sudo: true を要求し、サーバーがパスワードを挿入して出力から除去

禁止コア

決して実行されない操作のリスト: sudo 下でも、どのプロファイルでも、SFTP 経由でも実行不可

ガードプロファイル

バージョン管理され更新される、既製の禁止セット safe とホワイトリスト readonly

トンネル

任意のローカルポートへの SOCKS5(ssh -D と同等)とポート転送(ssh -L と同等)

ホスト鍵の検証

known_hosts はデフォルトで照合され、リストにない鍵は接続拒否を意味する

最新の暗号化

Ed25519 を先頭に、SHA-1、CBC、DSA は不使用

監査ログ

各呼び出しは JSONL に書き込まれ、ローテーションと gzip アーカイブ付き

ファイルアップロードなし

upload はデフォルトで公開されない: ガードが読まないファイルは、コードをホストに持ち込む手段になる

ツール

ツール

機能

execute-command

コマンドを実行。sudo と任意の connectionName に対応

download

サーバーからファイルを取得

list-servers

設定済み接続、そのステータス、アクティブなガードプロファイルを表示

list-ssh-hosts

SSH 設定から connectionName として利用可能なエイリアスを表示

open-tunnel

接続経由で SOCKS5 プロキシまたはポート転送を起動

close-tunnel

トンネルを閉じる

list-tunnels

開いているトンネルと接続カウンターを表示

list-ssh-hosts は --ssh-config-hosts フラグがある場合のみ表示され、トンネルツールは --disable-tunnels フラグで非表示になります。upload ツールはリストにありません。--enable-upload フラグでのみ公開されます。

余分なコマンドなしのホスト情報

接続時にサーバーはマシンの状態を 1 回だけ取得します: ホスト名、アドレス、OS、カーネル、稼働時間、ディスク、メモリ、プロセス数。すべてのプローブはマーカーで 1 つのコマンドに結合されるため、ssh へのアクセスは 6 回ではなく 1 回です。

サーバーは結果をキャッシュに保持し、list-servers で返します:

[connected] prod-1 | deploy@10.0.0.5:22 | hostname=prod-1 | os=Linux | updated=2026-08-19T18:14:23Z

Raw JSON:
[{"name":"prod-1","connected":true,"guards":"guards=safe ruleset=2026.08.19 ...",
  "status":{"reachable":true,"osVersion":"Ubuntu 24.04.1 LTS","kernelVersion":"6.8.0-51-generic",
  "uptime":"12 days","diskSpace":{"free":"9.8G","total":"229.6G"},
  "memory":{"free":"5.6G","total":"15.5G"},"processes":{"running":214}}}]

つまり、uname -a、df -h、free -h、uptime を問い合わせる必要はなく、回答はすでに届いています。エージェントは list-servers を 1 回呼び出して、そこからステータスを読み取ります。

プローブは 1 つずつガードを通過します。ホワイトリストを使用すると、許可されたフィールドのみがステータスに残ります。ステータスが不完全でも、ホストが利用できないことを意味するわけではありません。

出力のない成功したコマンドは、空文字列ではなく [exit code] 0 を返します。空の応答はモデルにとって不明瞭な結果と解釈され、echo $? で再確認しに行きますが、これはサーバーへの余分なアクセスと余分なトークンになります。

クイックスタート: 全マシンに 1 つのサーバー

MCP クライアントの設定:

{
  "mcpServers": {
    "ssh": {
      "command": "npx",
      "args": [
        "-y",
        "@perhamm/ssh-mcp-server",
        "--ssh-config-hosts",
        "--guards-profile", "safe"
      ],
      "env": {
        "SSH_MCP_SUDO_PASSWORD": "..."
      }
    }
  }
}

その後、エージェントは次のように動作します:

  1. list-ssh-hosts を呼び出し、必要なエイリアス(例: r-ulybka-prod-master)を見つけます。大きな設定ではリストが切り詰められるため、エージェントは filter を渡します: 部分文字列または r-ulybka-* 形式のパターン。

  2. connectionName: "r-ulybka-prod-master" を指定して execute-command を呼び出します。

  3. サーバーは ~/.ssh/config からエイリアスを読み取り、そこから HostName、User、Port、IdentityFile、ProxyJump を取得し、接続を確立してコマンドを実行します。

鍵はマシンから出ることはありません: サーバーがファイルを自分で読み取り、ダイアログには SSH 設定からのパスのみが入ります。IdentityFile が指定されていない場合は、SSH_AUTH_SOCK から ssh-agent が使用されます。HostName のないエイリアスは、ssh と同様に自身の名前で接続します。

設定で個別の Host ブロックとして宣言されたエイリアスのみが到達可能です。Host * ブロックはデフォルトを提供しますが、任意の名前を到達可能なホストにはしません。

エイリアスのリストは絞り込めます:

"args": [
  "-y", "@perhamm/ssh-mcp-server",
  "--ssh-config-hosts",
  "--allowed-hosts", "r-ulybka-*,*-stage-*",
  "--ssh-config-file", "/home/user/.ssh/config_work"
]

パターンは * と ? をサポートします。エイリアスがいずれのパターンにも一致しない場合、接続は確立されず、エージェントは SSH_HOST_NOT_ALLOWED エラーを受け取ります。

セーフモードとガード

ガードはバージョン管理されたルールセットで、各コマンドをサーバーに送信する前にチェックします。ルールは guards/default-guards.json にあり、リポジトリとともに更新されます。

プロファイル

プロファイル

動作

off

プロファイルのルールは無効。禁止コアのみが機能。デフォルト値

safe

破壊的なコマンドの禁止が追加され、それ以外は許可

readonly

読み取りと診断のみを許可し、safe のすべての禁止を継承

"args": ["-y", "@perhamm/ssh-mcp-server", "--ssh-config-hosts", "--guards-profile", "safe"]

safe がコアに加えて検出するもの: shutdown と reboot、ファイアウォールのリセット、sshd と kubelet の停止、kubectl delete、helm uninstall、docker system prune、パッケージの削除、DROP DATABASE、curl | sh、git push --force、ログのクリーンアップ、カーネルモジュールのアンロード、対話型エディタ。完全なリストと理由は JSON にあります。

readonly はさらに、コマンドの各部分がホワイトリストに含まれることを要求します: ls、cat、grep、find、ps、ss、df、journalctl、systemctl status、kubectl get/describe/logs、docker ps/logs など。このプロファイルでは sudo は完全に禁止され、su、doas、pkexec も同様です。

禁止コア

一部の操作は決して実行されません: off プロファイルでも、sudo 下でも、独自のガードファイル経由でも、コマンドを迂回する SFTP 経由でも。リストは forbidden ブロックにあります。

カテゴリ

閉じられるもの

アカウント

useradd、usermod、userdel、groupadd、passwd、chpasswd、chage、vipw、および /etc/passwd、/etc/shadow、/etc/group への書き込み

sudo

/etc/sudoers と /etc/sudoers.d への書き込み、visudo

スケジュール

crontab -l 以外の crontab、/etc/cron*、/var/spool/cron、/etc/anacrontab への書き込み、at と batch コマンド

systemd

/etc/systemd、/lib/systemd、/usr/lib/systemd へのユニットとタイマーの書き込み、systemctl edit、systemd-run

SSH

/etc/ssh/*、~/.ssh/*、authorized_keys、sshd_config の編集、および ssh-keygen、ssh-copy-id、ssh-add

インタープリタ

python、perl、ruby、node、php、lua、Rscript、およびスクリプトファイルの実行: bash /tmp/x.sh、sh -s、source。ガードは他人のコードを読まないため、このような実行は完全に閉じられる

一括削除

第 1 レベルのディレクトリまたはシステムサブディレクトリの rm -r、マスクによる rm -r、find -delete、xargs rm による削除、--no-preserve-root フラグ

ディスクと秘密

mkfs、wipefs、dd of=/dev/、/dev/sd* への書き込み、フォーク爆弾、/etc/shadow と秘密鍵の読み取り

通常の作業は引き続き可能です: crontab -l、cat /etc/ssh/sshd_config、systemctl restart nginx、rm -rf /var/lib/myapp/cache/tmp は通過します。解析可能な bash -c "..." も機能します: その内容は同じルールでチェックされます。

コアはファイルツールも閉じます。download は /etc/shadow と ~/.ssh の内容を取得できず、allowedRemotePaths はここで何も許可し直しません。ローカル側も保護されています: download はファイルを私たち自身の ~/.ssh に置くことはできません。

ファイルのアップロードは完全に無効です。upload ツールは --enable-upload が渡されるまで公開されず、readonly プロファイルはこのフラグがあってもアップロードを拒否します。

サーバーがユーザーの作成や cron の編集専用に必要な場合、コアはフォーク内で意図的に編集する必要があります: それを解除するフラグはありません。

セミコロンで迂回できない理由

コマンドは ;、|、&&、||、&、改行、$(...) の置換で部分に分割され、各部分が個別にチェックされます。引用符は解析時に考慮されます。したがって、ls; rm -rf / はどのプロファイルでも通過しません。行全体が許可された ls で始まっていてもです。

ラッパーはチェック前に除去されます: sudo、env、timeout 5、nohup、および LC_ALL=C 形式の代入は、コマンドをルールから隠しません。bash -c "..." 内のスクリプトは個別に解析され、同じルールでチェックされます。コマンドの長さは 5000 文字に制限されています。

ガードはエージェントのミスを防ぐものであり、意図的な迂回を防ぐものではありません。python -c のような任意のコードを含むインタープリタは、ルールでは解析できません。迂回が許されない場合は、SSH ユーザー自身の権限を制限します。

ルールの更新

ルールを最新に保つ 3 つの方法:

  1. アップストリームを自分のフォークにマージします。ルールファイルは version フィールドでバージョン管理され、バージョンは list-servers と拒否テキストに表示されます。

  2. 独自のファイルを保持し、--guards-file /etc/ssh-mcp/guards.json で指定します。そのルールは組み込みルールに追加され、バージョンは 2026.08.19+local-1 になります。

  3. スケジュールでファイルを更新します:

node scripts/update-guards.js https://example.com/guards.json /etc/ssh-mcp/guards.json

スクリプトは JSON を検証し、各正規表現をコンパイルしてからファイルを置き換えます。壊れたダウンロードは、動作中のルールセットを壊しません。

独自ファイルの形式:

{
  "version": "local-1",
  "profiles": {
    "safe": {
      "deny": [
        { "id": "no-ansible", "pattern": "^ansible-playbook\\b", "reason": "выкат идёт из CI" }
      ]
    }
  }
}

scope: "command" フィールドは、ルールにコマンド全体を部分ではなくチェックさせます。curl | sh と SQL に関するルールはこのように機能します。独自ファイルの forbidden ブロックに独自の禁止を追加できますが、組み込みの禁止をそこから削除することはできません: リストは結合されます。

古い --whitelist と --blacklist は引き続き存在し、ガードの前にチェックされます。

ダイアログにパスワードを出さない sudo

sudoパスワードはサーバープロセスの環境変数に格納されています。エージェントはsudo: trueを渡しますが、パスワード自体は呼び出しの引数にも出力にも表示されません。

{
  "mcpServers": {
    "ssh": {
      "command": "npx",
      "args": ["-y", "@perhamm/ssh-mcp-server", "--ssh-config-hosts", "--guards-profile", "safe"],
      "env": {
        "SSH_MCP_SUDO_PASSWORD": "..."
      }
    }
  }
}

ツール呼び出し:

{
  "tool": "execute-command",
  "params": {
    "cmdString": "systemctl restart nginx",
    "connectionName": "r-ulybka-prod-master",
    "sudo": true
  }
}

コマンドはsudo -S -k -p '' -u root -- /bin/sh -c '<コマンド>'としてサーバーに送信され、パスワードはチャネルのstdinに書き込まれます。コマンドラインには含まれないため、psや履歴には残りません。このようなコマンドでは疑似端末は無効化されます。無効化しないとttyが入力を出力に反映してしまうためです。念のため、パスワードは出力とエラーテキストの両方から削除されます。

変数名と対象ユーザーは--sudo-password-envフラグと--sudo-userフラグで変更できます。変数が空の場合、接続前にSUDO_PASSWORD_MISSINGで呼び出しが失敗します。readonlyプロファイルはsudoを完全に禁止します。

shellモードでは、sudoがシェルと同じstdinを読み取るため、パスワードはコマンドの直後に別の行として追加されます。-kフラグにより、パスワードの要求が常に行われ、その行がコマンドとして実行されないことが保証されます。sudoにはexecモードの方が適しています。

トンネル

open-tunnelはローカルリスナーを起動し、SSH接続を介してトラフィックを転送します。クラスターのサービスに直接アクセスできず、ノードにはアクセスできる場合に便利です。

ポート8777のSOCKS5:

{
  "tool": "open-tunnel",
  "params": {
    "type": "socks5",
    "localPort": 8777,
    "connectionName": "r-ulybka-prod-master"
  }
}

以降、任意のクライアントがプロキシ経由でアクセスし、名前はリモート側で解決されます:

curl --socks5-hostname 127.0.0.1:8777 http://prometheus.monitoring.svc:9090/api/v1/query?query=up
kubectl --request-timeout=30s ... # через HTTPS_PROXY=socks5h://127.0.0.1:8777

ssh -Lに相当する単一ポートの転送:

{
  "tool": "open-tunnel",
  "params": {
    "type": "local",
    "localPort": 15432,
    "remoteHost": "pg-master.internal",
    "remotePort": 5432
  }
}

localPortが指定されていない場合、ポートはシステムによって選択され、応答で返されます。トンネルはclose-tunnelまで、SSH接続が切断されるまで、またはサーバーが停止するまで存続します。

制限はフラグで設定します:

フラグ

デフォルト値

機能

--tunnel-bind-address

127.0.0.1

トンネルが待ち受けるアドレス

--allowed-tunnel-ports

制限なし

使用を許可するポートのリスト

--max-tunnels

8

同時に保持するトンネル数

--disable-tunnels

オフ

トンネルツールをリストから削除

デフォルトのリスナーはループバック上に起動します。ループバックより広いアドレスはプロキシをネットワークに公開するため、意図的に変更してください。

ホストキーの検証

サーバーキーは、ProxyJumpチェーンの途中のホストを含め、接続のたびにknown_hostsと照合されます。デフォルトはstrictモードで、ホストがknown_hostsにない場合は拒否されます。

モード

動作

strict

デフォルト。known_hostsに存在するホストにのみ接続

accept-new

未知のホストは初回接続時に記録されるが、キーの不一致は引き続き拒否

off

検証なし、アップストリームの動作

~/.ssh/known_hosts、~/.ssh/known_hosts2、/etc/ssh/ssh_known_hostsが検証され、UserKnownHostsFileを持つエイリアスの場合はSSH設定で指定されたファイルが検証されます。独自のリストは--known-hosts-fileフラグで指定します。ハッシュ化されたエントリ、パターン、[host]:port形式、@revokedマーカーがサポートされています。

拒否はSSH_HOST_KEY_REJECTEDコードとフィンガープリントを含むテキストで返されます:

Host key of prod.example.com is not in known_hosts (~/.ssh/known_hosts): ssh-ed25519 SHA256:xxxx.
Verify that fingerprint, add the host to known_hosts, or start the server with --host-key-checking accept-new.

キーの不一致はどのモードでも決して受け入れられません。サーバーは接続を拒否し、ホストが再作成されたか、中間者攻撃があることを通知します。

初めてホスト群に接続する場合は、--host-key-checking accept-newで一度だけ実行し、その後strictに戻すと便利です。

監査ログ

各呼び出しはJSON行として書き込まれます: コマンド、接続、sudoフラグ、ガードの判定、所要時間、出力サイズ。出力の内容はログに含まれず、sudoパスワードは削除されます。

{"time":"2026-08-19T08:12:44.101Z","pid":8123,"event":"command","result":"blocked","connection":"r-ulybka-prod-master","command":"useradd deploy","sudo":true,"code":"COMMAND_VALIDATION_FAILED","reason":"Blocked by the forbidden core ..."}
{"time":"2026-08-19T08:12:51.880Z","pid":8123,"event":"command","result":"ok","connection":"r-ulybka-prod-master","command":"systemctl status nginx","sudo":false,"durationMs":412,"bytes":1840}

connect、command、download、upload、tunnel-open、tunnel-close、host-keyイベントが書き込まれます。

デフォルトでは、ファイルは$XDG_STATE_HOME/ssh-mcp-server/audit.jsonl、つまり通常は~/.local/state/ssh-mcp-server/audit.jsonlに置かれ、パーミッションは0600です。

フラグ

デフォルト

機能

--audit-log <path>

XDG状態ディレクトリ

ログへのパス、値offで書き込みを無効化

--audit-max-size <bytes>

10485760

このサイズを超えるとファイルがローテーションされる。0で内蔵ローテーションを無効化

--audit-keep <count>

10

保持するgzipアーカイブの数

ローテーションは内蔵されています: 制限に達すると、現在のファイルはaudit.jsonl.1.gzに移動し、古いアーカイブはシフトされ、--audit-keepを超えたものは削除されます。10 MiBのアーカイブ10個は、非圧縮で約100メガバイトになり、gzip後は大幅に小さくなります。

ログをlogrotateで管理している場合は、--audit-max-size 0を設定し、copytruncateモードでローテーションを設定します。

書き込みエラーはコマンドを失敗させません。サーバーはstderrに一度だけ書き込み、動作を継続します。

接続方法

以下は、簡単なものから複雑なものへのシナリオです。argsでは、各フラグとその値は配列の2つの別々の要素です: "--host", "192.168.1.1"であり、"--host 192.168.1.1"ではありません。

ログインとパスワード

{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@perhamm/ssh-mcp-server",
        "--host", "192.168.1.1",
        "--port", "22",
        "--username", "root",
        "--password", "pwd123456"
      ]
    }
  }
}

秘密鍵

"args": [
  "-y", "@perhamm/ssh-mcp-server",
  "--host", "192.168.1.1",
  "--username", "root",
  "--privateKey", "~/.ssh/id_rsa",
  "--passphrase", "pwd123456"
]

鍵のパスワードは設定ファイルに書かず、SSH_MCP_PASSPHRASE変数に格納できます。

~/.ssh/configからの単一エイリアス

"args": ["-y", "@perhamm/ssh-mcp-server", "--host", "myserver"]

サーバーはHost myserverブロックからHostName、Port、User、IdentityFile、ProxyJumpを読み取り、Includeディレクティブとパターンも含みます。コマンドラインフラグが優先されます: --port 2222は設定ファイルのポートを上書きします。

踏み台とProxyJump

エイリアスにProxyJumpがある場合、チェーンは自動的に構築されます:

Host r-ulybka-prod-master
    HostName 10.20.30.40
    User ops
    ProxyJump bastion
    IdentityFile ~/.ssh/prod_key

各後続ホップは、ssh -Jと同様に、前のホップのチャネルを介して接続します。チェーンは手動で指定することもできます: --proxy-jump "bastion,gateway:2222"。チェーンの深さは5ホップに制限されています。

プロキシ

"args": [
  "-y", "@perhamm/ssh-mcp-server",
  "--host", "192.168.1.1",
  "--username", "root",
  "--password", "pwd123456",
  "--proxy", "socks5://user:pwd@proxy-host:1080"
]

socks://、socks5://、http://、https://がサポートされています。HTTPとHTTPSはBasic認証付きのCONNECTメソッドで動作し、デフォルトポートは80と443です。SOCKS5の場合はポートが必須です。古い--socksProxyフラグも動作しますが、SOCKSのみを受け付けます。--proxyと--proxy-jumpは同時には使用されません。

インタラクティブシェルを備えたジャンプホスト

transportModeのデフォルトはexecです。ログイン成功後にコマンドが実行されない場合や、デバイスがインタラクティブセッションのみを提供する場合は、shellに切り替えます:

"args": [
  "-y", "@perhamm/ssh-mcp-server",
  "--host", "bastion.example.com",
  "--username", "ops",
  "--password", "pwd123456",
  "--transport-mode", "shell",
  "--shell-ready-timeout", "15000"
]

shellモードでは、コマンドは単一の永続セッションを通じて順番に送信され、uploadとdownloadは機能しません。SFTPが無効になっているためです。

2要素認証

--try-keyboardフラグはkeyboard-interactiveを有効にします。パスワードと鍵は自動的に入力され、2番目の要素のコードはSSH_MCP_2FA_CODE変数から読み取られます。

1つのサーバーでの複数接続

SSH設定のエイリアスに加えて、接続を記述したファイルを使用する従来の方法も残っています。

[
  {
    "name": "dev",
    "host": "1.2.3.4",
    "port": 22,
    "username": "alice",
    "privateKey": "~/.ssh/dev_key",
    "guardProfile": "safe",
    "commandTimeoutMs": 120000
  },
  {
    "name": "prod",
    "host": "5.6.7.8",
    "port": 22,
    "username": "bob",
    "privateKey": "~/.ssh/prod_key",
    "guardProfile": "readonly",
    "allowedRemotePaths": ["/var/log", "/tmp"]
  }
]
"args": ["-y", "@perhamm/ssh-mcp-server", "--config-file", "/abs/path/ssh-config.json"]

キーが接続名であるオブジェクト形式もサポートされています。接続はconnectionNameパラメータで選択され、指定がない場合は最初の接続が使用されます。

コマンドとパスの制限

ホワイトリストとブラックリスト

"args": [
  "-y", "@perhamm/ssh-mcp-server",
  "--host", "192.168.1.1",
  "--username", "root",
  "--privateKey", "~/.ssh/id_rsa",
  "--whitelist", "^ls( .*)?,^cat .*,^df.*",
  "--blacklist", "^rm .*,^shutdown.*"
]

パターンはカンマ区切りの正規表現です。コマンドは最初にホワイトリスト、次にブラックリスト、次にガードプロファイルでチェックされ、3つのチェックすべてに合格する必要があります。

コマンドテンプレート

--command-templateは各コマンドをラップします。<quotedCommand>はコマンドをエスケープされた引数として置換し、<command>はそのまま挿入します。テンプレートは作業ディレクトリの置換後に適用されます。

su root -c <quotedCommand>
docker exec -i mycontainer sh -c <quotedCommand>

ファイル操作のパス

--allowed-local-pathsは、uploadとdownloadで利用可能なローカルディレクトリのリストを拡張します(デフォルトでは現在のディレクトリのみ)。--allowed-remote-pathsはリモートパスを制限し、絶対POSIXパスをカンマ区切りで指定します。このフラグがない場合、SFTPはホストのファイルシステム全体を参照でき、サーバーは起動時にその旨を警告します。

タイムアウトと出力制限

パラメータ

デフォルト

制限対象

ツール呼び出しのtimeout

なし

単一コマンド、接続設定を上書き

commandTimeoutMs

30000

execモードのコマンド

shellCommandTimeoutMs

30000

shellモードのコマンド

connectionTimeoutMs

30000

接続の確立とハンドシェイク

sftpTimeoutMs

300000

SFTP操作

maxOutputBytes

10485760

単一コマンドのキャプチャされた出力

keepaliveIntervalMs

10000

keepaliveの間隔

出力制限を超えるとコマンドは中断され、ツールは既に収集された部分とともにOUTPUT_LIMIT_EXCEEDEDを返します。エラーはcode、message、retriableの構造で返されます。

コマンドラインフラグ

  --config-file <path>             Файл с описанием соединений
  --ssh-config-file <path>         Путь к SSH-конфигу (по умолчанию ~/.ssh/config)
  --ssh <config>                   Соединение как JSON или пары key=value
  -h, --host <host>                Хост или алиас из SSH-конфига
  -p, --port <port>                Порт
  -u, --username <name>            Пользователь
  -w, --password <password>        Пароль
  -k, --privateKey <path>          Путь к приватному ключу
  -P, --passphrase <passphrase>    Пароль от ключа
  -a, --agent <path>               Сокет ssh-agent
  -W, --whitelist <patterns>       Белый список команд, через запятую
  -B, --blacklist <patterns>       Чёрный список команд, через запятую
  --proxy <url>                    Прокси SOCKS5, HTTP или HTTPS
  -s, --socksProxy <url>           Старый флаг только для SOCKS5
  --allowed-local-paths <paths>    Локальные каталоги для upload и download
  --allowed-remote-paths <paths>   Удалённые каталоги для SFTP
  --transport-mode <mode>          exec или shell (по умолчанию exec)
  --shell-ready-timeout <ms>       Таймаут готовности shell (по умолчанию 10000)
  --command-template <template>    Шаблон с <command> или <quotedCommand>
  --pty                            Псевдотерминал для exec (по умолчанию включён)
  --try-keyboard                   Keyboard-interactive для 2FA
  --pre-connect                    Подключиться ко всем хостам при старте
  --ssh-config-hosts               Разрешить хосты из SSH-конфига на лету
  --allowed-hosts <patterns>       Шаблоны разрешённых алиасов, через запятую
  --proxy-jump <chain>             Цепочка ProxyJump, через запятую
  --guards-profile <name>          off, safe или readonly (по умолчанию off)
  --guards-file <path>             Свой набор правил поверх встроенного
  --sudo-password-env <var>        Переменная с паролем sudo
  --sudo-user <user>               Пользователь для sudo (по умолчанию root)
  --host-key-checking <mode>       strict, accept-new или off (по умолчанию strict)
  --known-hosts-file <paths>       Свои файлы known_hosts, через запятую
  --host-key-algorithms <list>     Алгоритмы хост-ключа, через запятую
  --enable-upload                  Опубликовать инструмент upload (по умолчанию выключен)
  --audit-log <path|off>           Путь к аудит-логу (по умолчанию каталог состояния XDG)
  --audit-max-size <bytes>         Порог ротации, 0 отключает (по умолчанию 10485760)
  --audit-keep <count>             Сколько архивов держим (по умолчанию 10)
  --disable-tunnels                Убрать туннельные инструменты
  --tunnel-bind-address <addr>     Адрес для туннелей (по умолчанию 127.0.0.1)
  --allowed-tunnel-ports <ports>   Разрешённые порты туннелей, через запятую
  --max-tunnels <count>            Лимит одновременных туннелей (по умолчанию 8)
  --version, -v                    Версия пакета
  --help                           Справка

セキュリティ

  • 本番環境では--guards-profile safeを有効にし、当直のインシデント分析にはreadonlyが適しています。offでは禁止されたコアのみが残り、その他はすべて実行され、サーバーはログに警告を書き込みます。

  • 鍵、鍵のパスワード、sudoパスワードはファイルと環境変数から読み取られます。MCPクライアントの設定には鍵自体ではなく鍵へのパスを保存します。

  • トンネルはループバックで待ち受けます。SOCKS5には認証がないため、0.0.0.0上のプロキシは、ポートに到達できるすべてのユーザーに内部ネットワークを公開し、サーバーは起動時にその旨の警告を書き込みます。

  • --allowed-remote-pathsがない場合、SFTPを介して~/.ssh/authorized_keysを含むホスト上の任意のパスを読み書きできます。

  • ホストキーはstrictモードでknown_hostsと照合されます。--host-key-checking offで検証を無効化するのはラボ環境のみにしてください。

  • 呼び出し頻度の制限はありません。

開発

npm install
npm run build
npm test

テストはNode.jsの組み込みランナーで実行され、test/にあります。

アップストリームとライセンス

このプロジェクトはclassfang/ssh-mcp-server(作者 junki.cn)から発展したもので、ライセンスはISCです。アップストリームの著作権はLICENSEに保持され、元のリポジトリへのリンクもそこにあります。

ガードのセットはtufantunc/ssh-mcp(MIT)のアイデアに一部基づいています。

NPMパッケージ: @perhamm/ssh-mcp-server。

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    F
    maintenance
    An MCP server that allows AI models to execute system commands on local machines or remote hosts via SSH, supporting persistent sessions and environment variables.
    1
    9 npm
    28
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that enables remote SSH command execution and bidirectional file transfers through a standardized interface. It allows AI assistants to securely manage remote servers while keeping credentials isolated and applying command-level security controls.
    ISC
  • A
    license
    A
    quality
    B
    maintenance
    MCP server for managing multiple SSH servers via AI assistants, offering tools for remote command execution, file operations, and system monitoring.
    11
    71 PyPI
    2
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that gives AI agents SSH capabilities to execute commands, transfer files, and inspect remote systems through a preconfigured host list.
    33 npm
    MIT