SSD Nodes Learn Hosting plans →
How to do am Matt ConnorBy Matt Connor

5 DeepSeek Harness plugins wey VPS owners need

See five DeepSeek Harness plugins for VPS: spend caps, tool rules, injection scanning, durable memory, plus LAN access only after authentication.

Which DeepSeek Harness plugins dey worth installing

DeepSeek Harness plugins na third-party code wey dey run inside your agent, with your agent privileges, for machine wey you dey pay for. The community list get more than twenty categories and over a thousand entries. For rented virtual private server (VPS), you need five: dsh-budget for spend caps, dsh-permission-rules for tool gating, dsh-defend for injection and secret scanning, dsh-memory for facts wey dey survive session, and dsh-web-lan-access only after you don decide how you go authenticate.

The harness na dsh, DeepSeek open-source agent harness, wey dem build so say everything na plugin. The README itself call am developer preview and warn THERE WILL BE COMPATIBILITY-BREAKING CHANGES. This one fact shape every choice wey follow. Pin wetin you install, expect upgrade to break am, and keep the set small enough say you fit actually read everything inside. If the harness never dey run, start with DeepSeek Harness install for VPS and come back here. If the parts wey these plugins hook into — the agent loop, its tools, and its memory — still dey unclear, work through the fundamentals first, because every choice wey follow easier to judge once you sabi wetin each layer dey do.

How dsh take install plugin, and where the config dey land

dsh dey build itself from Cordis plugins, so one running instance na tree of plugins, no be one program. Profile na named composition of those plugins. The two templates na web and headless. $DSH_HOME default to ~/.dsh, and profile dey for $DSH_HOME/profiles/<name>/. E hold e own package.json, one dsh.profile manifest, and one cordis.patch.yml.

dsh plugin --profile web list
dsh plugin --profile web add dsh-budget
dsh plugin --profile web remove dsh-budget

Four source forms dey work: bare npm package name, scoped name like @towzai/dsh-memory, GitHub reference like github:PerryLink/dsh-budget#main, and local path with link: or ./. Use the GitHub form when possible, because you fit replace #main with commit and get the same code back next month.

dsh plugin --profile web add "github:PerryLink/dsh-budget#461d478"

Layers dey apply for fixed order: each bundle for the order wey profile list dem, then profile cordis.patch.yml, then home-level cordis.patch.yml, then any --patch overlay. Order matter because later layer fit reconfigure or remove wetin earlier layer set up. So if plugin look installed but e no do anything, open profile cordis.patch.yml and check two things: say e insert block dey there, and say no later layer disable am.

As of 17 August 2026, npm package @deepseek-ai/dsh dey for 0.1.0-rc.7, while the plugins below build for 0.1.0-rc line. dsh-permission-rules and dsh-defend declare compatibility with 0.1.0-rc.5 to 0.1.0-rc.6, dsh-budget declare 0.1.0-rc.6 alone, dsh-memory set only peer ranges wey start from ^0.1.0-rc.6, and dsh-web-lan-access no declare any dsh version. For 10 October 2026, the latest tag for npm na 0.2.0-rc.2, so the gap don wide pass when dem choose these pins. This gap normal for this ecosystem, and na the common reason plugin stop to load: harness dey move faster than the plugins around am. Upgrade the harness intentionally, then test one plugin at a time.

Read plugin before you trust am

A dsh plugin no dey sandbox away from harness. E dey load inside the same Cordis tree, for the same process, as the same operating system user, with access to the same model credentials and the same working tree. To install one dey closer to running another person script with sudo than to adding browser extension. Na the same trust question wey Claude Code plugins dey raise, and the answer still be the same: read the code, or no install am.

Four things to check, for this order:

  • Which extension points e dey tap. tools/pre-execute mean say e dey see every tool call and fit block am. agent/pre-step mean say e dey see your messages. webServer.tapIndex mean say e dey rewrite the page wey e serve to your browser. Plugin wey no tap any of dem fit do very little; plugin wey tap all of dem na your security boundary.
  • Whether e dey talk to network. Search the source for fetch, http, and any hard-coded hostname. Cost meter wey dey phone home dey send your usage pattern go somewhere.
  • Whether e dey read credentials. Anything wey touch credentials.* or provider key need get clear reason for the README.
  • The license and the last commit date. Plugin wey no get license, wey nobody touch for months, for ecosystem wey dey change every week, na liability.

After that, install by commit instead of branch, then read the insert block wey installer write inside cordis.patch.yml. That block name the plugin id and the config wey e register, and na the shortest honest description of wetin you just add. Keep provider keys away from plugin reach where harness allow am, similar to how to keep secrets away from AI agents.

dsh-budget: how I fit stop agent wey dey spend all night?

Agent wey dey run unattended for VPS dey do so because na the reason you put am there. But na still risk. dsh-budget dey count tokens and estimated cost for each model, session, and day, and e dey enforce caps against those totals.

dsh plugin --profile web add "github:PerryLink/dsh-budget#461d478"

The default values dey generous: 10 USD per session, 50 per day, and 500 per month. Dem fit work for funded team. For personal server, dem high reach say runaway loop fit finish before cap ever trigger, so reduce dem from the first day.

Chartdsh-budget default caps and a lower starting point for one small VPS (USD)
Di data wey dey behind dis chart
[
  {
    "label": "Per session",
    "plugin_default_usd": 10,
    "suggested_start_usd": 2
  },
  {
    "label": "Per day",
    "plugin_default_usd": 50,
    "suggested_start_usd": 5
  },
  {
    "label": "Per month",
    "plugin_default_usd": 500,
    "suggested_start_usd": 40
  }
]

The suggested column na starting point for one operator on one box. E no be published figure. Increase am when real usage for one month show say you need am. Monthly cap of 40 USD with session cap of 2 go fail early and clearly. Na wetin you want while you still dey learn how much the tool dey consume.

- id: budget
  config:
    budgets:
      session: 2
      daily: 5
      monthly: 40
    warnRatio: 0.8
    overLimit: block

The setting wey dey change how the machine behave na overLimit. The default na alert. E go print warning but continue spending, so this plugin dey act like dashboard out of the box. Set am to block and the harness go refuse more model calls once cap reach, meaning say overnight job go stop instead of billing until morning. degrade na the third mode. E blocks the call and gives guidance wey names cheaper model from the degradation map. This one make sense when job must finish but e no need your best model. warnRatio default na 0.8, so e go alert you when spending reach 80 percent of the cap.

Two limits wey you need understand. Cost dey come from built-in price table wey merges with the prices wey you provide. The maintainer warns say built-in prices fit change. prices empty by default. For pinned commit 461d478, defaultPrice, the fallback for model wey no dey either table, na 1.0 USD per million input tokens and 3.0 per million output. For current main, checked 10 October 2026, the default na zero and the model go show as unpriced. Enter the real prices for your models. Otherwise, the dashboard na guess wey disguise as measurement.

Second, for 461d478, the plugin aggregates inside the running process from the session event stream. So totals reset whenever harness restart. Crash loop, or supervisor wey restart dsh, go also reset daily cap. Current main dey save day and month buckets by default (persistence.enabled: true, snapshotted every 10 seconds) and restore dem when startup happen. So restart no longer clears daily or monthly cap there, as long as harness supplies the storage domain. Without am, aggregation remain process-local. main also target the 0.2 harness line, so if you move the pin, you must move the harness too. For either case, treat dsh-budget as guardrail against your own jobs. Keep spend limit for provider account as the actual ceiling. Na the wider point for how to control AI agent cost on VPS.

For everyday use, use /budget for overview, /budget models for breakdown by model, and /budget unblock <scope> to remove a block after you decide say the job should continue.

dsh-permission-rules: which tool calls you no suppose ever run?

dsh-permission-rules dey put declarative rules for the tools/pre-execute waterfall, so dem dey evaluate rule before tool run. Three actions dey. allow allow the call pass, deny block am and return reason wey model fit read, while ask route am go the official approval seam.

dsh plugin --profile web add "github:PerryLink/dsh-permission-rules#b30b4fb"

Rules dey inside .dsh/rules.yaml relative to session working directory. Global fallbackPath and optional searchUp fit dey available to move upward toward filesystem root. Matching cover tool-name globs, parameter key and value globs, workspace-relative path globs, agent selectors like main or subagent, and network targets.

rules:
  - match: { tools: [bash], params: { command: "rm -rf*" } }
    action: deny
    reason: "No recursive deletes"
  - match: { tools: [edit, write], paths: ["**/.env*", "**/secrets/**"] }
    action: ask
    reason: "Secret files need confirmation"
  - match: { tools: ["mcp__*"] }
    action: ask
    reason: "MCP tools need confirmation"

Evaluation na first match wins. So broad allow near the top fit quietly cancel every narrower rule under am. Write denials first, then permissive rules last. Tool-name glob cover mcp__*. Na so you fit control tools wey come from model context protocol (MCP) server instead of the harness itself. This matter as soon as you dey run MCP servers for VPS.

Plan for one behaviour: ask need person or process wey go answer am. For headless profile, nobody fit dey watch. Unanswered ask no go wait for person to show. If no answerer dey composed, harness approval chain go fail closed and refuse the call. For unattended box, ask rule therefore behave like deny wey you no intentionally write. Use deny for anything wey you no go ever approve. Keep ask for the profile wey you dey monitor directly. If you want approvals to work unattended, you need real answering path. How to gate AI agent actions with approvals na the subject.

dsh-defend: prompt injection and leaked secrets nko?

dsh-defend dey scan for points three: inbound messages for agent/pre-step, tool arguments for tools/pre-execute including guard against destructive-delete, and tool results for tools/post-execute. That last one na the interesting part, because na there content wey dem fetch from web page dey get check before model act on am.

dsh plugin --profile web add "github:PerryLink/dsh-defend#7ba3427"

Defaults dey cautious instead of strict: detection.injectionAction, detection.jailbreakAction and detection.secretAction all na ask, while detection.secretBlockCritical na true, so e go block critical secret no matter wetin the other settings talk. For unattended box, change the actions wey you care about to block, because ask when nobody dey available to ask no be decision.

The audit design deserve credit. defend/detection events dey record rule id, family, category, severity, decision and scan facts, but dem never record the matched text; secrets dey recorded by type only. So enabling audit log no go create another copy of the credential wey you dey try protect.

Make you understand wetin this one give you. Detection dey use rules, and README talk am plainly say new phrasing and multi-step attacks fit pass through. E reduce how often obvious attacks succeed. E no make agent safe to point at untrusted content, so keep permission rules underneath am.

dsh-memory: wetin agent go remember tomorrow?

Two different plugins get the name dsh-memory, so e good make you know this before you type install command. Install am by explicit source so you go get the one wey you read about.

The one I go put for small server na the SQLite build. E register as memory, keep one file for $DSH_HOME/memory/memory.db wey all profiles share, and expose memory_write, memory_search and memory_forget. Search dey use keywords over the stored text and tags. No embedding service, API key, or extra process dey involved.

dsh plugin --profile web add "github:ben7am1n/dsh-memory#def7c6a"

The configuration wey you go touch small: path for the database file, promptRecentCount (default 10) for how many unpinned memories dem go inject, and promptMaxChars (default 2000) for the rendering budget. E depend on node:sqlite, wey Node 22 and 24 still mark as experimental. So, you suppose test Node upgrade instead of assuming say e go work.

This na wetin memory really change for the machine: injected memories dey enter system prompt for every turn. promptMaxChars na the maximum size for the rendered section, no be fixed amount. But once your stored memories fill am, 2000-character budget mean say dem go add some hundred input tokens to every request, forever. Na real cost for your bill, and na why dsh-budget suppose dey for the box before dsh-memory. Keep promptMaxChars small and use memory_forget prune instead of allowing the file grow.

The alternative build dey store memories for YAML file and dey use embedding search with automatic prompt injection. You install am with dsh plugin --profile web add github:towzai/dsh-memory. The embedding search need local ollama instance and embedding model, qwen3-embedding:0.6b by default. You fit override am with DSH_MEMORY_EMBED_MODEL. If ollama no dey available, e go fall back to keyword-only search. Semantic recall better pass keyword recall. But e also mean say another service and model weights go dey resident for the same server. For small plan, na memory wey the work you rent the box to do suppose use. Choose am when you get extra RAM. The general tradeoff between recall quality and resident cost dey covered for local memory for agents.

dsh-web-lan-access: web UI suppose listen pass loopback?

npx @deepseek-ai/dsh web dey serve interface for 127.0.0.1:3080. Browser fit only expose crypto.randomUUID() for secure context, so if you load that same page through plain HTTP from another machine, e go fail. dsh-web-lan-access fix this by tapping webServer.tapIndex to inject small polyfill, and e change server binding to 0.0.0.0.

Read the warning wey e get by itself before you install am. For the commit wey this text cite, e27e909, README talk say binding 0.0.0.0 go make agent reachable without authentication by anybody for the same local area network (LAN), and for server wey get public IP address, by the whole internet. But small list of sensitive methods (settings.*, credentials.*, llm.discoverModels) remain pinned to loopback and go return 403 from remote origins. This don change. Current harness builds, checked 10 October 2026, dey authenticate browser: launch token for the printed URL dey exchange for signed session cookie, and every Host API route and stream require that cookie. The plugin current README call trustedHosts Origin/Host fence, no be identity. E talk say binding 0.0.0.0 expose authentication surface for every reachable interface. E also now enable Host-backed settings for authenticated remote page, so for current builds, remote browser wey don sign in fit reach Host settings too. The risk don move, e no disappear: anybody wey fit reach the port fit test the login, the printed URL na credential by itself, and if na plain HTTP, that token go cross the network as cleartext.

Most times, you no need this plugin at all. Forward the port through SSH instead.

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

Then open http://127.0.0.1:3080 for your local browser. The harness still dey listen only on loopback, so nothing dey exposed. Because browsers treat 127.0.0.1 as secure origin, crypto.randomUUID() dey available and you no need polyfill. Na one command; no plugin and no new attack surface.

Install the plugin only when forwarding no go work, for example when phone for the same network must reach the UI. If you install am, bind am behind private network interface, keep firewall rule wey allow only that interface, and list the names wey you go use under trustedHosts for the web-runtime entry. For real multi-user access, dsh-passwords dey available. E add subuser permissions, hourly token and daily time quotas for each subuser, automatic TLS (transport layer security) certificates through Let's Encrypt, and encrypted audit log. Treat am like platform, no be ordinary plugin: e need ports 80 and 443, e ship with im own installer, and the documented quick path pipe shell script from the network straight into bash. Prefer npm install -g dsh-passwords, then dsh-passwords install, so the code go sit for disk where you fit read am before e run.

Plugin gut how you fit remove am cleanly

Uninstall get two steps, but people dey skip the second one.

dsh plugin --profile web remove dsh-budget
dsh plugin --profile web list

list no suppose show am again. Then open $DSH_HOME/profiles/web/cordis.patch.yml and delete any insert block wey still name that plugin, because na that entry dey load am into the tree. Restart the harness so e fit rebuild the tree; plugin wey don already load go remain loaded until you do this. Finally, remember say data dey survive code. $DSH_HOME/memory/memory.db and .dsh/rules.yaml go still remain after uninstall. Delete dem yourself if na removing the data you wan do.

What I read, and when

Every reference for here na a commit, no be branch, because main go don become different code by the time you read am. I read everything on 17 August 2026, and the harness itself dey for 0.1.0-rc.7 on npm that day. I check the defaults and behaviour wey I describe above again against the primary sources on 10 October 2026. At that time, the latest tag for npm na 0.2.0-rc.2.

Exact commits behind this shortlist
  • The community plugin list for f2918fb, 17 August 2026. I link am once intentionally. E na directory, and directory no be recommendation.
  • dsh-budget for 461d478, 17 August 2026. Apache 2.0. E declare dsh 0.1.0-rc.6, Node 22.19 or 24 and up.
  • dsh-permission-rules for b30b4fb, 17 August 2026. Apache 2.0. E declare dsh 0.1.0-rc.5 to 0.1.0-rc.6.
  • dsh-defend for 7ba3427, 17 August 2026. Apache 2.0. E declare dsh 0.1.0-rc.5 to 0.1.0-rc.6.
  • dsh-memory for def7c6a, 13 August 2026. MIT. SQLite build. E no get dsh compatibility field; na only peer ranges from ^0.1.0-rc.6.
  • dsh-web-lan-access for e27e909, 16 August 2026. MIT. E no get dsh compatibility field.

Check those pins again before you copy any command. For developer-preview ecosystem, version number wey get date beside am na the only kind wey get real meaning.

FAQ

DSH Harness plugins wey I suppose install first for VPS?

Install dsh-budget and dsh-permission-rules before anything else. Budget wey get overLimit: block go stop unattended run from spending all night, while .dsh/rules.yaml file go stop tool call wey you for never approve. Add dsh-defend once agent dey read anything from public web, and dsh-memory when you notice say you dey paste the same context into every session. Leave themes and status chips: dem add code wey dey run with your agent privileges, but dem no change wetin machine dey do.

Plugins for dsh get sandbox separate from harness?

No. Plugin dey load into the same Cordis tree as harness, for the same process, as the same operating system user, with the same model credentials and same working tree. Plugin wey tap tools/pre-execute fit see and block every tool call; one wey tap agent/pre-step fit see your messages. So read the source, check the license and the date of the last commit, then install by commit instead of branch so code no fit change under you.

dsh-budget go really stop agent, or e go only warn me?

E depend on overLimit. Default na alert, wey dey warn at warnRatio and continue spending. block dey reject further model calls once e reach cap, while /budget unblock <scope> dey remove the cap when you choose to continue. degrade dey block and show guidance wey name cheaper model from degradation map. One limit dey important: for the pinned commit 461d478, totals dey aggregate inside the running process, so restarting harness go reset dem, and restart loop go defeat daily cap. Current main dey preserve day and month buckets across restarts by default. Either way, keep spend limit for provider account as the real ceiling.

How I fit remove dsh plugin completely?

Run dsh plugin --profile web remove <package-name>, confirm with dsh plugin --profile web list, then open $DSH_HOME/profiles/web/cordis.patch.yml and delete any leftover insert block for that plugin, because na that entry dey load am. Restart harness so plugin tree fit rebuild. Data wey plugin write go remain for disk: $DSH_HOME/memory/memory.db and .dsh/rules.yaml both survive uninstall until you delete dem yourself.

E safe to expose dsh web UI over network?

No, not by itself. dsh web dey listen on 127.0.0.1:3080, while dsh-web-lan-access dey change that binding to 0.0.0.0. For the commit wey this document cite, its README talk say this one make agent reachable without authentication by anybody for the same network, with only settings.*, credentials.* and llm.discoverModels pinned to loopback. Current harness builds, wey dem check on 10 October 2026, dey authenticate browser session with launch token inside the printed URL and signed session cookie, but login surface go then expose for every interface, and plain HTTP URL go send that token as cleartext. Use SSH port forward, ssh -N -L 3080:127.0.0.1:3080 you@your-server, or put the port behind private network interface plus firewall rule, and keep TLS in front of anything wey people fit reach from outside.