DeepSeek Harness plugin

dsh-ssh-plugin

SSH tool plugin for DeepSeek Harness: persisted SSH connections, workspace-bound defaults, and the ssh_exec model tool

Jump to install

Source facts

Repository
YOLO-LZL/dsh-ssh-plugin
Latest update
Aug 14, 2026
Category
Tools & Capabilities
GitHub stars
0
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/YOLO-LZL/dsh-ssh-plugin
Plugin: dsh-ssh-plugin
Author: YOLO-LZL

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer3 files
README.mdSource · read only

dsh-ssh-plugin

A DeepSeek Harness plugin that adds the ssh_exec model tool — run commands on a remote Linux server over the system ssh client — plus persisted SSH connections: save connections once, bind them to a workspace, and let ssh_exec use them by default.

  • Key-based auth only (BatchMode=yes) — no password/passphrase prompts, so a missing or unauthorized key fails fast instead of hanging.
  • No remote-shell quoting layer — the remote command travels through ssh stdin to bash -s.
  • Session sandbox aware — runs the client under the calling session's standing policy; danger-full-access runs it unconfined.
  • Recognizes your local ~/.ssh/config — hosts defined there need no manual ssh_connections save; pass the alias as ssh_exec host and ssh resolves it, and ssh_connections list shows them read-only.
  • Dual-face package — the host half registers the ssh-connections settings namespace and the ssh_connections tool; the browser half registers the "SSH Connections" card in Settings → Plugins.
  • All harness services except tools/shell are optional — profiles without settings or workspaceRegistry degrade gracefully (see below).

Install

dsh plugin --profile <name> add dsh-ssh-plugin          # from npm
dsh plugin --profile <name> add github:you/dsh-ssh-plugin   # from git
dsh plugin --profile <name> add ./dsh-ssh-plugin        # from a local checkout

A local checkout must be built first: pnpm install && pnpm bundle (git installs build automatically through prepare).

Then boot with dsh --profile <name>.

The plugin declares the harness packages as peer dependencies; @deepseek-ai/dsh-base (the first bundle of every profile) provides them.

Usage

ssh_exec

The model gains an ssh_exec tool. Ask in natural language (e.g. "ssh to root@10.0.0.5 and show disk usage"), or pass explicit arguments:

ArgRequiredNotes
hostyes*Remote host as [user@]host, e.g. root@10.0.0.5, or any alias defined in ~/.ssh/config.
commandyesBash command(s) run on the remote host via bash -s.
portnoSSH port. Default 22.
key_pathnoAbsolute path to the private key. Omit for ~/.ssh defaults and ssh-agent.
timeout_msnoForeground timeout in ms. Default 30000.
connectionnoLabel of a saved connection; fills in host/port/user/keyPath.

\* host is required in the schema, but at execution the effective host resolves as explicit host → explicit connection → workspace default. Explicit port/key_path always win over the resolved connection's values. A host that is a ~/.ssh/config alias is handed to ssh unchanged — ssh applies the config's HostName/User/Port/IdentityFile itself, so no ssh_connections save is needed for config hosts.

ssh_connections

The model also gains an ssh_connections tool for durable connection management (persisted through the harness settings store, so it survives restarts):

  • save — persist a connection (label, host, optional port/user/keyPath). Labels are unique.
  • list — show saved connections plus hosts discovered from the local ~/.ssh/config (read-only; pass the alias as ssh_exec host, no save needed).
  • delete — remove one by label (also unbinds workspaces that pointed at it).
  • use — bind the current workspace to a connection label so ssh_exec may omit host; omit label to clear the workspace default.

SSH config discovery

On every call the plugin reads the local OpenSSH client config (~/.ssh/config, or sshConfigPath when configured) and parses it:

  • Concrete Host aliases become visible to the model in ssh_connections list and are suggested in ssh_exec error messages.
  • Per ssh semantics, the first obtained value wins: global directives and Host * blocks provide defaults, later matching blocks cannot override them. HostName/User/Port/IdentityFile are resolved; Match blocks and Include directives are not expanded — hosts must live in the file itself.
  • Discovery is best-effort: a missing/unreadable config yields an empty list, never an error. Config hosts are never persisted — they exist only in your ~/.ssh/config.

Settings card

With a web profile, Settings → Plugins shows an "SSH Connections" card styled like the built-in plugin cards (Bash/Terminal, Agent loop, Web search): a collapsible card with an unsaved badge and discard/save actions. Edit the same connections list (add/remove rows, save). The card only writes the connections field; workspace bindings are managed by ssh_connections use.

Data model

The ssh-connections settings namespace (schemastery schema, validated for duplicate labels):

{
  connections: [{
    label: string            // unique, non-empty
    host: string             // [user@]host, non-empty
    port?: number            // 1..65535, default 22
    user?: string            // optional; prepended to host when host has no user part
    keyPath?: string         // absolute private-key path; omit for ~/.ssh + ssh-agent
  }],
  workspaceDefaults: { [workspaceId: string]: string }   // workspaceId → label
}

Only key paths are stored — key content never leaves disk (role('secret') is reserved for a future keyContent field).

Configuration

Set row-level defaults in a later patch layer (profile cordis.patch.yml or --patch):

- id: tool-ssh
  name: dsh-ssh-plugin
  config:
    timeoutMs: 30000
    connectTimeout: 15
    sshConfigPath: C:\Users\me\.ssh\config   # optional; defaults to ~/.ssh/config

Degradation matrix

CompositionBehavior
No ctx.settings (e.g. TUI)No namespace, no ssh_connections tool; ssh_exec works with explicit args only.
No ctx.workspaceRegistryuse and the workspace-default resolution report "workspace registry unavailable"; everything else works.
No ~/.ssh/config (or unreadable)ssh_connections list shows saved connections only; ssh_exec suggestions omit config aliases.
Namespace not exposed to the browserThe card renders an "unavailable" placeholder.

Requirements

  • A reachable Linux target with bash and key-based SSH access set up (~/.ssh/authorized_keys).
  • On Windows, a session whose standing sandbox policy is danger-full-access; the restricted token otherwise refuses to start ssh.exe.

Development

pnpm install
pnpm bundle     # tsdown → lib/index.js (host) + lib/client.js (browser bundle)
pnpm types      # tsc --emitDeclarationOnly → lib/types/**/*.d.ts
pnpm test       # vitest (model + wiring)