FuzzySoul
dsh-free-vision
Vision bridge plugin for DeepSeek Harness (dsh): image understanding for text-only models via luma-mcp, free Qwen3-VL-Flash by default.
- Stars
- 1
- Language
- JavaScript
- Created
- Aug 15, 2026
- Updated
- Aug 15, 2026
Introduction
dsh-free-vision · Free Vision for DSH
English | 中文
A free vision plugin for DeepSeek Harness (dsh): gives text-only models the ability to read images — screenshots, code errors, UI layouts, documents, OCR — powered by free-tier vision models, with a built-in settings UI and zero MCP configuration.
Features
Free-first, multi-provider
Free-tier models work out of the box; switch providers in one click:
| Provider | Model | Free quota | Key env var | Signup |
|---|---|---|---|---|
| Qwen (default) | Qwen3-VL-Flash | Bailian free tier (500K tokens on activation) | DASHSCOPE_API_KEY | Aliyun Bailian |
| Doubao | Doubao vision | Volcengine free tokens (200K+, up to 500K) | VOLCENGINE_API_KEY | Volcano Ark |
| SiliconFlow | DeepSeek-OCR | Free OCR calls | SILICONFLOW_API_KEY | SiliconFlow |
| Zhipu | GLM-4.6V | Metered | ZHIPU_API_KEY | Zhipu |
| Hunyuan | HY-Vision | Metered | HUNYUAN_API_KEY | Tencent TokenHub |
| Custom | Any OpenAI-compatible | — | CUSTOM_API_KEY + CUSTOM_BASE_URL + CUSTOM_MODEL_NAME | — |
A 1MB screenshot ≈ 2,600 tokens — the Qwen free quota covers ~190,000 images.
Settings UI (Settings → Free Vision)

The plugin registers its own settings section; every option is editable visually and saves take effect immediately (next tool call, no restart):
- Provider cards: click to switch; free tiers carry a "FREE 免费" badge;
- Per-provider key slots: configure once, switching providers automatically uses the matching key;
- Signup links: jump straight to each provider's free-key registration page;
- Live status line: shows the active provider and key source (file / env);
- Advanced settings: model name, tool name, max tokens, temperature, multi-crop, timeout, extra env;
- Graceful no-key mode: the plugin loads fine without a key — a yellow banner and a friendly tool message point to Settings, never an opaque plugin error.
Zero MCP configuration
The vision engine (luma-mcp) ships as a version-locked dependency and runs in-process — no cordis.patch.yml edits, no second "who is actually reading images" channel.
Engineering guarantees
- Auto-reconnect: the engine recovers from crashes with exponential backoff;
- Direct connection: proxy env vars are stripped from the engine process (a stray proxy causes 502);
- One generic tool:
image_understandcovers OCR / UI / debug / describe tasks; - CI + 13 unit tests, shipped with every release.
Install
DSH plugins install into a profile (dsh web uses the web profile) via dsh plugin.
Option 1: from npm (recommended)
dsh plugin --profile web add dsh-free-vision
Restart dsh web, then open Settings → Free Vision:
- Pick a provider card (free tiers carry a badge);
- Paste that provider's API key into the linkage area (or click the signup link);
- Click Save — the status line turns green and the model can read images via
image_understand.
ERR_PNPM_IGNORED_BUILDSon first install: if pnpm refuses dependency build scripts, addluma-mcp(sharp native dep) toallowBuildsin the profile'spnpm-workspace.yamland reinstall.
Option 2: from the GitHub repo (development)
git clone https://github.com/FuzzySoul/dsh-free-vision.git
cd dsh-free-vision
npm install
# install into the web profile (Windows cross-drive: use the npm tarball instead of file: paths)
Verify & uninstall
After install, restart dsh web — Settings → Free Vision showing the config cards means it works. You can also run dsh --profile web --dump-config to confirm the plugin layer is mounted.
Uninstall: dsh plugin --profile web remove dsh-free-vision, then restart dsh web.
Technical details: docs/ARCHITECTURE.md.
Configuration
Settings UI vs config file
The UI persists to ~/.dsh/free-vision.json (same fields, UI recommended):
{
"keys": { "qwen": "sk-...", "volcengine": "" },
"modelProvider": "qwen",
"modelName": "",
"toolName": "image_understand",
"maxTokens": 8192,
"temperature": 0.7,
"multiCrop": true,
"toolCallTimeoutMs": 200000,
"lumaEnv": {}
}
Key resolution order: keys[active provider] > legacy top-level apiKey (auto-migrated) > provider env var.
FAQ
Settings say "no API key" but I can read images?
Restart dsh web and check the status line. Early versions had a dual channel (manual mcp-luma + plugin) causing stale state; since 0.5.0 the channel is unified and the UI reflects the actual effective provider and key source.
502 errors?
Bailian & co. are mainland-China endpoints and must be reached directly. The plugin already strips proxy env vars from the engine process; do not set HTTP_PROXY for the plugin yourself.
"Unsupported image format"?
luma detects format by file extension; copy extension-less attachments to .png / .jpg first, or use an http(s) URL / data URI.
How do I switch providers?
Click a card in Settings — each provider keeps its own key and switching takes effect immediately.
Development
npm install
npm test # vitest unit tests (13)
node test-plugin.mjs # end-to-end smoke test (needs a provider API key env)
Attribution
| Part | Source | License |
|---|---|---|
| dsh-free-vision plugin | FuzzySoul | MIT |
| Vision engine luma-mcp | JochenYang/luma-mcp | MIT |
| MCP SDK | modelcontextprotocol | MIT |
Links
- awesome-dsh-plugin — curated DSH plugin list (this plugin's listing entry);
- dsh-market — visual plugin market inside DSH;
- liustack/modlens — another DSH vision plugin;
- DeepSeek Harness — the official repository.