deepseek-web-retrieval 0.2.0 → 0.3.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +187 -1
  2. package/README.md +13 -9
  3. package/dist/cli.js +4228 -178
  4. package/docs/adr/0001-refuse-drift-between-plan-and-apply.md +29 -0
  5. package/docs/agents/codex.md +193 -0
  6. package/docs/agents/domain.md +51 -0
  7. package/docs/agents/issue-tracker.md +45 -0
  8. package/docs/{opencode-v2.md → agents/opencode-v2.md} +30 -7
  9. package/docs/{pi.md → agents/pi.md} +35 -7
  10. package/docs/agents/triage-labels.md +15 -0
  11. package/docs/design/installer-design.md +184 -0
  12. package/docs/hosts.jsonc +59 -33
  13. package/docs/integration.md +45 -52
  14. package/docs/research/control-matrix.md +257 -0
  15. package/docs/{mcp-compatibility.md → research/mcp-compatibility.md} +39 -108
  16. package/package.json +5 -3
  17. package/src/core/auth.ts +1 -1
  18. package/src/core/client.ts +42 -249
  19. package/src/core/constants.ts +5 -0
  20. package/src/core/descriptions.ts +19 -0
  21. package/src/core/format.ts +31 -1
  22. package/src/core/jsonc.ts +16 -0
  23. package/src/core/options.ts +2 -3
  24. package/src/core/search.ts +5 -7
  25. package/src/core/transport.ts +253 -0
  26. package/src/core/types.ts +13 -11
  27. package/src/installer/apply.ts +176 -0
  28. package/src/installer/cli.ts +215 -0
  29. package/src/installer/detect.ts +85 -0
  30. package/src/installer/formats/index.ts +58 -0
  31. package/src/installer/formats/json.ts +151 -0
  32. package/src/installer/formats/rules.ts +62 -0
  33. package/src/installer/formats/toml.ts +163 -0
  34. package/src/installer/formats/value.ts +57 -0
  35. package/src/installer/hosts/codex.ts +128 -0
  36. package/src/installer/hosts/index.ts +134 -0
  37. package/src/installer/hosts/opencode.ts +118 -0
  38. package/src/installer/hosts/pi.ts +115 -0
  39. package/src/installer/hosts/shared.ts +31 -0
  40. package/src/installer/paths.ts +18 -0
  41. package/src/installer/render.ts +62 -0
  42. package/src/installer/revert.ts +61 -0
  43. package/src/installer/rulesContent.ts +32 -0
  44. package/src/installer/state.ts +63 -0
  45. package/src/installer/types.ts +126 -0
  46. package/src/installer/uninstall.ts +33 -0
  47. package/src/mcp/auth.ts +2 -1
  48. package/src/mcp/cli.ts +21 -5
  49. package/src/mcp/config.ts +70 -27
  50. package/src/mcp/server.ts +81 -65
  51. package/src/opencode/auth.ts +3 -2
  52. package/src/opencode/plugin.ts +93 -56
  53. package/src/mcp/format.ts +0 -31
@@ -0,0 +1,184 @@
1
+ # Installer design
2
+
3
+ Design note for the install-time flow, shipped as the `deepseek-web-retrieval init`,
4
+ `uninstall`, and `list` subcommands for **OpenCode, Pi, and Codex**. It records how the
5
+ [control tiers](../research/control-matrix.md) map to the artifacts the installer emits, so
6
+ the design survives between conversations. Research backing lives in
7
+ [control-matrix.md](../research/control-matrix.md); host facts in [hosts.jsonc](../hosts.jsonc).
8
+ Remaining hosts get host modules here as their guides ship.
9
+
10
+ ## Principles
11
+
12
+ - **Never overwrite user configuration without the user's knowledge.** Every write is
13
+ shown as a plan — old value → new value, per file — and confirmed before it is
14
+ applied. Single-value keys are snapshotted so rollback can restore what was there.
15
+ - **Post-install behavior and impact scope must be controllable and knowable.** The
16
+ installer reports what changes, which existing tools, rules, and MCP servers the
17
+ choice affects, what stops working, and how to undo it. If a choice cannot fully take
18
+ effect — a higher configuration layer outranks it — that is reported, never silently
19
+ dropped.
20
+
21
+ ## Goal
22
+
23
+ At install time the user makes two decisions: per capability (search and fetch
24
+ independently), how strongly the tools are routed — and separately, the effective scope
25
+ of the whole install.
26
+
27
+ - **Optional** — registered, the model picks freely.
28
+ - **Preferred** — registered plus rules steering the model toward them.
29
+ - **Forced** — deterministic routing (replacement, exclusion, or de-facto).
30
+ - **Off** — the capability's tool is not registered at all. When the other capability
31
+ stays on, the MCP entry still lands and carries that capability's server-side
32
+ false-only switch (`DEEPSEEK_ENABLE_SEARCH` / `DEEPSEEK_ENABLE_FETCH`); both off
33
+ refuses to install anything.
34
+ - **Scope** — project-level (this checkout, shareable via VCS) or global (every project
35
+ for that host on the machine).
36
+
37
+ ## Stock configuration
38
+
39
+ The tier definitions assume a clean host. Real installs land on configuration that
40
+ already exists, and the installer runs three phases before anything is written:
41
+
42
+ 1. **Detect.** Read the host config, the rules files, and the registered MCP servers.
43
+ Report the conflict surface: existing rules steering toward another web tool; other
44
+ web-capable MCP servers already on the field; array-valued keys the plan must merge
45
+ into rather than replace (`disabledTools`, `permissions.deny`, permissions
46
+ `exclude`, `disabled_tools`); and higher layers (Claude Code managed policy, Devin
47
+ enterprise team settings) that would outrank what the
48
+ installer writes.
49
+ 2. **Merge or snapshot.** Array keys merge with existing entries, recording exactly
50
+ which entries the installer appended; single-value keys (`websearch.provider`, Pi's
51
+ `exposure`) snapshot the prior value before overwriting; files the installer creates
52
+ are tracked as created. Nothing is written until the user approves the full plan.
53
+ 3. **Verify.** After applying, confirm the chosen tier actually holds: the deny rules
54
+ take effect, no higher layer overrides them, and the model sees exactly the intended
55
+ tools.
56
+
57
+ ## Tier semantics against stock configuration
58
+
59
+ - **Optional is inherently stock-safe**: purely additive — it appends new entries
60
+ without altering existing keys or values, and removes nothing. It is the safe default.
61
+ - **Preferred** can conflict without any config being touched: existing rules pointing
62
+ at another web tool produce contradictory instructions whose outcome depends on each
63
+ host's load order (Claude Code concatenates every level; Devin ranks team above
64
+ project above user); competing MCP servers stay on the field; and approval-friction
65
+ asymmetry (for example Cursor's `autoAcceptWebSearch` making the built-in search
66
+ zero-friction) can outweigh prompt-level steering. The installer surfaces these
67
+ conditions; it does not resolve them.
68
+ - **Forced is conditional**: the exclusion kill switches remove the built-in
69
+ competitor, not third-party web MCP servers — those must be excluded too (the
70
+ per-host keys cover them), or routing is not actually forced. Concretely: Pi's
71
+ per-server `enabled` key lets the plan disable detected web-capable competitors
72
+ (each prior value snapshotted for uninstall); Codex has no per-server kill switch,
73
+ so a detected web-capable competitor makes the plan refuse the tier instead of
74
+ promising non-exclusive routing; OpenCode's forced is replacement, which no
75
+ third-party server overrides. Detection classifies a server web-capable from its
76
+ name plus its command/args/url — a heuristic the plan notes never hide. Forced also
77
+ overrides
78
+ explicit user choices (OpenCode's `websearch.provider`), and its deny rules affect
79
+ workflows beyond this project (a Claude Code deny cannot be carved out by allow
80
+ rules), so the plan must state the blast radius before the user approves it.
81
+ - **Forced is not universally available**: where hosts.jsonc records `forced: "none"`
82
+ (Cursor's search today), the wizard does not offer the tier — the tier-level analogue
83
+ of the scope rule: honor or report, never offer what cannot be delivered. Some kill
84
+ switches are session-scoped (Copilot fetch's `--deny-tool`/`--excluded-tools` flags);
85
+ an installer cannot persist them, so the plan reports that the exclusion evaporates on
86
+ restart and offers what persistence exists.
87
+
88
+ ## Scope
89
+
90
+ The effective scope is a first-class install-time choice, decided by the user alongside
91
+ the tiers — not inferred from the artifacts. The installer maps the choice onto the
92
+ host's scope pairs (Pi's agent dir versus `.pi/`,
93
+ Cursor's `cli-config.json` versus `.cursor/cli.json`, Claude Code's
94
+ settings hierarchy, OpenCode's global versus project config) under three rules:
95
+
96
+ - **Honor or report, never silently downgrade.** Some keys exist at only one scope:
97
+ Devin's `disabled_tools` is user-level only (project config allows just
98
+ `permissions`, `read_config_from`, and `hooks`); Cline's
99
+ `global-settings.json` and MCP settings file are user-scope at 0.0.13. When the
100
+ chosen scope cannot be honored for an artifact, the plan says so and offers the
101
+ alternative — the global fallback for a kill switch, or a different tier that works
102
+ at project scope — instead of quietly writing to the other scope.
103
+ - **Blast radius is part of the plan.** Global scope changes every project the user
104
+ opens with that host; project scope is confined to one checkout but is often
105
+ committed, which shares the config and rules with the whole team — including the
106
+ `${DEEPSEEK_API_KEY}` expansion that relies on each member's environment. The impact
107
+ report states which applies.
108
+ - **Layers above the user still outrank the choice.** Managed, enterprise, and system
109
+ layers override anything the installer writes at either scope; the detect phase
110
+ reports them instead of failing silently.
111
+
112
+ Uninstall is scope-aware: removing a project-scope install never touches user-scope
113
+ entries and vice versa, and a list mode shows what is installed where. The invariant is
114
+ guarded, not just assumed: two records for one host never claim the same file. When a
115
+ scope choice would overlap the other scope's record — Codex's project-scope fallback
116
+ onto `~/.codex/config.toml` beside a global install — the plan refuses with guidance,
117
+ and uninstall runs the same check defensively before touching anything.
118
+
119
+ ## Rollback
120
+
121
+ Uninstall reverses exactly what the plan applied: overwritten values restore their
122
+ snapshots, merged arrays remove only the entries the installer appended, appended rules
123
+ content is removed, and files the installer created are deleted — nothing more, nothing
124
+ less. The [OpenCode v2 guide](../agents/opencode-v2.md) documents the failure mode this
125
+ avoids: `plugin remove` deletes the plugin entry but leaves `websearch.provider`
126
+ pointing at the removed plugin, and the user must clean up by hand.
127
+
128
+ ## Tier-to-artifact mapping
129
+
130
+ | Choice | Artifacts |
131
+ | --- | --- |
132
+ | Optional | Host config registering the server, plus host-side per-tool filtering where supported (Copilot `tools` whitelist, Codex `enabled_tools`); Pi needs `"exposure": "direct"` |
133
+ | Preferred | The above plus a rules file for the host (file names per host in the [per-host reference](../research/control-matrix.md#per-host-reference)) |
134
+ | Forced (replacement) | OpenCode plugin options (`setDefaultWebsearch` / `fetchOverrideWebfetch`) |
135
+ | Forced (exclusion) | The built-in competitor's kill switch (per-host keys in the per-host reference), plus the exclusion of any other web-capable MCP servers the detect phase found — Pi sets their `enabled` key to `false`; Codex, lacking a per-server kill switch, refuses the tier instead |
136
+ | Forced (de-facto) | Nothing beyond the Optional artifacts — no competitor exists |
137
+ | Off | The MCP entry with the capability's false-only server-side switch instead of that tool (`DEEPSEEK_ENABLE_SEARCH` / `DEEPSEEK_ENABLE_FETCH`); both capabilities off refuses to install |
138
+
139
+ OpenCode additionally appends `permissions` allow entries for exactly the tools it
140
+ registers (`websearch`, `deepseek_fetch`, and `webfetch` when fetch is forced), merged
141
+ into any existing `permissions` array rather than replacing it.
142
+
143
+ ## Non-negotiables
144
+
145
+ - **Cost warning on the Forced tier.** Search and Fetch are billed per successful
146
+ request; deterministic routing removes both the model's discretion and its restraint as
147
+ a cost brake. Every forced-tier plan carries a note naming the README's "Privacy and
148
+ cost" section.
149
+ - **Rules content.** Name the full tool ids (`mcp__deepseek__deepseek_web_search`), state
150
+ trigger conditions rather than unconditional preference, and list exclusions
151
+ (localhost/private-network URLs go to local fetch tools; the server blocks them by
152
+ default).
153
+
154
+ ## Implementation notes
155
+
156
+ - JSON edits go through `jsonc-parser` (the library behind VS Code's JSON support), so
157
+ comments and formatting in `opencode.jsonc` and Pi's `mcp.json` survive apply and
158
+ uninstall; TOML edits go through `smol-toml` and drop comments, which the plan reports
159
+ as a note. The hand-written JSONC stripper that predated this lived in `scripts/jsonc.ts`.
160
+ - Install state lives per host and scope (global under
161
+ `~/.config/deepseek-web-retrieval/`, project under `.deepseek-web-retrieval/`); it
162
+ records snapshots, appended entries, created files, and created path prefixes — never
163
+ full file contents, so other servers' secrets stay out of the state file.
164
+ - Re-applying over a previous init inherits the original snapshots instead of recording
165
+ the installer's own output as the "previous" value.
166
+ - Verify is file-level: after apply it re-reads each written file and asserts every op
167
+ holds (set values in place, appended entries present, rules block present). Higher
168
+ layers would be a plan-time detect concern, and none of the three shipped hosts
169
+ documents a layer above user config, so there is nothing to check there yet.
170
+
171
+ ## Server-side gap (resolved)
172
+
173
+ The MCP server now honors `DEEPSEEK_ENABLE_SEARCH` / `DEEPSEEK_ENABLE_FETCH`
174
+ (false-only switches through the shared option pipeline) and refuses to start when both
175
+ are disabled; the OpenCode plugin honors the matching `searchEnabled` / `fetchEnabled`
176
+ options. Per-capability control is uniform across hosts, including those without
177
+ host-side tool filtering.
178
+
179
+ ## Hosts without an installer story
180
+
181
+ Claude Code, Cursor, Devin, GitHub Copilot, and Cline still have no
182
+ host module; their artifacts (from the tier-to-artifact mapping) remain hand-edited
183
+ config until a module lands here. OpenCode's `opencode plugin add` remains available but
184
+ cannot pass options or manage snapshots; `init` supersedes it for tiered installs.
package/docs/hosts.jsonc CHANGED
@@ -1,13 +1,23 @@
1
1
  {
2
2
  // Single source of truth for the host compatibility matrix. Machine consumers:
3
- // scripts/render-matrix.ts (regenerates the table in docs/integration.md via
4
- // `bun run docs:matrix`), scripts/ci-matrix.ts (GitHub Actions matrix),
3
+ // scripts/render-matrix.ts (regenerates the host table in docs/integration.md and the
4
+ // control matrix in docs/research/control-matrix.md via `bun run docs:matrix`),
5
+ // scripts/ci-matrix.ts (GitHub Actions matrix),
5
6
  // test/e2e/run.ts (Docker build args), and test/hosts.test.ts (invariants).
6
7
  // Narrative docs reference this file; they must not restate these facts.
7
8
  //
8
9
  // Mechanism ids in "paths" align with the Mechanisms table in
9
10
  // docs/integration.md: native-provider, native-override, plugin, extension,
10
11
  // mcp, wrapper. "paths" is ordered: the first entry is the recommended path.
12
+ // "control" aligns with docs/research/control-matrix.md: per capability, the optional/
13
+ // preferred tiers ("yes" or structurally "n/a") and the forced tier —
14
+ // "replacement" (swap the built-in implementation), "exclusion" (disable or
15
+ // deny the built-in competitor), "de-facto" (no built-in competitor), or
16
+ // "none" — plus the config key that realizes it.
17
+ // Version mentions inside `key` strings and per-host prose are research-provenance
18
+ // anchors verified at the locked version, not lock restatements; re-verify them
19
+ // whenever "baseline" or a host "version" changes (docs/research/control-matrix.md
20
+ // tracks the known drift points).
11
21
  // Rows render in file order — keep open-source hosts first, then alphabetical.
12
22
  "baseline": "2026-10-19",
13
23
  "hosts": [
@@ -20,7 +30,11 @@
20
30
  "nativeSearchProvider": false,
21
31
  "nativeFetchOverride": false,
22
32
  "paths": ["mcp", "plugin"],
23
- "status": "no-adapter-yet"
33
+ "status": "no-adapter-yet",
34
+ "control": {
35
+ "search": { "optional": "yes", "preferred": "yes", "forced": "de-facto", "key": "no built-in web-search tool at 0.0.13 (binary-verified)" },
36
+ "fetch": { "optional": "yes", "preferred": "yes", "forced": "exclusion", "key": "`disabledTools` in `~/.cline/data/settings/global-settings.json`" }
37
+ },
24
38
  },
25
39
  {
26
40
  "name": "codex",
@@ -31,29 +45,15 @@
31
45
  "nativeSearchProvider": false,
32
46
  "nativeFetchOverride": false,
33
47
  "paths": ["mcp"],
34
- "status": "no-adapter-yet"
35
- },
36
- {
37
- "name": "continue",
38
- "display": "Continue",
39
- "version": "1.5.47",
40
- "license": "Apache-2.0",
41
- "npm": "@continuedev/cli",
42
- "nativeSearchProvider": false,
43
- "nativeFetchOverride": false,
44
- "paths": ["mcp"],
45
- "status": "no-adapter-yet"
46
- },
47
- {
48
- "name": "gemini",
49
- "display": "Gemini",
50
- "version": "0.64.0",
51
- "license": "Apache-2.0",
52
- "npm": "@google/gemini-cli",
53
- "nativeSearchProvider": false,
54
- "nativeFetchOverride": false,
55
- "paths": ["mcp"],
56
- "status": "no-adapter-yet"
48
+ "status": "supported",
49
+ "adapter": "src/mcp",
50
+ "installer": "src/installer/hosts/codex",
51
+ "guide": "docs/agents/codex.md",
52
+ "e2eScenario": "codex",
53
+ "control": {
54
+ "search": { "optional": "yes", "preferred": "yes", "forced": "exclusion", "key": "`web_search = \"disabled\"` (top-level config.toml)" },
55
+ "fetch": { "optional": "yes", "preferred": "yes", "forced": "de-facto", "key": "no built-in fetch tool at 0.163.0" }
56
+ },
57
57
  },
58
58
  {
59
59
  "name": "opencode",
@@ -63,10 +63,15 @@
63
63
  "npm": "@opencode/cli",
64
64
  "nativeSearchProvider": true,
65
65
  "nativeFetchOverride": true,
66
- "paths": ["plugin"],
66
+ "paths": ["native-provider", "native-override"],
67
67
  "status": "supported",
68
+ "control": {
69
+ "search": { "optional": "n/a", "preferred": "n/a", "forced": "replacement", "key": "`websearch.provider: \"deepseek\"` or plugin `setDefaultWebsearch`" },
70
+ "fetch": { "optional": "yes", "preferred": "yes", "forced": "replacement", "key": "`fetchOverrideWebfetch: true`" }
71
+ },
68
72
  "adapter": "src/opencode",
69
- "guide": "docs/opencode-v2.md",
73
+ "installer": "src/installer/hosts/opencode",
74
+ "guide": "docs/agents/opencode-v2.md",
70
75
  "e2eScenario": "opencode"
71
76
  },
72
77
  {
@@ -79,8 +84,13 @@
79
84
  "nativeFetchOverride": false,
80
85
  "paths": ["mcp", "extension"],
81
86
  "status": "supported",
87
+ "control": {
88
+ "search": { "optional": "yes", "preferred": "yes", "forced": "de-facto", "key": "no built-in web tool at 1.3.0 (source-verified)" },
89
+ "fetch": { "optional": "yes", "preferred": "yes", "forced": "de-facto", "key": "no built-in web tool at 1.3.0 (source-verified)" }
90
+ },
82
91
  "adapter": "src/mcp",
83
- "guide": "docs/pi.md",
92
+ "installer": "src/installer/hosts/pi",
93
+ "guide": "docs/agents/pi.md",
84
94
  "e2eScenario": "pi"
85
95
  },
86
96
  {
@@ -92,7 +102,11 @@
92
102
  "nativeSearchProvider": false,
93
103
  "nativeFetchOverride": false,
94
104
  "paths": ["mcp"],
95
- "status": "no-adapter-yet"
105
+ "status": "no-adapter-yet",
106
+ "control": {
107
+ "search": { "optional": "yes", "preferred": "yes", "forced": "exclusion", "key": "`permissions.deny: [\"WebSearch\"]` removes the tool from context" },
108
+ "fetch": { "optional": "yes", "preferred": "yes", "forced": "exclusion", "key": "`permissions.deny: [\"WebFetch\"]`, or `CLAUDE_CODE_DISABLE_WEB_FETCH=1`" }
109
+ },
96
110
  },
97
111
  {
98
112
  "name": "cursor",
@@ -102,7 +116,11 @@
102
116
  "nativeSearchProvider": false,
103
117
  "nativeFetchOverride": false,
104
118
  "paths": ["mcp"],
105
- "status": "no-adapter-yet"
119
+ "status": "no-adapter-yet",
120
+ "control": {
121
+ "search": { "optional": "yes", "preferred": "yes", "forced": "none", "key": "" },
122
+ "fetch": { "optional": "yes", "preferred": "yes", "forced": "exclusion", "key": "`permissions.deny: [\"WebFetch(*)\"]`" }
123
+ },
106
124
  },
107
125
  {
108
126
  "name": "devin",
@@ -112,7 +130,11 @@
112
130
  "nativeSearchProvider": false,
113
131
  "nativeFetchOverride": false,
114
132
  "paths": ["mcp"],
115
- "status": "no-adapter-yet"
133
+ "status": "no-adapter-yet",
134
+ "control": {
135
+ "search": { "optional": "yes", "preferred": "yes", "forced": "exclusion", "key": "`disabled_tools` / `permissions.deny` in config.json" },
136
+ "fetch": { "optional": "yes", "preferred": "yes", "forced": "exclusion", "key": "`disabled_tools` / `permissions.deny` in config.json" }
137
+ },
116
138
  },
117
139
  {
118
140
  "name": "github-copilot",
@@ -123,7 +145,11 @@
123
145
  "nativeSearchProvider": false,
124
146
  "nativeFetchOverride": false,
125
147
  "paths": ["mcp"],
126
- "status": "no-adapter-yet"
148
+ "status": "no-adapter-yet",
149
+ "control": {
150
+ "search": { "optional": "yes", "preferred": "yes", "forced": "exclusion", "key": "`githubMcpTools` settings (competitor ships via the bundled GitHub MCP server)" },
151
+ "fetch": { "optional": "yes", "preferred": "yes", "forced": "exclusion", "key": "`--deny-tool web_fetch` / `--excluded-tools` (session flags)" }
152
+ },
127
153
  }
128
154
  ]
129
155
  }
@@ -3,11 +3,11 @@
3
3
  [DeepSeek Web Retrieval](../README.md) is not tied to one host. Whether a coding agent can
4
4
  use it depends on that agent's extension points.
5
5
 
6
- **Research baseline:** 2026-10-19. This matrix covers CLI/terminal agents only; IDE and
7
- editor extension surfaces are out of scope. Versions are the latest stable CLI release
8
- checked on that date unless noted otherwise. `No` means no documented native provider or
9
- override was found in the checked version; several hosts still ship built-in web tools.
10
- MCP tools can add equivalent tools, but do not replace built-ins.
6
+ **Research baseline:** the `baseline` field of [hosts.jsonc](hosts.jsonc). This matrix covers
7
+ CLI/terminal agents only; IDE and editor extension surfaces are out of scope. Versions are
8
+ the latest stable CLI release checked at that baseline unless noted otherwise. `No` means no
9
+ documented native provider or override was found in the checked version; several hosts still
10
+ ship built-in web tools. MCP tools can add equivalent tools, but do not replace built-ins.
11
11
 
12
12
  ## Mechanisms
13
13
 
@@ -15,7 +15,8 @@ MCP tools can add equivalent tools, but do not replace built-ins.
15
15
  | --- | --- | --- | --- | --- |
16
16
  | Native websearch provider | Yes | No | Host plugin API | OpenCode v2 adapter |
17
17
  | Native tool / fetch override | No | Yes | Host tool API | OpenCode v2 adapter |
18
- | Custom tool plugin | Yes | Yes | Host plugin API | Cline CLI/SDK and Pi; no adapter yet |
18
+ | Custom tool plugin | Yes | Yes | Host plugin API | Cline CLI/SDK; no adapter yet |
19
+ | Extension API | Yes | Yes | Host extension API | Pi; no adapter yet |
19
20
  | MCP server | Yes | Yes | Host MCP client | Shipped (`src/mcp/`; Pi guide first) |
20
21
  | CLI/HTTP wrapper | Yes | Yes | Host can call external tools | Not shipped |
21
22
 
@@ -30,12 +31,10 @@ Rows are sorted with open-source hosts first, then by host name alphabetically.
30
31
 
31
32
  | Host | Version checked | Open source | Native search provider | Native fetch override | Best path | Status |
32
33
  | --- | --- | --- | --- | --- | --- | --- |
33
- | Cline | 0.0.13 | Yes (Apache-2.0) | No | No | MCP server or plugin | No adapter yet |
34
- | Codex | 0.163.0 | Yes (Apache-2.0) | No | No | MCP server | No adapter yet |
35
- | Continue | 1.5.47 | Yes (Apache-2.0) | No | No | MCP server | No adapter yet |
36
- | Gemini | 0.64.0 | Yes (Apache-2.0) | No | No | MCP server | No adapter yet |
37
- | OpenCode | 2.0.32 | Yes (MIT) | Yes | Yes | plugin | Supported |
38
- | Pi | 1.3.0 | Yes (MIT) | No | No | MCP server or extension | Supported |
34
+ | Cline | 0.0.13 | Yes (Apache-2.0) | No | No | MCP server or custom tool plugin | No adapter yet |
35
+ | Codex | 0.163.0 | Yes (Apache-2.0) | No | No | MCP server | Supported |
36
+ | OpenCode | 2.0.32 | Yes (MIT) | Yes | Yes | native websearch provider or native tool/fetch override | Supported |
37
+ | Pi | 1.3.0 | Yes (MIT) | No | No | MCP server or extension API | Supported |
39
38
  | Claude Code | 2.1.303 | No | No | No | MCP server | No adapter yet |
40
39
  | Cursor | 2026.10.08 | No | No | No | MCP server | No adapter yet |
41
40
  | Devin | 3000.11.92 | No | No | No | MCP server | No adapter yet |
@@ -44,8 +43,8 @@ Rows are sorted with open-source hosts first, then by host name alphabetically.
44
43
  <!-- /generated: host-matrix -->
45
44
 
46
45
  `Open source` refers to the CLI/client code at the checked version, verified from the
47
- project repositories on 2026-10-19. It does not cover the hosted model service. Cline,
48
- Codex, Continue, and Gemini CLI are Apache-2.0; OpenCode and Pi are MIT. Claude Code and
46
+ project repositories on 2026-10-19. It does not cover the hosted model service. Cline and
47
+ Codex are Apache-2.0; OpenCode and Pi are MIT. Claude Code and
49
48
  Cursor are proprietary. GitHub Copilot CLI and Devin CLI publish installers and docs, not
50
49
  source code, under proprietary terms.
51
50
 
@@ -55,41 +54,38 @@ listed as supported only after an adapter and guide exist; for the remaining hos
55
54
  `No adapter yet` means the shipped MCP server already provides the path, but no guide for
56
55
  that host exists yet. All version locks live in [hosts.jsonc](hosts.jsonc), the single
57
56
  source of truth for this table; OpenCode is pinned to the adapter's tested target, not
58
- necessarily the latest OpenCode release.
57
+ necessarily the latest OpenCode release. Control tiers per host and capability — optional,
58
+ preferred, or forced routing — are researched in [control-matrix.md](research/control-matrix.md),
59
+ whose per-host reference also carries MCP registration and rules files.
59
60
 
60
61
  ## Host notes
61
62
 
63
+ One line per host. The [per-host reference](research/control-matrix.md#per-host-reference) carries
64
+ the details: built-in web tools and their kill switches, MCP registration, and rules files.
65
+
62
66
  - **OpenCode v2** — The only shipped adapter. It uses OpenCode's native plugin API and
63
67
  exposes both a websearch provider and a fetch tool/override. See
64
- [OpenCode v2](opencode-v2.md).
65
- - **Claude Code** — Ships built-in `WebSearch` and `WebFetch` tools. No documented native
66
- provider or override; MCP servers can add tools, and hooks can block calls but do not
67
- replace the fetch implementation.
68
- - **Codex** — MCP servers can add tools. No documented native websearch provider or fetch
69
- override.
70
- - **Gemini** — Gemini CLI ships built-in `google_web_search` and `web_fetch` tools. No
71
- documented native provider or override; MCP servers and extensions can add tools.
72
- - **Cursor** — Cursor CLI uses the same `mcp.json` servers as the editor. No documented
73
- native provider or fetch override.
74
- - **GitHub Copilot** — Copilot CLI supports MCP servers; plugins can bundle MCP servers.
75
- No documented native provider or fetch override.
76
- - **Cline** — Cline CLI supports MCP. CLI/SDK plugins can add custom tools, but the built-in
77
- `fetch_web_content` tool is not replaced.
78
- - **Continue** — Continue CLI supports MCP servers. A built-in `search_web` tool exists, but
79
- it is not a custom provider, and there is no documented fetch override.
80
- - **Devin** — Devin CLI supports MCP servers. Plugins bundle skills, rules, hooks, and MCP
81
- servers, not arbitrary custom tools. Windsurf Desktop/Cascade is a separate IDE surface
82
- and is not included in this row.
83
- - **Pi** — Pi 1.3.0 has native MCP support and a TypeScript extension API that can add
84
- custom tools. The core ships read/bash/edit/write tools; web search/fetch are added by
85
- extensions or MCP. No native websearch provider or fetch override. Supported through the
86
- MCP server; see [Pi](pi.md).
68
+ [OpenCode v2](agents/opencode-v2.md).
69
+ - **Claude Code** — Ships built-in `WebSearch` and `WebFetch` tools. See
70
+ [Claude Code](research/control-matrix.md#claude-code).
71
+ - **Codex** — Ships a built-in `web_search` tool. Supported through the MCP server; see
72
+ [Codex](agents/codex.md) and [Codex in the per-host reference](research/control-matrix.md#codex).
73
+ - **Cursor** — Uses the same `mcp.json` servers as the editor; ships built-in web search
74
+ and `WebFetch` tools. See [Cursor](research/control-matrix.md#cursor).
75
+ - **GitHub Copilot** — Ships a built-in `web_fetch` tool, and web search via the bundled
76
+ GitHub MCP server. See [GitHub Copilot](research/control-matrix.md#github-copilot).
77
+ - **Cline** — Ships a built-in `fetch_web_content` tool. See
78
+ [Cline](research/control-matrix.md#cline).
79
+ - **Devin** — Ships built-in `web_search` and `webfetch` tools. See
80
+ [Devin](research/control-matrix.md#devin).
81
+ - **Pi** — No built-in web tools; MCP plus a TypeScript extension API. Supported through
82
+ the MCP server; see [Pi](agents/pi.md) and [Pi in the per-host reference](research/control-matrix.md#pi).
87
83
 
88
84
  ## Roadmap
89
85
 
90
- - **MCP server** — shipped in `src/mcp/` with the [Pi](pi.md) guide; the broadest path for
86
+ - **MCP server** — shipped in `src/mcp/` with the [Pi](agents/pi.md) guide; the broadest path for
91
87
  hosts that support MCP tools. Protocol compatibility across these hosts is researched in
92
- [mcp-compatibility.md](mcp-compatibility.md).
88
+ [mcp-compatibility.md](research/mcp-compatibility.md).
93
89
  - **Host-specific guides** — added as requests and testing land; the server itself is
94
90
  host-agnostic.
95
91
 
@@ -100,16 +96,12 @@ necessarily the latest OpenCode release.
100
96
  [tools reference](https://code.claude.com/docs/en/tools-reference)
101
97
  - Codex: [MCP](https://developers.openai.com/codex/mcp),
102
98
  [CLI](https://developers.openai.com/codex/cli)
103
- - Gemini CLI: [tools reference](https://geminicli.com/docs/reference/tools/),
104
- [MCP](https://geminicli.com/docs/tools/mcp-server/)
105
99
  - Cursor: [MCP](https://cursor.com/docs/mcp),
106
100
  [CLI changelog](https://cursor.com/docs/cli/changelog)
107
101
  - Copilot CLI: [repository](https://github.com/github/copilot-cli),
108
102
  [MCP docs](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers)
109
103
  - Cline: [MCP](https://docs.cline.bot/mcp/mcp-overview),
110
104
  [tools reference](https://docs.cline.bot/tools-reference/all-cline-tools)
111
- - Continue: [MCP](https://docs.continue.dev/customize/deep-dives/mcp),
112
- [agent tools](https://docs.continue.dev/ide-extensions/agent/how-it-works)
113
105
  - Devin CLI: [extensibility](https://docs.devin.ai/cli/extensibility/index),
114
106
  [MCP](https://docs.devin.ai/cli/extensibility/mcp/overview)
115
107
  - Pi: [extensions](https://pi.dev/docs/latest/extensions),
@@ -119,15 +111,13 @@ Version sources:
119
111
 
120
112
  - npm: [Claude Code](https://www.npmjs.com/package/@anthropic-ai/claude-code),
121
113
  [Codex](https://www.npmjs.com/package/@openai/codex),
122
- [Gemini CLI](https://www.npmjs.com/package/@google/gemini-cli),
123
114
  [Cline CLI](https://www.npmjs.com/package/@cline/cli),
124
- [Continue CLI](https://www.npmjs.com/package/@continuedev/cli),
125
115
  [Pi](https://www.npmjs.com/package/@earendil-works/pi-coding-agent)
126
116
  - Releases: [Copilot CLI](https://github.com/github/copilot-cli/releases)
127
117
  - Changelogs: [Cursor CLI](https://cursor.com/docs/cli/changelog),
128
118
  [Devin CLI](https://docs.devin.ai/cli/changelog),
129
119
  [Pi](https://pi.dev/changelog)
130
- - OpenCode: `2.0.32` adapter target in this repository
120
+ - OpenCode: the adapter's tested target, locked in [hosts.jsonc](hosts.jsonc)
131
121
 
132
122
  ## Evaluating a host
133
123
 
@@ -137,11 +127,14 @@ Check the host's documentation for these questions:
137
127
  2. Can a plugin add a custom tool, or replace the built-in fetch tool?
138
128
  3. Does the host support MCP servers?
139
129
  4. Can the host call an external CLI or HTTP tool?
130
+ 5. Which rules or instruction files does the host read, and can they steer tool preference?
131
+ 6. Which built-in web tools does it ship, and can each be disabled or denied?
140
132
 
141
- Record the answers in `docs/<agent>.md`. Add a link from the README Usage section only after
142
- the adapter ships. To request evaluation for another host,
143
- [open an issue](https://github.com/gwokhou/deepseek-web-retrieval/issues) with links to its
144
- plugin, tool, or MCP documentation.
133
+ Record the answers in the per-host reference in
134
+ [research/control-matrix.md](research/control-matrix.md#per-host-reference). Add a link from
135
+ the README Usage section only after the adapter ships. To request evaluation for another
136
+ host, [open an issue](https://github.com/gwokhou/deepseek-web-retrieval/issues) with links
137
+ to its plugin, tool, or MCP documentation.
145
138
 
146
139
  ## Why the distinction matters
147
140
 
@@ -155,5 +148,5 @@ code and docs need to match the mechanism the host actually provides.
155
148
  the host table with `bun run docs:matrix`.
156
149
  - Put shared retrieval logic in `src/core/`.
157
150
  - Put host-specific glue in `src/<agent>/`, or in `src/mcp/` for the cross-host MCP server.
158
- - Document setup and usage in `docs/<agent>.md`.
151
+ - Document setup and usage in `docs/agents/<agent>.md`.
159
152
  - Link the guide from the README Usage section.