zcode-ssh
by KrystalQAQ
README.md
# zcode-ssh
SSH 主机注册表 + 远程操作,做成 ZCode 插件。移植自 [pi-ssh](https://github.com/KrystalQAQ/pi-ssh),引擎源自 [dsh-ssh](https://github.com/zhu1090093659/dsh-web/tree/dev/packages/dsh-ssh)(Apache-2.0,版权署名保留:© zhu1090093659 / linxin666)。
## 功能
**7 个 MCP 工具**(server id `ssh`,模型可直接调用):
| 工具 | 说明 |
|---|---|
| `ssh_list` | 列出已配置主机(alias/host/user/auth/env/tags),支持模糊查询 |
| `ssh_exec` | 在远端执行命令(超时控制、stdout/stderr 分离、2MB 截断保护、取消传播) |
| `ssh_upload` | SFTP 上传(本机 → 远端) |
| `ssh_download` | SFTP 下载(远端 → 本机) |
| `ssh_tunnel` | 本地端口转发隧道(start/list/stop/stop-all,只听 127.0.0.1) |
| `ssh_cluster` | 多机并发执行(按 alias/environment/tags 筛选,默认并发 8) |
| `ssh_manage` | 主机注册表增删改查 + `~/.ssh/config` 导入 + 连通性测试 |
前 6 个是 agent 操作工具(对注册表只读);`ssh_manage` 承接原 pi 版 `/ssh` 的管理能力,由人工在对话中确认后驱动。
**1 个命令** `/ssh`:
```
/ssh 菜单
/ssh list 主机表
/ssh import 从 ~/.ssh/config 一键导入
/ssh add [alias] 添加主机
/ssh edit <alias> 编辑主机
/ssh remove <alias> 删除主机(同时断开连接与隧道)
/ssh test [alias] 测连接(缺省测全部)
/ssh tunnel [list|stop <id>|stop-all [alias]] 隧道管理
```
ZCode 的命令是提示词而非交互对话框,因此 `/ssh` 会引导 agent 调用对应工具,并在写操作前与你确认字段。
**引擎能力**(与 pi-ssh / dsh-ssh 一致):
- 每 alias 持久连接池:30 分钟空闲断开、断线自动重连(最多 3 次)
- key / password / ssh-agent(SSH_AUTH_SOCK / Pageant / 显式 socket)认证,支持加密 key
- ProxyJump 多级跳板(插件内 alias 或 `[user@]host[:port]` 地址)
- OpenSSH ProxyCommand(%h/%p/%r/%n 展开)
- `~/.ssh/config` 导入:Host/HostName/User/Port/IdentityFile/IdentityAgent/ProxyJump/ProxyCommand/Include;wildcard、Match、已存在 alias 跳过并给出原因
## 安装
插件从本地市场安装(`.zcode-plugin/plugin.json` 声明 MCP server,`node ${CLAUDE_PLUGIN_ROOT}/dist/server.cjs` 启动)。`dist/server.cjs` 已随插件打包,装好即用,不需要 `npm install`;运行需要机器上有 `node`(≥ 20)。
## 数据与安全
- 主机配置:`~/.zcode/ssh/hosts.json`(可用 `$ZCODE_SSH_HOME` 覆盖),原子写入,目录 0700 / 文件 0600
- 密码与 key 口令明文存于该文件(与 ssh 生态惯例一致的信任模型;不写日志)
- agent 认证只存 socket 路径,不接触私钥材料
- 隧道只监听 127.0.0.1
- 模型拿不到 ProxyCommand 原文(只报告"该主机配置了 proxy-command"布尔值)——命令可能内嵌堡垒机凭据
- 删除主机或修改连接字段会立即断开该 alias 的连接池与隧道
- `ssh_upload`/`ssh_download` 在本机读写任意本地路径(宿主进程权限,非沙箱)
## 布局
```
.zcode-plugin/plugin.json ZCode 插件清单(commands + mcpServers)
mcp/server.ts 7 个 MCP 工具(原 pi 的 tools.ts + /ssh 管理逻辑)
commands/ssh.md /ssh 命令(提示词驱动 ssh_manage)
src/engine.ts 引擎门面
src/store.ts 主机存储(原子 JSON + ~/.ssh/config 导入)
src/ssh-config.ts ssh_config 解析器
src/home.ts 数据目录(~/.zcode/ssh)
src/protocol.ts 类型契约
src/engine/ connection-pool / proxy-command / sftp / tunnel / cluster
dist/server.cjs esbuild 单文件产物(安装后直接运行)
build.mjs 构建脚本(stub 掉 ssh2 可选原生绑定)
smoke/engine-smoke.mjs 引擎集成冒烟测试(内嵌 ssh2 服务端,17 项)
smoke/mcp-smoke.mjs MCP 协议测试(真实 stdio 握手 + tools/call,15 项)
```
## 开发
```sh
npm install
npm run typecheck # tsc --noEmit
npm run build # 打 dist/server.cjs
npm run smoke # 引擎 17 项
npm run smoke:mcp # MCP 协议 15 项(需先 build)
```
## 已知限制(继承 pi-ssh)
- 上传/下载均为单文件(agent 工具不遍历目录):上传目标必须是绝对路径,下载不支持整目录
- exec 断线重放可能对非幂等命令重复执行
- ProxyJump 与 ProxyCommand 不能同主机混用;仅首跳可用 ProxyCommand
- 断点续传未实现
- 交互式 PTY 终端未移植(pi 版同样未移植)
## License
Apache-2.0。引擎代码源自 dsh-ssh(Apache-2.0)经 pi-ssh 移植,修改记录见 `NOTICE`。
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues