mcpField
R
remote-ssh-mcp

remote-ssh-mcp

本地服务
github.com/the-nine-nation云与基础设施1今天更新

关于 remote-ssh-mcp

remote-ssh-mcp 将持久化的远程 Bash 会话封装为 MCP 工具,面向需要通过 SSH 执行多步远程任务的 AI Agent。会话保留目录和环境状态,并使用本机 OpenSSH 配置连接主机。

主要功能

  1. 01持久会话保留目录与环境
  2. 02通过主机别名发现并连接
  3. 03轮询长时间运行的命令
  4. 04中断命令并管理会话
  5. 05输出截断与审计日志

适用场景

  1. 01在远程主机上执行多步调试
  2. 02运行构建、部署或下载任务
  3. 03查看命令输出并恢复卡住的会话

MCP 相关

通过 stdio 向 MCP 客户端提供 SSH 主机发现、会话打开、命令执行、输出查看、中断和关闭等工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"the-nine-nation-remote-ssh": {
"command": "npx",
"args": [
"-y",
"@zyluo/remote-ssh-mcp"
],
"env": {
"SSH_MCP_ALLOWED_HOSTS": "<SSH_MCP_ALLOWED_HOSTS>",
"SSH_MCP_CONFIG": "<SSH_MCP_CONFIG>"
}
}
}
}
启动命令npx -y @zyluo/remote-ssh-mcp
需要配置的环境变量
SSH_MCP_ALLOWED_HOSTSComma-separated additional SSH Host aliases to allow
SSH_MCP_CONFIGPath to remote-ssh-mcp config.json

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@zyluo/remote-ssh-mcp0.2.0

工具

7

收录的工具列表 · 更新于 2 周前

参数类型必填说明
reloadboolean否

详细介绍

Remote SSH MCP 标志

Remote SSH MCP

为 AI Agent 提供持久、有状态的远程 Bash 会话
基于 Model Context Protocol

为什么选择 · 功能 · 工作原理 · 工具 · 快速开始 · 配置 · 安全性 · 简体中文

MIT 许可证 Node.js 20+ TypeScript MCP stdio OpenSSH 版本 0.2.2 GitHub 发布版本 npm 版本 GitHub 星标数

Remote SSH MCP — 通过 SSH 连接到远程服务的 AI Agent 终端


为什么选择 Remote SSH MCP?

大多数 Agent 访问远程机器的方式如下:

bash → ssh host "cmd" → disconnect → repeat

每次调用都要付出同样的代价:

痛点发生的情况
🔁 浪费 TokenBanner、MOTD、登录杂音以及 pwd / whoami 探测会塞满上下文
🧊 状态丢失cwd、export、venv 激活状态及 Shell 副作用都会消失
🔌 不稳定每次新建连接都可能遇到超时、主机密钥提示、ProxyJump 和认证抖动
🌀 错误循环模型用更长的探测命令来补救 → 消耗更多 Token

Remote SSH MCP 将长期运行的远程 Bash 会话变为一流的 MCP 工具。一个会话 ID 可保留工作目录、环境变量和 Shell 副作用。需要干净的环境时,可以开启新会话。

为什么选择它,而不是在 bash 中一次性执行 ssh?

面向 Agent 工作流(多步骤远程操作:部署、调试、构建、检查日志)的实际优势:

维度一次性 ssh host "…"Remote SSH MCP
💰 Token 消耗每一步都要重新支付连接开销并探测状态;模型经常重新执行 cd / pwd在 ssh_open 时只支付一次;之后 ssh_run 主要返回命令输出。结构化工具和 head/tail 上限可减少工具结果冗余。在多步骤会话中,与每次都重新连接相比,远程工具上下文通常可减少约 50–80%(具体节省取决于 MOTD 大小以及模型输出的冗长程度)。
✅ 成功率N 个步骤 ≈ N 次握手 → N 次失败机会(超时、跳板、Agent、主机密钥)每个会话只需一次握手;后续命令通过活动 shell 执行。长时间运行的任务使用 running + ssh_peek,而不是终止工具调用后重新启动。减少重新连接 → 任务中途出现“SSH 失败”循环的情况大幅减少。
🧳 可移植性远程端无需额外安装任何东西,但每台 Agent 机器都要重新实现同一套脆弱的 ssh … 模式只需在运行 Claude / Cursor / Grok / 等的机器上安装一次。远程主机无需安装任何东西(无需 Node、MCP 守护进程或 Agent)。只需要一个普通 shell 账户,以及 SSH 所需的工具(bash、base64、stty、…)。密钥和跳板主机保留在本地 ~/.ssh/config 中。
🧠 模型易用性模型需要自行拼接 ssh 字符串、处理转义和故障恢复稳定的工具:open → run → peek → close。会话 ID 是唯一句柄。
🔐 信任边界容易过度暴露密钥,或在带外提示输入密码仅使用 OpenSSH 客户端;工具从不接受密码或私钥内容

一句话说明可移植性:在你的开发机 / AI 主机上部署 MCP;SSH 配置中的所有服务器都可以访问——远程服务器群无需安装任何软件包。

┌─────────────────────────┐         SSH (OpenSSH)         ┌──────────────────┐
│  Your laptop / CI agent │  ───────────────────────────► │  prod / staging  │
│  Claude · Cursor · Grok │     ~/.ssh/config · agent     │  no MCP install  │
│  + remote-ssh-mcp       │                               │  plain Bash OK   │
└─────────────────────────┘                               └──────────────────┘

Token 消耗示意(多步骤远程调试示例):

One-shot path (per step × 8):
  ssh wrapper + banner/MOTD + pwd/whoami + re-cd + command output
  → noise dominates; context fills with reconnect junk

Session path:
  ssh_open  → once (handshake + READY)
  ssh_run × 8 → mostly the real stdout/stderr (truncated head+tail)
  → context stays on the work product, not the transport

它不会重新实现 SSH。系统 OpenSSH 客户端仍负责处理所有工作,因此 ~/.ssh/config、已知主机、SSH Agent、ProxyJump 路由和硬件密钥都能像以前一样正常工作。

ssh_hosts()              → discover allowed Host aliases
ssh_open(host)           → session id
ssh_run(id, command)     → same cwd + env as last time
ssh_peek / ssh_interrupt → observe or recover long / stuck work
ssh_close(id)            → release the shell and connection

功能

🧠 持久化远程会话
  • 一个稳定的会话 ID对应一个长期运行的远程 Bash
  • cwd 和环境变量会在多次 ssh_run 调用之间保留
  • 需要全新环境时,可打开一个新会话
  • 多个会话可以连接到同一主机或不同主机(最多 maxSessions 个)
🔧 原生 OpenSSH 集成
  • 启动真正的 ssh 二进制程序——不使用自定义加密栈
  • 遵循 ~/.ssh/config、Include、Agent 套接字和 ProxyJump 配置
  • 强制使用 BatchMode=yes 和 StrictHostKeyChecking=yes
  • 从不接受模型提供的密码、私钥文本或任意 SSH 选项参数
📡 适用于长时间运行的命令
  • ssh_run 最多等待 wait_sec(默认 10s),然后返回 status: "running",同时远程命令继续运行
  • 使用 ssh_peek(wait_sec=...) 长轮询,而不是忙等循环
  • 可选硬性 timeout_sec,超时后发送 Ctrl-C;默认不会自动终止
  • 适用于 docker pull、构建、下载和部署等不应无限期阻塞工具调用的任务
🛡️ 安全与控制平面
  • 基于 ssh_config 的精确主机别名允许列表,并支持可选的配置 / 环境变量覆盖
  • 忽略包含 *、? 或 ! 的模式
  • 故障时关闭中断:如果 Ctrl-C 后无法确认 shell 已恢复,则关闭会话
  • 内置拒绝列表,拦截少数明显具有破坏性的模式(并非完整的策略引擎)
  • 空闲会话清理、会话数量上限,以及带有哈希命令的 JSONL 审计日志(0600)
📦 为模型清理工具结果
  • 分离 stdout / stderr 流
  • 按字节截取输出的开头和结尾,并确保截取位置符合 UTF-8 边界
  • 在模型看到输出前剥除 ANSI / PTY 噪声(颜色、CSI、括号粘贴标记、仅含控制字符的空行)
  • 精简的打开帧:TERM=dumb、NO_COLOR、关闭括号粘贴 — 从源头减少杂项
  • 精简 JSON 负载:省略空的 stderr、值为 false 的截断标记和请求回显字段,让同时包含 content + structuredContent 的响应保持精简
  • ssh_hosts 仅返回安全元数据:alias、hostname、user、port、proxy_jump
  • 绝不泄露 IdentityFile、证书、Agent 套接字或 ProxyCommand
🔌 MCP 原生支持
  • 为 Claude Desktop、Cursor 和其他 MCP 宿主提供 stdio 传输
  • 兼容旧版和当前 MCP 握手
  • 父进程 / stdio 退出时会关闭所有已跟踪的 SSH 连接

工作原理

flowchart LR
  A[AI Agent] -->|MCP tools| B[Remote SSH MCP]
  B -->|spawn| C[OpenSSH client]
  C -->|SSH + PTY| D[Remote Bash]
  D --> E[(cwd / env / side effects)]

  subgraph Local machine
    B
    C
    F[~/.ssh/config<br/>agent / keys]
    C -.-> F
  end

  subgraph Remote host
    D
    E
  end

典型 Agent 工作流

1. ssh_hosts()                 # pick an alias from the allowlist
2. ssh_open(host="prod")       # get session id "s_…"
3. ssh_run(id, "cd app && …")  # state sticks to this id
4. ssh_run(id, "npm test")     # still in app/, env preserved
5. ssh_peek(id, wait_sec=20)   # long-poll a slow job
6. ssh_close(id)               # clean up when done

MCP 工具

工具功能
🗂️ ssh_hosts列出允许使用的 Host 别名(仅含安全元数据)。编辑 ~/.ssh/config 后传入 reload=true
🔓 ssh_open为允许使用的 Host 别名打开一个干净的持久 Shell → 返回会话 id
▶️ ssh_run在现有会话中运行非交互式命令
👀 ssh_peek查看最新的 N 行输出及状态;运行期间可选用 wait_sec 长轮询
⛔ ssh_interrupt发送 Ctrl-C 并等待确认 Shell 已恢复
📋 ssh_list列出会话、当前工作目录、状态、空闲倒计时和容量
🔒 ssh_close清理远程临时状态并关闭连接
工具参数(必需项)
工具关键参数
ssh_openhost(必需的 Host 别名),可选的 name 标签
ssh_runid、command,可选的 wait_sec、可选的 timeout_sec
ssh_peekid、可选的 lines(默认值为 50,最大值为 1000)、可选的 wait_sec
ssh_interrupt / ssh_closeid
ssh_hosts可选的布尔值 reload

快速开始

要求
要求说明
Node.js20 或更高版本
OpenSSH 客户端PATH 中的系统 ssh(或设置 sshPath)
远程主机Bash + base64、stty、mkdir、cat、rm
SSH 设置~/.ssh/config 中的 Host 别名,且主机密钥已受信任

⚠️ 首次主机密钥确认和身份验证必须在普通终端中完成。MCP 服务绝不会显示密码或信任提示。

安装
git clone https://github.com/the-nine-nation/remote-ssh-mcp.git
cd remote-ssh-mcp
npm install
npm run build
npm test

运行服务:

node /absolute/path/to/remote-ssh-mcp/dist/index.js

或从 npm 安装(发布后):

npx @zyluo/remote-ssh-mcp
# or
npm install -g @zyluo/remote-ssh-mcp
remote-ssh-mcp

或者,从此仓库本地安装软件包后,使用 remote-ssh-mcp 可执行文件。

MCP 宿主配置

大多数 stdio 宿主接受如下格式(外层键可能因产品而异):

{
  "mcpServers": {
    "remote-ssh": {
      "command": "node",
      "args": [
        "/absolute/path/to/remote-ssh-mcp/dist/index.js"
      ],
      "env": {
        "SSH_MCP_ALLOWED_HOSTS": "prod,staging"
      }
    }
  }
}

Cursor · Claude Desktop · Claude Code · 其他支持 MCP 的宿主:将 command / args 指向构建后的 dist/index.js,并设置 SSH_MCP_ALLOWED_HOSTS(或依靠从 ~/.ssh/config 自动发现)。

SSH_MCP_ALLOWED_HOSTS 会向允许列表添加别名。默认情况下,服务还会从 ~/.ssh/config 及其 Include 文件中发现精确的 Host 条目。工具输入仅接受安全别名 — 不接受 user@host、端口或额外的 SSH 选项。

编辑 ~/.ssh/config 后,请调用 ssh_hosts(reload=true),而不是重启服务。

凭据边界

身份验证始终由本地 OpenSSH 客户端处理:

  • 工具不接受密码或私钥材料
  • ssh_hosts 绝不返回密钥路径、证书、Agent 套接字或 ProxyCommand
  • Agent 应使用 Host 别名调用 ssh_open,不得从磁盘读取 ~/.ssh 中的私钥

配置

可选配置文件(默认路径):

~/.config/remote-ssh-mcp/config.json
{
  "allowedHosts": ["prod", "staging"],
  "sshConfigPath": "~/.ssh/config",
  "sshPath": "ssh",
  "maxTimeoutSec": 1800,
  "defaultWaitSec": 10,
  "maxWaitSec": 30,
  "openTimeoutSec": 20,
  "idleTimeoutSec": 1800,
  "interruptGraceSec": 5,
  "maxSessions": 8,
  "outputMaxBytes": 32768,
  "outputHeadBytes": 4096,
  "auditLogPath": "~/.local/state/remote-ssh-mcp/audit.jsonl"
}
环境变量
变量用途
SSH_MCP_CONFIG配置文件路径
SSH_MCP_ALLOWED_HOSTS以逗号分隔的附加 Host 别名
SSH_MCP_SSH_CONFIGSSH 配置路径
SSH_MCP_SSH_PATHOpenSSH 可执行文件
SSH_MCP_MAX_TIMEOUT_SEC显式命令超时上限
SSH_MCP_DEFAULT_WAIT_SECssh_run 在返回 running 前等待的时长
SSH_MCP_MAX_WAIT_SECssh_run / ssh_peek 的 wait_sec 上限
SSH_MCP_OPEN_TIMEOUT_SEC连接 / 握手超时
SSH_MCP_IDLE_TIMEOUT_SEC空闲会话的存续时间
SSH_MCP_INTERRUPT_GRACE_SEC按下 Ctrl-C 后用于标记恢复的宽限时间
SSH_MCP_MAX_SESSIONS活跃会话数上限
SSH_MCP_OUTPUT_MAX_BYTES每个流保留的输出上限
SSH_MCP_OUTPUT_HEAD_BYTES截断时保留的开头字节数
SSH_MCP_AUDIT_LOGJSONL 审计日志路径

环境变量会覆盖文件中的设置。审计日志以 0600 权限创建,并记录会话、主机、结果、持续时间、命令长度、命令名称和 SHA-256——不记录完整参数字符串(以减少密钥泄露)。


执行语义

Agent(以及你)应该了解的详细规则:

主题行为
并发一个会话一次只运行一条前台命令;额外调用 ssh_run 会返回 busy
wait_sec仅限制 MCP 调用的等待时长。超时后:status: "running",远程任务会继续运行
不要重试返回 running 后,切勿重新发起同一条长时间运行的命令——使用 ssh_peek 轮询
硬超时只有显式指定 timeout_sec 才会创建截止时间并发送 Ctrl-C
ssh_peek默认返回最后 50 行(最多 1000 行);仍受字节数上限限制;可选长轮询 wait_sec
stdin用户命令的输入为 /dev/null——不要运行 vim、top 或交互式安装程序
中断恢复按下 Ctrl-C 后等待协议标记恢复;若恢复失败 → 关闭会话(失败时关闭)
输出stdout / stderr 分别保留开头和结尾;始终保持有效的 UTF-8 边界
拒绝列表仅拦截少数高风险模式——并非完整的策略引擎
信任模型本地可信的开发者工具——不是多租户远程执行服务
主机退出MCP 主机 / stdio 退出会关闭所有 SSH 连接;nohup / setsid 启动的任务可能仍会运行

示例: 使用 wait_sec: 10 且不指定 timeout_sec 启动 docker pull。返回 running 表示原始拉取任务仍在运行——不要再启动一个。调用 ssh_peek 并设置正数 wait_sec,直到任务变为 idle、中断该任务,或另开一个会话并行处理。


开发

npm run typecheck
npm test
npm run build
npm audit --omit=dev

测试套件涵盖 MCP stdio 发现与调用、持久化 cwd / 环境状态、流分离、任意分块边界下的帧处理、超时失败时关闭、Shell 退出、允许列表发现、输出截断以及安全拒绝列表。

设计说明和线缆协议:远程SSH-MCP设计.md。


安全

请不要通过公开的 GitHub issues 报告安全漏洞。在配置好私密公告流程之前,请通过维护者 GitHub 个人资料中的邮箱联系维护者。

即使 MCP 传输正常,远程命令也可能产生不可逆的副作用。请使用最小权限账户、将允许列表范围控制得尽可能小,并仔细检查主机权限。


项目状态

项目状态
版本0.2.2
许可证MIT
语言TypeScript(Node ≥ 20)
协议基于 stdio 的 MCP
到主机的传输系统 OpenSSH

更新日志

未发布 — 连接与进度反馈
  • 自定义 sshConfigPath / SSH_MCP_SSH_CONFIG 现在不仅控制主机发现,也会通过 OpenSSH -F 控制实际连接。默认的 ~/.ssh/config 保持原生 OpenSSH 行为;自定义文件遵循 -F 语义(跳过系统范围的配置)。
  • 主机发现现在也支持 Host=prod、HostName = example.com 和 Include=... 语法。
  • ssh_open 失败时,除了原始错误,还会附带 reason 和可执行的 hint,涵盖主机信任、身份验证、DNS、网络、超时和本地配置问题。
  • 除非短进度输出的后缀可能是不完整的协议标记,否则会立即发送。
  • 已完成的 ssh_peek 响应包含 command_status 和 duration_ms,将 shell 状态(idle)与命令结果区分开。会话终止时仍在等待的 peek 会保留已有输出以及超时/中断详情。之后对已移除会话的调用仍会返回 session_gone。
0.2.2 — 减少远程输出噪声与令牌消耗

由 PTY 支持的交互式 bash 经常注入转义序列,这些序列在 JSON 转义后看起来像“二进制”内容(\u001b[?2004h、彩色 CSI、光标代码)。这些噪声会在每次 ssh_peek / ssh_run 时消耗上下文。

更改功能
即时清理去除 ANSI/OSC/CSI,处理回车符覆盖(进度条),丢弃仅含控制字符的空行,然后应用 lines 窗口
静默打开会话导出 TERM=dumb / NO_COLOR / CLICOLOR=0,禁用括号粘贴,并在打开时发送一次 \033[?2004l
精简工具负载丢弃空的 stderr、值为 false 的标志(truncated、interrupted 等)和回显的 lines;保留空的 stdout,以明确表示无输出
测试覆盖清理、打开帧静默处理、会话即时路径和精简 JSON

升级:运行 npm i -g @zyluo/[email protected](或在 MCP 配置中升级软件包),然后重启 MCP 进程,以加载新的服务二进制文件。

0.2.1
  • 修复打开帧被 PTY 回显时的 READY 标记解析问题
0.2.0
  • 在 npm / GitHub 上首次公开发布

Star 历史

如果这个项目帮你节省了令牌并减少了不稳定的重新连接,欢迎在 GitHub 上点亮 ⭐,让更多人发现它。

Star 历史

专为需要真正远程 shell 的 Agent 打造,而不是又一个一次性 ssh host "…"。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。