DeepSeek Harness (dsh) Setup with QCode

Connect DeepSeek Harness (dsh) 0.2.2-rc.1 to QCode.cc with Custom model API: OpenAI Chat Completions for GPT and Chinese models, Anthropic Messages for Claude.

Updated 2026-11-10

Need an API key? Sign up →Endpoints & base URLs →

On This Page

Last verified: 2026-11-09 · 📄 Per official docs (DeepSeek Harness 0.2.2-rc.1, published on npm and GitHub on 2026-11-04; the repository docs were read on 2026-11-09)

At a glance

Item Details
What it is DeepSeek Harness (dsh) is an open-source agent harness developed by DeepSeek AI, with a Web UI started by dsh web
Models you can use Claude ✅ (Anthropic Messages provider) · GPT ✅ · GLM / Kimi / DeepSeek / Qwen ✅ (OpenAI Chat Completions provider) · Gemini ❌ (QCode does not offer Gemini models for now)
Protocol & Base URL OpenAI Chat Completions: https://api.qcode.cc/openai/v1 · Anthropic Messages: https://api.qcode.cc/api
Where to configure Settings → Models → Add model provider → Custom model API
Written to $DSH_HOME/profiles/<profile>/cordis.patch.yml; the key goes to $DSH_HOME/.credentials.yaml
Official docs Configure models · repository

DeepSeek Harness is in developer preview. The official README says: "THERE WILL BE COMPATIBILITY-BREAKING CHANGES." Check the version you run against this page.

Which protocol

The API protocol of a custom provider must be the one the gateway speaks. The picker offers three: OpenAI Chat Completions, OpenAI Responses and Anthropic Messages, stored as openai-completions, openai-responses and anthropic-messages. A provider speaks one protocol, so a gateway that serves two needs two providers.

QCode serves Claude only on the Anthropic protocol and GPT only on the OpenAI protocols; the four Chinese families work on both. See Endpoints & API Paths. That gives two providers:

Provider API protocol Base URL Model IDs (examples)
qcode OpenAI Chat Completions (openai-completions) https://api.qcode.cc/openai/v1 gpt-6-sol, deepseek-v4-pro, glm-5.3, kimi-k3, qwen3.8-max
qcode-claude Anthropic Messages (anthropic-messages) https://api.qcode.cc/api claude-sonnet-5, claude-opus-5

The provider IDs are names you choose. Use the model IDs listed on qcode.cc/models, character for character; the Chinese ids are also listed in Chinese Models. Do not add a trailing / to a base URL, and do not put claude-… IDs behind the OpenAI base URL.

Install

DeepSeek Harness needs Node.js 24.9 or newer (the npm package declares node >=24.9.0, and the v0.2.2-rc.1 release notes say: "Raise the minimum supported Node.js version to 24.9."). Install Node.js, then run:

npx @deepseek-ai/dsh web

The command starts the Web UI at http://127.0.0.1:3080 by default and opens it in the default browser for a local launch. An SSH launch only prints the host URL. Pass --no-open to run the server without opening a browser.

To run from a repository checkout instead:

git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm run build
pnpm dsh web

$DSH_HOME is the harness data root; it defaults to ~/.dsh unless you set the DSH_HOME environment variable. Review the official safety notice before running the project.

Configure

Model changes take effect on the next request without restarting the server.

  1. Open the Web UI, then Settings → Models, and choose Add model provider.
  2. Switch the card to Custom model API. It is meant for a relay, a company gateway, a self-hosted server, or any provider absent from the installed catalog.
  3. Fill in the form for the first provider:

  4. Provider ID: qcode (lowercase; it is permanent, so pick it deliberately)

  5. Display name: QCode (optional)
  6. Base URL: https://api.qcode.cc/openai/v1
  7. API protocol: OpenAI Chat Completions
  8. API key: your QCode key (starts with cr_)
  9. In the form's Models list (the official guide calls it the model catalog), choose Add model and enter each model ID, for example deepseek-v4-pro and gpt-6-sol. Fetch available models asks the endpoint which models it serves; it is a convenience, and the official guide says that when it fails or lists nothing you add the model ids by hand and they work just the same. On QCode the OpenAI endpoint lists the GPT models, so add the Chinese IDs by hand.
  10. Choose Create provider. Then repeat with Provider ID qcode-claude, Display name QCode Claude, Base URL https://api.qcode.cc/api, API protocol Anthropic Messages, the same key and the model claude-sonnet-5, and choose Create provider again.
  11. Open the model picker and select a model. Selecting a model also makes it the default for new sessions.

Keys are write-only: after saving, the page receives a redacted descriptor, never the literal secret. The key is stored in $DSH_HOME/.credentials.yaml, while settings retain only its credential reference.

What the page writes

For reference, the same providers in $DSH_HOME/profiles/<profile>/cordis.patch.yml look like this. For the standard dsh web launch <profile> is web, so the path is $DSH_HOME/profiles/web/cordis.patch.yml. The page writes this document for you; edit it by hand only if you need a setting the form does not offer.

- id: llm-pi-ai
  config:
    providers:
      qcode:
        displayName: QCode
        apiKeyEnv: QCODE_API_KEY
        api: openai-completions
        baseURL: https://api.qcode.cc/openai/v1
        models:

          - id: deepseek-v4-pro
          - id: gpt-6-sol
      qcode-claude:
        displayName: QCode Claude
        apiKeyEnv: QCODE_CLAUDE_API_KEY
        api: anthropic-messages
        baseURL: https://api.qcode.cc/api
        models:

          - id: claude-sonnet-5

apiKeyEnv is a credential reference: the page derives it from the Provider ID (qcode → QCODE_API_KEY, qcode-claude → QCODE_CLAUDE_API_KEY) and stores the key you typed under that name. The official troubleshooting entry for MISSING_CREDENTIAL says: store the provider key through the Models page or supply the referenced environment variable. A Cordis config override replaces the complete entry config, so keep your other providers when you edit an existing override.

Verify

  1. Select a model you added in the model picker and send a short message such as ping.
  2. Open probe.qcode.cc, enter your QCode key and check that the request appears with that model.
  3. To test the key and path without dsh:
KEY="cr_your_key"

# OpenAI Chat Completions provider
curl -sS https://api.qcode.cc/openai/v1/chat/completions \
  -H "Authorization: Bearer $KEY" \
  -H "content-type: application/json" \
  -d '{"model":"deepseek-v4-pro","max_tokens":32,"messages":[{"role":"user","content":"ping"}]}'

# Anthropic Messages provider
curl -sS https://api.qcode.cc/api/v1/messages \
  -H "x-api-key: $KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model":"claude-sonnet-5","max_tokens":32,"messages":[{"role":"user","content":"ping"}]}'

Troubleshooting

Symptom Cause Fix
MISSING_CREDENTIAL No key stored, or the referenced environment variable is empty Store the key through Settings → Models, or export the variable named in apiKeyEnv before starting dsh
UNKNOWN_MODEL The selected model is not in the provider's list Select a configured model or add the model ID to the provider
Fetching available models returns 401 Wrong key Check the key; model discovery calls the OpenAI-compatible GET /models endpoint
Fetching lists nothing or fails The endpoint's listing is in a format discovery does not read Enter the model IDs by hand
model_not_available_on_endpoint A claude-… ID was added to the OpenAI Chat Completions provider Put Claude IDs in the Anthropic Messages provider with Base URL https://api.qcode.cc/api
404 Trailing / or wrong path prefix in a base URL Compare with Endpoints & API Paths
The gateway refuses every request although the key and URL are right Its request shape differs from OpenAI's Official advice: start with compat.supportsDeveloperRole: false and compat.maxTokensField: max_tokens on the route
Only reasoning models fail pi-ai sends their system prompt as the developer role Set compat.supportsDeveloperRole: false
The Effort menu does not appear for a model you entered by hand The model declares no reasoning levels Turn on Reasoning levels in the model's Model options

Known limitations

  • Developer preview: configuration fields and behaviour can change between releases; this page was checked against 0.2.2-rc.1, the version npm tags as latest on 2026-11-09.
  • The form has no field for the compat switches; set them on the route in cordis.patch.yml as described in the official guide.
  • A model you enter by hand declares no reasoning levels until you add them, and starts as text-only until you select Image in its Model options (see the official guide's sections on image input and reasoning effort).

Get started with QCode

One API key for Claude Code, Codex and more — billed per token, per-model prices on qcode.cc/models

Enterprise →