🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

SSH 远程工作区 JeremyLyc/dsh-plugin-ssh

MCP
JeremyLyc5 天前有提交已提供中文文档扫描:含敏感能力兼容 / 相关生态

在对话中操作远端服务器,侧栏浏览目录并传文件

30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/29 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/JeremyLyc/dsh-plugin-ssh.git

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
生态应用
桌面端 / Web 外壳,不以 dsh plugin add 安装
装得上吗
本站尚未做安装检查
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 5 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 28 处,展示前 26 条)
  • 读取本地文件
    lib/index.js:67
    const stats = statSync(file)
  • 读取本地文件
    lib/index.js:365
    binding = JSON.parse(await readFile(join(directory, BINDING_FILE), 'utf8'))
  • 写入本地文件
    lib/index.js:373
    await writeFile(join(directory, BINDING_FILE), `${JSON.stringify(binding, null, 2)}\n`, 'utf8')
  • 读取本地文件
    lib/index.js:378
    instructions = await readFile(instructionsPath, 'utf8')
  • 写入本地文件
    lib/index.js:383
    await writeFile(instructionsPath, next, 'utf8')
  • 读取本地文件
    lib/index.js:472
    raw = await readFile(join(directory, BINDING_FILE), 'utf8')
  • 读取本地文件
    lib/index.js:484
    const stale = await readFile(instructionsPath, 'utf8')
  • 写入本地文件
    lib/index.js:486
    await writeFile(instructionsPath, instructionsFor({
  • 写入本地文件
    lib/index.js:540
    await mkdir(directory, { recursive: true })
  • 读取本地文件
    lib/index.js:546
    const previous = JSON.parse(await readFile(join(directory, BINDING_FILE), 'utf8'))
  • 写入本地文件
    lib/index.js:559
    await writeFile(join(directory, BINDING_FILE), `${JSON.stringify(binding, null, 2)}\n`, 'utf8')
  • 写入本地文件
    lib/index.js:566
    await writeFile(instructionsPath, instructionsFor(binding), 'utf8')
  • 发起网络请求
    lib/client.js:106
    const response = await fetch(API + path, options);
  • 发起网络请求
    lib/client.js:267
    const response = await fetch(`${API}/download?${query.toString()}`);
  • 读取本地文件
    lib/config.js:125
    if (existsSync(sshConfigPath)) {
  • 读取本地文件
    lib/config.js:127
    for (const [alias, directives] of parseSshConfig(readFileSync(sshConfigPath, 'utf8'))) {
  • 读取本地文件
    lib/config.js:136
    if (existsSync(file)) {
  • 读取本地文件
    lib/config.js:139
    parsed = JSON.parse(readFileSync(file, 'utf8'))
  • 读取本地文件
    lib/tools.js:40
    raw = await readFile(join(directory, BINDING_FILE), 'utf8')
  • 读取本地文件
    lib/ssh.js:43
    if (!existsSync(path)) {
  • 读取本地文件
    lib/ssh.js:46
    return readFileSync(path)
  • 读取本地文件
    lib/ssh.js:57
    if (existsSync(path)) return path
  • 读取本地文件
    lib/ssh.js:136
    options.privateKey = readFileSync(fallback)
  • 读取本地文件
    lib/ssh.js:291
    if (!existsSync(localPath) || statSync(localPath).isDirectory()) {
  • 读取本地文件
    lib/ssh.js:291
    if (!existsSync(localPath) || statSync(localPath).isDirectory()) {
  • 读取本地文件
    server.mjs:38
    stamp = file === undefined ? 0 : statSync(file).mtimeMs
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DeepSeek Harness 的 SSH 远程工作区:智能体工具加侧边栏面板(文件浏览器、目录选择器、密码输入框)

README

由 DeepSeek 最新模型翻译生成
dsh-plugin-ssh 把一台远端 Linux 服务器变成 DeepSeek Harness 里的「工作区」:智能体用对话操作服务器,你在侧栏里浏览它的目录、传文件、切换工作目录。 SSH remote workspaces for DeepSeek Harness. One plugin gives you agent tools (mcp__ssh__), a sidebar panel, a server-files tab, a workspace bound to a remote directory, and a composer pill showing where the agent is actually working. 这个插件做什么 DSH 的工作区必须是一个真实存在的本地目录,而智能体真正要干活的是远端服务器。
展开完整文档(README 剩余 1 节)
dsh-plugin-ssh

把一台远端 Linux 服务器变成 DeepSeek Harness 里的「工作区」:智能体用对话操作服务器,你在侧栏里浏览它的目录、传文件、切换工作目录。

SSH remote workspaces for DeepSeek Harness. One plugin gives you
agent tools (mcp__ssh__), a sidebar panel, a server-files tab, a workspace bound to a remote
directory, and a composer pill showing where the agent is actually working.

这个插件做什么

DSH 的工作区必须是一个真实存在的本地目录,而智能体真正要干活的是远端服务器。这个插件在两者之间架一座桥:

┌─────────────────────────── DSH Host 进程 ───────────────────────────┐ │ │ 浏览器 │ lib/index.js ── HTTP /ssh-panel/api/ ──► lib/ssh.js ── ssh2 ──► 服务器(面板) │ │ ▲ │ │ └─ 写绑定 + AGENTS.md │ │ │ │ │ │ server.mjs(MCP stdio)── mcp__ssh__* 工具 ────┘ │ └─────────────────────────────────────────────────────────────────────┘

- 会话工具:mcp__ssh__ssh_exec / ssh_upload / ssh_download / ssh_hosts,模型直接调用。
- 左侧栏 SSH 远程 面板:选主机、跑命令、传文件、一键建远程工作区。
- 右侧栏「服务器文件」页签:浏览服务器任意目录、预览文本、切换工作目录。
- 远程工作区:本地占位目录 + .dsh-ssh-workspace.json 绑定 + 自动生成的 AGENTS.md,该工作区里的每个会话都确切知道「我在哪台机器、在哪个目录、用哪个工具」。
- 密码弹窗:主机没有预置密钥/密码时才问,密码只活在 Host 进程内存里。
- 输入框下方的当前目录 pill:prod:/srv/app 或本地工作区路径,切目录即时跟随。

截图

在 DSH 里用对话操作服务器:右侧是服务器文件页签,输入框下方是状态栏

安装

前置:DSH 桌面版(配置档目录 ~/.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

2. 让 profile 能解析这个包
cd ~/.dsh/profiles/desktop
pnpm add "link:$HOME/.dsh/plugins/dsh-plugin-ssh" --ignore-scripts

3. 面板部分走包自带的 bundle 补丁:把包名加进 dsh.profile.bundles(package.json 里的 dsh.bundle.patch 指向 cordis.patch.yml,它会插入 ssh-panel 条目):

{
"dsh": {
"profile": {
"bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-plugin-ssh"]
}
}
}

4. 会话工具需要一条显式条目(要绝对路径指向 server.mjs),追加到 ~/.dsh/profiles/desktop/cordis.patch.yml:

- insert:
- id: mcp-ssh # 会话工具:MCP stdio 服务器 name: "@deepseek-ai/dsh-mcp-client" config: serverName: ssh transport: stdio command: node args:
- '<插件目录>/server.mjs' env: DSH_SSH_HOSTS: '<你的 ssh-hosts.json>' toolCallTimeoutMs: 300000 failOnStartupError: false

保存即热加载;日志出现 ssh-panel: endpoints registered at /ssh-panel/api 就绪。客户端 bundle 改动需要刷新窗口。

配置主机

~/.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 | 连接目标,username 也可写 user |
| privateKeyPath | 私钥路径,支持 ~;不填且没密码时回退 id_ed25519 → id_rsa → id_ecdsa |
| password / passphrase | 密码 / 私钥口令;支持 ${ENV},未设置的环境变量按「没有」处理 |
| hostKeySha256 | 钉住主机指纹(SHA256:...),填了就严格校验 |
| strictHostKey | true 时拒绝未钉住指纹的主机 |
| connectTimeoutMs | 连接超时,默认 10000 |

密码策略:配置里有密钥或密码 → 连接时不再询问;都没有 → 面板弹密码框,密码只存在 Host 进程内存(setRuntimePassword),不写任何文件,DSH 重启后重新问。

工具

| 工具 | 作用 |
| mcp__ssh__ssh_hosts | 列主机、默认主机、认证方式 |
| mcp__ssh__ssh_exec | 执行命令,返回 stdout/stderr/退出码,workdir/timeoutMs 可选 |
| mcp__ssh__ssh_upload | 本地文件 → 远端(SFTP,自动建父目录) |
| mcp__ssh__ssh_download | 远端文件 → 本地(SFTP) |

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

HTTP 端点

全部 kind: exact,只接受本机/渲染进程请求,且拒绝来自非回环地址的调用:

| 方法 | 路径 | 作用 |
| GET | /ssh-panel/api/hosts | 主机列表与告警 |
| POST | /ssh-panel/api/connect | {host, password?} → 验连;缺凭据回 needsPassword |
| POST | /ssh-panel/api/exec | 执行命令 |
| POST | /ssh-panel/api/upload | base64 上传 |
| GET | /ssh-panel/api/download | 下载(≤64 MB) |
| POST | /ssh-panel/api/workspace | 建绑定目录 + AGENTS.md |
| GET | /ssh-panel/api/binding | 读工作区绑定 |
| POST | /ssh-panel/api/root | 切换远端工作目录(改写绑定与 AGENTS.md) |
| GET | /ssh-panel/api/ls | 列一层目录(目录优先) |
| GET | /ssh-panel/api/read | 读文本(≤512 KB,二进制拒绝) |

远程工作区是怎么「绑定」的

创建时在本地目录写两份文件,AGENTS.md 里用标记包住工作目录块:

远端工作目录:/srv/app。所有远端命令都以它为工作目录,mcp__ssh__ssh_exec 请显式传 workdir: "/srv/app"。

切换目录只替换标记内的内容,不重复追加,也不动你手写的其它说明。

开发

npm install
需要一台已配置在 ~/.dsh/ssh-hosts.json 里的主机
DSH_SSH_TEST_HOST=prod node test/host-api.mjs
DSH_SSH_TEST_HOST=prod DSH_SSH_TEST_PASSWORD_HOST=legacy node test/host-api.mjs
node test/smoke.mjs # MCP stdio 全链路:握手 → tools/list → 执行 → 上传下载往返

lib/client.js 是手写的浏览器 bundle(DSH 的模块格式:window.__ModuleLoader__.load({id, factory})),没有构建步骤;改完刷新窗口即可。lib/index.js 是 Host 半侧,改动会随插件条目重新加载。

安全说明

- 面板能执行任意命令,请把它当成 ssh 本身:只在本机使用,端点拒绝非回环来源。
- 密码不落盘;ssh-hosts.json 里若写密码,注意该文件的权限。
- 命令输出与文件内容会进入模型上下文,敏感数据请自行判断。
- 上传/下载上限:64 MB(下载)/ 96 MB(请求体)。

兼容性

在 DSH Desktop 0.2.1-rc.3(dsh-mcp-client、sidebar.panellist、conversation.composer.dock 等 slot 均有)上验证;依赖 ssh2、@modelcontextprotocol/sdk、zod。

License

MIT © 2026 JeremyLyc
预览分享卡片长什么样 ↓JeremyLyc/dsh-plugin-ssh
分享 · DeepSeek Harness Hub
JeremyLyc/dsh-plugin-ssh

在对话中操作远端服务器,侧栏浏览目录并传文件

这是你的仓库?认领条目

回到顶部