OpenCode on DeepSeek Harness
Run free OpenCode models — Zen (muse-spark-1.3-contributor-free, space-bunny-free) and Go (deepseek-v4.1-flash) — inside DeepSeek Harness without 403 FreeTierError or 400 MissingSessionID errors.
Why this exists: OpenCode's gateways only serve requests carrying a valid x-opencode-session, and the Zen gateway additionally demands CLI origin proof (User-Agent, client headers, ses_… IDs) plus read/bash tool definitions on free-tier calls. DeepSeek Harness strips the user agent, uses UUID session IDs the gateways reject, and can send tool-less requests — so calls fail. This plugin restores what's needed at the network layer, only for OpenCode traffic (opencode and opencode-go routes, zen/v1 and zen/go/v1 URLs). Everything else (DeepSeek, OpenAI, GitHub, tools) passes through byte-for-byte untouched.
Install
Recommended — from npm:
dsh plugin --profile web add @viztor/dsh-opencode
Or declare it in your profile's package.json:
{
"dependencies": {
"@viztor/dsh-opencode": "^0.3.0"
},
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app",
"@viztor/dsh-opencode"
]
}
}
}
Then run pnpm install in your profile directory.
Configure (no YAML needed)
Open DSH Web → Settings → Plugins → OpenCode Integration, flip toggles, hit Save:
| Setting | Default | What it does |
|---|
| Inject User-Agent | on | Restores the OpenCode CLI User-Agent DSH strips |
| User-Agent Override | empty | Custom string instead of the canonical CLI one |
| Inject Origin Headers | on | Adds x-opencode-client: cli + x-opencode-project: global |
| Inject Core Tools | on | Adds fallback read/bash schemas to free-tier /responses calls |
| Providers | opencode, opencode-go | Which route IDs get the treatment |
The Defaults above live in code (resolveConfig in src/index.ts — e.g. DEFAULT_PROVIDERS, toggles defaulting to on, empty override meaning "use canonical"). cordis.patch.yml pins the same values explicitly so a deployment's effective config reads in one place; the UI clearing a field falls back to the file value, then the code default. Single source of truth stays in code — the file mirrors, never contradicts.
Headless / declarative config
For servers or cordis.patch.yml overlays:
- id: dsh-opencode
name: "@viztor/dsh-opencode"
config:
providers: [opencode, opencode-go]
injectUserAgent: true
userAgent: ""
injectOriginHeaders: true
injectCoreTools: true
debug: false
Full option reference (types, debug/debugFile): see cordis.patch.yml header comments.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|
403 FreeTierError on free models | Headers stripped or tools missing | Keep all three inject toggles on |
400 MissingSessionID | No session header attached | Plugin must be in bundles; check it loaded |
| Paid/other providers misbehaving | Shouldn't happen — they're never touched | File an issue with a redacted log |
Compatibility
Last verified: 2026-10-01 — refreshed on every release (see Contributing).
| Component | Verified version |
|---|
| Plugin | @viztor/dsh-opencode@0.3.0 (npm + GitHub Packages) |
| Host | DSH Web profile (dsh-profile-web, patchReload: live) |
| Runtime | Node 24+ |
| Gateway | zen/v1 (/responses + chat completions) and zen/go/v1 (chat completions) |
| Models | muse-spark-1.3-contributor-free, space-bunny-free, deepseek-v4.1-flash (Go) |
| Checks | vp check clean, 44/44 deterministic tests, registry install resolves |
Links
Attribution
Evolved from nobu121/dsh-opencode-session by @nobu121, which pioneered the x-opencode-session approach for OpenCode Go. This project extends it to OpenCode Zen free-tier compatibility, deterministic session hashing, configurable headers, and a Web settings UI.