How to use DeepSeek Harness (dsh) with a custom API: FastMetal setup

The short version
- DeepSeek Harness (
dsh) is DeepSeek's open-source coding agent, MIT licensed and in developer preview. It reads and edits files, runs shell commands and keeps a plan. - It talks to any OpenAI-compatible endpoint. Add FastMetal as a Custom model API with base URL
https://api.fastmetal.ai/v1and protocol OpenAI Chat Completions. - Turn thinking on through Reasoning levels (
high: high), which sendsreasoning_effort. Leave dsh's DeepSeek thinking format off: on FastMetal it gets you answers with no thinking. - We tested it with DeepSeek V4 Pro and DeepSeek V4.1 Flash. Both wrote and ran tests, edited the code and confirmed the fix.
Everything below was checked with dsh 0.2.2-rc.1. DeepSeek warns that the harness will change in breaking ways while it is in preview, so check the version if a field name has moved.
What you need
- Node.js 24.9 or newer. The
@deepseek-ai/dshpackage requires it. - A FastMetal API key, from the API keys page.
Start the Web UI
No install step. From any folder:
npx @deepseek-ai/dsh web
This starts the Web UI at http://127.0.0.1:3080 and opens it in your browser. Settings live in ~/.dsh.
Add FastMetal as a Custom model API
Go to Settings, then Models, choose Add model provider, and switch the card to Custom model API.
| Field | Value |
|---|---|
| Provider ID | fastmetal |
| Base URL | https://api.fastmetal.ai/v1 |
| API protocol | OpenAI Chat Completions |
| API key | your FastMetal key |
The Provider ID can't be renamed later, since sessions and defaults refer to it, so pick it carefully.
Under Model catalog, Fetch available models lists everything your key can use. Tick what you want, or type the ids:
deepseek-v4-pro
deepseek-v4.1-flash
Turn on thinking
For each model, open Model options and enable Reasoning levels. Leave off empty and set high to the API value high. dsh then sends reasoning_effort, and the model thinks before it acts.
dsh also has a switch that sends DeepSeek's own thinking: {"type": "enabled"} field instead. Skip it for this provider. We sent both shapes to FastMetal's DeepSeek V4.1 Flash: reasoning_effort: "high" came back with reasoning tokens, and thinking came back with none.
Or write the config file
The Web UI saves to ~/.dsh/profiles/web/cordis.patch.yml. Here is the same setup written by hand. apiKeyEnv holds the name of an environment variable, so the key never lands in the file.
- id: llm-pi-ai
config:
providers:
fastmetal:
displayName: FastMetal
apiKeyEnv: FASTMETAL_API_KEY
api: openai-completions
baseURL: https://api.fastmetal.ai/v1
reasoning: high
models:
- id: deepseek-v4-pro
name: DeepSeek V4 Pro
reasoningEfforts:
off:
high: high
- id: deepseek-v4.1-flash
name: DeepSeek V4.1 Flash
reasoningEfforts:
off:
high: high
- id: agent-default-model
config:
provider: fastmetal
model: deepseek-v4-pro
Put the same block in ~/.dsh/profiles/headless/cordis.patch.yml and dsh will take one task from the command line, do it, and exit:
export FASTMETAL_API_KEY="your-api-key"
npx @deepseek-ai/dsh headless "run the tests and fix what fails"
One catch: an entry in this file replaces that plugin's whole config. If you use other providers too, list them all under the same llm-pi-ai entry.
What happened when we ran it
We gave the headless profile a small Python file with two bugs (mul() added instead of multiplying, sub() had its operands reversed) and asked it to write a test, run it, fix the code and run the test again.
DeepSeek V4 Pro with thinking on:
- Read the file and named both bugs.
- Wrote a test file with plain asserts.
- Ran it with
python, hit a syntax error, worked out thatpythonon the machine was 2.7, and re-ran withpython3. - Saw the tests fail, then made two edits.
- Re-ran the tests and reported them all passing.
That was 10 tool calls in about 48 seconds. An agent resends the whole conversation on every call, and prompt caching is what keeps that affordable: on the last call, 7,680 of 7,951 input tokens were cache reads, which bill at the cached-input rate.
DeepSeek V4.1 Flash took a smaller job (an add() that subtracted), fixed it and verified the result in about 11 seconds.
Troubleshooting
dsh won't start
Check node --version. Anything below 24.9 is unsupported.
Model not found
Model ids must match the gateway exactly. A model page's URL swaps dots for dashes, so it is not the id. List the ids your key can use:
curl https://api.fastmetal.ai/v1/models \
-H "Authorization: Bearer your-api-key"
No thinking in the output
You probably have compat.thinkingFormat: deepseek set. Remove it and use Reasoning levels as above.
FAQ
Is DeepSeek Harness an official DeepSeek project?
Yes. It is published by DeepSeek under the deepseek-ai GitHub organization, MIT licensed, as @deepseek-ai/dsh on npm. It is in developer preview.
Can I use models other than DeepSeek?
Yes. Any FastMetal model that supports tool calling can go under the same provider, including GLM, Kimi, Qwen and Claude. How well a model works as an agent varies, so try a small task first. The router name auto can't be an agent's model.
How is it billed?
Per token, per million tokens, from your prepaid balance, like every other FastMetal API call. Agent work is mostly input tokens. See the DeepSeek V4 Pro model page and pricing for current rates.
Does it work with the Anthropic-compatible endpoint instead?
dsh also offers an Anthropic Messages protocol, and FastMetal serves one, but we tested the OpenAI Chat Completions setup above. That is the one we recommend.
Next steps
The full reference is the DeepSeek Harness guide. Setups for Claude Code, Cursor, OpenCode and others are in the agent guides.