Skip to main content
Glama

SSH MCP Server —— 面向 AI 智能体的远程服务器工具

它使用你机器上已有的 OpenSSH 客户端:你的密钥、你的 ~/.ssh/config、你的跳板主机、你的代理转发。无需捆绑任何东西,无需编译,没有原生绑定。

可与 Claude Code、Codex CLI、opencode、Gemini CLI、Qwen Code、Hermes 及其他 MCP 客户端配合使用。

MCP Registry Glama npm downloads tests

安装 · 工具 · 设置 · 安全 · 路线图 · 文档 · 更新日志


30 秒完成安装

无需全局安装。npx 会在首次使用时下载该包:

npx -y @hypnosis/ssh-mcp-server

为每个项目将其添加到 Claude Code

claude mcp add ssh -s user \
  -e SSH_PROFILES_FILE="$HOME/.claude/ssh-profiles.json" \
  -- npx -y @hypnosis/ssh-mcp-server

然后创建 ~/.claude/ssh-profiles.json,至少包含一台机器:

{
  "profiles": {
    "production": {
      "host": "server.example.com",
      "username": "admin",
      "privateKeyPath": "~/.ssh/your_private_key"
    }
  }
}

这样就已经足够建立连接了。

Codex、opencode、Qwen Code 及其他客户端的配置方法见设置 SSH MCP server

环境要求

Node.js 18+,并且系统 ssh 客户端位于 PATH 中。在 Windows 上,请使用基于密钥的配置文件;目前不支持密码和口令配置文件。

npm version Node.js TypeScript MCP SDK License

如果你更想要固定版本、离线使用,或希望每次启动少一次注册表检查:请运行 npm install -g @hypnosis/ssh-mcp-server,然后在命令中使用 ssh-mcp-server,而不是 npx

Related MCP server: ssh-mcp-server

适用人群

  • 希望更快完成审计、故障检查和日常服务器维护的 DevOps 和 SRE

  • 借助 AI 助手交付产品、并把自己构建的东西运行在自己服务器上的 Vibe 编码者和独立开发者

  • 希望使用结构化工具,而不是不受限制的原始 shell 的 系统管理员和平台工程师

  • 没有专职运维团队、自己运营 VPS 的 开发者和小型团队

  • Homelab、NAS 和路由器用户——手头那些仍然好用的硬件,已经跟不上现代协议了。

为什么选择 SSH MCP server,而不是原始 shell

更少的 token,更低的 AI 成本

原始 shell 给 AI 智能体的是一个信息洪流:重复的命令、ASCII 表格和日志转储。要把这些噪音转化为服务器的全貌,需要烧掉大量 token——花的是你的钱。

更快的服务器调试

专用工具可以批量执行常规检查、限制嘈杂的输出,并只返回关键部分。智能体花在解读终端输出上的时间更少,也就能更快地找到修复方案。

更少的猜测,更少的 AI 错误

结构化答案会说明发现了什么、哪些内容无法测量、哪些内容被截断。这让智能体几乎没有空间用幻觉来填补空白——也意味着更少的错误修复、更平稳的部署和更可靠的代码。

SSH 兼容性:现代服务器、老旧设备和 Windows

使用你现有的 OpenSSH 配置

不捆绑任何 SSH 实现,没有原生绑定,无需针对每个平台重新构建。命令通过系统 ssh 客户端执行,因此你的密钥、你的 ~/.ssh/config、你的跳板主机和你的代理转发都会像在终端中一样正常工作。在支持的情况下,每个目标共享一条多路复用连接,意味着你只需认证一次,而不是每条命令认证一次。

对老旧服务器、路由器和 NAS 设备的 SSH 支持

用现代的 scp 向路由器发送文件,你会得到这样的结果:

scp app.conf router:/etc/
# scp: subsystem request failed on channel 0

其实什么也没有坏——当前的 scp 使用的是新协议,而路由器并不认识。在终端里,你只能去翻论坛帖子,然后带着一个额外的 flag 回来。在这里你什么都不用做:先尝试传输,识别到拒绝后改用旧协议,同时记住这台机器,下次传文件就直接走旧协议。

针对更老的 SSH 客户端和缺失工具的降级方案

老旧设备得到的是降级方案,而不是死胡同。当某个现代功能缺失时,服务器会尽可能走老路:

你的机器

你会得到什么

一台性能不足以支持现代文件传输的路由器或 NAS

文件仍然能送达——会自动使用旧协议

一台十年前的服务器

工作流仍然有效;只是每条命令都会新建连接,而不是复用连接

一个精简到无法对文件做哈希的镜像

上传会提示“无法验证”,而不是声称已匹配而实际上没人核对过

一台根本没有安装某个工具的机器

答案会显示“未测量”——绝不会出现一个被读作“什么都没有”的零

为 Model Context Protocol 而生

基于官方 MCP SDK 构建,全程使用 TypeScript,拥有 2500+ 单元测试,外加一套针对真实容器而非 mock 运行的实时测试套件。


原始 SSH 对比 SSH MCP server:同一项工作,两种做法

SSH 服务器健康检查

场景: 刚刚上线了一次部署。服务器感觉变慢了,而你不知道该归咎于磁盘、内存、服务、容器还是错误。

问题: “这台机器健康吗?”

原始 SSH

$ uptime
 10:42:17 up 18 days,  3:21,  2 users,  load average: 0.42, 0.31, 0.28
$ df -hT
Filesystem     Type   Size  Used Avail Use% Mounted on
/dev/sda1      ext4    40G   35G  5.0G  87% /
overlay        overlay  40G   35G  5.0G  87% /var/lib/docker/overlay2/...
$ free -h
               total        used        free      shared  buff/cache   available
Mem:           7.7Gi       4.9Gi       612Mi       121Mi       2.2Gi       2.5Gi
$ systemctl --failed
  UNIT              LOAD   ACTIVE SUB    DESCRIPTION
● api-worker.service loaded failed failed API background worker
$ docker ps -a
CONTAINER ID   IMAGE          STATUS                     PORTS
8e14d0b41c2a   api:latest     Up 3 minutes               0.0.0.0:8080->8080/tcp
65b894af2430   worker:latest  Exited (1) 2 minutes ago
$ ss -tulpn
Netid  State   Local Address:Port   Process
tcp    LISTEN  0.0.0.0:22          users:(("sshd",pid=842,fd=3))
tcp    LISTEN  0.0.0.0:8080        users:(("docker-proxy",pid=1942,fd=4))
$ journalctl -p err --since -1h | tail -50
Aug 20 10:39:14 prod api-worker[22104]: database connection timed out
Aug 20 10:39:14 prod systemd[1]: api-worker.service: Failed with result 'exit-code'.

这仍然只是一个删减过的结果。完整的检查还需要更多命令来查看 CPU、服务状态、容器数量和最近错误,每条命令都有自己的输出格式。更糟的是,一台没有 ss 的机器,在端口检查从未运行的情况下,看起来可能像是没有任何端口在监听。

结构化 MCP 结果

ssh_snapshot({ "profile": "production" })
{
  "disk_pct": 87,
  "mem_pct": 64,
  "cpu_pct": 12,
  "load": "0.42 0.31 0.28",
  "containers": 7,
  "ports": 14,
  "services_running": 3,
  "recent_errors": 21,
  "unavailable": []
}

智能体从中获得什么

原始 SSH

结构化 MCP

你的收益

多条命令和 ASCII 表格

一次结果中的命名字段

一次调用、命名字段、更少的往返

缺失的工具可能看起来像空输出

unavailable 明确指出哪些内容未被测量

更少的猜测和更少的错误修复

由你自行梳理磁盘、服务和错误

问题信号已经被呈现出来

更快的调试

完整的 ssh_audit_baseline 结果可能比几条原始命令的输出还要长——在我们的实验室测量中约为 1,077 个 token,而原始命令输出为 765 个。节省来自完整的工作流,而不是来自让某一次响应变得更短。

在一次真实的故障排查会话中,专用工具把 49 次独立的命令调用减少到了 4 次 MCP 调用。每多一次调用,模型都要在已累积的对话之上再开启一个新回合。提示缓存可以降低重复输入的成本,但新命令及其输出仍然会消耗上下文。更少的往返意味着整个会话中更少的 token、更少的重复分析,以及一条通向答案的更快路径。

需要的是完整画面,而不仅仅是脉搏? ssh_audit_baseline 会批量检查系统、磁盘、内存、端口、sshd、失败的单元、Docker、防火墙和更新。结果以 CRITICAL / WARNING / OK 呈现;未测量的部分会被明确指出,而不是被静默地当作零。

Linux 服务器日志搜索

场景: API 正在超时,但同样的消息可能出现在 nginx、syslog、journald 或某个你用普通用户无法读取的应用程序日志中。

问题: “这个错误是从哪里来的?”

原始 SSH

$ grep -i "timeout" /var/log/nginx/error.log
2026/08/20 10:38:54 [error] upstream timed out while reading response header
$ grep -i "timeout" /var/log/syslog
Aug 20 10:39:14 prod api-worker[22104]: database connection timed out
$ grep -i "timeout" /var/log/app/*.log 2>/dev/null
$ journalctl -u api --since "1 hour ago" | grep -i timeout
Aug 20 10:39:14 prod api[22104]: database connection timed out after 30000ms

第三条命令看起来没问题,但 2>/dev/null 也把权限错误隐藏了起来。“没有匹配”和“什么都没读到”现在看起来一模一样。繁忙的日志还可能返回数千行,把事故的其余内容挤出智能体的上下文。

结构化 MCP 结果

ssh_log_search({ "profile": "production",
                 "path": ["/var/log/nginx/error.log", "/var/log/syslog", "/var/log/app/*.log"],
                 "query": "timeout", "context": 2, "since": "1h" })
{
  "matches": 34,
  "lines": [
    { "file": "/var/log/nginx/error.log", "line": 4821,
      "text": "upstream timed out while reading response header", "context": false },
    { "file": "/var/log/nginx/error.log", "line": 4822,
      "text": "client closed connection", "context": true }
  ],
  "files_searched": 6,
  "files_unreadable": ["/var/log/app/private"],
  "files_skipped": 12,
  "files_undated": [],
  "limited": false,
  "truncated": false
}

智能体从中获得什么

原始 SSH

结构化 MCP

你的收益

四次搜索和四个输出

跨文件和 glob 的一次搜索

更少的 token 和往返

权限错误可能悄然消失

files_unreadable 标出每一条未能读取的路径

不会错误地得出“日志是干净的”结论

输出可以无限增长,没有有用的上限

limitedtruncated 暴露每一次截断

基于部分结果做出更安全的决策

since 使用服务器的时钟,namesOnly: true 只返回匹配的路径,而 ssh_log_tail 一次调用即可读取多个日志的最后 N 行。

安全的远程配置编辑

场景: 你需要在生产服务器上替换一份 nginx 配置。连接断开、模式错误或未经校验的复制,都可能让服务留下一个损坏的文件。

问题: “我能否替换这份配置,而不会留下一个只写了一半的文件?”

原始 SSH

$ sudo sh -c 'cat > /etc/nginx/conf.d/api.conf' <<'EOF'
server {
    listen 80;
    location / { proxy_pass http://127.0.0.1:8080; }
}
EOF
$ echo $?
0

退出码为零只能说明 shell 执行完了。它并不能证明哪些字节真正写入,而且 > 会在新文件的第一个字节到达之前就截断旧文件。如果连接在写入中途断开,服务就会留下一个不完整的配置。

结构化 MCP 结果

ssh_file_write({ "profile": "production",
                 "files": [{ "path": "/etc/nginx/conf.d/api.conf",
                             "content": "server {\n    listen 80;\n    location / { proxy_pass http://127.0.0.1:8080; }\n}\n",
                             "mode": "644", "sudo": true, "verify": true }] })
{
  "files": [{ "path": "/etc/nginx/conf.d/api.conf", "written": true,
              "verified": "verified", "reason": null, "bytes": 79 }]
}

智能体从中获得什么

原始 SSH

结构化 MCP

你的收益

目标在复制完成前被截断

完整的临时文件通过一次重命名替换它

不会出现写了一半的配置

只有退出码

字节数和校验结果都有明确的命名

你知道实际落盘了什么

权限藏在 shell 文本里

sudomodeverify 是每个文件的字段

所有权可预测,引号错误更少

verified 有三种诚实的结局:verified、当服务器没有哈希工具时的 unavailable,以及未请求校验时的 skipped。对于读取,ssh_file_read 接受路径列表;ssh_file_list 处理通配符、递归、大小和模式。

使用 sudo 运行批量 SSH 命令

场景: 部署已就绪,但在流量切换前必须检查 nginx 语法、服务状态和最近的错误。任何一项检查失败都不应消失在合并的输出中。

问题: “每一项预检都通过了吗?”

原始 SSH

$ ssh admin@server.example.com 'sudo nginx -t'
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ ssh admin@server.example.com 'sudo systemctl is-active nginx'
active
$ ssh admin@server.example.com 'sudo tail -5 /var/log/nginx/error.log'
2026/08/20 10:38:54 [error] upstream timed out while reading response header

三次连接返回三个互不相关的输出。如果用 ; 连接命令,shell 只报告最后一个退出码;如果用 && 连接,第一次失败后后面的检查就消失了。

结构化 MCP 结果

ssh_exec({ "profile": "production",
           "command": ["nginx -t", "systemctl is-active nginx",
                       "tail -5 /var/log/nginx/error.log"],
           "sudo": true })
{
  "commands": [
    { "command": "nginx -t", "exit_code": 0, "truncated": false, "clipped_bytes": 0,
      "stdout": "", "stderr": "nginx: configuration file /etc/nginx/nginx.conf test is successful\n" },
    { "command": "systemctl is-active nginx", "exit_code": 0, "truncated": false,
      "clipped_bytes": 0, "stdout": "active\n", "stderr": "" },
    { "command": "tail -5 /var/log/nginx/error.log", "exit_code": 0, "truncated": false,
      "clipped_bytes": 0, "stdout": "2026/08/21 09:14:02 [error] upstream timed out\n", "stderr": "" }
  ],
  "job_id": null
}

代理获得什么

原始 SSH

结构化 MCP

你的收益

三次调用和互不相关的输出

一个有序的命令列表

更少的往返次数

合并的 shell 可能隐藏中间状态

每条命令保留自己的 exit_code

不会漏掉失败的检查

sudo 和引号在命令文本中重复

sudo 应用于整个批次

更少的引号错误

破坏性命令防护在第一条命令运行前检查完整列表。如果有一条被拒绝,其他所有条目都被标记为未运行,且不会向服务器发送任何内容。

每条命令携带自己的 stdoutstderr。运行过但未输出任何内容的命令有空的字符串;从未运行的命令则完全没有该字段,因此两者不会混淆。每条命令超过 128 KB 的输出会保留两端——头部用于表格,尾部用于日志——中间有接缝标明数量,clipped_bytes 说明被裁剪了多少。裁剪发生在字节边界上,并回退到字符边缘,因此被裁剪的答案永远不会带有替换标记。

sudo 在没有终端的情况下到达服务器:当配置文件有密码时,密码通过标准输入交给 sudo。通过密钥认证的配置文件没有密码可提供,因此那里的 sudo 只在已经免密的情况下有效——而且读取自身标准输入的命令永远不会被给予密码,否则密码会混入数据中。

运行长时间运行的 SSH 任务

场景: 备份或迁移的运行时间将超过代理会话。连接可能会关闭,但你之后仍然需要它的状态、输出和退出码。

问题: “这个任务能撑过对话吗?”

原始 SSH

$ ssh admin@server.example.com 'pg_dump app | gzip > /srv/backups/app.sql.gz'
client_loop: send disconnect: Broken pipe

终端没了。你现在必须重新连接、找到进程、检查目标文件,然后猜测备份是完成了还是中途停止了。

结构化 MCP 结果

ssh_exec({ "profile": "production",
           "command": "pg_dump app | gzip > /srv/backups/app.sql.gz",
           "detach": true })
{
  "commands": [{
    "command": "pg_dump app | gzip > /srv/backups/app.sql.gz",
    "exit_code": null,
    "truncated": false,
    "timed_out": false,
    "blocked": false,
    "blocked_reason": null,
    "not_run": false,
    "warning": null
  }],
  "job_id": "mst0f2q1-9ab3c4d5"
}

代理获得什么

原始 SSH

结构化 MCP

你的收益

任务绑定在一个 SSH 会话上

远程任务有持久的 id

安全断开和重启

重新连接意味着搜索进程和文件

状态和退出码有明确的命名状态

不用猜测是否完成

再次读取输出会重复旧文本

输出从字节偏移处继续

长任务上更少的 token 消耗

任务状态存储在远程磁盘上,而不是这个服务器的内存中。ssh_job_status 区分 runningfinishedlostssh_job_output 从最后的字节偏移处继续;ssh_job_kill 向整个进程组发送信号,而不仅仅是它的 shell。

向旧式路由器和 NAS 设备传输文件

场景: 当前的 OpenSSH 客户端尝试 SFTP,但路由器或 NAS 只理解经典的 scp 协议。文件仍然必须完整到达并安全地替换其目标。

问题: “这台旧设备还能接收经过校验的文件吗?”

原始 SSH

$ scp app.conf operator@router:/etc/app.conf
subsystem request failed on channel 0
scp: Connection closed

通常的下一步是记起旧式标志、重试复制,然后运行一个单独的哈希命令——如果设备有哈希工具的话。

结构化 MCP 结果

ssh_upload({ "profile": "router", "local_path": "./app.conf",
             "remote_path": "/etc/app.conf", "sudo": true,
             "mode": "644", "owner": "root:root", "verify": true })
{
  "files": [{
    "path": "/etc/app.conf",
    "written": true,
    "verified": "verified",
    "reason": null,
    "bytes": 1284
  }]
}

代理获得什么

原始 SSH

结构化 MCP

你的收益

现代 SFTP 模式在第一个错误处停止

经典 scp 回退是自动的且被记住

旧设备仍然可用

成功的复制不能证明完整性

SHA-256 校验有明确的命名结果

损坏不会被误认为成功

直接替换可能留下部分目标

临时文件在传输完成后被移入到位

工作文件在中断中幸存

如果设备既没有 sha256sum 也没有 openssl,结果会显示 unavailable 并说明原因,而不是报告虚假的匹配。整个目录使用 recursive: true 并一次性批量校验其哈希。

面向 AI 代理的破坏性命令保护

防护在本地运行,在命令到达 SSH 之前。它区分可以恢复的操作和破坏承载数据的容器的操作,并检查链和批次内的命令顺序。

在破坏性链开始前阻止它

一个安全的备份-替换序列:

cp -r /srv/app /srv/app.bak && mv /srv/app /srv/app-old && rm -rf /srv/app

顺序错误的相同操作:

rm -rf /srv/app && cp -r /srv/app /srv/app.bak && mv /srv/app /srv/app-old
# REFUSED before the first command runs

shell 会删除目录,然后才发现备份源已经没了。防护看到后面的步骤读取了已被前面步骤破坏的目标,因此整个调用留在你的机器上。同样的检查也能捕获 dropdb app && pg_dump app > backup.sql

拒绝不可逆的丢失,警告可恢复的更改

拒绝——容器本身

仅警告——其内容

DROP DATABASEdropdb

DROP TABLETRUNCATEDELETE FROM

docker volume rmdocker compose down -v

docker rm -fdocker system prune -a

crontab -r

编辑单个任务

mkfswipefs -alvremovezfs destroy

chmod 777

rebootshutdownhalt

git reset --hard

docker compose down -v 被拒绝,因为 -v 会移除命名的 Docker 卷,包括数据库卷。没有 -v 时,停止服务不会被当作同样的不可逆操作。

递归删除文件系统根目录、主目录或 /etc/var/usr 等系统树也会被拒绝,包括符号链接指向这些位置的情况。未解析的目标如 rm -rf "$DIR"/* 也会被拒绝:“无法检查”不会被当作“安全”。

确认有意的破坏性命令

没有什么是永久禁止的。在已审查的命令中添加 # CONFIRMED-DESTRUCTIVE 即可放行。当防护拒绝批次中的一条时,整个批次在执行前停止,因此服务器永远不会处于半运行操作之后的状态。

防护在单次调用内工作。它无法将一次调用中的删除与下一次调用中的读取联系起来,也无法推理它不认识的工具。它是安全带,不是策略引擎:可恢复的操作仍然由你决定。路径限制和引号规则记录在 docs/security.md 中。

用于服务器操作的 SSH MCP 工具

18 个工具。完整参数和示例见 docs/tools.md

MCP 工具安全注解

标准 MCP 注解告诉客户端哪些工具是只读的、破坏性的、幂等的或开放世界的。参见完整表格

运行 SSH 命令并管理远程文件

工具

功能

ssh_exec

运行一条命令或一个批次,带破坏性命令防护和可选的分离执行

ssh_file_read

读取一个或多个文件,文本或二进制

ssh_file_write

以原子重命名和可选的 SHA-256 校验写入文件

ssh_file_list

列出目录,支持可选的通配符和递归

监控长时间运行的 SSH 任务

工具

功能

ssh_job_status

后台任务的状态:运行中、已完成或丢失

ssh_job_output

从字节偏移处读取累积输出

ssh_job_list

列出任务,清理超过 TTL 的已完成任务

ssh_job_kill

向任务的整个进程组发送信号

搜索日志并检查服务器健康

工具

功能

ssh_log_tail

一个或多个日志的最后 N 行,支持通配符

ssh_log_search

跨日志进行模式搜索

ssh_snapshot

一次性健康快照:服务、资源、Docker、网络、错误

ssh_monitor

传输控制:统计、重载、测试、列表、关闭

通过 SSH 上传和下载文件

带完整性检查的二进制安全传输。详情见 docs/transfer.md

工具

功能

ssh_upload

上传文件或目录

ssh_download

下载文件或目录

对于二进制和大文件,请使用 ssh_upload / ssh_download —— base64 块和 heredoc 不是二进制安全的,也不是原子的。

通过 SSH 审计 Linux 服务器

只读并批量化为一次往返。详情见 docs/audit.md

工具

功能

ssh_audit_baseline

系统、磁盘、内存、网络、ssh、服务、Docker、防火墙、更新

ssh_tls_check

域名的证书过期、SAN、链和续期钩子

ssh_disk_breakdown

磁盘去哪了:du 前 N 项、Docker、journald、缓存

ssh_service_status

systemctl status 加上一个单元的 journalctl 尾部

Windows SSH 兼容模式

Windows 会自动使用兼容模式。当连接多路复用不可用时,服务器会切换为每条命令一个连接。基于密钥的 SSH 仍可使用相同的工具——无需单独设置,也没有 Windows 特有的实现。

破坏性命令防护参见面向 AI 代理的破坏性命令保护

设置 SSH MCP 服务器

先运行30 秒内安装中的包,然后创建配置文件。

创建 SSH 连接配置文件

把它放在你喜欢的位置——通常放在代理自己的配置旁边。下面的示例使用 ~/.claude/ssh-profiles.json;对于其他代理,替换目录即可(~/.codex/~/.qwen/~/.config/opencode/):

{
  "profiles": {
    "production": {
      "host": "server.example.com",
      "username": "admin",
      "port": 22,
      "privateKeyPath": "~/.ssh/your_private_key"
    }
  }
}

显式选择 SSH 配置文件

服务器没有可回退的默认配置文件:每个配置文件都对应一台不同的机器,而发错机器的命令不是事后一条错误消息就能撤销的。不带名称询问时,返回结果会列出可供选择的名称:

ssh_exec({ command: "uptime" })
→ No profile specified. Name one explicitly: production

服务器无法用于 SSH 的配置文件——没有 host、没有 username,或 mode: "local"——会被静默跳过,无法识别的字段会被原样保留,因此该文件可以与其他工具共享。带有损坏字段的配置文件则是另一种情况:它会连同字段和值一起被点名,而其他正常的配置文件继续正常工作。

每个配置文件可选地包含一个 pathSecurity 块,用于将文件工具可能访问的路径加入白名单或黑名单——参见 docs/security.md

将 SSH 密码和口令移出配置文件

优先使用密钥。如果密码或加密密钥口令不可避免,请将其放在单独的 secrets 文件中,绝不能放在配置文件本身:

{
  "secretsFile": "~/.config/ssh-mcp/secrets.json",
  "profiles": {
    "production": {
      "host": "server.example.com",
      "username": "admin"
    }
  }
}

secrets 文件以配置文件名为键——参见 secrets.json.example

{
  "production": { "password": "..." }
}

secrets 文件必须只有你本人可读(chmod 600)。相对路径相对于配置文件解析;secrets 不会出现在 argv 中,并且会在日志中被遮蔽。参见凭据安全

配置 Claude Code、Codex 和其他 MCP 客户端

选择你使用的客户端,并将其指向同一个配置文件。

Claude Code

一条命令;-s user 让服务器在每个项目中都可用:

claude mcp add ssh -s user \
  -e SSH_PROFILES_FILE="$HOME/.claude/ssh-profiles.json" \
  -- npx -y @hypnosis/ssh-mcp-server

Codex CLI

codex mcp add ssh \
  --env SSH_PROFILES_FILE="$HOME/.codex/ssh-profiles.json" \
  -- npx -y @hypnosis/ssh-mcp-server

opencode

将其放入 ~/.config/opencode/opencode.json

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ssh": {
      "type": "local",
      "command": ["npx", "-y", "@hypnosis/ssh-mcp-server"],
      "enabled": true,
      "environment": {
        "SSH_PROFILES_FILE": "~/.config/opencode/ssh-profiles.json"
      }
    }
  }
}

Qwen Code

一条命令,与其他相同:

qwen mcp add ssh \
  -e SSH_PROFILES_FILE="$HOME/.qwen/ssh-profiles.json" \
  npx -y @hypnosis/ssh-mcp-server

其他 MCP 客户端

Gemini CLI、Hermes、Cline、编辑器插件或你自己的代理都以相同方式工作。它们只需要一个要运行的命令和一个环境变量。

重启你的 MCP 客户端

重启客户端,然后运行 ssh_monitor({ action: "list" }) 以确认配置文件已加载。

SSH MCP 服务器配置

变量

作用

默认值

SSH_PROFILES_FILE

配置文件 JSON 的路径——必填

SSH_MCP_LOG_LEVEL

debuginfowarnerror

info

LOG_LEVEL

回退项,仅在 SSH_MCP_LOG_LEVEL 未设置时使用

info

SSH_MCP_LOG_TIMESTAMP

日志行中的时间戳

true

SSH_MCP_CONTROL_PERSIST

共享连接在最后一条命令后保持存活的秒数;0 表示立即关闭

600

SSH_MCP_CONTROL_DIR

控制套接字存放位置

~/.ssh/ssh-mcp

SSH_MCP_PROFILES_CACHE_TTL

配置文件缓存 TTL(毫秒)

60000

SSH_MCP_PROFILES_WATCH

配置文件更改时重新加载

true

共享连接刻意比本进程存活得更久:退出时关闭它会切断同一台机器上另一个窗口正在使用的通道。

SSH MCP 服务器限制

  • 取消: 关闭 SSH 可能会让远程命令继续运行。当控制很重要时,请使用分离任务。

  • 原子写入: BSD 和 macOS 无法预先检查跨文件系统的重命名。

SSH MCP 服务器路线图

  • 针对 macOS SSH 主机进行完整测试运行

  • 在 Windows 上进行端到端兼容性测试

  • 多主机审计——在一次调用中比较多个 SSH 配置文件的健康状态

  • 从现有的 ~/.ssh/config 导入配置文件

  • 针对大文件和不稳定连接的可恢复传输

  • 远程操作时间线——命令、传输和防护决策汇聚在一条审计轨迹中

  • 现成的 SSH 故障排查手册

  • 到达模型的回答 —— 已完成: 命令输出、匹配的日志行、机器名称和快照部分在字段中传递,而不仅仅是文本

  • 更小的 MCP 工具模式 —— 已完成: 工具列表轻了 10%,分离任务现在会显示它写入的最后几行,而不是被盲目轮询

开发和测试 SSH MCP 服务器

npm install
npm run build           # tsc
npx tsc --noEmit        # types, plus dead declarations
npm run test:unit       # unit tests
npm run lab:up          # start the two test containers
npm run test:live       # live suite against those containers

实时测试套件针对真实容器运行——一个 BusyBox,一个 coreutils——因为两者会在细微之处产生分歧,而模拟对象只会附和编写它的人。布局参见 docs/architecture.md

喜欢 SSH MCP Server 吗?⭐

如果你喜欢这个工具,在 GitHub 上给它点个星标——这能帮助更多人发现这个项目。

为 SSH MCP 服务器做贡献

欢迎在 github.com/hypnosis/ssh-mcp-server 提交 Issue 和拉取请求。

许可证

MIT——参见 LICENSE

Install Server
A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
Response time
3wRelease cycle
12Releases (12mo)
Commit activity

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Enables AI assistants to securely connect to and manage remote servers via SSH, supporting command execution, file transfers via SFTP, and multi-server management with both password and SSH key authentication.
    9
    80
    2
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables AI assistants to securely execute remote SSH commands, perform file transfers, and monitor system status through a standardized interface. It features robust security controls including command whitelisting, blacklisting, and credential isolation to prevent unauthorized operations.
    10
    22
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI assistants to manage remote servers via SSH with 43 specialized tools for command execution, file editing, directory operations, and background tasks across Linux, macOS, and Windows.
    44
    5
    GPL 3.0

View all related MCP servers

Related MCP Connectors

  • Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.

  • Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.

  • Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hypnosis/ssh-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server