deepseek-web-retrieval 0.5.1 → 0.7.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 +21 -1
- package/README.md +167 -45
- package/dist/cli.js +2303 -1836
- package/docs/adr/0002-shared-config-base-layer.md +43 -0
- package/docs/agents/codex.md +60 -32
- package/docs/agents/opencode-v2.md +69 -39
- package/docs/agents/pi.md +60 -31
- package/docs/design/config-layering-design.md +180 -0
- package/docs/design/installer-design.md +33 -20
- package/docs/integration.md +41 -7
- package/docs/research/control-matrix.md +17 -4
- package/docs/research/mcp-compatibility.md +9 -2
- 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 +99 -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/apply.ts +5 -3
- package/src/installer/cli.ts +92 -25
- package/src/installer/config-command.ts +116 -0
- package/src/installer/hosts/codex.ts +5 -3
- package/src/installer/hosts/opencode.ts +9 -5
- package/src/installer/hosts/pi.ts +10 -6
- package/src/installer/ownership.ts +54 -1
- package/src/installer/paths.ts +7 -1
- package/src/installer/state.ts +73 -19
- package/src/installer/types.ts +12 -0
- package/src/mcp/auth.ts +2 -3
- package/src/mcp/cli.ts +9 -51
- package/src/mcp/serve.ts +60 -0
- package/src/mcp/server.ts +7 -2
- package/src/opencode/plugin.ts +22 -2
- package/src/pi/extension.ts +78 -9
- package/src/version.ts +12 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Configuration layering design
|
|
2
|
+
|
|
3
|
+
Design note for the shared configuration base layer across the three shipped adapters (MCP
|
|
4
|
+
server, OpenCode plugin, Pi extension). It records the parameter taxonomy, the precedence
|
|
5
|
+
model, and the per-adapter composition so the design survives between conversations. Host
|
|
6
|
+
capability facts live in [control-matrix.md](../research/control-matrix.md); the config
|
|
7
|
+
surface inventory was verified against the code on 2026-10-23.
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
The state this design replaced — recorded here as history, not as the present. The option
|
|
12
|
+
pipeline was already single-sourced (names, defaults, clamping in
|
|
13
|
+
`src/core/constants.ts` → `src/core/env.ts` → `src/core/options.ts`), but the *channels*
|
|
14
|
+
that fed it were fragmented per host, and a multi-host user configured the same intent in
|
|
15
|
+
up to three ways:
|
|
16
|
+
|
|
17
|
+
- **Pi** — extension runs in-process; `DEEPSEEK_*` shell variables just worked.
|
|
18
|
+
- **Codex** — stdio children do not inherit the parent environment, and the installer's
|
|
19
|
+
`env_vars` entry forwarded **only** `DEEPSEEK_API_KEY`; every other knob set in the
|
|
20
|
+
shell never reached the server unless the user hand-edited `config.toml` to add each
|
|
21
|
+
variable name. (The entry now forwards every `DEEPSEEK_*` name — see the Codex
|
|
22
|
+
consequence in [ADR-0002](../adr/0002-shared-config-base-layer.md).)
|
|
23
|
+
- **OpenCode** — the plugin resolved **only** `ctx.options` (opencode.json plugin
|
|
24
|
+
options, camelCase); `DEEPSEEK_*` variables configured nothing there, so the same
|
|
25
|
+
knob had a second, differently-named vocabulary. (The plugin now composes
|
|
26
|
+
file < environment < `ctx.options` — see the per-adapter composition below.)
|
|
27
|
+
|
|
28
|
+
One intent ("20 results, block pinterest.com"), three configuration acts, two
|
|
29
|
+
vocabularies, one silent-failure trap. The isolation was accidental, not chosen.
|
|
30
|
+
|
|
31
|
+
## Parameter taxonomy
|
|
32
|
+
|
|
33
|
+
Isolation versus unification is decided per class, not globally:
|
|
34
|
+
|
|
35
|
+
| Class | Parameters | Policy |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| **API behavior** — describes the user↔DeepSeek relationship, host-independent | `count`, `maxResults`, `minRerank`, `minAuthority`, `allowUnknownAuthority`, `blockedDomains`, `includeDomains`, `language`, `searchLocalization`, `maxRetries`, `retryBaseDelayMs` | Shared base; identical everywhere unless a host layer overrides |
|
|
38
|
+
| **Host-sensitive** — interacts with host output caps / deadlines (OpenCode 2,000 lines / 50 KiB; Pi MCP 20 KB + 60 s; Pi extension uncapped; Claude Code 25k tokens) | `searchTimeoutMs`, `fetchTimeoutMs`, `fetchMaxChars`, `maxSummaryChars` | Shared base gives the safe default; **per-host override in the host-native layer is the recommended place** to raise them |
|
|
39
|
+
| **Host integration** — describes the host's tool landscape, not the API | `searchEnabled`, `fetchEnabled`, `setDefaultWebsearch`, `fetchOverrideWebfetch`, `fetchRegisterTool`, `apiKeySource` | **Deliberately isolated.** Installer-written, host-native config only; the shared file rejects them |
|
|
40
|
+
|
|
41
|
+
Security-shaped knobs (`fetchAllowedDomains`, `fetchBlockedDomains`, `fetchBlockPrivateHosts`)
|
|
42
|
+
are classed as API behavior: they are deployment policy about the DeepSeek call itself, and a
|
|
43
|
+
shared base strengthens rather than weakens them (one policy instead of three drifting ones).
|
|
44
|
+
|
|
45
|
+
## The layering model
|
|
46
|
+
|
|
47
|
+
Precedence, low → high, identical semantics in every adapter:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
built-in defaults < shared config file < DEEPSEEK_* environment < host-native config
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- **Host-native config** means: OpenCode `ctx.options` (opencode.json plugin entry), Pi's
|
|
54
|
+
`deepseekWebRetrieval` settings namespace (the two switches), and — for MCP hosts — the
|
|
55
|
+
per-server `env` block in the host's MCP registration (that block is *how* an environment
|
|
56
|
+
variable arrives, not a fifth layer).
|
|
57
|
+
- Host-native layers keep outranking the base: installer-written intent (capability tiers)
|
|
58
|
+
and explicit per-host overrides always win, so the blast radius of a bad shared value is
|
|
59
|
+
bounded by whatever the host layer pins.
|
|
60
|
+
- The two vocabularies stay as they are — `DEEPSEEK_*` snake-case names for the environment,
|
|
61
|
+
camelCase `PluginOptions` keys for the file and OpenCode options — both generated from the
|
|
62
|
+
same single source and documented side by side.
|
|
63
|
+
|
|
64
|
+
## The shared config file
|
|
65
|
+
|
|
66
|
+
- **Path:** `$XDG_CONFIG_HOME/deepseek-web-retrieval/config.json`, defaulting to
|
|
67
|
+
`~/.config/deepseek-web-retrieval/config.json`. On win32 an explicit, non-empty
|
|
68
|
+
`XDG_CONFIG_HOME` still wins; otherwise the conventional Roaming root applies —
|
|
69
|
+
`%APPDATA%\deepseek-web-retrieval\config.json`, falling back to
|
|
70
|
+
`<home>\AppData\Roaming\deepseek-web-retrieval\config.json` when `%APPDATA%` is
|
|
71
|
+
unset. User scope, one file. A project-scope file
|
|
72
|
+
is a confirmed non-goal for this iteration (open question below).
|
|
73
|
+
- **Format:** JSON object; keys are the camelCase `PluginOptions` vocabulary (class 1 and 2
|
|
74
|
+
only). Example:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"count": 20,
|
|
79
|
+
"blockedDomains": ["pinterest.com"],
|
|
80
|
+
"language": "zh",
|
|
81
|
+
"searchLocalization": "203.0.113.7"
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- **Validation:** the file's parsed object feeds the existing `resolvePluginOptions` —
|
|
86
|
+
clamps, IP validation, and domain normalization all come along for free. Unknown keys and
|
|
87
|
+
class-3 (host-integration) keys are **rejected with a one-line stderr warning** and
|
|
88
|
+
otherwise ignored; a missing or unparseable file contributes nothing (a warning line for
|
|
89
|
+
the unparseable case), mirroring the Pi settings reader's conventions.
|
|
90
|
+
- **The API key is deliberately absent.** Auth keeps its existing channels
|
|
91
|
+
(`DEEPSEEK_API_KEY`, OpenCode's auth store, Pi's env) — a config file is liable to end up
|
|
92
|
+
synced through dotfiles, and widening key storage is a security-surface decision this
|
|
93
|
+
design does not make.
|
|
94
|
+
|
|
95
|
+
## Per-adapter composition
|
|
96
|
+
|
|
97
|
+
- **MCP server** (`src/mcp/serve.ts`): `resolveEnvOptions(env)` becomes
|
|
98
|
+
`resolveEnvOptions(env, readFileOptions())` — file keys under environment keys. The server
|
|
99
|
+
reads the file itself, so **the Codex `env_vars` trap disappears** regardless of what the
|
|
100
|
+
host forwards.
|
|
101
|
+
- **Pi extension** (`src/pi/extension.ts`): `resolveExtensionOptions` inserts the file
|
|
102
|
+
between defaults and the environment; the settings namespace stays on top, unchanged.
|
|
103
|
+
- **OpenCode plugin** (`src/opencode/plugin.ts`): `resolvePluginOptions(ctx.options)` becomes
|
|
104
|
+
`resolvePluginOptions({ ...fileOptions(), ...pluginOptionsFromEnv(process.env), ...ctx.options })`
|
|
105
|
+
— file, then environment, then the host layer. Additive only: existing opencode.json
|
|
106
|
+
options keep winning exactly as before; the change is that the file and environment now
|
|
107
|
+
work on this host too.
|
|
108
|
+
|
|
109
|
+
## Installer changes
|
|
110
|
+
|
|
111
|
+
- **Codex `env_vars`:** enumerate **every** `DEEPSEEK_*` name (generated from
|
|
112
|
+
`src/core/constants.ts`, the single source) instead of only `DEEPSEEK_API_KEY`, so
|
|
113
|
+
environment overrides work on Codex without hand-editing `config.toml`. The note the
|
|
114
|
+
installer prints is updated to match.
|
|
115
|
+
- No other host artifacts change: the installer never writes the shared file (it is a user
|
|
116
|
+
authoring surface, like a shell profile), and capability tiers stay where they are.
|
|
117
|
+
|
|
118
|
+
## Visibility
|
|
119
|
+
|
|
120
|
+
A bad shared value now fails everywhere at once, so effective configuration must be visible:
|
|
121
|
+
|
|
122
|
+
- The MCP server's startup stderr line (already printing the client identity and enabled
|
|
123
|
+
tools) additionally prints **deviations from defaults only** — e.g.
|
|
124
|
+
`config: count=20 blockedDomains=1 language=zh` — keeping the line short while showing
|
|
125
|
+
every non-default knob a multi-layer resolution produced.
|
|
126
|
+
- The OpenCode plugin and Pi extension print the same deviation summary once, at
|
|
127
|
+
registration time, through their host's logging channel (implementer picks the least
|
|
128
|
+
noisy channel per host; the content contract is "non-default effective values").
|
|
129
|
+
- `deepseek-web-retrieval config` is the user-facing arm: it prints every knob with its
|
|
130
|
+
value and source, replays the file's warnings where a human actually looks, and its
|
|
131
|
+
`--search` variant verifies the whole chain (key, config, network) with one billed
|
|
132
|
+
request.
|
|
133
|
+
|
|
134
|
+
## What this design does not change
|
|
135
|
+
|
|
136
|
+
- `need_content` stays hardcoded `false` ([search-inline-content.md](../research/search-inline-content.md)).
|
|
137
|
+
- `ori_question` remains per-call-only (`original_question` input / Pi session fallback); it
|
|
138
|
+
is not configurable.
|
|
139
|
+
- Auth surfaces, capability tiers, and the installer's plan/confirm flow.
|
|
140
|
+
|
|
141
|
+
## Testing
|
|
142
|
+
|
|
143
|
+
- Unit: file reader (missing / unparseable / unknown-key / class-3-key rejection with
|
|
144
|
+
warning), precedence matrix per adapter (defaults < file < env < host) asserted through
|
|
145
|
+
each adapter's existing resolution entry points.
|
|
146
|
+
- The installer's Codex plan snapshot gains the full `env_vars` list.
|
|
147
|
+
- Existing suites stay green; e2e scenarios unaffected (the file is absent in CI, which is
|
|
148
|
+
itself the empty-layer case).
|
|
149
|
+
|
|
150
|
+
## Rollout
|
|
151
|
+
|
|
152
|
+
Additive and non-breaking: no existing configuration loses effect, no precedence between
|
|
153
|
+
existing layers changes. Documentation updates ship with the code: README gains a
|
|
154
|
+
"Configuration" section with the precedence table and the two-vocabulary table; the host
|
|
155
|
+
guides' option tables gain a shared-file column; the control-matrix note's Pi sentence
|
|
156
|
+
("There is no per-extension options channel: the runtime config surface is the
|
|
157
|
+
`DEEPSEEK_*` environment") is updated to name the file as part of that surface.
|
|
158
|
+
|
|
159
|
+
**Amendment, 2026-10-23** — two changes approved after this design was confirmed alter
|
|
160
|
+
the effective behavior of *untouched* configurations, superseding the "no existing
|
|
161
|
+
configuration loses effect" sentence for those two knobs:
|
|
162
|
+
|
|
163
|
+
1. `maxResults` now follows the effective `count` when unset, so `count`-only
|
|
164
|
+
configurations return `count` results instead of silently truncating to the old
|
|
165
|
+
default of 10 (the one-directional asymmetry is documented at the resolution site in
|
|
166
|
+
`src/core/options.ts`).
|
|
167
|
+
2. Transient failures (408/425/429/5xx) retry twice by default instead of zero
|
|
168
|
+
(rationale and the dated vendor-survey correction live in
|
|
169
|
+
`docs/research/search-api-defaults.md`).
|
|
170
|
+
|
|
171
|
+
## Decisions (confirmed 2026-10-23)
|
|
172
|
+
|
|
173
|
+
1. **Project-scope file:** not in this iteration — hosts already own project-scope
|
|
174
|
+
semantics, and the extra precedence row is not yet earned by demand.
|
|
175
|
+
2. **Invalid-key warnings:** one stderr line per bad key at first resolution — the noise
|
|
176
|
+
buys typo detection (`"retries"` vs `"maxRetries"`) in a hand-edited file.
|
|
177
|
+
3. **File naming:** `config.json` inside the `~/.config/deepseek-web-retrieval/`
|
|
178
|
+
directory (win32: `%APPDATA%\deepseek-web-retrieval\`) — room for future siblings.
|
|
179
|
+
4. **ADR:** the layering decision is recorded as
|
|
180
|
+
[ADR 0002](../adr/0002-shared-config-base-layer.md) alongside this design note.
|
|
@@ -6,6 +6,8 @@ Design note for the install-time flow, shipped as the `deepseek-web-retrieval in
|
|
|
6
6
|
the design survives between conversations. Research backing lives in
|
|
7
7
|
[control-matrix.md](../research/control-matrix.md); host facts in [hosts.jsonc](../hosts.jsonc).
|
|
8
8
|
Remaining hosts get host modules here as their guides ship.
|
|
9
|
+
Examples involving other hosts describe design requirements for future modules;
|
|
10
|
+
the current CLI accepts only the three shipped hosts above.
|
|
9
11
|
|
|
10
12
|
## Principles
|
|
11
13
|
|
|
@@ -27,17 +29,16 @@ of the whole install.
|
|
|
27
29
|
- **Optional** — registered, the model picks freely.
|
|
28
30
|
- **Preferred** — registered plus rules steering the model toward them.
|
|
29
31
|
- **Forced** — deterministic routing (replacement, exclusion, or de-facto).
|
|
30
|
-
- **Off** — the capability
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
refuses to install anything.
|
|
32
|
+
- **Off** — the DeepSeek capability is hidden from the model through the adapter's
|
|
33
|
+
registration switch or Codex's host-side `disabled_tools` filter; the mapping below
|
|
34
|
+
describes each path. Both off refuses to install anything.
|
|
34
35
|
- **Scope** — project-level (this checkout, shareable via VCS) or global (every project
|
|
35
36
|
for that host on the machine).
|
|
36
37
|
|
|
37
38
|
## Stock configuration
|
|
38
39
|
|
|
39
40
|
The tier definitions assume a clean host. Real installs land on configuration that
|
|
40
|
-
already exists, and the installer
|
|
41
|
+
already exists, and the installer uses three phases:
|
|
41
42
|
|
|
42
43
|
1. **Detect.** Read the host config, the rules files, and the registered MCP servers.
|
|
43
44
|
Report the conflict surface: existing rules steering toward another web tool; other
|
|
@@ -50,14 +51,15 @@ already exists, and the installer runs three phases before anything is written:
|
|
|
50
51
|
which entries the installer appended; single-value keys (`websearch.provider`, Pi's
|
|
51
52
|
`exposure`) snapshot the prior value before overwriting; files the installer creates
|
|
52
53
|
are tracked as created. Nothing is written until the user approves the full plan.
|
|
53
|
-
3. **Verify.** After applying,
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
3. **Verify.** After applying, re-read the files and confirm the planned values and rules
|
|
55
|
+
were written. Runtime tool visibility and model routing are checked by host-specific
|
|
56
|
+
end-to-end scenarios, not by the installer itself.
|
|
56
57
|
|
|
57
58
|
## Tier semantics against stock configuration
|
|
58
59
|
|
|
59
|
-
- **Optional
|
|
60
|
-
without
|
|
60
|
+
- **Optional keeps built-in routing unchanged**: it registers the DeepSeek capability
|
|
61
|
+
without preference rules or competitor exclusion. An existing DeepSeek registration
|
|
62
|
+
may still need replacement, which the plan shows and snapshots; inspect the preview.
|
|
61
63
|
- **Preferred** can conflict without any config being touched: existing rules pointing
|
|
62
64
|
at another web tool produce contradictory instructions whose outcome depends on each
|
|
63
65
|
host's load order (Claude Code concatenates every level; Devin ranks team above
|
|
@@ -101,16 +103,17 @@ settings hierarchy, OpenCode's global versus project config) under three rules:
|
|
|
101
103
|
alternative — the global fallback for a kill switch, or a different tier that works
|
|
102
104
|
at project scope — instead of quietly writing to the other scope.
|
|
103
105
|
- **Blast radius is part of the plan.** Global scope changes every project the user
|
|
104
|
-
opens with that host; project scope
|
|
105
|
-
|
|
106
|
+
opens with that host; project scope normally writes into one checkout, while shared
|
|
107
|
+
config fallbacks such as Codex's retain user-wide effects. Project-local artifacts are
|
|
108
|
+
often committed, which shares the config and rules with the whole team — including the
|
|
106
109
|
`${DEEPSEEK_API_KEY}` expansion that relies on each member's environment. The impact
|
|
107
110
|
report states which applies.
|
|
108
111
|
- **Layers above the user still outrank the choice.** Managed, enterprise, and system
|
|
109
112
|
layers override anything the installer writes at either scope; the detect phase
|
|
110
113
|
reports them instead of failing silently.
|
|
111
114
|
|
|
112
|
-
Uninstall
|
|
113
|
-
|
|
115
|
+
Uninstall follows the files recorded for the chosen scope, including Codex's user-level
|
|
116
|
+
config even for a project-scope install; list shows those actual paths. The invariant is
|
|
114
117
|
guarded, not just assumed: two records for one host never claim the same file. When a
|
|
115
118
|
scope choice would overlap the other scope's record — Codex's project-scope fallback
|
|
116
119
|
onto `~/.codex/config.toml` beside a global install — the plan refuses with guidance,
|
|
@@ -133,10 +136,13 @@ Do not delete an ownership sidecar while its install is still active.
|
|
|
133
136
|
|
|
134
137
|
## Rollback
|
|
135
138
|
|
|
136
|
-
Uninstall
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
139
|
+
Uninstall restores overwritten values from their snapshots only while the current value
|
|
140
|
+
still matches what the installer wrote; later user edits are kept and reported. Merged
|
|
141
|
+
arrays lose only matching entries the installer appended, and managed rules blocks are
|
|
142
|
+
removed while surrounding user content is retained. Installer-created config files are
|
|
143
|
+
deleted only when left empty; an empty rules file is also removed. TOML comments are not
|
|
144
|
+
restored because the codec reserializes the document. The
|
|
145
|
+
[OpenCode v2 guide](../agents/opencode-v2.md) documents the failure mode this
|
|
140
146
|
avoids: `plugin remove` deletes the plugin entry but leaves `websearch.provider`
|
|
141
147
|
pointing at the removed plugin, and the user must clean up by hand.
|
|
142
148
|
|
|
@@ -192,6 +198,14 @@ into any existing `permissions` array rather than replacing it.
|
|
|
192
198
|
documents a layer above user config, so there is nothing to check there yet.
|
|
193
199
|
- Only a bare `--apply` enables writes; assigning a value such as `--apply=false`
|
|
194
200
|
is a usage error and writes nothing.
|
|
201
|
+
- `--pin` is opt-in version pinning: the ref written into host config gets the
|
|
202
|
+
running CLI's version appended (`name` becomes `name@<version>`; a ref already
|
|
203
|
+
ending in a version keeps it), so a host resolves that exact release instead of
|
|
204
|
+
the latest publish. Without the flag the ref stays unpinned, byte-identical to
|
|
205
|
+
before; re-running `init --pin` from a newer CLI moves the pin. Ref identity —
|
|
206
|
+
orphan, upgrade, and unexcludable-competitor detection — compares package names
|
|
207
|
+
with the `@version` suffix stripped (`samePackageName` in ownership.ts), so a
|
|
208
|
+
pinned ref still matches the lineage an earlier init registered.
|
|
195
209
|
- File verification precedes the install-record commit. A write or verification
|
|
196
210
|
failure restores the pre-apply files and record and checks the restored values.
|
|
197
211
|
`ApplyError.status` is `rolled_back` only after recovery and new-claim cleanup
|
|
@@ -215,8 +229,7 @@ host module; their artifacts (from the tier-to-artifact mapping) remain hand-edi
|
|
|
215
229
|
config until a module lands here. OpenCode's `opencode plugin add` remains available but
|
|
216
230
|
cannot pass options or manage snapshots; `init` supersedes it for tiered installs.
|
|
217
231
|
|
|
218
|
-
|
|
219
|
-
### Persistence and concurrent operations
|
|
232
|
+
## Persistence and concurrent operations
|
|
220
233
|
|
|
221
234
|
Install records distinguish absent files from invalid or unreadable files. The
|
|
222
235
|
reader validates version, host/scope identity, tiers, file metadata, and recorded
|
package/docs/integration.md
CHANGED
|
@@ -48,11 +48,11 @@ Codex are Apache-2.0; OpenCode and Pi are MIT. Claude Code and
|
|
|
48
48
|
Cursor are proprietary. GitHub Copilot CLI and Devin CLI publish installers and docs, not
|
|
49
49
|
source code, under proprietary terms.
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
`No adapter yet` means
|
|
55
|
-
|
|
51
|
+
OpenCode, Pi, and Codex have supported setup guides and installer host modules. The
|
|
52
|
+
MCP server in `src/mcp/` provides a possible stdio path for the remaining hosts, but
|
|
53
|
+
protocol compatibility alone does not establish a tested host setup. For those rows,
|
|
54
|
+
`No adapter yet` means no supported host-specific adapter or setup guide is shipped.
|
|
55
|
+
All version locks live in [hosts.jsonc](hosts.jsonc), the single
|
|
56
56
|
source of truth for this table; OpenCode is pinned to the adapter's tested target, not
|
|
57
57
|
necessarily the latest OpenCode release. Control tiers per host and capability — optional,
|
|
58
58
|
preferred, or forced routing — are researched in [control-matrix.md](research/control-matrix.md),
|
|
@@ -63,7 +63,7 @@ whose per-host reference also carries MCP registration and rules files.
|
|
|
63
63
|
One line per host. The [per-host reference](research/control-matrix.md#per-host-reference) carries
|
|
64
64
|
the details: built-in web tools and their kill switches, MCP registration, and rules files.
|
|
65
65
|
|
|
66
|
-
- **OpenCode v2** —
|
|
66
|
+
- **OpenCode v2** — Uses OpenCode's native plugin API and
|
|
67
67
|
exposes both a websearch provider and a fetch tool/override. See
|
|
68
68
|
[OpenCode v2](agents/opencode-v2.md).
|
|
69
69
|
- **Claude Code** — Ships built-in `WebSearch` and `WebFetch` tools. See
|
|
@@ -82,7 +82,41 @@ the details: built-in web tools and their kill switches, MCP registration, and r
|
|
|
82
82
|
the native extension adapter (the recommended path), with the MCP server as the fallback;
|
|
83
83
|
see [Pi](agents/pi.md) and [Pi in the per-host reference](research/control-matrix.md#pi).
|
|
84
84
|
|
|
85
|
-
##
|
|
85
|
+
## Upgrading existing installs
|
|
86
|
+
|
|
87
|
+
For an installation managed by `init`:
|
|
88
|
+
|
|
89
|
+
1. Run `npx deepseek-web-retrieval@latest list` from the original project directory,
|
|
90
|
+
using the same home and `XDG_CONFIG_HOME` as the original installation.
|
|
91
|
+
2. Run `npx deepseek-web-retrieval@latest init` with the original `--host`, `--scope`,
|
|
92
|
+
`--search`, and `--fetch` values, changing only the settings you intend to change.
|
|
93
|
+
Review the plan and repeat with `--apply`; re-init preserves the original snapshots
|
|
94
|
+
needed for uninstall. A global install can still claim shared configuration from a
|
|
95
|
+
particular project, so keep the original working directory for upgrades.
|
|
96
|
+
3. Refresh the package in the host and start or reload a session as described in its
|
|
97
|
+
guide. For Pi's extension path, use `pi update --extensions`. To pin the host's
|
|
98
|
+
package to the exact version being run, pass `--pin` to init (it writes
|
|
99
|
+
`deepseek-web-retrieval@X.Y.Z` into the registration); upgrading a pinned install
|
|
100
|
+
means re-running init with the newer CLI, since updating the CLI alone does not
|
|
101
|
+
move an independently pinned host package. `--package` still overrides the ref
|
|
102
|
+
entirely.
|
|
103
|
+
|
|
104
|
+
When upgrading from 0.4.0, Pi's default changes from MCP to the native extension.
|
|
105
|
+
Pass `--path mcp` explicitly to retain MCP, or `--path extension` to migrate; the plan
|
|
106
|
+
shows the old path's removals and retains the original uninstall snapshots. OpenCode's
|
|
107
|
+
native plugin and Codex's MCP path remain the same. Standalone MCP installs no longer
|
|
108
|
+
require OpenCode or Pi SDKs; native adapters use the SDKs provided by their hosts.
|
|
109
|
+
|
|
110
|
+
Keep install records and ownership sidecars: deleting them loses recovery information
|
|
111
|
+
and can cause a later init to refuse an existing registration. If an operation was
|
|
112
|
+
interrupted, follow the [recovery guidance](design/installer-design.md#persistence-and-concurrent-operations)
|
|
113
|
+
before retrying. For manual installations, update the package reference or checkout and
|
|
114
|
+
follow the host guide rather than adopting the config through init.
|
|
115
|
+
|
|
116
|
+
Code importing the core's removed `formatFetchContent` helper must migrate to
|
|
117
|
+
`formatFetchedContent`, which returns both `content` and `truncated`.
|
|
118
|
+
|
|
119
|
+
## Available paths and future hosts
|
|
86
120
|
|
|
87
121
|
- **MCP server** — shipped in `src/mcp/` (the fallback path in the [Pi](agents/pi.md) guide
|
|
88
122
|
and the path in the [Codex](agents/codex.md) guide); the broadest route for hosts that
|
|
@@ -118,7 +118,11 @@ paths imply the available scopes; keys locked to a single scope are enumerated i
|
|
|
118
118
|
([rmcp_client.rs at rust-v0.163.0](https://github.com/openai/codex/blob/rust-v0.163.0/codex-rs/codex-mcp/src/rmcp_client.rs));
|
|
119
119
|
`enabled_tools`/`disabled_tools` (verbatim raw tool-name match, filtered before
|
|
120
120
|
registration so the model never sees a disabled tool; an empty `enabled_tools` allow-list
|
|
121
|
-
exposes nothing), per-tool approval modes, and output limits
|
|
121
|
+
exposes nothing), per-tool approval modes, and output limits: MCP tool output can be
|
|
122
|
+
capped per tool via `output_token_limit` ("Token budget for one MCP tool's output,
|
|
123
|
+
before the standard 20% serialization allowance"; the default cap is not published
|
|
124
|
+
there)
|
|
125
|
+
([mcp_types.rs at rust-v0.163.0](https://github.com/openai/codex/blob/rust-v0.163.0/codex-rs/config/src/mcp_types.rs)).
|
|
122
126
|
stdio children do not inherit the parent environment (only `HOME`, `PATH`, and explicit
|
|
123
127
|
`env`), so `DEEPSEEK_API_KEY` must be passed explicitly. When a tool result has
|
|
124
128
|
`structuredContent`, Codex replaces the content blocks with the serialized JSON. No SSE.
|
|
@@ -146,6 +150,13 @@ paths imply the available scopes; keys locked to a single scope are enumerated i
|
|
|
146
150
|
tool from model requests entirely; `webfetch` has no disable config key at 2.0.32 — the
|
|
147
151
|
deterministic paths are a permissions deny (`action: "webfetch"`) or a plugin
|
|
148
152
|
tool-transform removal, the latter being what `fetchOverrideWebfetch` does.
|
|
153
|
+
- **Tool output caps** — plugin tool results truncate at 2,000 lines / 50 KiB: every
|
|
154
|
+
tool result passes through `ToolOutput.truncate` (`MAX_LINES = 2000`,
|
|
155
|
+
`MAX_BYTES = 50 KiB`), with the full output retained to a `tool-output/` file for
|
|
156
|
+
7 days
|
|
157
|
+
([tool-output.ts at v2.0.32](https://github.com/anomalyco/opencode/blob/v2.0.32/packages/core/src/tool-output.ts));
|
|
158
|
+
caps and model-channel behavior recorded in
|
|
159
|
+
[result-quality-passthrough.md](result-quality-passthrough.md).
|
|
149
160
|
- **MCP registration** — out of scope for this host: the shipped path is the plugin
|
|
150
161
|
adapter, and OpenCode's MCP support is not part of it.
|
|
151
162
|
- **Rules** — `AGENTS.md` only (no CLAUDE.md fallback in v2): global
|
|
@@ -170,7 +181,9 @@ paths imply the available scopes; keys locked to a single scope are enumerated i
|
|
|
170
181
|
`process.env` (no forwarding), and results bypass the MCP layer entirely, so neither the
|
|
171
182
|
20 KB truncation nor the 60 s request timeout applies. There is no per-extension options
|
|
172
183
|
channel: the runtime config surface is the `DEEPSEEK_*` environment (the same pipeline as
|
|
173
|
-
the MCP server)
|
|
184
|
+
the MCP server), the shared config file
|
|
185
|
+
(`~/.config/deepseek-web-retrieval/config.json`, layered under the environment), plus a
|
|
186
|
+
`deepseekWebRetrieval` settings namespace the installer writes for
|
|
174
187
|
the off tier — Pi preserves unknown settings keys on read and on its own rewrites
|
|
175
188
|
(`pi install`), verified at 1.3.0. Action methods such as `getSettings()` cannot be
|
|
176
189
|
called during extension loading, so the adapter reads the settings files itself.
|
|
@@ -181,8 +194,8 @@ paths imply the available scopes; keys locked to a single scope are enumerated i
|
|
|
181
194
|
prerequisite for every tier. SSE is rejected. Text results over 20 KB are
|
|
182
195
|
middle-truncated with the full text saved to a file, and the per-request default
|
|
183
196
|
timeout is 60 s. Pi is content-first for the model, with a `structuredContent`
|
|
184
|
-
fallback used only when a result has no content blocks
|
|
185
|
-
|
|
197
|
+
fallback used only when a result has no content blocks, unlike Codex's preference for
|
|
198
|
+
`structuredContent`, and a re-declared (not validated) tool
|
|
186
199
|
`outputSchema`.
|
|
187
200
|
- **Rules** — `AGENTS.md`/`CLAUDE.md` context files from the agent dir, the working
|
|
188
201
|
directory, and its parents; `SYSTEM.md` replaces the system prompt and `APPEND_SYSTEM.md`
|
|
@@ -117,7 +117,10 @@ differences:
|
|
|
117
117
|
content-first, falling back to `structuredContent` only when a result has no content
|
|
118
118
|
blocks (verified in `tools.ts` at v1.3.0). No `outputSchema` is declared: the SDK
|
|
119
119
|
rejects text-only results for a tool with a declared schema, and no host in the
|
|
120
|
-
matrix validates the schema anyway.
|
|
120
|
+
matrix validates the schema anyway. The per-host model-channel facts behind this —
|
|
121
|
+
which of `content`/`structuredContent` provably reaches the model on each host,
|
|
122
|
+
native adapter paths included — are recorded in
|
|
123
|
+
[result-quality-passthrough.md](result-quality-passthrough.md).
|
|
121
124
|
2. **stdio is the universal transport.** Every host in the matrix launches stdio servers
|
|
122
125
|
with the same conceptual JSON (`mcpServers` → `command`/`args`/`env`), differing only in
|
|
123
126
|
file location and cosmetic field names. stdio needs no OAuth and no URL config, and the
|
|
@@ -129,7 +132,7 @@ differences:
|
|
|
129
132
|
1.0.81+). A v1.x-built server still works today — modern clients fall back to the legacy
|
|
130
133
|
handshake — but it can never offer the stateless era; v2 serves both from one entry
|
|
131
134
|
point.
|
|
132
|
-
4. **Streamable HTTP only for a hosted deployment.** All
|
|
135
|
+
4. **Streamable HTTP only for a hosted deployment.** All seven MCP hosts surveyed here support it (with
|
|
133
136
|
different `type` strings: `http`, `streamable-http`, `streamableHttp`), and OAuth 2.1
|
|
134
137
|
resource-server behavior (RFC 9728 metadata) then applies; prefer pre-registered clients
|
|
135
138
|
over the now-deprecated Dynamic Client Registration.
|
|
@@ -139,6 +142,10 @@ differences:
|
|
|
139
142
|
truncation, environment passing, output caps, and per-host approval surfaces; consult
|
|
140
143
|
it per host rather than this summary.
|
|
141
144
|
|
|
145
|
+
These protocol findings describe compatibility at the research baseline, not completed
|
|
146
|
+
end-to-end support for every host. The shipped server exposes stdio; supported setup
|
|
147
|
+
guides and installer coverage are listed in the [integration model](../integration.md).
|
|
148
|
+
|
|
142
149
|
## Sources
|
|
143
150
|
|
|
144
151
|
### Specification and SDKs
|