SSD Nodes Learn 🎉 VPS from $5.50/mo
How to do am Matt ConnorBy Matt Connor

How to Run DeepSeek Harness Private on VPS

Run DeepSeek Harness safely on Linux VPS: pin the npm version, understand plugin powers, and use SSH tunnel to open port 3080 without exposing your agent.

Wetin be DeepSeek Harness

The DeepSeek Harness (dsh) na Node.js agent runtime wey you fit run for VPS (virtual private server), and the safe way to run am na to bind am to 127.0.0.1, make your browser reach am through SSH (secure shell) tunnel. E dey serve web UI (user interface) for port 3080 instead of dey live inside terminal. That web server no ask for password of im own, so if you publish port 3080, anybody wey find am fit get agent wey dey read your files and run commands as your Linux user.

DeepSeek release am on 13 August 2026 under MIT licence, as npm package @deepseek-ai/dsh. The project describe itself as developer preview and talk say compatibility-breaking changes dey expected. Every version number for here na snapshot from August 2026, so check the repository before you copy any of am enter important box.

One idea dey run through the whole design: everything na plugin. The model adapter, tool registry, session log, sandbox, scheduler and the agent loop itself na plugins wey load into one shared context, and you fit replace any of dem. No privileged core dey wey plugins only decorate. Na this make the harness worth trying, and na here the one real risk dey.

Harness no be model

Harness na the thing wey dey run agent loop. Model dey do the reasoning for another place, so nothing go work until you give am either API (application programming interface) key or address of model endpoint wey you host by yourself.

You configure am for UI under Settings, then Models. Catalog get ready-made cards for the big API providers (DeepSeek, OpenAI, Anthropic), where you paste key. "Add a custom provider" na the interesting option: e dey take provider ID, display name, base URL, API protocol, and credential. E dey speak OpenAI-compatible protocol, so any gateway or local server wey implement that protocol go work. Custom providers fit also query the OpenAI-compatible GET /models endpoint to fill model list by itself.

Na so you go point harness to model wey dey the same VPS. Ollama exposes OpenAI-compatible API for http://127.0.0.1:11434/v1/, and e want make you fill API key field with any string, ollama by convention, because the field dey required but dem no dey use the value. Whether model wey small enough to fit your VPS go dey good enough to drive agent na the harder question. The difference between Ollama and vLLM as local model server go decide how much RAM the answer go cost.

Keys wey you type for UI na write-only. Harness dey store dem for $DSH_HOME/.credentials.yaml and e dey keep only credential reference for settings.yaml. $DSH_HOME dey default to ~/.dsh. Treat that file like password file, because na password file e be: anybody wey read am fit spend your API budget.

Wetin you need before you install

  • a VPS wey dey run Ubuntu 24.04 or another current Linux, with SSH access
  • Node.js 22.19 or newer for the 22.x line, or Node.js 24 and above, because na these versions the project dey build and test against
  • a normal user account, no be root, because the agent dey run shell commands as the person wey start the process
  • pnpm for the PATH if you plan install plugins, because the plugin command dey shell out to am
  • port 3080 closed for your firewall and for your provider separate network firewall

Ubuntu own nodejs package old pass wetin the harness need, so install Node from NodeSource or nvm instead of using apt install nodejs. If the VPS new, harden SSH before anything else fit take ten minutes and e worth am, because the tunnel wey you dey depend on only good as the SSH server behind am.

Install DeepSeek Harness for VPS, pin am one version

node --version
npx @deepseek-ai/dsh@0.1.0-rc.6 web

npx dey download the package and run its dsh binary. web na alias for --profile web, wey dey start the browser application, and the process go print the address wey e dey listen on. The default na http://127.0.0.1:3080.

Pin the version. npx @deepseek-ai/dsh web dey resolve whichever tag latest point to for the time wey you run am, and the project don already release several release candidates and talk say breaking changes dey come. 0.1.0-rc.6 na wetin latest point to on 13 August 2026. Pinned version mean say the box wey you set up today go behave the same way next month, so upgrade go become decision wey you make instead of accident wey you discover.

For daily use, install am once instead of resolving am again every time you start am.

npm install -g @deepseek-ai/dsh@0.1.0-rc.6
dsh --profile web --help

That second line worth running, because the launcher and the web app get separate flag sets. dsh --help dey show the launcher's own options. dsh --profile web --help dey show the flags wey the web application accept, and na there --port, --host and the repeatable --trusted-host dey.

Now confirm wetin e dey listen on.

ss -tlnp | grep 3080

The local address column suppose read 127.0.0.1:3080. If e read 0.0.0.0:3080, the UI dey reachable from internet, and you suppose stop the process before you do anything else.

Keno you no suppose ever publish port 3080

The web server no get authentication layer. Its configuration expose one listen host and one listen port, and na everything wey e expose be that. Access control for deployments wey no dey use loopback na separate trusted-host setting; e no be login screen.

Now think about wetin dey behind that port. The agent dey edit files for workspace and dey run shell commands, and your provider credentials dey stored for disk beside am. So open port 3080 na remote shell wey get chat interface, dey run as the user wey start am, with your API key attached. Nobody need exploit for this. Dem only need the port number, and scanners dey find port numbers within hours after host come online.

The CLI (command line interface) agree with this. As of 0.1.0-rc.6, e deliberately no support --host 0.0.0.0 and e go exit with usage error instead of starting. That refusal na feature, so no go find patch wey go remove am.

Two other deployment options make sense when tunnel no suit you. Put the box for private overlay network so e get address wey only your own devices fit route to. Na this self-hosted Headscale control server provide. Or put reverse proxy in front, make e authenticate request before request reach port 3080. For example, Authentik single sign-on server fit do forward auth. Reverse proxy wey no get auth in front no be security control. Na only longer URL.

Use SSH tunnel take reach web UI

Run this for your laptop, no be for server.

ssh -N -L 3080:127.0.0.1:3080 you@your-server

-L dey open port 3080 for your laptop, then e forward anything wey connect to am through the encrypted SSH session. Server dey resolve the 127.0.0.1:3080 part, so connection dey reach the harness from loopback, exactly as if you dey sit for the machine. -N mean say make e no start remote shell, because na the forward only you need.

Then open http://127.0.0.1:3080 for your local browser. If port 3080 don already dey busy for your laptop, change the number for left side: ssh -N -L 3180:127.0.0.1:3080 you@your-server, then browse go http://127.0.0.1:3180. Number for left na local one, while number for right belong to server, so na only left one you go change.

Save am for ~/.ssh/config and stop typing am.

Host dsh
  HostName 203.0.113.10
  User deploy
  IdentityFile ~/.ssh/id_ed25519
  LocalForward 3080 127.0.0.1:3080

After that, ssh -N dsh go start the tunnel. If browser report say connection refuse, e usually mean say tunnel dey up but nothing dey listen for the far side, because SSH dey forward the port whether harness dey run or not. Check the server with the ss command wey dey above.

Make the harness keep running after you log out

An npx command dey die together with your shell. A systemd user service dey survive, and e go bring the harness back after crash or reboot.

loginctl enable-linger $USER
mkdir -p ~/.config/systemd/user
command -v dsh

enable-linger important because user services normally dey stop when your last session end, so without am the harness go die as soon as you close the tunnel. Take the absolute path wey command -v dsh print and put am inside the unit, because systemd no dey search the PATH wey your login shell build.

[Unit]
Description=DeepSeek Harness web UI
After=network-online.target

[Service]
Type=simple
WorkingDirectory=%h/projects/site
ExecStart=/usr/local/bin/dsh web
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target

WorkingDirectory no be decoration. The dsh process dey use the directory wey start am as the default filesystem location, so if service start for wrong place, agent go get wrong default workspace. You still fit choose the workspace for the UI.

systemctl --user daemon-reload
systemctl --user enable --now dsh
systemctl --user status dsh

Unit wey refuse to start almost always get wrong ExecStart path or Node version wey the binary no accept, and journalctl --user -u dsh -n 50 show which one. This same pattern fit cover how to keep any coding agent alive for VPS, and the failure modes dey the same.

Wetin plugin fit do

A plugin na module wey dey contribute services, typed events, and effects wey fit reverse for shared context. Na these extension points you suppose read well:

  • register model provider for ctx.llm
  • add tools wey model fit use for ctx.tools
  • provide shell backend wey dey behind ctx.shell
  • provide filesystem access or policy behind ctx.fs
  • register human commands for ctx.commands
  • run background work through ctx.jobs
  • wrap spawned processes with ctx.sandbox backend
  • intercept requests and tool calls through agent/* and tools/* events
  • extend durable session state
  • control UI through ctx.agents

Read this list the way attacker go read am. Plugin fit provide filesystem layer and shell layer, and e fit dey inside every tool call wey model make. No permission dialog dey between plugin and these connection points, because plugin na ordinary Node code wey load for the same process with everything else. To install plugin mean say you dey run code from stranger with your agent permissions, and your agent permissions na the permissions of your Unix user.

Na the same trust decision you dey make when you attach MCP server to agent for VPS, where MCP mean model context protocol. Na also why to run coding agent safely for VPS dey start with the account wey e run under, instead of starting with the model, and why npm supply chain attacks dey hit servers hard: na the install step be the breach, and nothing go prompt you.

Plugins wey dey come from

Plugins dey inside profiles. Profile na named composition wey dey stored under $DSH_HOME. By default, na ~/.dsh. Each profile directory hold the out-of-tree plugins wey e install. CLI manage dem by forwarding your arguments directly go pnpm, with the profile directory as the working directory.

dsh plugin --profile web add github:deepseek-harness/turtle-ui
dsh plugin --profile web remove turtle-ui

Because arguments dey reach pnpm unchanged, add, remove, update and why dey behave the same way dem dey behave for any pnpm project. Plugin fit be npm package or GitHub reference. pnpm must dey for PATH first. For Node 22 and later, corepack enable pnpm go put am there.

Discovery dey work through GitHub topic. Plugin authors add dsh-plugin topic to their repository. You fit find available plugins by browsing that topic. Topic na label wey author apply to their own repository. Nobody review am and nobody sign am. Topic page rank repositories by stars. Stars measure popularity, not safety.

Four habits fit make this easier to manage. Read the source before you install, because most plugins small enough to read within ten minutes. Pin the exact version or commit instead of tracking a branch. Run the harness under a user wey no own anything else, for VPS wey you go agree to rebuild. Give the agent its own API key with its own spending limit. Keep am separate from the key wey your production services dey use.

If you prefer compare designs before you commit to one, the Omnigent multi-agent harness solve the same problem with different structure. The trade-offs go clear once plugins enter the picture.

Wetin go first spoil

Node don too old. The project target Node 22.19 and newer versions for the 22.x line, or Node 24 and above, and na dem CI dey test. Older runtime go fail for startup because the code dey use syntax and APIs wey e no get. Run node --version before you do anything else.

Port 3080 don already dey use. E fit be second harness, stale process, or another application wey dey use 3080 too. Find am with ss -tlnp | grep 3080, then stop am or start the harness for another place with dsh web --port 3180. --port belong to the web app, so run am after web.

Browser no fit connect through the tunnel. Confirm say you browse go 127.0.0.1, no be server public address, because na your laptop get the forwarded port. Then confirm say harness dey listen for the server, because SSH go set up the forward whether anything dey answer for the far end or not.

dsh plugin fail immediately. The command na wrapper around pnpm, so if pnpm binary no dey, e go stop before any plugin work start.

Agent no fit see your project. Workspace dey default to the directory wey process start from, so if unit WorkingDirectory na your home directory, agent go get your home directory. Choose workspace for the UI, or fix the unit and reload am.

FAQ

E safe to expose DeepSeek Harness web UI for port 3080?

No. The web server no get login of im own, and the agent behind am dey edit files and run shell commands as the user wey start the process, while your provider API key dey stored for the same disk. Keep the listener for 127.0.0.1 and reach am through SSH tunnel. Private overlay network, or reverse proxy wey authenticate every request before e reach the port, also dey work. As of version 0.1.0-rc.6, the CLI dey refuse --host 0.0.0.0 and exit with usage error. This one show wetin the authors think about the idea.

I need DeepSeek API key, or I fit use local model?

Either one dey work, because the harness na runtime and e no be model. Under Settings and then Models, you fit paste key inside catalog provider card, or choose "Add a custom provider" and give am base URL wey speak OpenAI-compatible protocol. Local Ollama server dey answer for http://127.0.0.1:11434/v1/ and e accept any string for the API key field. Keys dey enter $DSH_HOME/.credentials.yaml, wey by default dey point to ~/.dsh/.credentials.yaml.

Wetin plugin actually get after I install DeepSeek Harness plugin?

The permissions of the account wey dey run the harness. Plugin na Node code wey load inside the same process, and the extension points include shell backend, filesystem layer, tool registry, and events wey wrap every tool call. Nothing sandbox plugin away from those seams unless the plugin provide the sandbox by itself. Read the source before you install am, and run the harness as user wey no own anything wey matter to you.

Which version I suppose install, and e go continue to work?

Install exact version, for example npx @deepseek-ai/dsh@0.1.0-rc.6 web. Na that version the latest tag point to on 13 August 2026. The project call itself developer preview and e talk say compatibility-breaking changes dey expected, so command wey no get pinned version fit behave different from one day to another. Check the repository before you upgrade, and expect config keys and plugin interfaces to change while the version still start with 0.

#deepseek#agent-harness#self-hosting#nodejs#plugins