我开源了 ssh-mcp:让支持 MCP 的 AI 客户端通过 SSH 查服务器、查数据库、读文件和部署

ssh-mcp

一个本地运行的 MCP 工具,把 AI 接入真实运维环境,同时把目标、凭据和执行边界留在本机。

前言

最近我整理并开源了 ssh-mcp。如果你使用支持 MCP 的 AI Agent(例如 Codex),应该会遇到同一个问题:AI 可以很快读懂日志、分析报错并给出修复建议,但到了线上排障阶段,很多工作仍然要人工完成:登录服务器、查看服务状态、读取配置、查询数据库,再把结果复制回对话框。

直接把生产环境的 SSH 密码交给 AI,风险太高;完全不让 AI 接触真实环境,又只能停留在"告诉我应该执行什么命令"。

ssh-mcp 想解决的就是这一步。它是一个面向支持 MCP 的 AI Agent/客户端的本地 MCP server,允许客户端在用户明确登记的范围内执行 SSH 排障、查看远端文件、查询 MySQL/MariaDB/PostgreSQL,并进行带校验和备份信息的文件部署。本文用 Codex CLI 作为示例,其他能启动本地 stdio MCP server 的客户端也可以接入。

项目地址:https://github.com/lswzw/ssh-mcp

ssh-mcp 是什么

ssh-mcp 通过 MCP over stdio 与 MCP 客户端通信。它在客户端所在的本机运行一个 bridge,并按需连接或启动单实例 daemon;不监听 HTTP/TCP 公网端口,也不是云端代理。bridge、daemon、目标配置和凭据由本机管理;在目标已登记且启用、凭据库已解锁并通过本地策略检查的前提下,命令、SQL 和文件操作才会发往远端目标。

使用前,先在本地 TUI 中登记目标、填写凭据、验证连接并确认 SSH 主机指纹。之后远程操作只能发往这些已经登记且启用的目标;MCP 客户端不能在对话中新增、修改或删除目标,不能读取密码、主密码、私钥或凭据明文,也不能访问未登记目标或扫描网络。

简单来说,它提供的是一条"有范围的本地运维通道":AI 负责理解任务、串联信息和解释结果,人负责在 TUI 中登记目标并决定可用范围。

支持哪些功能

当前版本通过 stdio MCP 提供 11 个工具,覆盖目标发现、SSH、SFTP 文件操作、工作会话和数据库访问。

功能 用途
SSH 命令执行 通过 run_ssh 执行已登记 Linux 主机上的非交互命令,查看服务、磁盘、内存、端口和日志。
远端文件读取 通过 read_ssh_file 使用受限 SFTP 读取单个普通文件,不把路径拼接进 Shell 命令。
数据库 SQL 通过 run_sql 访问已登记的 MySQL、MariaDB 或 PostgreSQL,执行查询或明确配置的写操作;只读账号和可写账号可以分开配置。
SSH 工作会话 使用 open_ssh_sessionset_ssh_session_contextexecute_ssh_sessionclose_ssh_session 连续执行共享工作目录的命令。
文件部署 通过 deploy_ssh_binary 将本机普通文件部署到远端已存在的普通文件,校验大小和 SHA-256,备份旧文件后再激活。
目标发现 通过 list_targetsdescribe_target_capabilitylist_databases 先确认目标及其能力。

执行类工具返回结构化 MCP 数据。例如 run_ssh 会返回标准输出、标准错误、退出码、超时和截断信息;远程操作还会给出 execution_outcome,帮助 Agent 区分"没有派发""执行失败"和"结果暂时无法确认"。目标列表和能力查询等本地结果不一定包含这些字段,audit_outcome 也独立于远端执行结果。

SSH 工作会话保存的是 daemon 内存中的声明式工作目录和非机密环境变量,不是持久化的交互式 Shell;它不提供别名、函数、后台任务、交互输入或 TTY。会话默认空闲 5 分钟后失效,bridge 关闭、目标配置变化、凭据库锁定或 daemon 退出时也会失效。

实际使用示例

1. 排查服务器状态

在支持 MCP 的客户端中直接说明任务即可。以 Codex 为例:

text 复制代码
使用 ssh-mcp 检查已登记生产主机的磁盘空间,找出占用最高的目录,并判断是否有服务因为磁盘不足而异常。

比较稳妥的调用顺序是:

  1. 调用 list_targets,确认目标已经登记并启用。
  2. 调用 describe_target_capability,查看当前目标允许的操作。
  3. 使用 run_ssh 执行 df -hdusystemctl status 等非交互命令。
  4. 让 Agent 根据结构化结果给出判断和下一步建议。

需要 root 权限时,可以显式使用非交互 sudo -n。对于 daemon 能识别为需要密码输入、编辑器或交互式 TTY 的常见命令,服务会在派发前拒绝;任意自定义程序的提示不保证都能被静态识别。

2. 查看远端配置

查看配置文件时,不必让 AI 拼接一条 Shell 命令:

json 复制代码
{
  "target": "203.0.113.10",
  "path": "/srv/example/config/application.yaml",
  "offset": 0,
  "max_bytes": 16384
}

read_ssh_file 只允许规范化绝对路径对应的普通文件,拒绝目录、符号链接、设备、FIFO 和 socket。文件能力需要先在 TUI 中启用,单次读取最多 64 KiB;有效 UTF-8 按文本返回,其他字节按 Base64 返回,并标记为不可信远端输出。

3. 查询数据库

例如,查询最近的任务状态:

json 复制代码
{
  "target": "203.0.113.20:5432",
  "database": "example",
  "statement": "SELECT id, status FROM jobs ORDER BY id DESC LIMIT 20",
  "timeout_seconds": 30,
  "max_rows": 1000,
  "max_bytes": 16384
}

只读 SQL 使用只读账号;可能写入数据的 SQL 必须配置明确的可写账号。没有可写凭据时,工具返回 write_credential_not_configured,请求会在连接远端之前停止,不会自动降级到只读账号。过程调用、动态 SQL、文件或主机副作用 SQL,以及 DROP/TRUNCATE/ALTER ... DROP 和无条件 UPDATE/DELETE 等可识别高危类别也不会派发。数据库传输可配置为经 CA 校验的 tls_verified,该模式需要填写本机绝对 CA 文件路径,验证失败不会降级为明文;legacy_plaintext 仅作为兼容选项,生产环境建议优先使用验证 TLS。

4. 部署文件并重启服务

需要把本机的普通文件部署到远端已有文件时,可以让 MCP 客户端调用 deploy_ssh_binary。以 Codex 为例:

json 复制代码
{
  "target": "203.0.113.10",
  "source_path": "/srv/builds/example",
  "remote_path": "/srv/example/example",
  "start_action": "systemctl restart example.service",
  "max_bytes": 67108864,
  "timeout_seconds": 600
}

源文件必须是 daemon 所在本机上的普通非符号链接文件,remote_path 必须是规范化绝对路径,且远端目标必须是已存在的普通文件,工具不会创建新的 live 文件;单个文件默认最多 64 MiB、上限 256 MiB,start_action 是可选的非交互命令。部署过程不是直接覆盖线上文件,而是:

  1. 在远端目标目录创建临时文件。
  2. 上传文件并校验大小和 SHA-256。
  3. 将原文件移动到排他备份。
  4. 重命名临时文件并激活。
  5. 按请求执行受限的启动动作;该动作仍要经过 SSH 固定拦截和目标黑名单检查。

如果上传、激活或启动过程中发生超时、连接中断或协议错误,导致结果无法确认,结果会标记为 outcome_unknown。这表示"可能已经执行,但客户端无法确认",不能直接重复部署,应该先核验线上文件、备份文件和服务状态。

安全设计

ssh-mcp 的重点不是承诺绝对安全,而是把能明确验证的边界放到远端连接之前。

  • 只有本地 TUI 登记且启用的目标才能进行远程访问;MCP 客户端不能新增、修改或删除目标,也不能扫描未登记主机。黑名单和文件操作开关也只能由本地 TUI 修改。
  • 凭据由本地凭据库管理,主密码解锁后才在 daemon 内存中使用;AI 和 MCP 客户端拿不到密码明文。敏感字段采用加密封装,但 state.db 中的普通元数据不是完整加密数据库。
  • SSH 目标保存前会测试连接并确认主机指纹,连接时继续校验已保存的指纹。
  • 每个 SSH 目标都可以配置英文逗号分隔的 Go RE2 命令黑名单;黑名单只作用于 SSH,不作用于数据库。
  • daemon 内置 11 类可识别的高危拦截,包括格式化或分区、直接写块设备、破坏基础系统目录、无条件批量更新或删除、动态脚本效果和未登记远端跳转。
  • 远端输出始终视为不可信输入。远程操作的 execution_outcome 会区分 completedfailed_knownnot_dispatchedoutcome_unknown;另一个 status 字段还可能是 failedrejectedunlock_required 等本地状态。

这些设计适合日常排障和受控变更,但不要把它当成主机沙箱、堡垒机或防篡改审计系统。固定规则是有限的本地静态识别,未命中规则不代表操作一定安全;工具约束也不能阻止本机其他程序直接使用 Shell、系统 ssh 或数据库客户端。生产环境仍应配合最小权限账号、网络策略和人工复核。

安装和接入 MCP 客户端

当前本地主机支持 Linux、macOS 和 Windows;远端 SSH 按 Linux 命令语义执行。客户端需要能够启动本地 stdio MCP server,并且本地需要一个可以打开交互终端的桌面环境。程序本身不需要云端或特定模型提供商的 API key。

1. 优先下载预编译版本

发布页有对应资产时,建议直接从 GitHub Releases 下载:

平台 文件名
Linux amd64 ssh-mcp-linux-amd64发布后下载
macOS arm64 ssh-mcp-darwin-arm64发布后下载
Windows amd64 ssh-mcp-windows-amd64.exe发布后下载

Linux/macOS 下载后需要设置执行权限;其他 CPU 架构目前请从源码构建。下载版不需要另外安装 Go。注册 MCP 前,请确认文件来自项目发布页并能正常启动。

如果你的 Agent 具备终端和文件操作权限,也可以把下面这段话发给它,让它协助下载和注册:

text 复制代码
请从 https://github.com/lswzw/ssh-mcp/releases/latest 下载适合当前系统和架构的 ssh-mcp 预编译版本,放到稳定路径并注册为当前 MCP 客户端的 stdio server(启动参数为 serve),完成后验证工具列表;如果客户端不支持本地 stdio,或需要主密码、目标登记、主机指纹确认,请提示我手动完成。

无论是否自动安装,首次使用仍需在本地 TUI 中设置主密码、登记目标并确认 SSH 主机指纹。

2. 没有匹配版本时从源码构建

下面命令以 Linux/macOS 为例;Windows 请使用对应的 .exe 文件路径。源码构建要求 Go 1.26.5

bash 复制代码
git clone https://github.com/lswzw/ssh-mcp.git
cd ssh-mcp
make build

构建完成后,Linux 和 macOS 的程序位于 bin/ssh-mcp,Windows 对应 bin/ssh-mcp.exe

3. 打开本地控制台并登记目标

以下示例假设程序位于 bin/ssh-mcp;如果使用下载的预编译文件,请替换成实际路径:

bash 复制代码
./bin/ssh-mcp manage

第一次打开 TUI 时设置主密码,然后按提示添加 SSH 或数据库目标。保存前程序会测试连接;SSH 首次连接或指纹变化时,需要人工核对指纹并确认。如果 TUI 无法自动打开终端,可以设置 SSH_MCP_TERMINAL;修改后先停止 daemon,再重新加载客户端配置。

4. 接入 MCP server

serve 使用 stdio MCP。任何能启动本地 stdio MCP server 的 Agent/客户端都可以接入,通用配置契约如下(字段名可能因客户端而异):

text 复制代码
transport: stdio
command: /absolute/path/to/bin/ssh-mcp
args: ["serve"]

其中 command 必须是可执行文件的绝对路径,args 只需传入 serve

Codex CLI 示例

如果使用 Codex CLI,可以执行(下载预编译文件时请把程序路径替换成实际的绝对路径):

bash 复制代码
codex mcp add ssh-mcp -- "$PWD/bin/ssh-mcp" serve
codex mcp get ssh-mcp

其他客户端请使用自己的 MCP server 配置或注册命令。serve 会在需要时连接或启动本地 daemon,不需要手动启动网络服务。

5. 发起第一次请求

在所用 MCP 客户端的任务中明确要求使用 ssh-mcp。以 Codex 为例:

text 复制代码
使用 ssh-mcp 查看已登记 SSH 主机的内存和磁盘使用情况。

日常可以使用下面两个命令查看服务状态或停止 daemon。存在活动 bridge 会话时,普通 stop 会拒绝停止;需要强制停止时,必须在交互终端执行 stop --force 并连续两次输入 yes,这可能让正在进行的远程操作变成 outcome_unknown

bash 复制代码
./bin/ssh-mcp status
./bin/ssh-mcp stop

需要强制停止时执行:

bash 复制代码
./bin/ssh-mcp stop --force

当前支持范围

为了避免误解,当前版本有几项明确限制:

  • 远端 SSH 只支持已登记的 IP、端口、账号密码直连和 Linux 命令语义;不支持主机名、远端 Windows/macOS 命令语义、SSH 私钥或 agent。
  • MCP 不提供交互式 TTY;需要交互输入的常见命令会返回 interactive_input_required,任意自定义程序的提示不保证能被静态识别。
  • 不支持独立或持久端口转发;命令中的静态 SSH 转发仍须指向已登记目标并通过策略检查,动态转发会被拒绝。
  • 数据库目标使用 IP:端口,支持 MySQL/MariaDB 和 PostgreSQL。
  • 普通 SSH 命令和 SQL 默认直接执行,不存在日常审批队列;高风险操作由固定拦截和目标黑名单增加限制。
  • audit.log 是本地尽力而为的运行记录,不是防篡改证据。

把能力边界写清楚,反而更容易判断它是否适合自己的环境。

总结

ssh-mcp 适合希望让 Codex 或其他 MCP 客户端参与真实运维、但又不愿把生产凭据交给云端代理的开发者、后端工程师和 SRE。它把 SSH、文件、数据库和部署集中到一个 MCP 入口,同时把目标登记、凭据保管和高风险边界留在本地用户手里。

如果你正在使用 Codex CLI 或其他支持 stdio 的 MCP 客户端,可以从一个测试环境开始登记目标,先尝试服务状态检查和只读 SQL 查询,再逐步启用文件读取或部署能力。

项目地址:https://github.com/lswzw/ssh-mcp

项目采用 GPL-3.0 开源,欢迎 Star、提交 Issue 和贡献代码。

本文关键词: CodexMCPssh-mcpSSHAI 运维MySQLPostgreSQLDevOpsGo

相关推荐
Delite80214 分钟前
油水共存工况下的锈蚀防控:液相锈蚀测试技术与应用解析
大数据·人工智能
yunwei3714 分钟前
CPU 噪声会拖慢 GPU 推理吗:用 eBPF 定量测量调度器与 IRQ 影响
linux·人工智能·性能优化
m0_4626052215 分钟前
week4
人工智能
2601_9499506317 分钟前
在线刷题用什么小程序?认识一下能导资料、AI出题的练题簿
人工智能·学习·小程序·刷题·小程序推荐
TMT星球18 分钟前
美团2026年Q2财报:收入1046亿元,同比增长14.4%
大数据·人工智能
xfan_me19 分钟前
手机在网状态接口-空号查询-空号过滤API
数据库·人工智能·python·智能手机
laotiemen66627 分钟前
亲测好用的家居MES,实践经验分享!
大数据·人工智能·云计算·软件需求
镭封27 分钟前
2026免费AI配音5款实测:哪些真正无水印可导出音频
人工智能·音视频·媒体
V哥AI增长29 分钟前
AI搜索中用户评价的可引用性机制与结构化改造实证
人工智能