dsh-plugin-ssh: Turning Remote Linux Servers into DSH Workspaces

前言

DeepSeek Harness(DSH)要求工作区对应本机上一个真实存在的目录,而很多日常开发、运维任务实际跑在远端 Linux 上。若只靠本机 Shell 或单独开 SSH 客户端,agent 会话与「当前在哪台机器、哪个目录」容易脱节;同时连接多台服务器时,还存在命令误发到别的主机的风险。下面介绍社区插件 dsh-plugin-ssh(维护者 JeremyLyc,MIT 许可证,当前 package 版本 0.4.0),它用工作区绑定、原生会话工具与侧栏面板,在 DSH Host 与远端之间架桥。

这是什么

dsh-plugin-ssh 面向 DSH 桌面版:为 DeepSeek Harness 提供 SSH 远程工作区——会话级 agent 工具(ssh_exec / ssh_upload / ssh_download / ssh_workspace)、左侧「SSH 远程」面板、右侧「服务器文件」页签、目录选择与密码弹窗,并在输入框下方用 composer pill 显示 agent 实际工作的目录(例如 prod:/srv/app 或本地工作区路径)。

架构上,浏览器侧 lib/index.js 经 HTTP /ssh-panel/api/* 调用 Host 侧 lib/ssh.js(ssh2)连服务器;lib/tools.js 注册原生工具,按工作区绑定取主机。仓库在 GitHub:JeremyLyc/dsh-plugin-ssh;社区目录页:skillhub.cn 条目。分类为客户端插件。

核心功能

会话工具(无 host 参数)

模型可直接调用四个工具,均不接受 host 参数——目标主机只来自当前会话工作区下的 .dsh-ssh-workspace.json 绑定:

工具 作用
ssh_exec 在绑定主机上执行命令,返回 stdout/stderr/退出码;可选 workdir、timeoutMs
ssh_upload 本地文件经 SFTP 上传到绑定主机(自动建父目录)
ssh_download 从绑定主机 SFTP 下载到本地
ssh_workspace 回报当前绑定的主机、登录目录与远端工作目录

非零退出码以 [exit code: N] 返回,不算工具错误;超时会向远端发 KILL 并标 [timed out after Nms]。

隔离:一个会话只碰自己的服务器

插件在工具契约层面限制跨机误操作:工具签名里没有 host,也没有 defaultHost 兜底;每次调用由 exec.agent 读工作区目录下的 .dsh-ssh-workspace.json。未绑定的普通工作区会直接拒绝;绑定指向配置里不存在的主机会拒绝,不会回退默认主机。

README 说明:MCP 路径(server.mjs)拿不到会话身份,可能接受任意 host 别名,因此不要与原生工具同时启用 MCP 条目,否则可能绕过隔离。原生工具因能拿到 exec.agent 而适合做隔离。

侧栏与远程工作区

  • 左侧栏「SSH 远程」:选主机、执行命令、传文件、一键创建远程工作区。
  • 右侧栏「服务器文件」:浏览服务器任意目录、预览文本、切换工作目录。
  • 远程工作区:本地占位目录 + .dsh-ssh-workspace.json + 自动生成的 AGENTS.md;切换远端目录时只替换 AGENTS.md 里 <!-- dsh-ssh:root --> 标记块内的说明,不重复追加。
  • 密码弹窗:主机未配置密钥或密码时才询问;密码经 setRuntimePassword 只存在于 Host 进程内存,不写文件,DSH 重启后需重新输入。

HTTP 端点(面板用)

端点 kind: exact,仅接受本机/渲染进程请求,拒绝非回环地址。主要包括:GET /ssh-panel/api/hosts、POST /ssh-panel/api/connect、POST /ssh-panel/api/exec、上传/下载、建工作区、读绑定、切换 root、ls、read 等(下载 ≤64 MB,读文本 ≤512 KB)。

安装与启用

前置:DSH 桌面版(profile 目录 ~/.dsh/profiles/desktop)、Node.js 20+。

  1. 克隆插件并安装依赖:
git clone https://github.com/JeremyLyc/dsh-plugin-ssh ~/.dsh/plugins/dsh-plugin-ssh
cd ~/.dsh/plugins/dsh-plugin-ssh && npm install --omit=dev
  1. 让 desktop profile 链接该包:
cd ~/.dsh/profiles/desktop
pnpm add "link:$HOME/.dsh/plugins/dsh-plugin-ssh" --ignore-scripts
  1. 在 profile 的 package.json 里把包名加入 dsh.profile.bundles(包内 cordis.patch.yml 会插入 ssh-panel 条目,注册面板与四个会话工具):
{
  "dsh": {
    "profile": {
      "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-plugin-ssh"]
    }
  }
}
  1. 日志出现 ssh-panel: workspace-scoped tools registered (…) 与 ssh-panel: endpoints registered at /ssh-panel/api 即表示 Host 侧就绪;客户端 bundle 改动后需刷新 DSH 窗口。

兼容性说明:作者在 DSH Desktop 0.2.1-rc.3 上验证(依赖 sidebar.panellist、conversation.composer.dock 等 slot)。依赖包括 ssh2、@modelcontextprotocol/sdk、zod。

配置主机

配置文件默认路径 ~/.dsh/ssh-hosts.json,可用环境变量 DSH_SSH_HOSTS 指定;会与 ~/.ssh/config 合并。示例:

{
  "defaultHost": "prod",
  "hosts": {
    "prod": {
      "host": "10.0.0.10",
      "port": 22,
      "username": "deploy",
      "privateKeyPath": "~/.ssh/id_ed25519",
      "remoteRoot": "/srv/app"
    },
    "legacy": {
      "host": "10.0.0.11",
      "username": "ops",
      "password": "${LEGACY_SSH_PASSWORD}"
    }
  }
}

常用字段:host / port / username(或 user)、privateKeyPath(支持 ~)、password / passphrase(支持 ${ENV})、hostKeySha256、strictHostKey、connectTimeoutMs(默认 10000)。未配私钥且无密码时会尝试 id_ed25519 → id_rsa → id_ecdsa。

配置里已有密钥或密码则连接时不弹窗;都没有则面板弹密码框。若在 JSON 里写密码,请注意文件权限。

典型用法

  1. 按上文安装并配置 ssh-hosts.json。
  2. 在「SSH 远程」面板选择主机、验连;必要时在弹窗输入密码。
  3. 使用「一键建远程工作区」:在本地生成占位目录与绑定文件,并在该工作区打开会话。
  4. 在对话中让 agent 调用 ssh_exec 等工具;README 建议在 AGENTS.md 生成的远端目录块基础上,对 ssh_exec 显式传 workdir 与远端工作目录一致。
  5. 用右侧「服务器文件」浏览、预览、切换远端工作目录;输入框下方 pill 会跟随当前目录。

开发侧可运行仓库内测试,例如 node test/tools-isolation.mjs 校验隔离契约;需已配置主机时设置 DSH_SSH_TEST_HOST 等环境变量(见 README「开发」一节)。

适用场景与注意

适合:已在用 DSH 桌面版、需要在对话里操作固定远端 Linux(部署、查日志、传文件),且希望多台服务器之间由工作区绑定隔离的场景。

务必注意:

  • 面板与工具能执行任意远端命令,能力等价于本机 ssh;HTTP 端点虽限制回环来源,仍应只在本机可信环境使用。
  • 插件在 DSH Host 进程权限下运行;安装前请阅读源码与 MIT 许可证,自行评估风险。
  • 命令输出与文件内容会进入模型上下文;上传/下载有体积上限(下载 64 MB、请求体 96 MB)。
  • 社区目录 skillhub.cn 为独立生态站点,与 DeepSeek / 幻方无官方从属关系;插件星标等以 GitHub 页面为准(README 展示为社区 star 徽章)。

结尾

dsh-plugin-ssh 把「DSH 必须是本地目录」与「agent 在远端干活」统一到远程工作区绑定与无 host 参数的原生工具上,并辅以侧栏文件浏览与密码内存策略。需要细节、截图与 issue 时,见 GitHub 仓库 README 与 SkillHub 目录页。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye