Run npm install -g @deepseek-ai/dsh, then dsh web. The web profile initialises itself from a shipped template and serves the browser UI at http://127.0.0.1:3080, where you add a model provider under Settings.
DeepSeek Harness ships as a Node package called @deepseek-ai/dsh. There is no installer, no
container, and no account gate on the software itself — it is MIT-licensed and the whole install is
one command. What takes the extra five minutes is the part after the install: pointing it at a model
and understanding where it put its files.
Prerequisites
You need Node.js. dsh is distributed on npm and executed by Node, so a missing or ancient Node is
the single most common reason the install appears to "not work".
node -vIf that errors, install Node from nodejs.org or via a version manager
(nvm, fnm, volta) before continuing. On macOS, Homebrew's brew install node is fine.
Option 1 — global install (recommended)
npm install -g @deepseek-ai/dshThe -g flag puts the dsh binary on your PATH so you can launch it from any project directory
rather than per-repo. Confirm it landed:
dsh --helpThat prints the launcher's help — the flags the launcher itself understands, before it hands control to an app. This distinction matters later.
Option 2 — no install at all
npx @deepseek-ai/dsh webnpx downloads and runs it in one shot. Use this to evaluate the harness without committing a
global package. The tradeoff is that every invocation re-resolves the package, so it is slower to
start and pins nothing.
Option 3 — from source
Use this if you intend to modify the harness itself or want to track master rather than a
published release.
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm run build
pnpm dsh webNote this path uses pnpm, not npm. The repository is a pnpm workspace and installing it with npm will produce a broken node_modules layout.
Boot the browser UI
dsh webdsh web is exactly equivalent to dsh --profile web. Both boot the profile stored at
$DSH_HOME/profiles/web, which is created from a shipped template the first time you use it — you
do not need to scaffold anything by hand.
The UI is served at:
http://127.0.0.1:3080
If port 3080 is already taken, pass a different one. Because --port is an app flag rather than
a launcher flag, argument order matters:
dsh --profile web --port 3100The launcher consumes its own flags first; the first token it does not recognise begins the app's argument list.
Add a model provider
The harness is a runtime, not a model. Until you give it a credential it has nothing to talk to.
In the web UI, open Settings → Add provider, choose a provider from the catalog — DeepSeek,
Anthropic, OpenAI and others — and paste its API key. Keys are written to
$DSH_HOME/.credentials.yaml, kept separate from $DSH_HOME/settings.yaml so you can version or
share the latter without leaking the former.
For an OpenAI-compatible gateway or a self-hosted endpoint, register a custom provider instead. Custom providers read their credential from an environment variable you name yourself:
llm-pi-ai:
providers:
my-gateway:
apiKeyEnv: GATEWAY_API_KEY
api: openai-completions
baseURL: https://gateway.example/v1
models:
- id: vision-preview
input: [text, image]Two things to know about custom providers. The apiKeyEnv value is a variable name, not the key
itself — export GATEWAY_API_KEY in the shell you launch dsh from. And the provider ID
(my-gateway above) is permanent: renaming means creating a new provider and deleting the old one.
Verify the install
The most useful post-install command is not --version, it is:
dsh --profile web --dump-configThis prints the actual plugin tree the profile boots — every configuration row that patches can target. If something behaves unexpectedly later, this output is where you look first, because it shows the composed result of all patch layers rather than what you think you configured.
Its sibling, --dump-default-config, prints the composed tree without initialising the profile.
Use it to see what a profile would look like from scratch, uncontaminated by your local edits.
What you now have
At this point you have a working harness with:
- the
dshlauncher on your PATH, - a
webprofile under$DSH_HOME/profiles/web, - a credential in
$DSH_HOME/.credentials.yaml, - and a browser agent at
127.0.0.1:3080.
The next thing worth understanding is that the harness ships four distinct agent modes, and the one you get by default is not always the one you want.
Common install problems
dsh: command not found after a global install. npm's global bin directory is not on your PATH.
Run npm bin -g and add that directory to your shell profile.
EACCES permission errors during npm install -g. Your global npm prefix is in a
root-owned location. Either reconfigure the prefix to a user-owned directory or use a Node version
manager, which sidesteps the problem entirely. Do not fix this with sudo npm install -g — it
leaves root-owned files in your npm cache that cause harder failures later.
The UI loads but every request fails. You have a profile but no working credential. Re-check
Settings, and for custom providers confirm the variable named by apiKeyEnv is actually exported in
the shell that launched dsh — not just in your .zshrc, which an already-running process will not
have re-read.
Frequently asked
Do I need to install dsh globally?
No. npx @deepseek-ai/dsh web works without a global install and is the fastest way to try it. Install globally when you want the dsh command available in every project directory.
Where does dsh store its files?
In the harness home directory, $DSH_HOME. Profiles live under $DSH_HOME/profiles/<name>, settings in $DSH_HOME/settings.yaml, and credentials in $DSH_HOME/.credentials.yaml.
Can I run dsh without a DeepSeek account?
Yes. The provider catalog includes other vendors such as Anthropic and OpenAI, and you can register a fully custom OpenAI-compatible endpoint with its own base URL.
How do I update dsh?
Re-run the global install to pull the newest published version. Because this is a v0.1 developer preview with breaking changes between releases, read the changelog before upgrading a profile you rely on.