Use OpenAI, Anthropic, or Any OpenAI-Compatible API with DeepSeek Harness
Add OpenAI, Anthropic, Bedrock, or any OpenAI-compatible endpoint as a custom model provider in DeepSeek Harness, with the exact settings.yaml YAML fields.
DeepSeek Harness (dsh) isn't limited to DeepSeek's own models. From Settings → Models, choose Add provider to pick a directory-listed provider like Anthropic or OpenAI, or Add a custom provider for any OpenAI-compatible endpoint — a self-hosted gateway, a company proxy, or another vendor entirely. This guide covers both paths, plus the settings.yaml fields you'll need to hand-edit for vision models and provider overrides.
Two ways to add a provider
dsh's Web UI exposes two distinct flows under Settings → Models:
- Add provider — pick from a built-in directory (Anthropic, OpenAI, and others). Endpoint, protocol, and model list are already baked in; you just supply credentials.
- Add a custom provider — for anything not in that directory. You define the endpoint yourself.
Adding a directory-listed provider
Choose Add provider, select the provider, and fill in the API key. For most directory providers that's the entire setup. A handful need provider-native auth instead of a plain key, because they authenticate differently than a bearer-token API call:
| Provider | Auth mechanism |
|---|---|
| Bedrock | AWS credentials |
| Vertex | Google Application Default Credentials + GCP project |
| Azure | API key plus an api-version field |
| Codex | OAuth flow, not a static key |
For anything on this list, filling in only the API key field won't be enough — you'll need to complete the provider's own auth flow from the same Settings page.
Adding a custom OpenAI-compatible provider
Choose Add a custom provider. You'll need to fill in:
- Provider ID — lowercase, and permanent. Changing it later is effectively deleting and recreating the provider, because request logs, session history, and credential references all key off this ID. Pick something stable up front.
- Display name — cosmetic, shown in the UI.
- Base URL — your endpoint's root, e.g.
https://gateway.example/v1. - API protocol — the wire format your endpoint speaks.
- Credentials — however your endpoint authenticates.
- At least one model — either fetched automatically or typed by hand.
If your endpoint implements the OpenAI-compatible GET /models route, click Fetch available models to pull the model list automatically instead of typing IDs by hand. If it doesn't implement that route, the button will fail (often with a 401 or a generic error) and you'll need to add models manually.
Editing settings.yaml directly for finer control
The Web UI form doesn't expose every knob — most notably, there's no checkbox for "this model accepts image input." For that, and for anything else you want scripted or version-controlled, edit $DSH_HOME/settings.yaml directly.
Declaring a custom provider with a vision-capable model
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] # models without this default to text-only
Any model entry without an explicit input field is treated as text-only by default — send it an attached image and dsh rejects the attachment before it's ever sent to the API. This is the setting that fixes the "image gets rejected" error covered in our API key setup guide.
Overriding a directory provider's model capabilities
Directory providers (added via Add provider) don't expose a models: list to edit directly, since it's baked into the built-in directory entry. To change how one of their models is treated, use modelOverrides instead:
llm-pi-ai:
providers:
anthropic:
modelOverrides:
claude-sonnet-4-5:
input: [text]
A hard limit worth knowing
DeepSeek's own chat-completions route is documented as text-only — there's no configuration, override, or workaround that lets DeepSeek's native models accept image input through this route. If your workflow needs vision, route those specific requests to a different provider (Anthropic, OpenAI, or a custom vision-capable endpoint) rather than trying to force it through DeepSeek's own API.
Why the Provider ID choice matters more than it looks
It's easy to breeze past the Provider ID field during setup, but it's the one decision in this whole flow you can't casually revisit. Because request logs, session history, and credential references are all keyed to that ID internally, renaming it later isn't a rename at all — it's deleting the old provider and standing up a new one, which orphans any history tied to the old ID. A few practical guidelines:
- Use something that describes the endpoint, not a specific model —
internal-gatewayages better thangpt4-proxyif you later point the same gateway at a different model. - Avoid encoding a date or version number into the ID unless you genuinely intend to keep multiple side-by-side providers for A/B comparisons.
- If you're setting this up for a team (see Running DeepSeek Harness in a Team), agree on the ID convention before anyone starts creating providers, since IDs created independently by different people won't automatically merge.
Model configuration is shared, not per-profile
Like credentials, everything you configure here — directory providers, custom providers, modelOverrides — lives in $DSH_HOME/settings.yaml, which is shared across every profile on the machine, not scoped to one. Set up a custom provider once and it's available whether you're running the web profile interactively or a headless profile in CI. Only the profile's own cordis.patch.yml (which plugins/bundles are active) is profile-scoped; model routing is not.
Common errors when configuring a custom provider
| Error | Fix |
|---|---|
MISSING_CREDENTIAL | The provider has no resolved key/credential — set it in Settings → Models or via environment variable |
UNKNOWN_MODEL | The model ID you selected isn't in any configured provider's model list — add it, or pick one that's already there |
Fetch available models returns 401 | Check the key; this button only works against endpoints implementing OpenAI-compatible GET /models |
| Attached image rejected pre-send | Model lacks input: [text, image] — see the YAML above |
| Requesting an image response from a DeepSeek-native model | Not supported — DeepSeek's chat-completions route is text-only regardless of configuration |
FAQ
Can I change a custom provider's Provider ID after creating it?
No — it's designed as permanent. Session history, request logs, and credential references all key off the ID, so changing it is equivalent to deleting the provider and starting over. Choose a stable, descriptive ID the first time.
What happens if my endpoint doesn't support GET /models?
The Fetch available models button will fail. You'll need to add each model ID manually in the custom provider form instead of relying on auto-discovery.
Can DeepSeek's own models accept image input if I configure it right?
No. DeepSeek's chat-completions route is documented as text-only; this is a limitation of the route itself, not something input: [text, image] or any other setting can override. Use a different provider for vision workloads.
Do directory providers like Anthropic or OpenAI need custom-provider setup?
No — use Add provider instead of Add a custom provider. Directory providers already have their endpoint, protocol, and model list built in; you only supply credentials (and, for a few like Bedrock/Vertex/Azure/Codex, provider-native auth rather than a plain API key).
Where do custom provider settings actually get saved?
Non-sensitive fields (base URL, protocol, model list) go to $DSH_HOME/settings.yaml; credentials go to the separate $DSH_HOME/.credentials.yaml. See Setting Up Your DeepSeek API Key and Models for the full breakdown of where each file lives.
Next steps
- Setting Up Your DeepSeek API Key and Models — credential storage and resolution order.
- DeepSeek Harness Quickstart — the full install-to-first-session path.
- Compare model routing approaches in DeepSeek Harness vs Claude Code.
- Browse provider and model-management plugins in Models & Providers.