mcpField
🔐
🔐 ssh-mcp-server

🔐 ssh-mcp-server

ローカル
github.com/classfang開発ツール9872 週間前に更新

🔐 ssh-mcp-server について

ssh-mcp-serverは、MCP対応のAIアシスタントなどがSSH経由でリモートホストを操作するためのMCPサーバーです。コマンド実行、ファイル操作、バックグラウンドジョブを提供し、コマンド制限とローカルでの認証情報管理を備えています。

主な機能

  1. 01SSHパスワード、鍵、2FA認証
  2. 02コマンドの許可リストと拒否リスト
  3. 03execとshellのトランスポートモード
  4. 04ファイルとディレクトリの転送
  5. 05バックグラウンドジョブの管理
  6. 06stdioとStreamable HTTP接続

活用シーン

  1. 01MCP経由でリモートホスト上のコマンドを実行
  2. 02踏み台やプロキシ経由でサーバーに接続
  3. 03ローカルとリモート間でファイルを転送
  4. 04長時間ジョブの開始と状態確認

MCP 対応

MCPクライアントにSSHコマンド、ファイル操作、サーバー一覧、バックグラウンドジョブのツールを提供します。標準はstdioで、Streamable HTTPのエンドポイントも利用できます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"ssh": {
"command": "npx",
"args": [
"-y",
"@fangjunjie/ssh-mcp-server"
]
}
}
}
起動コマンドnpx -y @fangjunjie/ssh-mcp-server

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npm@fangjunjie/ssh-mcp-server

ツール

4

掲載時のツール一覧 · 3 週間前に更新

パラメーター型必須説明
cmdStringstringはい実行するコマンド
directorystringいいえコマンド実行時の作業ディレクトリ
connectionNamestringいいえSSH 接続名(任意、デフォルトは 'default')
timeoutnumberいいえコマンド実行のタイムアウト(ミリ秒、任意。接続の commandTimeoutMs または shellCommandTimeoutMs を上書きします。デフォルトは 30000ms)

詳細

ssh-mcp-server logo

ssh-mcp-server

NPM Version GitHub forks GitHub Repo stars GitHub Issues or Pull Requests GitHub Issues or Pull Requests GitHub Issues or Pull Requests GitHub Issues or Pull Requests

基于 SSH 的 MCP (Model Context Protocol) 服务器,允许通过 MCP 协议远程执行 SSH 命令。

English Document | 中文文档

📝 项目介绍

ssh-mcp-server 是一个桥接工具,可以让 AI 助手等支持 MCP 协议的应用通过标准化接口执行远程 SSH 命令。这使得 AI 助手能够安全地操作远程服务器,执行命令并获取结果,而无需直接暴露 SSH 凭据给 AI 模型。

💬 如有任何问题,欢迎加入微信群交流:

wechat

✨ 功能亮点

  • 🔒 安全连接:支持多种安全的 SSH 连接方式,包括密码认证和私钥认证(支持带密码的私钥)
  • 🛡️ 命令安全控制:通过灵活的黑白名单机制,精确控制允许执行的命令范围,防止危险操作
  • 🔄 标准化接口:符合 MCP 协议规范,与支持该协议的 AI 助手无缝集成
  • 🚇 双传输模式:同时支持 exec 和 shell 两种 transport,兼容直连主机与堡垒机或跳板机场景
  • 🌐 HTTP 接入:默认使用 stdio;加上 --mcp-transport http 后通过 Streamable HTTP 提供 MCP 端点
  • 📂 文件传输:支持双向文件传输功能,可上传本地文件到服务器或从服务器下载文件
  • 🔑 凭据隔离:SSH 凭据完全在本地管理,不会暴露给 AI 模型,增强安全性
  • 🚀 即用即走:使用 NPX 可直接运行,无需全局安装,方便快捷

📦 开源仓库

GitHub:https://github.com/classfang/ssh-mcp-server

NPM: https://www.npmjs.com/package/@fangjunjie/ssh-mcp-server

🛠️ 工具列表

工具名称描述
execute-command命令执行工具在远程服务器上执行 SSH 命令并获取执行结果
upload文件上传工具将本地文件或整个目录上传到远程服务器指定位置
download文件下载工具从远程服务器下载文件或整个目录到本地指定位置
read-file读文件工具通过 SFTP 读取远程文本文件,可按字节偏移分页,拒绝二进制文件
write-file写文件工具通过 SFTP 直接写入文本内容(覆盖或追加),不经过 shell 引号转义
list-servers服务器列表工具列出所有可用SSH服务器配置
job-start / job-status / job-kill / job-list后台任务工具启动超过命令超时限制的长任务,轮询输出与退出码,终止任务

📚 使用方法

0. 🤖 通过 AI Skill 快速配置(推荐)

如果你使用支持 skill 的 AI 编程助手(如 Claude Code),可以直接使用内置的 ssh-mcp-helper skill 通过交互式问答完成安装和配置,无需手动编辑 JSON 文件。

使用方式:

  1. 从本仓库 skills/ 目录安装该 skill
  2. 告诉你的 AI 助手:"帮我配置 ssh-mcp-server" 或 "给 Cursor 加一个 SSH MCP 连接"
  3. skill 会逐步引导你:检查 Node.js 环境 → 选择 MCP 客户端 → 选择认证方式 → 收集连接参数 → 生成并写入配置

该 skill 支持下文所有场景(账号密码、私钥、SSH config 复用、SOCKS 代理、堡垒机、多连接、2FA、命令限制等),并自动生成格式正确的配置。


下面的章节按从简单到复杂的顺序排列,最简单的入门方式就是用账号密码连接服务器。直接复制对应场景下的 mcp.json 配置到你的 MCP 客户端即可使用。

⚠️ 重要提示:在 MCP 配置文件中,每个命令行参数和其值必须是 args 数组中的独立元素。不要用空格将它们连接在一起。例如,使用 "--host", "192.168.1.1" 而不是 "--host 192.168.1.1"。

1. 🔑 账号密码(最简单)
{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--host", "192.168.1.1",
        "--port", "22",
        "--username", "root",
        "--password", "pwd123456"
      ]
    }
  }
}
2. 🔐 账号 + 私钥
{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--host", "192.168.1.1",
        "--port", "22",
        "--username", "root",
        "--privateKey", "~/.ssh/id_rsa"
      ]
    }
  }
}
3. 🔏 带密码的私钥
{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--host", "192.168.1.1",
        "--port", "22",
        "--username", "root",
        "--privateKey", "~/.ssh/id_rsa",
        "--passphrase", "pwd123456"
      ]
    }
  }
}
4. 📋 复用 ~/.ssh/config

如果你已经在 ~/.ssh/config 配置了主机别名,服务器会自动从中读取连接参数,mcp.json 里就不用再写一遍。

{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--host", "myserver"
      ]
    }
  }
}

假设你的 ~/.ssh/config 包含:

Host myserver
    HostName 192.168.1.1
    Port 22
    User root
    IdentityFile ~/.ssh/id_rsa

你也可以指定自定义的 SSH 配置文件路径:

{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--host", "myserver",
        "--ssh-config-file", "/path/to/custom/ssh_config"
      ]
    }
  }
}

注意:命令行参数优先级高于 SSH 配置值。例如,如果你指定了 --port 2222,它会覆盖 SSH 配置中的端口。

需要一次连接多台已在 SSH config 中配好的主机时,参见下文「10. 多 SSH 连接配置」的方式四。

5. 🌐 通过代理连接

当目标主机只能通过代理访问时,可使用 --proxy 配置 SOCKS5、HTTP 或 HTTPS 代理。

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

支持的 URL 格式:

socks://username:password@proxy-host:1080
socks5://username:password@proxy-host:1080
http://username:password@proxy-host:8080
https://username:password@proxy-host:8443

HTTP 和 HTTPS 代理通过 CONNECT 方法建立到 SSH 服务的隧道,用户名和密码使用 Basic 代理认证。HTTP、HTTPS 未填写端口时分别默认使用 80、443;SOCKS5 必须填写端口。HTTPS 代理证书使用 Node.js 默认信任链进行验证。

原有 socksProxy 配置和 --socksProxy 参数继续兼容,但只接受 socks:// 和 socks5://。不要同时配置 proxy 和 socksProxy。

6. 📝 コマンドのホワイトリスト/ブラックリスト

--whitelist と --blacklist を使用して、サーバーが実行できるコマンドの範囲を制限します。複数のパターンはカンマで区切り、各パターンには正規表現を指定します。本番環境では設定を強く推奨します。ホワイトリストはコマンド全体と照合されます。ホワイトリストを有効にすると、;、&、|、バッククォート、$()、>、<、または改行を含むコマンドは直接拒否され、コマンドの連結、パイプ、リダイレクト、コマンド置換で検証を回避することはできません。

ホワイトリストの例(読み取り専用の表示コマンドのみを許可):

{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--host", "192.168.1.1",
        "--port", "22",
        "--username", "root",
        "--password", "pwd123456",
        "--whitelist", "^ls(?: [A-Za-z0-9_./-]+)*$,^cat [A-Za-z0-9_./-]+$,^df(?: -[A-Za-z]+)*(?: [A-Za-z0-9_./-]+)?$"
      ]
    }
  }
}

ブラックリストの例(危険なコマンドをブロック):

{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--host", "192.168.1.1",
        "--port", "22",
        "--username", "root",
        "--password", "pwd123456",
        "--blacklist", "^\\s*[rR][mM] .*,^\\s*[sS][hH][uU][tT][dD][oO][wW][nN].*,^\\s*[rR][eE][bB][oO][oO][tT].*"
      ]
    }
  }
}

注意:ブラックリストの正規表現はデフォルトで大文字と小文字を区別するため、^shutdown.* では Shutdown /a を防げません。上記の例では [sS] などの文字クラスを使い、スコープ付きインラインフラグ (?i:パターン) を使わずに、異なる Node.js バージョンに対応しています。古い Node.js ではこのインライン構文がサポートされていない場合があり、裸の (?i) も JavaScript の正規表現ではサポートされていません。不正な正規表現があるとサーバーの起動に失敗します。JSON 文字列内のバックスラッシュはエスケープする必要があります。正規表現の \s は JSON では \\s と記述し、コマンド前の空白を許容します。

注意:ホワイトリストとブラックリストを両方指定した場合、システムはまずコマンド全体がホワイトリストに一致するかを確認し、次にブラックリストに該当するかを確認します。実行するには、両方の確認に通る必要があります。読みやすく監査しやすくするため、ホワイトリストの正規表現には常に ^ と $ を明示的に使用することをおすすめします。複数の操作を組み合わせて実行する必要がある場合は、ロジックを個別にレビューしたスクリプトにまとめ、固定のスクリプト呼び出しのみを許可してください。シェル構文の解析を文字列分割に頼らないでください。

7. 🧩 コマンドテンプレートでコマンドをラップする

commandTemplate は、実行する各コマンドをテンプレートでラップします。ユーザーの切り替え(su)、コンテナー内での実行、踏み台サーバー経由での実行などに適しています。コマンドをシェル引数として渡す場合は <quotedCommand> を使用し、そのまま挿入する場合は <command> を使用します。テンプレートはディレクトリの cd を連結した後に適用されるため、cd ... && <実際のコマンド> 全体がラップされます。

{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--host", "10.0.0.1",
        "--port", "22",
        "--username", "deploy",
        "--password", "xxx",
        "--command-template", "su root -c <quotedCommand>"
      ]
    }
  }
}

作業ディレクトリを /data に指定して ls /app を実行すると、実際に送信されるコマンドは次のとおりです。

su root -c 'cd -- '\''/data'\'' && ls /app'

その他の一般的なテンプレート:

sudo bash -c <quotedCommand>
docker exec -i mycontainer sh -c <quotedCommand>
ssh jumphost <quotedCommand>
8. 🚇 踏み台サーバー/ジャンプサーバー(transportMode: shell)

transportMode のデフォルトは exec です。次のような場合は shell に切り替えてください。

  • SSH ログインは成功するものの、exec によるコマンド実行に失敗する
  • コマンドを正常に実行する前に、リモート側でログインバナー、プロファイル、環境の初期化が完了するまで待つ必要がある
  • 接続先が本質的に踏み台サーバーである、または対話型シェルしか公開していないデバイスである

両者の違い:

  • exec:execute-command、upload、download をサポートします
  • shell:コマンドは永続的なシェルセッションを通じて順番に実行され、内部にコマンドキューがあります。ただし、このモードでは SFTP が無効になるため、upload/download はサポートされません
{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--host", "bastion.example.com",
        "--port", "22",
        "--username", "ops",
        "--password", "pwd123456",
        "--transport-mode", "shell",
        "--shell-ready-timeout", "15000"
      ]
    }
  }
}

JSON 設定ファイルでは、shellCommandTimeoutMs を使って、shell モードにおける単一コマンドのデフォルトタイムアウトを上書きすることもできます。

9. 🔐 多要素認証(2FA/MFA)

SSH サーバーで多要素認証(パスワード+秘密鍵+2FA 認証コード)が必要な場合は、tryKeyboard を有効にしてください。パスワードと秘密鍵は自動的に提供されます。パスワード以外のプロンプトに対しては、接続前にサーバー側の環境変数 SSH_MCP_2FA_CODE で認証コードを指定してください。

{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--host", "example.com",
        "--port", "22",
        "--username", "user",
        "--password", "your_password",
        "--privateKey", "/path/to/key",
        "--try-keyboard"
      ]
    }
  }
}

認証フロー:

  1. 秘密鍵認証(指定されている場合)
  2. パスワード認証(指定されている場合)
  3. SSH_MCP_2FA_CODE を使って 2FA 認証コードを提供するキーボード対話型認証
10. 🧩 複数 SSH 接続の設定

同じ MCP サーバーで複数の SSH 接続先を同時に管理するには、各接続に名前を付け、呼び出し時に connectionName で選択します。設定方法は 4 種類あります。

📄 方法 1:設定ファイルを使用する(推奨)

JSON 設定ファイル(例:ssh-config.json)を作成します。

配列形式:

[
  {
    "name": "dev",
    "host": "1.2.3.4",
    "port": 22,
    "username": "alice",
    "password": "{abc=P100s0}",
    "socksProxy": "socks://127.0.0.1:10808",
    "commandTimeoutMs": 120000,
    "maxOutputBytes": 10485760
  },
  {
    "name": "bastion",
    "host": "9.9.9.9",
    "port": 22,
    "username": "ops",
    "password": "pwd123456",
    "transportMode": "shell",
    "shellReadyTimeoutMs": 15000,
    "shellCommandTimeoutMs": 45000,
    "connectionTimeoutMs": 30000,
    "keepaliveIntervalMs": 10000,
    "keepaliveCountMax": 3
  },
  {
    "name": "prod",
    "host": "5.6.7.8",
    "port": 22,
    "username": "bob",
    "password": "yyy",
    "socksProxy": "socks://127.0.0.1:10808"
  },
  {
    "name": "secure-server",
    "host": "secure.example.com",
    "port": 22,
    "username": "admin",
    "password": "your_password",
    "privateKey": "/path/to/private/key",
    "tryKeyboard": true
  }
]

オブジェクト形式:

{
  "dev": {
    "host": "1.2.3.4",
    "port": 22,
    "username": "alice",
    "password": "{abc=P100s0}",
    "socksProxy": "socks://127.0.0.1:10808",
    "commandTimeoutMs": 120000,
    "maxOutputBytes": 10485760
  },
  "bastion": {
    "host": "9.9.9.9",
    "port": 22,
    "username": "ops",
    "password": "pwd123456",
    "transportMode": "shell",
    "shellReadyTimeoutMs": 15000,
    "shellCommandTimeoutMs": 45000
  },
  "prod": {
    "host": "5.6.7.8",
    "port": 22,
    "username": "bob",
    "password": "yyy",
    "socksProxy": "socks://127.0.0.1:10808"
  }
}

次に、--config-file パラメーターを使用します。

{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--config-file", "ssh-config.json"
      ]
    }
  }
}
🔧 方法 2:JSON 形式の --ssh パラメーターを使用する

JSON 形式の設定文字列を直接渡すことができます。

{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--ssh", "{\"name\":\"dev\",\"host\":\"1.2.3.4\",\"port\":22,\"username\":\"alice\",\"password\":\"{abc=P100s0}\",\"socksProxy\":\"socks://127.0.0.1:10808\"}",
        "--ssh", "{\"name\":\"bastion\",\"host\":\"9.9.9.9\",\"port\":22,\"username\":\"ops\",\"password\":\"pwd123456\",\"transportMode\":\"shell\",\"shellReadyTimeoutMs\":15000}",
        "--ssh", "{\"name\":\"prod\",\"host\":\"5.6.7.8\",\"port\":22,\"username\":\"bob\",\"password\":\"yyy\",\"socksProxy\":\"socks://127.0.0.1:10808\"}"
      ]
    }
  }
}
📝 方法 3:従来のカンマ区切り形式(後方互換性)

パスワードに特殊文字が含まれない単純なケースでは、従来の形式も引き続き使用できます。

npx @fangjunjie/ssh-mcp-server \
  --ssh "name=dev,host=1.2.3.4,port=22,user=alice,password=xxx" \
  --ssh "name=prod,host=5.6.7.8,port=22,user=bob,password=yyy"

⚠️ 注意:従来の形式では、パスワードに特殊文字(=、,、{、} など)が含まれている場合、問題が発生することがあります。パスワードに特殊文字が含まれる場合は、方法 1 または方法 2 を使用してください。

🔑 方法 4:--host のカンマ区切り複数値(~/.ssh/config を再利用)

--host ではカンマ区切りで複数のホストを指定でき、複数接続モードになります。各ホストは独立した接続となり、ホスト値自体が接続名になります。単一値の --host の動作は変わらず、接続名は引き続き default です。各ホストには、単一ホストの場合と同じマージルールが個別に適用されます。SSH config のエイリアスに一致すると、HostName/Port/User/IdentityFile が展開され、コマンドライン引数は項目ごとに上書きされます。複数のホストがすでに ~/.ssh/config で設定されている場合に適しており、JSON を記述する必要はありません。

{
  "mcpServers": {
    "ssh-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@fangjunjie/ssh-mcp-server",
        "--host", "myserver,anotherserver",
        "--pty", "false"
      ]
    }
  }
}

認証の解析方法は、CLI 認証パラメーター(--password/--privateKey/--agent)の指定有無によって、次の 2 通りに分かれます。

  • 指定しない場合:各エイリアスの認証情報は、それぞれ SSH config から解析されます(そのエイリアスの IdentityFile が優先され、次に ~/.ssh のデフォルト ID ファイルへフォールバックし、最後に SSH agent が使用されます)
  • 指定する場合:すべてのホストでその CLI 認証情報が共有され、SSH config の IdentityFile は使用されません(エイリアスと直接指定した IP アドレスで動作は同じで、異なるのはアドレスの展開のみです)。--passphrase は鍵の復号パスフレーズとして共有できます

その他の CLI ポリシーパラメーター(--pty、--whitelist、タイムアウトなど)はプロセスレベルのデフォルト値としてすべてのホストで共有されるため、サーバーごとに指定する必要はありません。いずれかのホストにユーザー名または認証情報が不足している場合、起動時にエラーとなり、そのホストが表示されます。ポート、ホワイトリスト、タイムアウトなど、ホストごとに異なるポリシーを設定する必要がある場合は、方法 1 を使用してください。

MCP ツールを呼び出す際は、connectionName パラメーターで接続先の名前を指定します。指定しない場合は、デフォルトの接続が使用されます。

例(prod 接続でコマンドを実行):

{
  "tool": "execute-command",
  "params": {
    "cmdString": "ls -al",
    "connectionName": "prod"
  }
}

例(タイムアウトオプションを指定してコマンドを実行):

{
  "tool": "execute-command",
  "params": {
    "cmdString": "ping -c 10 127.0.0.1",
    "connectionName": "prod",
    "timeout": 5000
  }
}
⏱️ コマンド実行のタイムアウト

execute-command ツールは、コマンドが無期限に停止するのを防ぐタイムアウトオプションをサポートしています。

  • timeout:1 回の呼び出しにおけるコマンド実行のタイムアウト時間(ミリ秒、任意)。指定すると接続設定が上書きされ、指定しない場合は該当する接続の設定、またはデフォルト値の 30000ms が使用されます
  • JSON 設定ファイルで接続ごとに commandTimeoutMs を設定すると、このデフォルト値を変更できます。これにより、呼び出しのたびに timeout を手動で渡す必要がなくなります(exec モード)
  • shell モードに対応する設定項目は shellCommandTimeoutMs です
  • 呼び出しパラメーターの timeout は、上記 2 つの設定項目より常に優先されます
  • 接続ではデフォルトで SSH keepalive が有効になっており(keepaliveIntervalMs: 10000、keepaliveCountMax: 3)、connectionTimeoutMs で接続確立の時間が制限されます
  • SFTP の起動および転送操作のタイムアウトは、sftpTimeoutMs で制御されます(デフォルトは 300000ms)
  • エラーレスポンスには、上位のエージェントが処理しやすいよう、安定した code、message、retriable フィールドが含まれるようになりました
  • コマンドが正常に実行されてもゼロ以外の終了コードで終了した場合(grep で一致なし、diff で差分あり、など)、execute-command はコマンドの出力を直接返し、末尾に [exit code] N を追加します。ツールエラーとして扱われず、JSON にもラップされません。タイムアウト、接続失敗、検証失敗などの実際のエラーは、引き続き前述の code/message/retriable を返します

これは、ping、tail -f、または実行がブロックされる可能性のあるその他の長時間実行プロセスで特に便利です。

📄 ファイルの読み書きとディレクトリ転送
  • read-file:リモートテキストファイルの指定したバイト範囲(offset/length、デフォルトは最大 65536 バイト)を読み取ります。内容の前に [bytes] 開始-終了 of 合計サイズ のヘッダーが付き、読み終わっていない場合はページ分割に便利な next offset が返されます。バイナリコンテンツ(NUL バイトまたは大量の無効な UTF-8)が検出されると、処理を拒否し、download を使用するよう案内します
  • write-file:テキストコンテンツをリモートファイルに直接書き込みます(append: true で追記、mode で新規ファイルの権限を指定)。コンテンツはシェルを経由しないため、引用符、$、バッククォート、複数行のコンテンツをエスケープする必要はありません
  • upload/download のパスがディレクトリの場合は再帰的に転送します。リモートディレクトリが存在しない場合は作成され、シンボリックリンクなどの通常ファイル以外はスキップされます。1 回につき最大 2000 ファイルです(それより大きなディレクトリは先にアーカイブしてください)。ファイルは 1 つずつ転送され、パスの検証は単一ファイルの場合と同じです
  • 上記はすべて SFTP を使用し、allowedLocalPaths/allowedRemotePaths による制限を受けます。shell モードでは使用できません
📦 コマンド出力の制限

大きなファイルや無限に続く出力によって MCP サーバーのメモリが枯渇するのを防ぐため、1 つのコマンドで捕捉する stdout と stderr の合計量を制限します。

  • JSON 接続設定の maxOutputBytes で上限を設定します。デフォルト値は 10485760(10 MiB)です
  • maxOutputBytes は 0 以上の整数である必要があります。0 を設定すると制限を無効にできますが、信頼できないコマンドに対して無効にすることは推奨されません
  • 出力が制限を超えると、リモートコマンドは中断され、ツールは捕捉済みの切り詰められた出力と OUTPUT_LIMIT_EXCEEDED エラーを返します。中断されたコマンドを誤って成功として報告することはありません
  • pty が false の場合、成功したコマンドが stderr に書き込んだ警告や進捗情報は [stderr] セクションに保持されます
  • exec モードと shell モードの両方にこの制限が適用されます。違いは、exec モードではそのコマンドのチャネルだけを閉じるのに対し、shell モードではチャネルがその接続上のすべてのコマンドで共有され、コマンド中断後もリモート側が書き込みを続けるため、接続が切断されることです(shell モードのコマンドタイムアウト時と同じ処理です)
🧵 バックグラウンドタスク

execute-command はタイムアウト後にコマンドを放棄します。ビルドやデプロイなどの長時間タスクには、バックグラウンドタスクを使用してください。

  • job-start:リモートでコマンドをバックグラウンド起動し、すぐに job_id を返します。コマンドは execute-command と同じく、commandWhitelist/commandBlacklist による検証を受けます
  • job-status:状態(running/exited/killed/lost)、終了コード、実行時間、出力を返します。offset を指定しない場合は出力末尾(tailBytes、デフォルトは 8192)を返します。offset を指定すると、そのバイト位置から読み取り、戻り値に next offset が含まれます。繰り返しポーリングすると、新たに追加された内容だけを読み取れます
  • job-kill:まず SIGTERM を送信し、5 秒後も終了していない場合は SIGKILL を送信して、子プロセスを再帰的に終了させます
  • job-list:最近のタスクとその状態を一覧表示します
  • タスクの状態(コマンド、出力、pid、終了コード)はリモートの ~/.ssh-mcp-jobs/<id>/ に保存されるため、MCP の再起動や SSH 接続の切断後も失われません。終了から 7 日を超えたタスクのディレクトリは、次回の job-start 時にクリーンアップされます
  • job-kill はコマンドラインにそのタスク ID が含まれるプロセスにのみシグナルを送信し、pid が再利用された場合に無関係なプロセスを誤って終了させるのを防ぎます。この場合、タスクの状態は lost と表示されます
  • リモート側には POSIX sh が必要です。setsid がある場合、タスクは独立したプロセスグループになります。shell(踏み台)モードでも使用できます
🗂️ すべての SSH サーバーを一覧表示する

MCP ツール list-servers を使用して、利用可能なすべての SSH サーバー設定を取得できます。

呼び出し例:

{
  "tool": "list-servers",
  "params": {}
}

戻り値の例:

[
  { "name": "dev", "host": "1.2.3.4", "port": 22, "username": "alice" },
  { "name": "prod", "host": "5.6.7.8", "port": 22, "username": "bob" }
]
🌐 HTTP トランスポート(Streamable HTTP)

プロセスはデフォルトで stdio を使用し、既存の command/args 設定はそのまま利用できます。クライアントから URL 経由で接続する場合は、--mcp-transport http を指定して、同じプロセスを MCP Streamable HTTP サービスとして実行します。デフォルトのエンドポイントは http://127.0.0.1:3000/mcp です。

まず、ローカルマシンでサービスを起動します。プロセス引数にトークンが表示されないよう、環境変数に設定してください。

export SSH_MCP_HTTP_TOKEN='replace-with-a-long-random-token'
npx -y @fangjunjie/ssh-mcp-server \
  --mcp-transport http \
  --http-host 127.0.0.1 \
  --http-port 3000 \
  --host 192.168.1.1 \
  --port 22 \
  --username root \
  --privateKey ~/.ssh/id_rsa

MCP クライアントの URL 設定:

{
  "mcpServers": {
    "ssh-mcp-server": {
      "url": "http://127.0.0.1:3000/mcp",
      "headers": {
        "Authorization": "Bearer replace-with-a-long-random-token"
      }
    }
  }
}

--http-token と SSH_MCP_HTTP_TOKEN の両方を設定した場合は、コマンドライン引数が優先されます。トークンを設定していない場合は、127.0.0.1 へのバインドのみを推奨します。0.0.0.0 またはその他のローカル以外のアドレスで待ち受ける場合、そのポートにアクセスできるすべてのクライアントがリモートコマンドを実行できるため、起動ログに警告が表示されます。

⚙️ コマンドラインオプションのリファレンス
选项:
  --config-file       JSON 配置文件路径(推荐用于多服务器配置)
  --ssh-config-file   SSH 配置文件路径(默认: ~/.ssh/config)
  --ssh               SSH 连接配置(可以是 JSON 字符串或旧格式)
  -h, --host          SSH 服务器主机地址或 SSH 配置中的别名(逗号分隔多值进入多连接模式)
  -p, --port          SSH 服务器端口
  -u, --username      SSH 用户名
  -w, --password      SSH 密码
  -k, --privateKey    SSH 私钥文件路径
  -P, --passphrase    私钥密码(如果有的话)
  -a, --agent         SSH agent socket 路径
  --try-keyboard      启用键盘交互式认证以支持 2FA/MFA(默认: false)
  -W, --whitelist     命令白名单,以逗号分隔的正则表达式
  -B, --blacklist     命令黑名单,以逗号分隔的正则表达式
  --proxy             代理地址,支持 SOCKS5、HTTP 和 HTTPS
  -s, --socksProxy    旧版 SOCKS5 代理地址(兼容参数)
  --allowed-local-paths   upload/download 允许访问的额外本地路径,逗号分隔
  --allowed-remote-paths  SFTP upload/download 允许访问的远端路径(POSIX 绝对路径或 Windows 盘符绝对路径,如 /var/log 或 C:/Users),逗号分隔
  --transport-mode    SSH transport 模式: exec 或 shell(默认: exec)
  --shell-ready-timeout   shell 就绪探测超时,单位毫秒(默认: 10000)
  --command-template  命令模板;shell 参数用 <quotedCommand>,原样插入用 <command>
  --pty <true|false>  为命令执行分配伪终端(默认: true)
  --pre-connect       启动时预连接所有配置的 SSH 服务器
  --mcp-transport     MCP 客户端传输:stdio 或 http(默认: stdio)
  --http-host         HTTP 监听地址(默认: 127.0.0.1)
  --http-port         HTTP 监听端口(默认: 3000,0 表示由系统分配)
  --http-path         HTTP 端点路径(默认: /mcp)
  --http-token        HTTP Bearer 令牌;未传时读取环境变量 SSH_MCP_HTTP_TOKEN
  --version, -v       打印包版本
  --help              打印帮助信息

🛡️ セキュリティに関する注意事項

このサーバーでは、リモートサーバーでコマンドを実行したり、ファイルを転送したりできます。安全に使用するため、以下の点に注意してください。

  • コマンドのホワイトリスト:実行可能なコマンドを制限するため、--whitelist オプションの使用を強く推奨します。ホワイトリストがない場合、リモートサーバー上であらゆるコマンドを実行できるため、重大なセキュリティリスクにつながる可能性があります。
  • 秘密鍵の安全性:サーバーは SSH 秘密鍵をメモリに読み込みます。ssh-mcp-server を実行するマシンが安全であることを確認してください。サーバーを信頼できないネットワークに公開しないでください。
  • HTTP エンドポイント:HTTP モードはデフォルトで 127.0.0.1 のみで待ち受けます。外部ネットワークに公開する場合は、--http-token または SSH_MCP_HTTP_TOKEN を設定してください。トークンはリモートコマンド実行の鍵となるため、長くランダムな文字列を使用し、環境変数に設定することを優先してください。
  • サービス拒否攻撃(DoS):サーバーには組み込みのレート制限がありません。攻撃者は大量の接続リクエストや大容量ファイルの転送をサーバーに送信して、DoS 攻撃を仕掛ける可能性があります。レート制限機能を備えたファイアウォールまたはリバースプロキシの背後でサーバーを実行することを推奨します。
  • パストラバーサル:サーバーにはローカルファイルシステムのパストラバーサル攻撃を防ぐ機能が組み込まれています。ただし、upload コマンドと download コマンドで使用するパスには引き続き注意が必要です。
  • ローカル転送範囲:デフォルトでは、現在の作業ディレクトリへのアクセスのみが許可されます。明確に信頼できる場合に限り、--allowed-local-paths または設定ファイルの allowedLocalPaths で範囲を広げることを推奨します。
  • リモート転送範囲:SFTP の upload/download では、POSIX の絶対パス(例:/var/log/app.log)と Windows のドライブ文字付き絶対パス(例:C:/Users/foo/bar.txt。自動的にスラッシュに正規化されます)を使用できます。allowedRemotePaths(または --allowed-remote-paths)が設定されていない場合、任意のリモートパスが許可されますが、起動時に警告が表示されます。モデルがプロンプトインジェクションを受けた後に ~/.ssh/authorized_keys や /etc/sshd_config などの機密ファイルを読み書きしないよう、allowedRemotePaths のホワイトリストを明示的に設定することを強く推奨します。

🌟 Star の推移

Star の推移

Star の推移を示すグラフ

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。