oaslananka/mcp-ssh-tool

GitHub: oaslananka/mcp-ssh-tool

面向运维和开发者的生产级 MCP SSH 自动化服务器,通过安全的策略引擎和审计机制让 AI 客户端可控地管理远程主机。

Stars: 3 | Forks: 3

# mcp-ssh-tool [![npm 版本](https://img.shields.io/npm/v/mcp-ssh-tool.svg)](https://www.npmjs.com/package/mcp-ssh-tool) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/4ffd566b12001131.svg)](https://github.com/oaslananka-lab/mcp-ssh-tool/actions/workflows/ci.yml) [![安全](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/fb7bc283db001132.svg)](https://github.com/oaslananka-lab/mcp-ssh-tool/actions/workflows/security.yml) [![官方 MCP 注册表](https://img.shields.io/badge/MCP%20Registry-active-green.svg)](https://registry.modelcontextprotocol.io/v0.1/servers/io.github.oaslananka%2Fmcp-ssh-tool/versions/latest) [![许可证:MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![npm 下载量](https://img.shields.io/npm/dm/mcp-ssh-tool.svg)](https://www.npmjs.com/package/mcp-ssh-tool) 面向运维人员、开发者和 AI 客户端的生产级 MCP SSH 自动化工具。`mcp-ssh-tool` 会开启持久 SSH 会话,并为命令执行、文件操作、传输、隧道、包/服务管理、指标、资源和引导式提示词暴露安全、结构化的工具。 v2 版本默认是安全的:开启了严格的主机密钥验证,禁止 root 登录,原生 sudo 受到策略管控,除非策略允许,否则破坏性命令和文件系统修改将被拒绝,并且除非配置了 Bearer 认证和允许的源,否则远程 HTTP 仅在回环地址上启动。 ## 为什么选择此服务器 - **信任:** 中心化策略引擎、结构化审计事件、脱敏日志、严格的主机密钥以及机器可读的错误信息。 - **MCP 质量:** 面向本地客户端的 stdio,面向远程客户端的 Streamable HTTP,仅在显式兼容性标志下启用旧版 SSE。 - **对 AI 友好的工具:** 稳定的输出 schema、`structuredContent`、只读/破坏性/幂等行为的注解、资源和精选提示词。 - **运维:** 会话 TTL/驱逐、命令超时、传输校验和验证、真实的 SSH 转发、Prometheus 指标和 OpenTelemetry 钩子。 - **可移植性:** 优先使用 SFTP,针对基本文件操作提供兼容 POSIX/BusyBox 的 shell 备选方案,以及明确的支持边界。 ## 快速开始 无需安装直接运行: ``` pnpm dlx mcp-ssh-tool --version ``` 或者全局安装: ``` pnpm add --global mcp-ssh-tool ``` 向你的客户端添加 stdio MCP 服务器: ``` { "servers": { "ssh-mcp": { "type": "stdio", "command": "mcp-ssh-tool", "args": [] } } } ``` 从你的 MCP 客户端中使用: ``` Open a safe SSH session to prod-1 as deploy, inspect host capabilities, then show disk usage. ``` ## 系统要求 - Node.js `22.22.2+` 或 `24.15.0+`(仅限 LTS) - 目标主机的 SSH 访问权限 - 用于严格主机验证的、已填充的 `known_hosts` 文件,或显式配置的每会话主机密钥策略 ## 传输层 | 模式 | 命令 | 适用场景 | |------|---------|----------| | stdio | `mcp-ssh-tool` | 本地桌面客户端,例如 ChatGPT、Claude Desktop、VS Code、Cursor 或 Codex。 | | Streamable HTTP | `mcp-ssh-tool --transport=http --host 127.0.0.1 --port 3000` | 远程 MCP 客户端、反向代理或 Inspector 会话。 | | 旧版 SSE | `mcp-ssh-tool --transport=http --enable-legacy-sse` | 仅用于临时的 v1 兼容。推荐使用 Streamable HTTP。 | 除非配置了 `--bearer-token-file`、允许的源和 `SSH_MCP_HTTP_PUBLIC_URL`,否则将拒绝非回环 HTTP 启动。 ## 非托管远程 Agent 模式 对于公共 ChatGPT 连接器部署,请启用远程 Agent 控制平面,而不是向用户索要 SSH 凭据: ``` SSHAUTOMATOR_REMOTE_AGENT_CONTROL_PLANE=true \ PUBLIC_BASE_URL=https://sshautomator.example.com \ MCP_RESOURCE_URL=https://sshautomator.example.com/mcp \ mcp-ssh-tool http --host 0.0.0.0 --port 3000 ``` 远程模式增加了 OAuth/DCR 端点、受保护的 `/mcp` 端点、Agent 注册 API 和出站 WebSocket Agent 连接。ChatGPT 接收 OAuth 作用域内的 MCP 访问权限。该平台存储身份、策略、审计记录、OAuth 元数据、哈希一次性令牌和 Agent 公钥;它不存储用户的 SSH 私钥、SSH 密码、root 密码或云登录凭据。 在用户自己的主机上注册 Agent: ``` npx mcp-ssh-tool agent enroll --server https://sshautomator.example.com --token --alias prod-1 npx mcp-ssh-tool agent run ``` 该 Agent 会验证签名的控制平面操作信封,执行本地策略,执行有界限的操作,对结果进行签名,然后通过出站连接返回结果。请参阅 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)、[docs/CHATGPT_CONNECTOR.md](docs/CHATGPT_CONNECTOR.md) 和 [docs/AGENT_INSTALL.md](docs/AGENT_INSTALL.md)。 ## 安全默认值 | 领域 | v2 默认值 | |------|------------| | 主机密钥 | `hostKeyPolicy=strict`,`knownHostsPath=~/.ssh/known_hosts` | | Root SSH 登录 | 被拒绝 | | 原生 `proc_sudo` | 除非 `allowRawSudo=true` 否则被拒绝 | | 破坏性命令 | 除非 `allowDestructiveCommands=true` 否则被拒绝 | | 破坏性文件系统操作 | 仅允许在策略前缀下进行,其他位置均被拒绝 | | 本地传输路径 | `file_upload` 和 `file_download` 仅限于操作系统临时目录,除非策略允许更多 | | HTTP 绑定 | `127.0.0.1` | | 旧版 SSE | 已禁用 | | 文件读取 | 大小受 `SSH_MCP_MAX_FILE_SIZE` 限制 | | 命令输出 | 受 `SSH_MCP_MAX_COMMAND_OUTPUT_BYTES` 限制 | | 传输 | 受 `SSH_MCP_MAX_TRANSFER_BYTES` 限制 | 每次会话的 `policyMode: "explain"` 会返回计划/判定结果而不实际执行。当 AI 客户端需要在执行修改操作前总结风险时,请使用此模式。 ## 策略示例 设置 `SSH_MCP_POLICY_FILE=/etc/mcp-ssh-tool/policy.json`: ``` { "mode": "enforce", "allowRootLogin": false, "allowRawSudo": false, "allowDestructiveCommands": false, "allowDestructiveFs": false, "allowedHosts": ["^prod-[0-9]+\\.example\\.com$"], "commandAllow": ["^(uname|df|uptime|systemctl status)\\b"], "commandDeny": ["rm\\s+-rf\\s+/", "shutdown", "reboot"], "pathAllowPrefixes": ["/tmp", "/var/tmp", "/home/deploy"], "pathDenyPrefixes": ["/etc/shadow", "/etc/sudoers", "/boot", "/dev", "/proc"], "localPathAllowPrefixes": ["/var/tmp/mcp-ssh-tool"], "localPathDenyPrefixes": [] } ``` 简单的部署可以使用环境变量覆盖,例如 `SSH_MCP_ALLOW_RAW_SUDO=true`、`SSH_MCP_ALLOWED_HOSTS=prod-1.example.com`、`SSH_MCP_PATH_ALLOW_PREFIXES=/tmp,/home/deploy` 或 `SSH_MCP_LOCAL_PATH_ALLOW_PREFIXES=/var/tmp/mcp-ssh-tool`。 ## 核心工具 - `ssh_open_session`、`ssh_close_session`、`ssh_list_sessions`、`ssh_ping`、`ssh_list_configured_hosts`、`ssh_resolve_host` - `proc_exec`、`proc_sudo`、`proc_exec_stream` - `fs_read`、`fs_write`、`fs_list`、`fs_stat`、`fs_mkdirp`、`fs_rmrf`、`fs_rename` - `file_upload`、`file_download` - `ensure_package`、`ensure_service`、`ensure_lines_in_file`、`patch_apply` - `os_detect`、`get_metrics` - `tunnel_local_forward`、`tunnel_remote_forward`、`tunnel_list`、`tunnel_close` 所有工具均返回文本以及稳定的 `structuredContent`。工具元数据包含标题、输出 schema 以及公开只读、破坏性、幂等和外部副作用行为的注解。 ## 资源和提示词 资源: - `mcp-ssh-tool://sessions/active` - `mcp-ssh-tool://metrics/json` - `mcp-ssh-tool://metrics/prometheus` - `mcp-ssh-tool://ssh-config/hosts` - `mcp-ssh-tool://policy/effective` - `mcp-ssh-tool://audit/recent` - `mcp-ssh-tool://capabilities/support-matrix` 提示词: - `safe-connect` - `inspect-host-capabilities` - `plan-mutation` - `managed-config-change` ## 支持矩阵 | 目标 | 状态 | |--------|--------| | Linux | 完全支持。 | | macOS/BSD | 支持会话、进程、文件系统和传输;包/服务辅助工具仅在经过测试的地方可用。 | | BusyBox/dropbear | 会话、进程和基本文件系统备选方案为实验性支持。 | | Windows SSH 目标 | 会话、进程、文件系统和传输为实验性支持;不支持 `proc_sudo` 或 `ensure_*`。 | ## 客户端示例 ChatGPT 或 Claude Desktop: ``` { "mcpServers": { "ssh-mcp": { "command": "pnpm", "args": ["dlx", "mcp-ssh-tool"] } } } ``` VS Code 或 Cursor: ``` { "servers": { "ssh-mcp": { "type": "stdio", "command": "mcp-ssh-tool" } } } ``` 通过 HTTP 的 MCP Inspector: ``` printf '%s' 'super-secret-token' > .mcp-token mcp-ssh-tool --transport=http --host 127.0.0.1 --port 3000 --bearer-token-file .mcp-token ``` ## 配置 高价值环境变量: | 变量 | 默认值 | 用途 | |----------|---------|---------| | `SSH_MCP_POLICY_FILE` | 未设置 | 标准的 JSON 策略源。 | | `SSH_MCP_HOST_KEY_POLICY` | `strict` | `strict`、`accept-new` 或 `insecure`。 | | `SSH_MCP_KNOWN_HOSTS_PATH` | `~/.ssh/known_hosts` | 用于严格验证的已知主机文件。 | | `SSH_MCP_MAX_FILE_SIZE` | `10485760` | `fs_read` 的最大字节数。 | | `SSH_MCP_MAX_FILE_WRITE_BYTES` | `10485760` | `fs_write` 在缓冲前接受的最大文本负载字节数。 | | `SSH_MCP_MAX_COMMAND_OUTPUT_BYTES` | `1048576` | 每个命令或流保留的最大标准输出/标准错误字节数。 | | `SSH_MCP_MAX_STREAM_CHUNKS` | `4096` | 返回截断元数据前保留的最大流式块数。 | | `SSH_MCP_MAX_TRANSFER_BYTES` | `52428800` | `file_upload` 和 `file_download` 的最大字节数。 | | `SSH_MCP_COMMAND_TIMEOUT` | `30000` | 默认命令超时时间。 | | `SSH_MCP_HTTP_HOST` | `127.0.0.1` | Streamable HTTP 绑定主机。 | | `SSH_MCP_HTTP_PORT` / `PORT` | `3000` | Streamable HTTP 端口。 | | `SSH_MCP_HTTP_MAX_REQUEST_BODY_BYTES` | `1048576` | Streamable HTTP 接受的最大 JSON 请求字节数。 | | `SSH_MCP_HTTP_MAX_SESSIONS` | `20` | 最大并发 Streamable HTTP/SSE MCP 会话数。 | | `SSH_MCP_HTTP_SESSION_IDLE_TTL_MS` | `900000` | 被遗弃的 HTTP 会话关闭前的空闲 TTL。 | | `SSH_MCP_HTTP_PUBLIC_URL` | 未设置 | 非回环 HTTP 发布稳定受保护资源元数据所必需。 | | `SSH_MCP_HTTP_TRUST_PROXY` | `false` | 仅在显式设置时才信任 `X-Forwarded-Proto`。 | | `SSH_MCP_LOCAL_PATH_ALLOW_PREFIXES` | 操作系统临时目录 | `file_upload` 和 `file_download` 的本地传输允许列表。 | | `SSH_MCP_TUNNEL_ALLOW_BIND_HOSTS` | `127.0.0.1,localhost,::1` | 隧道绑定主机允许列表。 | | `SSH_MCP_TUNNEL_DENY_BIND_HOSTS` | `0.0.0.0,::` | 隧道绑定主机拒绝列表。 | | `SSH_MCP_TUNNEL_ALLOW_REMOTE_HOSTS` | 未设置 | 可选的隧道目标主机允许列表。 | | `SSH_MCP_TUNNEL_DENY_REMOTE_HOSTS` | 未设置 | 隧道目标主机拒绝列表。 | | `SSH_MCP_TUNNEL_ALLOW_PORTS` | 未设置 | 可选的隧道端口允许列表,包括范围,例如 `1024-65535`。 | | `SSH_MCP_TUNNEL_DENY_PORTS` | 未设置 | 隧道端口拒绝列表。 | | `SSH_MCP_HTTP_BEARER_TOKEN_FILE` | 未设置 | 非回环 HTTP 所必需。 | | `SSH_MCP_HTTP_ALLOWED_ORIGINS` | 回环源 | 逗号分隔的允许源。 | 已弃用的别名 `STRICT_HOST_KEY_CHECKING` 和 `SSH_MCP_STRICT_HOST_KEY` 在一个 v2 兼容周期内仍被接受。推荐使用 `SSH_MCP_HOST_KEY_POLICY`。 ## 开发 使用 `.nvmrc` / `.node-version` 中指定的确切本地运行时,然后运行: ``` pnpm install --frozen-lockfile pnpm run check ``` 实时 SSH 测试套件为按需启用: ``` RUN_SSH_INTEGRATION=1 pnpm run test:integration RUN_SSH_E2E=1 pnpm run test:e2e ``` 本地质量关卡是分层的: - `pre-commit`:格式化暂存文件并仅对暂存的 TypeScript 进行 lint - `pre-push`:运行 `pnpm run check:push` - `task hooks`:当安装了 `pre-commit` 时,运行跟踪的 pnpm 钩子及 `.pre-commit-config.yaml` 钩子 - 手动/完全等效:`task ci` 或 `pnpm run check` ## CI/CD 归属 个人仓库 `https://github.com/oaslananka/mcp-ssh-tool` 是源仓库组织仓库 `https://github.com/oaslananka-lab/mcp-ssh-tool` 是 GitHub Actions、CI/CD、发布、安全和来源边界。 自动 CI/CD、供应链安全检查、可信的 npm 发布、MCP Registry 发布、GitHub Releases、Docker 镜像验证、SBOMs、证明和发布决策仅从组织仓库运行。个人仓库的 Actions 故意不被设为必需关卡。 这两个仓库在 `main`、发布标签、releases、标签、里程碑和活跃协作状态方面必须保持内容一致。组织发布生成的引用会被回填到个人源仓库。 npm 包的 `repository.url` 故意指向组织自动化仓库,以便 npm provenance 能够验证已发布的构件是否来自构建它的同一 GitHub Actions 仓库。MCP Registry 服务器名称保持为 `io.github.oaslananka/mcp-ssh-tool`,因为它已经被发布,更改它会破坏现有用户。 有关镜像、发布、试运行和手动回退指南,请参阅 [docs/ci-cd-topology.md](docs/ci-cd-topology.md)。 ## 文档 - [ARCHITECTURE.md](ARCHITECTURE.md) - [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) - [docs/SECURITY.md](docs/SECURITY.md) - [docs/CHATGPT_CONNECTOR.md](docs/CHATGPT_CONNECTOR.md) - [docs/AGENT_INSTALL.md](docs/AGENT_INSTALL.md) - [docs/MIGRATION.md](docs/MIGRATION.md) - [docs/API.md](docs/API.md) - [SECURITY_DECISIONS.md](SECURITY_DECISIONS.md) - [MIGRATION.md](MIGRATION.md) - [docs/ci-cd-topology.md](docs/ci-cd-topology.md) - [docs/development.md](docs/development.md) - [docs/release.md](docs/release.md) - [docs/publishing.md](docs/publishing.md) - [docs/npm-provenance.md](docs/npm-provenance.md) - [docs/mcp-registry.md](docs/mcp-registry.md) - [docs/chatgpt-app.md](docs/chatgpt-app.md) - [docs/doppler.md](docs/doppler.md) - [docs/operations.md](docs/operations.md) - [docs/repository-operations.md](docs/repository-operations.md) - [docs/docker.md](docs/docker.md) - [docs/client-configs.md](docs/client-configs.md) - [docs/security/release-integrity.md](docs/security/release-integrity.md) - [docs/security/chatgpt-app-threat-model.md](docs/security/chatgpt-app-threat-model.md) - [docs/security/ssh-threat-model.md](docs/security/ssh-threat-model.md) - [docs/branch-protection.md](docs/branch-protection.md) - [docs/maintenance-policy.md](docs/maintenance-policy.md) - [docs/api-stability.md](docs/api-stability.md) - [docs/threat-model.md](docs/threat-model.md) - [docs/configuration.md](docs/configuration.md) - [docs/security-model.md](docs/security-model.md) - [docs/troubleshooting.md](docs/troubleshooting.md) - [docs/enterprise-deployment.md](docs/enterprise-deployment.md) ## 许可证 MIT 许可证。请参阅 [LICENSE](LICENSE)。
标签:GNU通用公共许可证, LLM代理, MCP, MITM代理, Node.js, SSH, TypeScript, 主机密钥验证, 安全, 安全插件, 审计日志, 文件传输, 服务器管理, 用户代理, 策略引擎, 网络安全挑战, 自动化攻击, 自动化运维, 自定义请求头, 超时处理, 运维, 远程执行, 隧道