DeepSeek Harness

Point DeepSeek Harness (dsh) at HopsAPI - install, configure the provider, set the API key, and verify.

DeepSeek Harness (command name dsh) is DeepSeek's open-source agent harness, built on an "everything is a plugin" architecture - models, tools, skills, sessions, sandboxes, and the UI are all replaceable plugins. It calls DeepSeek's own API by default; point its model plugin at HopsAPI and the same harness reaches every model in the HopsAPI catalog.

dsh is in developer preview and its maintainers state that breaking changes are expected; field names may change between versions.

Before you start

  • A HopsAPI account and an API key (get one ↗)
  • Node.js installed (dsh ships through npm)

Configuration

1. Install dsh

The package is @deepseek-ai/dsh, which provides the dsh command.

npm install -g pnpm          # skip if already installed
pnpm add -g @deepseek-ai/dsh
dsh --version

pnpm's global bin directory must be on PATH - pnpm bin -g prints the exact location. During install, pnpm may report Ignored build scripts: node-pty, koffi …; that is safe to ignore, since both ship prebuilt binaries for every platform.

To try it without installing globally:

npx @deepseek-ai/dsh web

2. Configure a custom provider

dsh keeps its configuration under $DSH_HOME - ~/.dsh on macOS and Linux, %USERPROFILE%\.dsh on Windows. Use either method below.

dsh web

The terminal prints a tokenized URL (http://127.0.0.1:3080 by default) and opens the browser. Click Settings in the lower left.

dsh's web interface, with New Session and the workspace list on the left, the session composer in the middle, and a red box around the Settings entry in the lower left

Switch to Models on the left. The built-in DeepSeek (deepseek-official) entry talks to DeepSeek directly, so routing through HopsAPI needs a new custom provider - click Add a custom provider.

dsh's Models settings panel, with red circles around the Models nav item on the left and the "+ Add a custom provider" button, listing the built-in DeepSeek provider and an already-created API custom provider

Fill in the form:

FieldValue
Provider IDA lowercase identifier, for example gateway-codex
Display nameLeave blank to follow the Provider ID
Base URLhttps://hopsapi.com/v1
API protocolopenai-responses or openai-completions - see below
API keyYour HopsAPI API key

dsh's Custom provider form with red boxes around Provider ID set to api, Base URL https://api.com/v1, API protocol openai-responses, and the filled-in API key; the Models list below is empty and notes that unlisted IDs can still be sent directly

Click Fetch available models - dsh calls GET /v1/models to pull the models this key is authorized for. Tick the ones you want and click Add selected.

dsh's "Choose models to add" dialog listing %%BRAND%% models such as gpt-5.5, gpt-5.6, gpt-6-astra, grok-4.20, and kimi-k2.5, with the gpt-5.6 family and gpt-6-astra ticked, and Cancel and Add selected buttons at the bottom

With the model list populated, click Create provider.

The lower half of dsh's custom provider form, showing gpt-5.6, gpt-5.6-luna, gpt-5.6-sol, gpt-5.6-terra, and gpt-6-astra in the Models list, with an arrow pointing at the Create provider button

Pick the API protocol to match the models you want. The screenshots use openai-responses with GPT-family models, which do expose a Responses endpoint. Only some HopsAPI models support Responses (check responses_endpoint in GET /v1/models); for the rest, use openai-completions. Claude has its own native protocol - see Add a second provider for Claude. See Protocols & endpoints.

A provider maps to exactly one protocol, so create several if you need to - for example gateway-codex on openai-responses for GPT models and gateway-claude on anthropic-messages for Claude, then switch between their groups in the model picker.

The API key is written to $DSH_HOME/.credentials.yaml (readable only by your user) and the provider config to $DSH_HOME/settings.yaml. Both take effect immediately - no restart needed.

For model IDs, use the bare ID returned by GET /v1/models (such as gpt-5.6-sol or claude-opus-5) with no channel prefix - the gateway routes it through the channel authorized for that key. Leaving the model list empty is fine too: the picker then shows nothing, but unlisted IDs can still be sent directly. See List models.

3. Set the API key

apiKeyEnv names a credential. dsh resolves it in this order: environment variables at launch, $DSH_HOME/.credentials.yaml, a project-level .env, then a home-directory .env. If you configured it through the Web UI, the key is already in the credentials file and you can skip this step.

Add to ~/.zshrc:

export AI_GATEWAY_API_KEY=sk-YOUR_KEY

4. Verify

dsh --profile headless "Reply with exactly one word: ready. Do not call any tools."

If it prints ready, the model layer is reaching HopsAPI.

In the web interface, the model picker in the lower right of the composer gains a group for your provider. Pick one of its models and start chatting.

dsh's model picker expanded, with DeepSeek's built-in models above and a red circle around the API group containing gpt-5.6, gpt-5.6-luna, gpt-5.6-sol, gpt-5.6-terra, and gpt-6-astra, with gpt-5.6-sol selected

dsh's chat view where a "hello" message gets a reply, with usage of 8.9K tokens and a 13s runtime shown beneath it, and gpt-5.6-sol labelled in the lower right of the composer

For day-to-day use, launch the web UI with dsh web, or run a single task and exit with dsh --profile headless "run the tests".

Add a second provider for Claude

On HopsAPI, Claude speaks the native Anthropic protocol, which is a different thing from the OpenAI protocol used above. A dsh provider binds to exactly one protocol, so just create a second custom provider - both can share the same API key.

FieldValue
Provider IDFor example gateway-claude
Base URLhttps://hopsapi.com
API protocolanthropic-messages
API keyThe same HopsAPI API key

This Base URL has no /v1. The native Anthropic endpoint is https://hopsapi.com, unlike the https://hopsapi.com/v1 used for the OpenAI protocol - getting this wrong breaks the connection. See base URLs.

dsh's Custom provider form with red boxes around Provider ID set to api, Base URL https://api.com, API protocol anthropic-messages, and the filled-in API key; the API provider is already listed above

Click Fetch available models, tick the Claude models, then click Add selected.

"Choose models to add" dialog listing claude-fable-5, claude-fable-5-1, claude-opus-4-6, claude-opus-4-7, claude-opus-4-8, claude-opus-5, claude-sonnet-4-6, and claude-sonnet-5, all ticked

With the model list populated, click Create provider.

The lower half of dsh's custom provider form showing the eight Claude models in the list, with an arrow pointing at the Create provider button

Both groups then appear in the model picker, ready to switch between.

dsh's model picker expanded, showing the gateway-codex and gateway-claude groups, with a red circle around the eight Claude models under gateway-claude and claude-sonnet-5 selected

dsh's chat view where a "hello" message is answered by claude-sonnet-5, with usage of 16.9K tokens and a 14s runtime shown beneath it, and claude-sonnet-5 labelled in the lower right of the composer

Platform differences

The configuration itself is identical on all three platforms; only paths and the way you persist environment variables differ.

macOSLinuxWindows
Config root $DSH_HOME~/.dsh~/.dsh%USERPROFILE%\.dsh
API key persistence~/.zshrc~/.bashrcsetx
Shell tool sandboxBashBashPowerShell (Bash sandbox disabled)

Troubleshooting

TIMEOUT: Request timed out.

dsh is a Node application and does not read http_proxy / all_proxy, so a working system proxy does not mean dsh can connect. Confirm that https://hopsapi.com is reachable directly from the environment running dsh.

MISSING_CREDENTIAL

The credential named by apiKeyEnv resolved to nothing. Check that the environment variable is set in the same terminal that launched dsh, or that the key is stored in $DSH_HOME/.credentials.yaml.

The other cause is picking the wrong model: the built-in deepseek-official models stay listed in the picker even with no key configured, and their names look much like your custom route's.

Empty reply with no error

api is set to openai-responses but the model has no Responses endpoint. Switch the provider's api to openai-completions.

INVALID_REQUEST / 400 endpoint_not_supported

The payload says does not support the /v1/responses endpoint. Again, switch api to openai-completions.

401 or 402

401 usually means a wrong, disabled, or whitespace-padded key. 402 means the balance is insufficient or the key reached its spend limit. See Errors.

Plugin fails to load, or a duplicate route is reported

The same route name was registered twice. Check whether both $DSH_HOME/cordis.patch.yml and settings.yaml define the same provider.

Advanced: the patch layer

settings.yaml holds runtime user settings and applies from the next request onward. To change plugin assembly itself - replacing or disabling a plugin - use the patch layer at $DSH_HOME/cordis.patch.yml:

- id: llm-pi-ai
  config:
    providers:
      gateway-codex:
        apiKeyEnv: AI_GATEWAY_API_KEY
        api: openai-responses
        baseURL: https://hopsapi.com/v1
- id: agent-default-model
  config:
    provider: gateway-codex
    model: gpt-5.6-sol

dsh web --dump-config prints the assembled plugin tree so you can confirm the configuration took effect.

See List models or the console's Pricing page for the full catalog. Since dsh is agent-oriented, prefer chat models with tool-calling support.

On this page

On this page