DeepSeek Harness Setup Guide: Profiles, Config Layers, and Models
Configure DeepSeek Harness like a pro: profile bundles, cordis.patch.yml layering, $DSH_HOME, and settings.yaml model providers.
How Configuration Is Composed
The core idea of dsh setup is 'compose with configuration': every capability is a plugin, and profiles are just ordered lists of plugin bundles patched by a few YAML layers — you never edit the framework source to change behavior[1].
A profile directory contains two files: package.json (whose dsh.profile manifest lists an ordered bundles array) and cordis.patch.yml (the user patch layer for that profile). The web and headless profiles are auto-initialized on first use; other profiles are created with dsh plugin[2].
# list and inspect your profile
dsh --dump-default-config # composed config without launching
dsh --dump-config # current profile's composed config
dsh --help # launcher flags (app args go after them)Profiles and Bundles
Bundles are named groups of plugins. The default web profile bundles the Standard coding agent: file editing, shell, file and web search, skills, planning, goals, subagents, workflows, and the Web UI[1][2].
- web profile = Standard agent + Web UI (127.0.0.1:3080)
- headless profile = one-shot CLI sessions that print the final answer
- Code / Minimal / Creator are other preset compositions of the same plugin system[1]
- Custom profiles: create with dsh plugin --profile <name> <pnpm args>
You can add, remove, or reorder bundles — that is what 'compose with configuration' means[1].
The Patch Layering Order
When multiple layers define the same setting, the last one wins. The order is[2]:
This layering is what lets you keep a clean global config in $DSH_HOME while overriding per-project behavior in a profile, and per-run behavior with --patch. $DSH_HOME defaults to ~/.config/dsh on Linux, ~/Library/Application Support/dsh on macOS, and the equivalent on Windows.
1. bundle patches (in bundles[] order)
2. profile's cordis.patch.yml
3. $DSH_HOME/cordis.patch.yml (global, applies to all profiles)
4. --patch overlay flags (CLI, highest priority)Configure Model Providers (settings.yaml)
Model providers live in $DSH_HOME/settings.yaml under the llm-pi-ai section. The canonical example from the official docs[3]:
The input field declares the model's modalities (text/image); hand-entered models default to text-only. defaultInput acts as a fallback, and directory providers can be adjusted with modelOverrides. The related packages are dsh-llm-pi-ai (any-model adapter) and dsh-llm-deepseek (DeepSeek-specific)[3].
Model changes take effect on the next request — no restart needed[3].
llm-pi-ai:
providers:
my-gateway:
apiKeyEnv: GATEWAY_API_KEY
api: openai-completions
baseURL: https://gateway.example/v1
models:
- id: legacy-chat
- id: vision-preview
input: [text, image]Credentials
API keys are stored in $DSH_HOME/.credentials.yaml and are write-only from the UI: once stored, the UI shows only redacted descriptions. To change a key, use the Models page in the Web UI rather than hand-editing the credentials file[3].
- DeepSeek native: Settings → Models → enter your DeepSeek API key
- Directory providers (Anthropic, OpenAI, etc.): Add provider → select → enter key
- Custom provider: Provider ID (permanent, lowercase) + baseURL + API protocol + credential + models
- Special auth: Bedrock (AWS creds + region), Vertex (ADC project), Azure (api-version), Codex (OAuth) need more than an API key[3]
You can also point at an environment variable via apiKeyEnv (as in the settings.yaml example), which keeps secrets out of config files.
Inspect the Result
Before starting a session, dump the composed config to confirm your patches applied and the right models are visible[2]:
If a session then fails with MISSING_CREDENTIAL or UNKNOWN_MODEL, check the troubleshooting table in the use-any-model guide. For the full plugin install story (markets, bundles, safety), read the plugin ecosystem guide.
dsh --dump-config # inspect the final config tree
# then launch:
dsh --profile web # or: dsh web