deepseek-web-retrieval 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -1
- package/README.md +113 -53
- package/dist/cli.js +2427 -1813
- package/docs/adr/0002-shared-config-base-layer.md +43 -0
- package/docs/agents/claude-code.md +273 -0
- package/docs/agents/codex.md +50 -27
- package/docs/agents/opencode-v2.md +59 -33
- package/docs/agents/pi.md +50 -27
- package/docs/configuration.md +109 -0
- package/docs/design/config-layering-design.md +180 -0
- package/docs/design/installer-design.md +24 -13
- package/docs/hosts.jsonc +5 -1
- package/docs/integration.md +15 -9
- package/docs/research/control-matrix.md +49 -11
- package/docs/research/mcp-compatibility.md +6 -3
- package/docs/research/ori-question-sourcing.md +336 -0
- package/docs/research/result-quality-passthrough.md +159 -0
- package/docs/research/search-api-defaults.md +18 -2
- package/docs/research/search-inline-content.md +244 -0
- package/examples/opencode.global.jsonc +3 -2
- package/package.json +2 -1
- package/src/core/auth.ts +3 -0
- package/src/core/client.ts +26 -4
- package/src/core/config-file.ts +168 -0
- package/src/core/config-summary.ts +82 -0
- package/src/core/constants.ts +15 -1
- package/src/core/descriptions.ts +6 -2
- package/src/core/env.ts +102 -32
- package/src/core/format.ts +19 -1
- package/src/core/options.ts +22 -2
- package/src/core/search.ts +6 -0
- package/src/core/types.ts +11 -0
- package/src/installer/cli.ts +50 -16
- package/src/installer/config-command.ts +116 -0
- package/src/installer/hosts/claude-code.ts +325 -0
- package/src/installer/hosts/codex.ts +9 -4
- package/src/installer/hosts/index.ts +3 -0
- package/src/installer/hosts/opencode.ts +9 -5
- package/src/installer/hosts/pi.ts +34 -9
- package/src/installer/ownership.ts +54 -1
- package/src/installer/paths.ts +7 -1
- package/src/installer/state.ts +73 -20
- package/src/installer/types.ts +11 -1
- package/src/installer/uninstall.ts +4 -1
- package/src/mcp/auth.ts +2 -3
- package/src/mcp/cli.ts +4 -3
- package/src/mcp/serve.ts +10 -1
- package/src/mcp/server.ts +7 -2
- package/src/opencode/plugin.ts +22 -2
- package/src/pi/extension.ts +78 -9
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Share one config base layer across hosts
|
|
2
|
+
|
|
3
|
+
The option pipeline was single-sourced, but the channels feeding it were per
|
|
4
|
+
host: `DEEPSEEK_*` shell variables on Pi, only `ctx.options` on OpenCode, and
|
|
5
|
+
on Codex only the names the installer's `env_vars` entry forwards — just
|
|
6
|
+
`DEEPSEEK_API_KEY`, so every other knob set in the shell silently never
|
|
7
|
+
reached the server. One intent ("20 results, block pinterest.com") took up to
|
|
8
|
+
three configuration acts in two vocabularies. We decided that a shared config
|
|
9
|
+
file becomes the base layer under every existing channel, with the precedence
|
|
10
|
+
`built-in defaults < shared config file < DEEPSEEK_* environment < host-native
|
|
11
|
+
config`, a three-class parameter taxonomy that isolates host integration in
|
|
12
|
+
the host-native layer and rejects it from the file, and no API key in the
|
|
13
|
+
file — auth keeps its existing channels.
|
|
14
|
+
|
|
15
|
+
## Considered Options
|
|
16
|
+
|
|
17
|
+
- **Unify on the file alone** (retire the environment and host-option
|
|
18
|
+
vocabularies so there is one configuration act). But host integration —
|
|
19
|
+
`searchEnabled`/`fetchEnabled`, `setDefaultWebsearch`,
|
|
20
|
+
`fetchOverrideWebfetch`, `fetchRegisterTool`, `apiKeySource` — describes the
|
|
21
|
+
host's tool landscape, not the user↔DeepSeek relationship, so the host layer
|
|
22
|
+
must keep owning it, and retiring `DEEPSEEK_*` would break every existing
|
|
23
|
+
shell profile.
|
|
24
|
+
- **Keep the per-host channels as the only surface** (previous status quo).
|
|
25
|
+
The Codex `env_vars` trap stays — knobs set in the shell reach the server
|
|
26
|
+
only by hand-editing `config.toml` — and the same knob keeps two
|
|
27
|
+
vocabularies across hosts.
|
|
28
|
+
|
|
29
|
+
## Consequences
|
|
30
|
+
|
|
31
|
+
One file — `$XDG_CONFIG_HOME/deepseek-web-retrieval/config.json`, default
|
|
32
|
+
`~/.config/deepseek-web-retrieval/config.json`, camelCase keys — configures
|
|
33
|
+
every host, and host layers keep winning: installer-written intent and
|
|
34
|
+
explicit per-host overrides always outrank the base, bounding the blast
|
|
35
|
+
radius of a bad shared value. Unknown keys and host-integration keys in the
|
|
36
|
+
file draw a one-line stderr warning and are otherwise ignored. Because a bad
|
|
37
|
+
shared value now fails everywhere at once, every adapter prints a
|
|
38
|
+
deviations-from-defaults summary of its effective configuration.
|
|
39
|
+
|
|
40
|
+
The installer's Codex `env_vars` entry forwards every `DEEPSEEK_*` name, so
|
|
41
|
+
environment overrides work on Codex without hand-editing `config.toml`.
|
|
42
|
+
Design detail (per-adapter composition, validation, visibility, rollout)
|
|
43
|
+
lives in the [layering design note](../design/config-layering-design.md).
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# Claude Code
|
|
2
|
+
|
|
3
|
+
Claude Code adapter for [DeepSeek Web Retrieval](../../README.md).
|
|
4
|
+
|
|
5
|
+
Integration mechanism: MCP server over stdio, registered in Claude Code's own MCP config
|
|
6
|
+
files — `.mcp.json` at the project root (project scope) or the top-level `mcpServers` key
|
|
7
|
+
of `~/.claude.json` (user scope, where `claude mcp add --scope user` writes). Claude Code
|
|
8
|
+
negotiates MCP revision `2026-07-28`; the server accepts clients from `2024-11-05` through
|
|
9
|
+
`2026-07-28`, so the same build works for other MCP hosts (see
|
|
10
|
+
[the compatibility research](../research/mcp-compatibility.md)).
|
|
11
|
+
|
|
12
|
+
When registered, it adds:
|
|
13
|
+
|
|
14
|
+
- A `deepseek_web_search` tool backed by DeepSeek Search
|
|
15
|
+
- A `deepseek_fetch` tool backed by DeepSeek Fetch
|
|
16
|
+
|
|
17
|
+
The tools appear in Claude Code as `mcp__deepseek__deepseek_web_search` and
|
|
18
|
+
`mcp__deepseek__deepseek_fetch`. Claude Code's built-in `WebSearch` and `WebFetch` tools
|
|
19
|
+
are not replaced; see [Control tiers](#control-tiers) for routing them away.
|
|
20
|
+
|
|
21
|
+
For shared search/fetch limits, retries, and privacy behavior, see
|
|
22
|
+
[General behavior](../../README.md#general-behavior).
|
|
23
|
+
For configuration layers, the full knob mapping, and defaults, see the
|
|
24
|
+
[configuration guide](../configuration.md).
|
|
25
|
+
|
|
26
|
+
## Requirements
|
|
27
|
+
|
|
28
|
+
- Claude Code at the tested version in [`docs/hosts.jsonc`](../hosts.jsonc); init reports
|
|
29
|
+
version drift, and newer versions may require rechecking routing behavior
|
|
30
|
+
- Node.js 20 or newer (`npx` runs the server)
|
|
31
|
+
- A DeepSeek account with access to `/v1/tools/search` and `/v1/tools/fetch`
|
|
32
|
+
- A funded DeepSeek account; Search and Fetch are billed per successful request
|
|
33
|
+
- `DEEPSEEK_API_KEY` set in the shell that launches Claude Code
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
The quickest option is the installer CLI:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx deepseek-web-retrieval init --host claude-code --scope project \
|
|
41
|
+
--search <tier> --fetch <tier>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
It prints the full plan — every file, old value → new value, and notes about existing MCP
|
|
45
|
+
servers — and writes nothing until you pass `--apply`. Add `--pin` to register the exact
|
|
46
|
+
version of the CLI you are running instead of the always-latest package name. `uninstall`
|
|
47
|
+
removes recorded additions and restores snapshotted values that have not since been edited.
|
|
48
|
+
`--scope project` registers the server in `./.mcp.json` (shareable via VCS) and writes tier
|
|
49
|
+
artifacts to `./.claude/settings.json` and `./CLAUDE.md`; `--scope global` uses
|
|
50
|
+
`~/.claude.json`, `~/.claude/settings.json`, and `~/.claude/CLAUDE.md` instead — the two
|
|
51
|
+
scopes use disjoint files, so both can coexist. An `off` capability is written as the
|
|
52
|
+
tool's full id in the `permissions.deny` array — Claude Code's own mechanism, which removes
|
|
53
|
+
the tool from the model's context while the server keeps running — merging with any entries
|
|
54
|
+
you put there yourself. When `claude` is on PATH, `init` also probes `claude --version` and
|
|
55
|
+
adds a plan note when the installed release differs from the tested lock (see
|
|
56
|
+
[hosts.jsonc](../hosts.jsonc)) — version-anchored behavior such as the deny rules may have
|
|
57
|
+
drifted between the two.
|
|
58
|
+
|
|
59
|
+
For an existing installer-managed setup, follow the
|
|
60
|
+
[upgrade instructions](../integration.md#upgrading-existing-installs) from the original
|
|
61
|
+
project directory and scope.
|
|
62
|
+
|
|
63
|
+
### Manual install
|
|
64
|
+
|
|
65
|
+
Add the server to `.mcp.json` at the project root:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"mcpServers": {
|
|
70
|
+
"deepseek": {
|
|
71
|
+
"command": "npx",
|
|
72
|
+
"args": ["-y", "deepseek-web-retrieval"],
|
|
73
|
+
"env": { "DEEPSEEK_API_KEY": "${DEEPSEEK_API_KEY}" }
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
> [!NOTE]
|
|
80
|
+
> `"${DEEPSEEK_API_KEY}"` is Claude Code's own `${VAR}` expansion: the key is read from
|
|
81
|
+
> the environment that launches Claude Code and never sits in the file. A literal value
|
|
82
|
+
> works too if you prefer it in the file. For a user-scope install, the same entry goes
|
|
83
|
+
> under the top-level `mcpServers` key of `~/.claude.json`, or use
|
|
84
|
+
> `claude mcp add --scope user --env 'DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}' deepseek -- npx -y deepseek-web-retrieval`.
|
|
85
|
+
|
|
86
|
+
Claude Code asks once per project whether to use servers from `.mcp.json`; approve the
|
|
87
|
+
`deepseek` server when prompted (or via the `/mcp` menu), or its tools will not load in
|
|
88
|
+
that project.
|
|
89
|
+
|
|
90
|
+
To disable one capability, add the tool's full id to `permissions.deny` in
|
|
91
|
+
`.claude/settings.json` — Claude Code removes the tool from the model's context while the
|
|
92
|
+
server keeps running:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"permissions": {
|
|
97
|
+
"deny": ["mcp__deepseek__deepseek_web_search"]
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The ids match the tool names verbatim (`mcp__deepseek__deepseek_web_search`,
|
|
103
|
+
`mcp__deepseek__deepseek_fetch`). The server also honors
|
|
104
|
+
`DEEPSEEK_ENABLE_SEARCH`/`DEEPSEEK_ENABLE_FETCH` in the server's `env` block if you prefer
|
|
105
|
+
switching the tools off at the source; the installer uses `permissions.deny`.
|
|
106
|
+
|
|
107
|
+
### Local checkout
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
git clone https://github.com/gwokhou/deepseek-web-retrieval.git
|
|
111
|
+
cd deepseek-web-retrieval && bun install && bun run build
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"mcpServers": {
|
|
117
|
+
"deepseek": {
|
|
118
|
+
"command": "node",
|
|
119
|
+
"args": ["/absolute/path/to/deepseek-web-retrieval/dist/cli.js"],
|
|
120
|
+
"env": { "DEEPSEEK_API_KEY": "${DEEPSEEK_API_KEY}" }
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Control tiers
|
|
127
|
+
|
|
128
|
+
Claude Code ships built-in `WebSearch` and `WebFetch` tools; neither is replaceable, so
|
|
129
|
+
both capabilities use exclusion for the forced tier:
|
|
130
|
+
|
|
131
|
+
| Capability | Optional | Preferred | Forced |
|
|
132
|
+
| --- | --- | --- | --- |
|
|
133
|
+
| Search | Tools registered; the built-in `WebSearch` stays available | Plus a CLAUDE.md rules block steering the model to `mcp__deepseek__deepseek_web_search` | Exclusion: `permissions.deny: ["WebSearch"]` |
|
|
134
|
+
| Fetch | Tools registered; the built-in `WebFetch` stays available | Plus the rules block | Exclusion: `permissions.deny: ["WebFetch"]` |
|
|
135
|
+
|
|
136
|
+
The installer maps each tier to these artifacts. Deny entries land in
|
|
137
|
+
`~/.claude/settings.json` (user) or `./.claude/settings.json` (project) and merge with
|
|
138
|
+
your existing `permissions.deny` entries. The CLAUDE.md rules block lands in
|
|
139
|
+
`~/.claude/CLAUDE.md` (user) or `./CLAUDE.md` (project); Claude Code loads the user file
|
|
140
|
+
plus every CLAUDE.md from the cwd up the directory tree, concatenating the levels — so
|
|
141
|
+
the block steers wherever it is installed. Under a forced tier, other web-capable MCP
|
|
142
|
+
servers detected in the config are denied by server-level rules (`mcp__<server>` denies
|
|
143
|
+
every tool of that server), so routing stays exclusive.
|
|
144
|
+
|
|
145
|
+
> [!WARNING]
|
|
146
|
+
> Deny rules outrank allow rules at every settings level and **cannot be carved out** —
|
|
147
|
+
> denying `WebSearch` or `WebFetch` removes the tool for every workflow in the install's
|
|
148
|
+
> scope (every project on the machine for `--scope global`). A managed policy layer
|
|
149
|
+
> (`managed-settings.json`) outranks both files; the installer reports when one exists.
|
|
150
|
+
|
|
151
|
+
## Authentication
|
|
152
|
+
|
|
153
|
+
`DEEPSEEK_API_KEY` is the only source; MCP has no host credential store. It is forwarded
|
|
154
|
+
through the server's `env` block as `${DEEPSEEK_API_KEY}` and read per request, sent only
|
|
155
|
+
to `api.deepseek.com` as a Bearer token. Without it the server exits at startup with a
|
|
156
|
+
message on stderr.
|
|
157
|
+
|
|
158
|
+
## Usage
|
|
159
|
+
|
|
160
|
+
Ask naturally:
|
|
161
|
+
|
|
162
|
+
```text
|
|
163
|
+
Search the web for the latest Claude Code MCP config changes and cite the sources.
|
|
164
|
+
Fetch https://code.claude.com/docs/en/mcp and summarize the config keys.
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The model calls `mcp__deepseek__deepseek_web_search` or `mcp__deepseek__deepseek_fetch`.
|
|
168
|
+
|
|
169
|
+
The search tool accepts an optional `original_question` argument — the user's question in
|
|
170
|
+
their own words — forwarded as DeepSeek's `ori_question` to sharpen search intent; omit it
|
|
171
|
+
when the query already stands alone.
|
|
172
|
+
|
|
173
|
+
Tool output is capped at 25k tokens by default (`MAX_MCP_OUTPUT_TOKENS`), and successful
|
|
174
|
+
text results longer than 50,000 characters are saved to a file and referenced — not
|
|
175
|
+
dropped silently.
|
|
176
|
+
|
|
177
|
+
## Configuration
|
|
178
|
+
|
|
179
|
+
Set these in the server's `env` block in `.mcp.json` (or `~/.claude.json`). Values map onto
|
|
180
|
+
the shared option pipeline, so defaults and clamping match the other adapters.
|
|
181
|
+
`DEEPSEEK_API_KEY` goes in the same block as the `${VAR}` expansion.
|
|
182
|
+
|
|
183
|
+
> [!NOTE]
|
|
184
|
+
> A shared config file — `~/.config/deepseek-web-retrieval/config.json`
|
|
185
|
+
> (Windows: `%APPDATA%\deepseek-web-retrieval\config.json`), camelCase keys —
|
|
186
|
+
> sits under the environment layer and works with no env forwarding at all: the server
|
|
187
|
+
> reads the file itself, making it the way to set knobs without editing the MCP entry. The
|
|
188
|
+
> file carries neither the API key nor the host-integration switches. Run
|
|
189
|
+
> `npx deepseek-web-retrieval config` to see every knob's effective value and source
|
|
190
|
+
> (it replays file warnings visibly and exits 1 on file problems); `config --search "<query>"`
|
|
191
|
+
> verifies key, config, and network with one billed search.
|
|
192
|
+
|
|
193
|
+
### Search
|
|
194
|
+
|
|
195
|
+
The "Config file" column names each key's camelCase twin in the shared config file —
|
|
196
|
+
one vocabulary pair, one pipeline. `—` marks host-integration entries the file rejects.
|
|
197
|
+
|
|
198
|
+
| Env variable | Config file | Default | Description |
|
|
199
|
+
| --- | --- | --- | --- |
|
|
200
|
+
| `DEEPSEEK_ENABLE_SEARCH` | — | `true` | Register the search tool. Only an explicit `false`/`0`/`no`/`off` disables it; at least one tool must stay enabled. |
|
|
201
|
+
| `DEEPSEEK_SEARCH_COUNT` | `count` | `10` | Results requested from DeepSeek, 1–50. Billing is per request, not per result. |
|
|
202
|
+
| `DEEPSEEK_SEARCH_MAX_RESULTS` | `maxResults` | `10` | Results returned to the model after filtering, 0–50; defaults to `DEEPSEEK_SEARCH_COUNT` when unset. `0` returns no results. |
|
|
203
|
+
| `DEEPSEEK_SEARCH_MIN_RERANK` | `minRerank` | `0` | Drop results below this relevance score (0–3); results without a finite score pass at zero and are dropped at a positive threshold. |
|
|
204
|
+
| `DEEPSEEK_SEARCH_MIN_AUTHORITY` | `minAuthority` | `0` | Drop known authorities below this tier. Authority is 0–4. |
|
|
205
|
+
| `DEEPSEEK_SEARCH_ALLOW_UNKNOWN_AUTHORITY` | `allowUnknownAuthority` | `true` | Keep results whose authority is missing or unknown. Set `false`/`0`/`no`/`off` to drop them. |
|
|
206
|
+
| `DEEPSEEK_SEARCH_BLOCKED_DOMAINS` | `blockedDomains` | unset | Comma-separated; adds `-site:` operators to the query. |
|
|
207
|
+
| `DEEPSEEK_SEARCH_INCLUDE_DOMAINS` | `includeDomains` | unset | Comma-separated; restricts results with `site:` operators. |
|
|
208
|
+
| `DEEPSEEK_SEARCH_LANGUAGE` | `language` | unset | Adds a `lang:` operator, for example `zh,en`. |
|
|
209
|
+
| `DEEPSEEK_SEARCH_LOCALIZATION` | `searchLocalization` | unset | Valid IPv4 or IPv6 address sent as DeepSeek's `localization` to prefer geo-localized results; invalid values are ignored. Deployment-level only, never a per-call parameter. |
|
|
210
|
+
| `DEEPSEEK_SEARCH_MAX_SUMMARY_CHARS` | `maxSummaryChars` | `1200` | Per-result summary cap, 0–1,000,000. |
|
|
211
|
+
| `DEEPSEEK_SEARCH_TIMEOUT_MS` | `searchTimeoutMs` | `30000` | Search timeout, 1,000–120,000 ms. |
|
|
212
|
+
|
|
213
|
+
### Fetch
|
|
214
|
+
|
|
215
|
+
| Env variable | Config file | Default | Description |
|
|
216
|
+
| --- | --- | --- | --- |
|
|
217
|
+
| `DEEPSEEK_ENABLE_FETCH` | — | `true` | Register the fetch tool. Same false-only semantics as `DEEPSEEK_ENABLE_SEARCH`. |
|
|
218
|
+
| `DEEPSEEK_FETCH_MAX_CHARS` | `fetchMaxChars` | `16000` | Maximum characters returned, including the title, 0–1,000,000. |
|
|
219
|
+
| `DEEPSEEK_FETCH_TIMEOUT_MS` | `fetchTimeoutMs` | `30000` | Fetch timeout, 1,000–120,000 ms. |
|
|
220
|
+
| `DEEPSEEK_FETCH_ALLOWED_DOMAINS` | `fetchAllowedDomains` | unset | If set, only these hosts and subdomains may be fetched. |
|
|
221
|
+
| `DEEPSEEK_FETCH_BLOCKED_DOMAINS` | `fetchBlockedDomains` | unset | Always block these hosts and subdomains. Blocked wins over allowed. |
|
|
222
|
+
| `DEEPSEEK_FETCH_BLOCK_PRIVATE_HOSTS` | `fetchBlockPrivateHosts` | `true` | Reject localhost, private IPs, `.local`, `.internal`, and similar hosts. |
|
|
223
|
+
|
|
224
|
+
### Credentials and retries
|
|
225
|
+
|
|
226
|
+
| Env variable | Config file | Default | Description |
|
|
227
|
+
| --- | --- | --- | --- |
|
|
228
|
+
| `DEEPSEEK_API_KEY` | — | required | DeepSeek API key, expanded from the launching environment via `${DEEPSEEK_API_KEY}`. The server refuses to start without it. |
|
|
229
|
+
| `DEEPSEEK_MAX_RETRIES` | `maxRetries` | `2` | Retries for 408, 425, 429, and 5xx responses, 0–5. |
|
|
230
|
+
| `DEEPSEEK_RETRY_BASE_DELAY_MS` | `retryBaseDelayMs` | `250` | Base delay for exponential backoff. `Retry-After` is honored up to 10 seconds. |
|
|
231
|
+
|
|
232
|
+
## Troubleshooting
|
|
233
|
+
|
|
234
|
+
| Error or symptom | What to do |
|
|
235
|
+
| --- | --- |
|
|
236
|
+
| Server fails to start or `HTTP 401` from the tools | `DEEPSEEK_API_KEY` must be set in the environment that launches Claude Code; the `${DEEPSEEK_API_KEY}` expansion in the server's `env` block reads it at launch. |
|
|
237
|
+
| Project tools missing after install | Claude Code asks once per project whether to use `.mcp.json` servers; approve the `deepseek` server when prompted or via the `/mcp` menu. |
|
|
238
|
+
| Both tools missing after startup | At least one of `DEEPSEEK_ENABLE_SEARCH`/`DEEPSEEK_ENABLE_FETCH` must stay enabled; the server exits when both are false. |
|
|
239
|
+
| Forced tier still shows the built-in tool | The kill switch is the bare deny rule in `permissions.deny` at the install's scope; a managed policy layer (`managed-settings.json`) outranks it — the plan reports when one exists. |
|
|
240
|
+
| Routing not exclusive | Other MCP servers stay registered and are noted in the plan. Under a forced tier, web-capable servers detected in the config (and the other scope's file) are denied by server-level `mcp__<server>` rules; a server added after install is not covered — re-run init. |
|
|
241
|
+
| Fetch results appear as a file reference instead of content | Tool output is capped at 25k tokens by default; raise `MAX_MCP_OUTPUT_TOKENS` or lower `DEEPSEEK_FETCH_MAX_CHARS`. |
|
|
242
|
+
| `HTTP 402`, `HTTP 429` | Top up the DeepSeek account; wait, reduce concurrency, or set `DEEPSEEK_MAX_RETRIES`. |
|
|
243
|
+
| Fetch fails on localhost or an internal URL | Use a local fetch tool; DeepSeek cannot reach private networks. |
|
|
244
|
+
|
|
245
|
+
## Compatibility
|
|
246
|
+
|
|
247
|
+
| Component | Version |
|
|
248
|
+
| --- | --- |
|
|
249
|
+
| Claude Code | locked in [`docs/hosts.jsonc`](../hosts.jsonc) |
|
|
250
|
+
| MCP revision | `2026-07-28` negotiated; server accepts `2024-11-05`–`2026-07-28` |
|
|
251
|
+
| MCP SDK | `@modelcontextprotocol/server` 2.3.1 |
|
|
252
|
+
| Runtime | Node.js 20+ (stdio) |
|
|
253
|
+
| DeepSeek API | `/v1/tools/search`, `/v1/tools/fetch` |
|
|
254
|
+
|
|
255
|
+
Tested with Claude Code at the `docs/hosts.jsonc` lock on Linux over stdio: the keyless
|
|
256
|
+
Docker e2e verifies the installer's registration, tiers, and uninstall with a real
|
|
257
|
+
`claude mcp list` handshake, and the billed scenario (`bun run test:e2e claude-code`,
|
|
258
|
+
requires `DEEPSEEK_API_KEY`) runs headless prompts end to end with the deny kill switch
|
|
259
|
+
asserted for both capabilities.
|
|
260
|
+
|
|
261
|
+
## Uninstall
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
npx deepseek-web-retrieval uninstall --host claude-code --scope project
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
This removes the recorded `mcpServers.deepseek` entry and the installer-appended
|
|
268
|
+
`permissions.deny` entries only when their current values still match what the installer
|
|
269
|
+
wrote, removes the managed rules block, and deletes installer-created config files only
|
|
270
|
+
when left empty. Later user edits to configuration values are kept and reported. For a
|
|
271
|
+
manual installation, remove the `deepseek` entry from `.mcp.json` (or `~/.claude.json`),
|
|
272
|
+
any `deepseek-web-retrieval` rules block in your `CLAUDE.md`, and the deny entries the
|
|
273
|
+
setup added to `settings.json` if they were only for this integration.
|
package/docs/agents/codex.md
CHANGED
|
@@ -24,6 +24,8 @@ both the text and `structuredContent`.
|
|
|
24
24
|
|
|
25
25
|
For shared search/fetch limits, retries, and privacy behavior, see
|
|
26
26
|
[General behavior](../../README.md#general-behavior).
|
|
27
|
+
For configuration layers, the full knob mapping, and defaults, see the
|
|
28
|
+
[configuration guide](../configuration.md).
|
|
27
29
|
|
|
28
30
|
## Requirements
|
|
29
31
|
|
|
@@ -44,7 +46,9 @@ npx deepseek-web-retrieval init --host codex --scope global \
|
|
|
44
46
|
```
|
|
45
47
|
|
|
46
48
|
It prints the full plan — every file, old value → new value, and notes about existing
|
|
47
|
-
MCP servers — and writes nothing until you pass `--apply`. `
|
|
49
|
+
MCP servers — and writes nothing until you pass `--apply`. Add `--pin` to register the
|
|
50
|
+
exact version of the CLI you are running instead of the always-latest package name.
|
|
51
|
+
`uninstall` removes recorded
|
|
48
52
|
additions and restores snapshotted values that have not since been edited. Codex's config
|
|
49
53
|
lives in `~/.codex/config.toml` at the user level only, so the server registration and kill switch
|
|
50
54
|
are written there even for `--scope project`; the rules file follows the scope. An `off`
|
|
@@ -142,45 +146,64 @@ Fetch https://learn.chatgpt.com/docs/extend/mcp and summarize the config keys.
|
|
|
142
146
|
|
|
143
147
|
The model calls `mcp__deepseek__deepseek_web_search` or `mcp__deepseek__deepseek_fetch`.
|
|
144
148
|
|
|
149
|
+
The search tool accepts an optional `original_question` argument — the user's question in
|
|
150
|
+
their own words — forwarded as DeepSeek's `ori_question` to sharpen search intent; omit it
|
|
151
|
+
when the query already stands alone.
|
|
152
|
+
|
|
145
153
|
## Configuration
|
|
146
154
|
|
|
147
155
|
Set these in the server's `env` table. Values map onto the shared option pipeline, so
|
|
148
156
|
defaults and clamping match the other adapters. `DEEPSEEK_API_KEY` goes in `env_vars`.
|
|
149
157
|
|
|
158
|
+
> [!NOTE]
|
|
159
|
+
> A shared config file — `~/.config/deepseek-web-retrieval/config.json`
|
|
160
|
+
> (Windows: `%APPDATA%\deepseek-web-retrieval\config.json`), camelCase keys —
|
|
161
|
+
> sits under the environment layer and works with no env forwarding at all: the server
|
|
162
|
+
> reads the file itself, making it the way to set knobs without editing `env_vars` (the
|
|
163
|
+
> installer's `env_vars` entry also forwards every `DEEPSEEK_*` name). The file carries
|
|
164
|
+
> neither the API key nor the host-integration switches. Run
|
|
165
|
+
> `npx deepseek-web-retrieval config` to see every knob's effective value and source
|
|
166
|
+
> (it replays file warnings visibly and exits 1 on file problems); `config --search "<query>"`
|
|
167
|
+
> verifies key, config, and network with one billed search.
|
|
168
|
+
|
|
150
169
|
### Search
|
|
151
170
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
|
156
|
-
|
|
|
157
|
-
| `
|
|
158
|
-
| `
|
|
159
|
-
| `
|
|
160
|
-
| `
|
|
161
|
-
| `
|
|
162
|
-
| `
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
171
|
+
The "Config file" column names each key's camelCase twin in the shared config file —
|
|
172
|
+
one vocabulary pair, one pipeline. `—` marks host-integration entries the file rejects.
|
|
173
|
+
|
|
174
|
+
| Env variable | Config file | Default | Description |
|
|
175
|
+
| --- | --- | --- | --- |
|
|
176
|
+
| `DEEPSEEK_ENABLE_SEARCH` | — | `true` | Register the search tool. Only an explicit `false`/`0`/`no`/`off` disables it; at least one tool must stay enabled. |
|
|
177
|
+
| `DEEPSEEK_SEARCH_COUNT` | `count` | `10` | Results requested from DeepSeek, 1–50. Billing is per request, not per result. |
|
|
178
|
+
| `DEEPSEEK_SEARCH_MAX_RESULTS` | `maxResults` | `10` | Results returned to the model after filtering, 0–50; defaults to `DEEPSEEK_SEARCH_COUNT` when unset. `0` returns no results. |
|
|
179
|
+
| `DEEPSEEK_SEARCH_MIN_RERANK` | `minRerank` | `0` | Drop results below this relevance score (0–3); results without a finite score pass at zero and are dropped at a positive threshold. |
|
|
180
|
+
| `DEEPSEEK_SEARCH_MIN_AUTHORITY` | `minAuthority` | `0` | Drop known authorities below this tier. Authority is 0–4. |
|
|
181
|
+
| `DEEPSEEK_SEARCH_ALLOW_UNKNOWN_AUTHORITY` | `allowUnknownAuthority` | `true` | Keep results whose authority is missing or unknown. Set `false`/`0`/`no`/`off` to drop them. |
|
|
182
|
+
| `DEEPSEEK_SEARCH_BLOCKED_DOMAINS` | `blockedDomains` | unset | Comma-separated; adds `-site:` operators to the query. |
|
|
183
|
+
| `DEEPSEEK_SEARCH_INCLUDE_DOMAINS` | `includeDomains` | unset | Comma-separated; restricts results with `site:` operators. |
|
|
184
|
+
| `DEEPSEEK_SEARCH_LANGUAGE` | `language` | unset | Adds a `lang:` operator, for example `zh,en`. |
|
|
185
|
+
| `DEEPSEEK_SEARCH_LOCALIZATION` | `searchLocalization` | unset | Valid IPv4 or IPv6 address sent as DeepSeek's `localization` to prefer geo-localized results; invalid values are ignored. Deployment-level only, never a per-call parameter. |
|
|
186
|
+
| `DEEPSEEK_SEARCH_MAX_SUMMARY_CHARS` | `maxSummaryChars` | `1200` | Per-result summary cap, 0–1,000,000. |
|
|
187
|
+
| `DEEPSEEK_SEARCH_TIMEOUT_MS` | `searchTimeoutMs` | `30000` | Search timeout, 1,000–120,000 ms. |
|
|
165
188
|
|
|
166
189
|
### Fetch
|
|
167
190
|
|
|
168
|
-
| Env variable | Default | Description |
|
|
169
|
-
| --- | --- | --- |
|
|
170
|
-
| `DEEPSEEK_ENABLE_FETCH` | `true` | Register the fetch tool. Same false-only semantics as `DEEPSEEK_ENABLE_SEARCH`. |
|
|
171
|
-
| `DEEPSEEK_FETCH_MAX_CHARS` | `16000` | Maximum characters returned, including the title, 0–1,000,000. |
|
|
172
|
-
| `DEEPSEEK_FETCH_TIMEOUT_MS` | `30000` | Fetch timeout, 1,000–120,000 ms. |
|
|
173
|
-
| `DEEPSEEK_FETCH_ALLOWED_DOMAINS` | unset | If set, only these hosts and subdomains may be fetched. |
|
|
174
|
-
| `DEEPSEEK_FETCH_BLOCKED_DOMAINS` | unset | Always block these hosts and subdomains. Blocked wins over allowed. |
|
|
175
|
-
| `DEEPSEEK_FETCH_BLOCK_PRIVATE_HOSTS` | `true` | Reject localhost, private IPs, `.local`, `.internal`, and similar hosts. |
|
|
191
|
+
| Env variable | Config file | Default | Description |
|
|
192
|
+
| --- | --- | --- | --- |
|
|
193
|
+
| `DEEPSEEK_ENABLE_FETCH` | — | `true` | Register the fetch tool. Same false-only semantics as `DEEPSEEK_ENABLE_SEARCH`. |
|
|
194
|
+
| `DEEPSEEK_FETCH_MAX_CHARS` | `fetchMaxChars` | `16000` | Maximum characters returned, including the title, 0–1,000,000. |
|
|
195
|
+
| `DEEPSEEK_FETCH_TIMEOUT_MS` | `fetchTimeoutMs` | `30000` | Fetch timeout, 1,000–120,000 ms. |
|
|
196
|
+
| `DEEPSEEK_FETCH_ALLOWED_DOMAINS` | `fetchAllowedDomains` | unset | If set, only these hosts and subdomains may be fetched. |
|
|
197
|
+
| `DEEPSEEK_FETCH_BLOCKED_DOMAINS` | `fetchBlockedDomains` | unset | Always block these hosts and subdomains. Blocked wins over allowed. |
|
|
198
|
+
| `DEEPSEEK_FETCH_BLOCK_PRIVATE_HOSTS` | `fetchBlockPrivateHosts` | `true` | Reject localhost, private IPs, `.local`, `.internal`, and similar hosts. |
|
|
176
199
|
|
|
177
200
|
### Credentials and retries
|
|
178
201
|
|
|
179
|
-
| Env variable | Default | Description |
|
|
180
|
-
| --- | --- | --- |
|
|
181
|
-
| `DEEPSEEK_API_KEY` | required | DeepSeek API key, forwarded via `env_vars`. The server refuses to start without it. |
|
|
182
|
-
| `DEEPSEEK_MAX_RETRIES` | `
|
|
183
|
-
| `DEEPSEEK_RETRY_BASE_DELAY_MS` | `250` | Base delay for exponential backoff. `Retry-After` is honored up to 10 seconds. |
|
|
202
|
+
| Env variable | Config file | Default | Description |
|
|
203
|
+
| --- | --- | --- | --- |
|
|
204
|
+
| `DEEPSEEK_API_KEY` | — | required | DeepSeek API key, forwarded via `env_vars`. The server refuses to start without it. |
|
|
205
|
+
| `DEEPSEEK_MAX_RETRIES` | `maxRetries` | `2` | Retries for 408, 425, 429, and 5xx responses, 0–5. |
|
|
206
|
+
| `DEEPSEEK_RETRY_BASE_DELAY_MS` | `retryBaseDelayMs` | `250` | Base delay for exponential backoff. `Retry-After` is honored up to 10 seconds. |
|
|
184
207
|
|
|
185
208
|
## Troubleshooting
|
|
186
209
|
|
|
@@ -15,6 +15,8 @@ if you want all Markdown fetches to go through DeepSeek.
|
|
|
15
15
|
|
|
16
16
|
For shared search/fetch limits, retries, and privacy behavior, see
|
|
17
17
|
[General behavior](../../README.md#general-behavior).
|
|
18
|
+
For configuration layers, the full knob mapping, and defaults, see the
|
|
19
|
+
[configuration guide](../configuration.md).
|
|
18
20
|
|
|
19
21
|
## Requirements
|
|
20
22
|
|
|
@@ -38,7 +40,8 @@ npx deepseek-web-retrieval init --host opencode --scope <project|global> \
|
|
|
38
40
|
```
|
|
39
41
|
|
|
40
42
|
It prints the full plan — every file, old value → new value — and writes nothing until
|
|
41
|
-
you pass `--apply`.
|
|
43
|
+
you pass `--apply`. Add `--pin` to register the exact version of the CLI you are running
|
|
44
|
+
instead of the always-latest package name. It snapshots the current `websearch.provider` before the forced tier
|
|
42
45
|
replaces it, merges `permissions` without touching yours, preserves comments in
|
|
43
46
|
`opencode.jsonc`, and `uninstall` restores recorded values that have not since been edited.
|
|
44
47
|
Search has no `preferred` tier on OpenCode (the provider is host-level config, never a
|
|
@@ -112,11 +115,14 @@ follow the [upgrade instructions](../integration.md#upgrading-existing-installs)
|
|
|
112
115
|
**Global checkout**
|
|
113
116
|
|
|
114
117
|
```bash
|
|
115
|
-
git clone https://github.com/
|
|
118
|
+
git clone https://github.com/guokhou/deepseek-web-retrieval.git \
|
|
116
119
|
~/.config/opencode/vendor/deepseek-web-retrieval
|
|
117
120
|
```
|
|
118
121
|
|
|
119
|
-
Use `"package": "./vendor/deepseek-web-retrieval"`.
|
|
122
|
+
Use `"package": "./vendor/deepseek-web-retrieval"`. On Windows the global config root is
|
|
123
|
+
`%APPDATA%\opencode\` (unless `XDG_CONFIG_HOME` is explicitly set), so clone into
|
|
124
|
+
`%APPDATA%\opencode\vendor\deepseek-web-retrieval` there — the same root the installer
|
|
125
|
+
writes to.
|
|
120
126
|
|
|
121
127
|
**Project checkout**
|
|
122
128
|
|
|
@@ -131,7 +137,8 @@ Use `"package": "./.opencode/vendor/deepseek-web-retrieval"`.
|
|
|
131
137
|
**Auto-discovery**
|
|
132
138
|
|
|
133
139
|
Clone or copy the repository into `~/.config/opencode/plugins/deepseek-web-retrieval` or
|
|
134
|
-
`.opencode/plugins/deepseek-web-retrieval
|
|
140
|
+
`.opencode/plugins/deepseek-web-retrieval` (on Windows, `%APPDATA%\opencode\plugins\…`).
|
|
141
|
+
Auto-discovered plugins do not receive options,
|
|
135
142
|
so `webfetch` stays in place; the `deepseek` search provider and `deepseek_fetch` are still
|
|
136
143
|
added.
|
|
137
144
|
|
|
@@ -169,47 +176,66 @@ Fetch https://opencode.ai/v2/docs/build/plugins and summarize the plugin lifecyc
|
|
|
169
176
|
The model calls `websearch` (provider `deepseek`) or `deepseek_fetch`. When
|
|
170
177
|
`fetchOverrideWebfetch` is enabled, Markdown fetches go through `webfetch` instead.
|
|
171
178
|
|
|
179
|
+
DeepSeek's optional `ori_question` is not sent on this path: OpenCode's `websearch` tool
|
|
180
|
+
input is fixed to `query` at 2.0.32, so the provider has no channel for it (see the
|
|
181
|
+
[research note](../research/ori-question-sourcing.md)).
|
|
182
|
+
|
|
172
183
|
## Configuration
|
|
173
184
|
|
|
174
185
|
Set these in the plugin's `options` object.
|
|
175
186
|
|
|
187
|
+
> [!NOTE]
|
|
188
|
+
> These options use the same camelCase vocabulary as the shared config file
|
|
189
|
+
> (`~/.config/deepseek-web-retrieval/config.json`; on Windows,
|
|
190
|
+
> `%APPDATA%\deepseek-web-retrieval\config.json`), with the `DEEPSEEK_*` environment in
|
|
191
|
+
> between: `shared file < environment < options`. Configure once in the file — it works on
|
|
192
|
+
> every host — and override per host here in `options`; existing `options` keep winning
|
|
193
|
+
> exactly as before. `npx deepseek-web-retrieval config` shows the file/env/defaults view
|
|
194
|
+
> of every knob (these `options` sit above it, so check them here when it differs).
|
|
195
|
+
|
|
176
196
|
### Search
|
|
177
197
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
|
184
|
-
|
|
|
185
|
-
| `
|
|
186
|
-
| `
|
|
187
|
-
| `
|
|
188
|
-
| `
|
|
189
|
-
| `
|
|
190
|
-
| `
|
|
191
|
-
| `
|
|
198
|
+
The "Environment" column names each option's `DEEPSEEK_*` twin — the plugin reads the
|
|
199
|
+
environment as the layer beneath these options, and the same camelCase keys also work
|
|
200
|
+
in the shared config file beneath both. `—` marks host-integration options with no
|
|
201
|
+
environment or file channel.
|
|
202
|
+
|
|
203
|
+
| Option | Environment | Default | Description |
|
|
204
|
+
| --- | --- | --- | --- |
|
|
205
|
+
| `searchEnabled` | `DEEPSEEK_ENABLE_SEARCH` | `true` | Register the DeepSeek search provider at all. Only an explicit `false` disables it. |
|
|
206
|
+
| `count` | `DEEPSEEK_SEARCH_COUNT` | `10` | Results requested from DeepSeek, 1–50. Billing is per request, not per result. |
|
|
207
|
+
| `maxResults` | `DEEPSEEK_SEARCH_MAX_RESULTS` | `10` | Results returned to the model after filtering, 0–50; defaults to `count` when unset. `0` returns no results. |
|
|
208
|
+
| `minRerank` | `DEEPSEEK_SEARCH_MIN_RERANK` | `0` | Drop results below this relevance score. DeepSeek scores are 0–3. A result without a finite score passes while the threshold is `0` and is dropped once it is positive. |
|
|
209
|
+
| `minAuthority` | `DEEPSEEK_SEARCH_MIN_AUTHORITY` | `0` | Drop known authorities below this tier. Authority is 0–4. |
|
|
210
|
+
| `allowUnknownAuthority` | `DEEPSEEK_SEARCH_ALLOW_UNKNOWN_AUTHORITY` | `true` | Keep results whose authority is missing or unknown. Only an explicit `false` disables it. |
|
|
211
|
+
| `blockedDomains` | `DEEPSEEK_SEARCH_BLOCKED_DOMAINS` | `[]` | Add `-site:` operators to the search query. |
|
|
212
|
+
| `includeDomains` | `DEEPSEEK_SEARCH_INCLUDE_DOMAINS` | `[]` | Restrict results with `site:` operators. |
|
|
213
|
+
| `language` | `DEEPSEEK_SEARCH_LANGUAGE` | unset | Add a `lang:` operator, for example `zh,en`. |
|
|
214
|
+
| `searchLocalization` | `DEEPSEEK_SEARCH_LOCALIZATION` | unset | Valid IPv4 or IPv6 address sent as DeepSeek's `localization` to prefer geo-localized results; invalid values are ignored. Deployment-level only, never a per-call parameter. |
|
|
215
|
+
| `maxSummaryChars` | `DEEPSEEK_SEARCH_MAX_SUMMARY_CHARS` | `1200` | Per-result summary cap, 0–1,000,000. |
|
|
216
|
+
| `searchTimeoutMs` | `DEEPSEEK_SEARCH_TIMEOUT_MS` | `30000` | Search timeout, 1,000–120,000 ms. |
|
|
217
|
+
| `setDefaultWebsearch` | — | `false` | Make `deepseek` the default websearch provider when the plugin loads. |
|
|
192
218
|
|
|
193
219
|
### Fetch
|
|
194
220
|
|
|
195
|
-
| Option | Default | Description |
|
|
196
|
-
| --- | --- | --- |
|
|
197
|
-
| `fetchEnabled` | `true` | Register any DeepSeek fetch tooling (the separate tool and the webfetch override). |
|
|
198
|
-
| `fetchMaxChars` | `16000` | Maximum characters returned, including the title, 0–1,000,000. |
|
|
199
|
-
| `fetchTimeoutMs` | `30000` | Fetch timeout, 1,000–120,000 ms. |
|
|
200
|
-
| `fetchOverrideWebfetch` | `false` | Replace the built-in `webfetch`. |
|
|
201
|
-
| `fetchRegisterTool` | `true` | Register the separate `deepseek_fetch` tool. |
|
|
202
|
-
| `fetchAllowedDomains` | `[]` | If non-empty, only these hosts and subdomains may be fetched. |
|
|
203
|
-
| `fetchBlockedDomains` | `[]` | Always block these hosts and subdomains. Blocked wins over allowed. |
|
|
204
|
-
| `fetchBlockPrivateHosts` | `true` | Reject localhost, private IPs, `.local`, `.internal`, and similar hosts. |
|
|
221
|
+
| Option | Environment | Default | Description |
|
|
222
|
+
| --- | --- | --- | --- |
|
|
223
|
+
| `fetchEnabled` | `DEEPSEEK_ENABLE_FETCH` | `true` | Register any DeepSeek fetch tooling (the separate tool and the webfetch override). |
|
|
224
|
+
| `fetchMaxChars` | `DEEPSEEK_FETCH_MAX_CHARS` | `16000` | Maximum characters returned, including the title, 0–1,000,000. |
|
|
225
|
+
| `fetchTimeoutMs` | `DEEPSEEK_FETCH_TIMEOUT_MS` | `30000` | Fetch timeout, 1,000–120,000 ms. |
|
|
226
|
+
| `fetchOverrideWebfetch` | — | `false` | Replace the built-in `webfetch`. |
|
|
227
|
+
| `fetchRegisterTool` | — | `true` | Register the separate `deepseek_fetch` tool. |
|
|
228
|
+
| `fetchAllowedDomains` | `DEEPSEEK_FETCH_ALLOWED_DOMAINS` | `[]` | If non-empty, only these hosts and subdomains may be fetched. |
|
|
229
|
+
| `fetchBlockedDomains` | `DEEPSEEK_FETCH_BLOCKED_DOMAINS` | `[]` | Always block these hosts and subdomains. Blocked wins over allowed. |
|
|
230
|
+
| `fetchBlockPrivateHosts` | `DEEPSEEK_FETCH_BLOCK_PRIVATE_HOSTS` | `true` | Reject localhost, private IPs, `.local`, `.internal`, and similar hosts. |
|
|
205
231
|
|
|
206
232
|
### Credentials and retries
|
|
207
233
|
|
|
208
|
-
| Option | Default | Description |
|
|
209
|
-
| --- | --- | --- |
|
|
210
|
-
| `apiKeySource` | `"auto"` | Credential strategy: `"auto"`, `"opencode"`, or `"env"`. |
|
|
211
|
-
| `maxRetries` | `
|
|
212
|
-
| `retryBaseDelayMs` | `250` | Base delay for exponential backoff. `Retry-After` is honored up to 10 seconds. |
|
|
234
|
+
| Option | Environment | Default | Description |
|
|
235
|
+
| --- | --- | --- | --- |
|
|
236
|
+
| `apiKeySource` | — | `"auto"` | Credential strategy: `"auto"`, `"opencode"`, or `"env"`. |
|
|
237
|
+
| `maxRetries` | `DEEPSEEK_MAX_RETRIES` | `2` | Retries for 408, 425, 429, and 5xx responses, 0–5. |
|
|
238
|
+
| `retryBaseDelayMs` | `DEEPSEEK_RETRY_BASE_DELAY_MS` | `250` | Base delay for exponential backoff. `Retry-After` is honored up to 10 seconds. |
|
|
213
239
|
|
|
214
240
|
## Troubleshooting
|
|
215
241
|
|