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
package/docs/agents/pi.md
CHANGED
|
@@ -22,6 +22,8 @@ When loaded, it adds:
|
|
|
22
22
|
Pi 1.3.0 ships no built-in web tool, so the registered tools are the only web path. For
|
|
23
23
|
shared search/fetch limits, retries, and privacy behavior, see
|
|
24
24
|
[General behavior](../../README.md#general-behavior).
|
|
25
|
+
For configuration layers, the full knob mapping, and defaults, see the
|
|
26
|
+
[configuration guide](../configuration.md).
|
|
25
27
|
|
|
26
28
|
## Requirements
|
|
27
29
|
|
|
@@ -42,7 +44,9 @@ npx deepseek-web-retrieval init --host pi --scope <project|global> \
|
|
|
42
44
|
```
|
|
43
45
|
|
|
44
46
|
It prints the full plan — every file, old value → new value, and notes about existing
|
|
45
|
-
packages and MCP servers — and writes nothing until you pass `--apply`.
|
|
47
|
+
packages and MCP servers — and writes nothing until you pass `--apply`. Add `--pin` to
|
|
48
|
+
register the exact version of the CLI you are running instead of the always-latest
|
|
49
|
+
package name. The default path is
|
|
46
50
|
the extension: the plan appends `npm:deepseek-web-retrieval` to the `packages` array in
|
|
47
51
|
`~/.pi/agent/settings.json` (global) or `.pi/settings.json` (project), and Pi resolves the
|
|
48
52
|
source at the next session start (the first launch fetches the package from npm;
|
|
@@ -102,6 +106,12 @@ Fetch https://pi.dev/docs/latest/extensions and summarize the extension lifecycl
|
|
|
102
106
|
The model calls `deepseek_web_search` or `deepseek_fetch` — the same names over both paths;
|
|
103
107
|
only the MCP fallback prefixes them with `mcp__deepseek__`.
|
|
104
108
|
|
|
109
|
+
The search tool accepts an optional `original_question` input — the user's question in their
|
|
110
|
+
own words — forwarded as DeepSeek's `ori_question` to sharpen search intent. When the model
|
|
111
|
+
leaves it blank, the extension falls back to the most recent user message in the session
|
|
112
|
+
(best-effort; truncated to the API's 128-character limit). The MCP fallback path has no
|
|
113
|
+
session access, so there a blank input simply omits the parameter.
|
|
114
|
+
|
|
105
115
|
## Configuration
|
|
106
116
|
|
|
107
117
|
The runtime config surface is the same `DEEPSEEK_*` environment the MCP server reads
|
|
@@ -109,40 +119,53 @@ The runtime config surface is the same `DEEPSEEK_*` environment the MCP server r
|
|
|
109
119
|
`deepseekWebRetrieval` settings namespace for the off switches (written by the installer;
|
|
110
120
|
it outranks the environment and is preserved by Pi's own settings rewrites).
|
|
111
121
|
|
|
122
|
+
The shared config file (`~/.config/deepseek-web-retrieval/config.json`, camelCase keys —
|
|
123
|
+
on Windows, `%APPDATA%\deepseek-web-retrieval\config.json`)
|
|
124
|
+
also sits in this surface, layered under the environment, and needs no forwarding on any
|
|
125
|
+
path — the extension and the MCP server both read the file themselves. One file therefore
|
|
126
|
+
configures every host running this package, with this host's environment and settings
|
|
127
|
+
still outranking it. `npx deepseek-web-retrieval config` prints what actually resolves —
|
|
128
|
+
each knob's value and source, with file warnings surfaced and `--search "<query>"` running
|
|
129
|
+
one billed search through it all.
|
|
130
|
+
|
|
112
131
|
### Search
|
|
113
132
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
133
|
+
The "Config file" column names each key's camelCase twin in the shared config file —
|
|
134
|
+
one vocabulary pair, one pipeline. `—` marks host-integration entries the file rejects.
|
|
135
|
+
|
|
136
|
+
| Env variable | Config file | Default | Description |
|
|
137
|
+
| --- | --- | --- | --- |
|
|
138
|
+
| `DEEPSEEK_ENABLE_SEARCH` | — | `true` | Register the search tool. Only an explicit `false`/`0`/`no`/`off` disables it; at least one tool must stay enabled. |
|
|
139
|
+
| `DEEPSEEK_SEARCH_COUNT` | `count` | `10` | Results requested from DeepSeek, 1–50. Billing is per request, not per result. |
|
|
140
|
+
| `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. |
|
|
141
|
+
| `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. |
|
|
142
|
+
| `DEEPSEEK_SEARCH_MIN_AUTHORITY` | `minAuthority` | `0` | Drop known authorities below this tier. Authority is 0–4. |
|
|
143
|
+
| `DEEPSEEK_SEARCH_ALLOW_UNKNOWN_AUTHORITY` | `allowUnknownAuthority` | `true` | Keep results whose authority is missing or unknown. Set `false`/`0`/`no`/`off` to drop them. |
|
|
144
|
+
| `DEEPSEEK_SEARCH_BLOCKED_DOMAINS` | `blockedDomains` | unset | Comma-separated; adds `-site:` operators to the query. |
|
|
145
|
+
| `DEEPSEEK_SEARCH_INCLUDE_DOMAINS` | `includeDomains` | unset | Comma-separated; restricts results with `site:` operators. |
|
|
146
|
+
| `DEEPSEEK_SEARCH_LANGUAGE` | `language` | unset | Adds a `lang:` operator, for example `zh,en`. |
|
|
147
|
+
| `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. |
|
|
148
|
+
| `DEEPSEEK_SEARCH_MAX_SUMMARY_CHARS` | `maxSummaryChars` | `1200` | Per-result summary cap, 0–1,000,000. |
|
|
149
|
+
| `DEEPSEEK_SEARCH_TIMEOUT_MS` | `searchTimeoutMs` | `30000` | Search timeout, 1,000–120,000 ms. No host-side cap applies on the extension path. |
|
|
127
150
|
|
|
128
151
|
### Fetch
|
|
129
152
|
|
|
130
|
-
| Env variable | Default | Description |
|
|
131
|
-
| --- | --- | --- |
|
|
132
|
-
| `DEEPSEEK_ENABLE_FETCH` | `true` | Register the fetch tool. Same false-only semantics as `DEEPSEEK_ENABLE_SEARCH`. |
|
|
133
|
-
| `DEEPSEEK_FETCH_MAX_CHARS` | `16000` | Maximum characters returned, including the title, 0–1,000,000. The only output cap on this path. |
|
|
134
|
-
| `DEEPSEEK_FETCH_TIMEOUT_MS` | `30000` | Fetch timeout, 1,000–120,000 ms. No host-side cap applies on the extension path. |
|
|
135
|
-
| `DEEPSEEK_FETCH_ALLOWED_DOMAINS` | unset | If set, only these hosts and subdomains may be fetched. |
|
|
136
|
-
| `DEEPSEEK_FETCH_BLOCKED_DOMAINS` | unset | Always block these hosts and subdomains. Blocked wins over allowed. |
|
|
137
|
-
| `DEEPSEEK_FETCH_BLOCK_PRIVATE_HOSTS` | `true` | Reject localhost, private IPs, `.local`, `.internal`, and similar hosts. Set `false`/`0` to disable. |
|
|
153
|
+
| Env variable | Config file | Default | Description |
|
|
154
|
+
| --- | --- | --- | --- |
|
|
155
|
+
| `DEEPSEEK_ENABLE_FETCH` | — | `true` | Register the fetch tool. Same false-only semantics as `DEEPSEEK_ENABLE_SEARCH`. |
|
|
156
|
+
| `DEEPSEEK_FETCH_MAX_CHARS` | `fetchMaxChars` | `16000` | Maximum characters returned, including the title, 0–1,000,000. The only output cap on this path. |
|
|
157
|
+
| `DEEPSEEK_FETCH_TIMEOUT_MS` | `fetchTimeoutMs` | `30000` | Fetch timeout, 1,000–120,000 ms. No host-side cap applies on the extension path. |
|
|
158
|
+
| `DEEPSEEK_FETCH_ALLOWED_DOMAINS` | `fetchAllowedDomains` | unset | If set, only these hosts and subdomains may be fetched. |
|
|
159
|
+
| `DEEPSEEK_FETCH_BLOCKED_DOMAINS` | `fetchBlockedDomains` | unset | Always block these hosts and subdomains. Blocked wins over allowed. |
|
|
160
|
+
| `DEEPSEEK_FETCH_BLOCK_PRIVATE_HOSTS` | `fetchBlockPrivateHosts` | `true` | Reject localhost, private IPs, `.local`, `.internal`, and similar hosts. Set `false`/`0` to disable. |
|
|
138
161
|
|
|
139
162
|
### Credentials and retries
|
|
140
163
|
|
|
141
|
-
| Env variable | Default | Description |
|
|
142
|
-
| --- | --- | --- |
|
|
143
|
-
| `DEEPSEEK_API_KEY` | required | DeepSeek API key, read from the Pi process environment. |
|
|
144
|
-
| `DEEPSEEK_MAX_RETRIES` | `
|
|
145
|
-
| `DEEPSEEK_RETRY_BASE_DELAY_MS` | `250` | Base delay for exponential backoff. `Retry-After` is honored up to 10 seconds. |
|
|
164
|
+
| Env variable | Config file | Default | Description |
|
|
165
|
+
| --- | --- | --- | --- |
|
|
166
|
+
| `DEEPSEEK_API_KEY` | — | required | DeepSeek API key, read from the Pi process environment. |
|
|
167
|
+
| `DEEPSEEK_MAX_RETRIES` | `maxRetries` | `2` | Retries for 408, 425, 429, and 5xx responses, 0–5. |
|
|
168
|
+
| `DEEPSEEK_RETRY_BASE_DELAY_MS` | `retryBaseDelayMs` | `250` | Base delay for exponential backoff. `Retry-After` is honored up to 10 seconds. |
|
|
146
169
|
|
|
147
170
|
Invalid values fall back to the shared default.
|
|
148
171
|
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Configuration guide
|
|
2
|
+
|
|
3
|
+
The one reference for how every knob resolves on every host: the layering
|
|
4
|
+
chain, the shared config file, the full knob vocabulary, and which layer to set.
|
|
5
|
+
Behavior (what search and fetch do) lives in the README's
|
|
6
|
+
[General behavior](../README.md#general-behavior); per-host mechanics (output
|
|
7
|
+
caps, deadlines, how the environment reaches a stdio server) live in the host
|
|
8
|
+
guides: [Codex](agents/codex.md), [Claude Code](agents/claude-code.md),
|
|
9
|
+
[Pi](agents/pi.md),
|
|
10
|
+
[OpenCode](agents/opencode-v2.md).
|
|
11
|
+
|
|
12
|
+
## The resolution chain
|
|
13
|
+
|
|
14
|
+
Every knob resolves through one chain, low → high, identically on every host:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
built-in defaults < shared config file < DEEPSEEK_* environment < host-native config
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
A higher layer always wins, so nothing already configured loses effect. The
|
|
21
|
+
host-native layer means OpenCode's plugin options (`opencode.jsonc`), Pi's
|
|
22
|
+
`deepseekWebRetrieval` settings namespace, and — for MCP hosts — the per-server
|
|
23
|
+
`env` block in the host's registration (that block is how an environment
|
|
24
|
+
variable arrives, not a fifth layer).
|
|
25
|
+
|
|
26
|
+
## The shared config file
|
|
27
|
+
|
|
28
|
+
`$XDG_CONFIG_HOME/deepseek-web-retrieval/config.json` when `XDG_CONFIG_HOME` is
|
|
29
|
+
set (this wins on every platform, Windows included); otherwise
|
|
30
|
+
`~/.config/deepseek-web-retrieval/config.json` on Linux and macOS and
|
|
31
|
+
`%APPDATA%\deepseek-web-retrieval\config.json` on Windows. camelCase keys:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"count": 20,
|
|
36
|
+
"blockedDomains": ["pinterest.com"],
|
|
37
|
+
"language": "zh",
|
|
38
|
+
"searchLocalization": "203.0.113.7"
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Unknown keys and host-integration keys (below) draw a one-line stderr warning
|
|
43
|
+
and are otherwise ignored — a bad file never blocks startup. The API key never
|
|
44
|
+
goes in the file; it keeps its existing channels (`DEEPSEEK_API_KEY` in the
|
|
45
|
+
environment, or OpenCode's stored credential).
|
|
46
|
+
|
|
47
|
+
## Knob classes
|
|
48
|
+
|
|
49
|
+
| Knob class | Shared file | Examples |
|
|
50
|
+
| --- | --- | --- |
|
|
51
|
+
| API behavior — the user↔DeepSeek relationship | yes — that is the point of the file | `count`, `blockedDomains`, `language`, `maxRetries` |
|
|
52
|
+
| Host-sensitive — interacts with host output caps and deadlines | carries the safe defaults; a host layer is the recommended override point | `searchTimeoutMs`, `fetchTimeoutMs`, `fetchMaxChars`, `maxSummaryChars` |
|
|
53
|
+
| Host integration — the host's tool landscape | rejected — warned about and ignored | `searchEnabled`, `setDefaultWebsearch`, `apiKeySource` |
|
|
54
|
+
|
|
55
|
+
Keep host-independent intent in the shared file; prefer a host layer when a
|
|
56
|
+
host-sensitive knob would cross its host's cap or deadline.
|
|
57
|
+
|
|
58
|
+
## The knob vocabulary
|
|
59
|
+
|
|
60
|
+
One knob, two names: the camelCase key for the shared file and OpenCode's
|
|
61
|
+
options, the `DEEPSEEK_*` variable for the environment. The table generates
|
|
62
|
+
from the same config vocabulary the adapters resolve through, so it cannot
|
|
63
|
+
drift from the code (`bun run docs:matrix` regenerates it; CI checks it).
|
|
64
|
+
|
|
65
|
+
<!-- generated: knob-table — edit src/core/config-summary.ts or env.ts, then run `bun run docs:matrix` -->
|
|
66
|
+
|
|
67
|
+
| File / OpenCode key | Environment | Default |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| `count` | `DEEPSEEK_SEARCH_COUNT` | 10 |
|
|
70
|
+
| `maxResults` | `DEEPSEEK_SEARCH_MAX_RESULTS` | follows `count` (10) |
|
|
71
|
+
| `minRerank` | `DEEPSEEK_SEARCH_MIN_RERANK` | 0 |
|
|
72
|
+
| `minAuthority` | `DEEPSEEK_SEARCH_MIN_AUTHORITY` | 0 |
|
|
73
|
+
| `allowUnknownAuthority` | `DEEPSEEK_SEARCH_ALLOW_UNKNOWN_AUTHORITY` | true |
|
|
74
|
+
| `blockedDomains` | `DEEPSEEK_SEARCH_BLOCKED_DOMAINS` | unset |
|
|
75
|
+
| `includeDomains` | `DEEPSEEK_SEARCH_INCLUDE_DOMAINS` | unset |
|
|
76
|
+
| `language` | `DEEPSEEK_SEARCH_LANGUAGE` | unset |
|
|
77
|
+
| `searchLocalization` | `DEEPSEEK_SEARCH_LOCALIZATION` | unset |
|
|
78
|
+
| `maxSummaryChars` | `DEEPSEEK_SEARCH_MAX_SUMMARY_CHARS` | 1200 |
|
|
79
|
+
| `searchTimeoutMs` | `DEEPSEEK_SEARCH_TIMEOUT_MS` | 30000 |
|
|
80
|
+
| `fetchMaxChars` | `DEEPSEEK_FETCH_MAX_CHARS` | 16000 |
|
|
81
|
+
| `fetchAllowedDomains` | `DEEPSEEK_FETCH_ALLOWED_DOMAINS` | unset |
|
|
82
|
+
| `fetchBlockedDomains` | `DEEPSEEK_FETCH_BLOCKED_DOMAINS` | unset |
|
|
83
|
+
| `fetchTimeoutMs` | `DEEPSEEK_FETCH_TIMEOUT_MS` | 30000 |
|
|
84
|
+
| `fetchBlockPrivateHosts` | `DEEPSEEK_FETCH_BLOCK_PRIVATE_HOSTS` | true |
|
|
85
|
+
| `maxRetries` | `DEEPSEEK_MAX_RETRIES` | 2 |
|
|
86
|
+
| `retryBaseDelayMs` | `DEEPSEEK_RETRY_BASE_DELAY_MS` | 250 |
|
|
87
|
+
|
|
88
|
+
<!-- /generated: knob-table -->
|
|
89
|
+
|
|
90
|
+
## Special semantics
|
|
91
|
+
|
|
92
|
+
- **`maxResults` follows `count`** when left unset — configure only `count` and
|
|
93
|
+
the cap moves with it. An explicit `maxResults` still caps; `count` never
|
|
94
|
+
follows `maxResults`.
|
|
95
|
+
- **Some switches are false-only.** `allowUnknownAuthority`,
|
|
96
|
+
`fetchBlockPrivateHosts`, `searchEnabled`, and `fetchEnabled` are on by
|
|
97
|
+
default; the environment can only turn them off (`false`, `0`, `no`, or
|
|
98
|
+
`off`). The last two have no file key — they are host-integration keys — so
|
|
99
|
+
they exist only as `DEEPSEEK_ENABLE_SEARCH` and `DEEPSEEK_ENABLE_FETCH`. A
|
|
100
|
+
value like `=true` changes nothing.
|
|
101
|
+
- **Invalid environment values are dropped** at startup and the default
|
|
102
|
+
applies. `npx deepseek-web-retrieval config` reports every dropped or
|
|
103
|
+
unknown `DEEPSEEK_*` variable as a warning and exits 1, alongside file
|
|
104
|
+
problems.
|
|
105
|
+
- **`searchLocalization` must be a valid IPv4 or IPv6 address**; anything else
|
|
106
|
+
is dropped at option resolution. It is deployment-level configuration, never
|
|
107
|
+
a per-call tool parameter.
|
|
108
|
+
- **Domains** in the environment are comma-separated; entries that are not
|
|
109
|
+
domains are dropped (and reported by `config`).
|
|
@@ -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.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# Installer design
|
|
2
2
|
|
|
3
3
|
Design note for the install-time flow, shipped as the `deepseek-web-retrieval init`,
|
|
4
|
-
`uninstall`, and `list` subcommands for **OpenCode, Pi, and
|
|
5
|
-
[control tiers](../research/control-matrix.md) map to the artifacts the installer emits, so
|
|
6
|
-
|
|
4
|
+
`uninstall`, and `list` subcommands for **OpenCode, Pi, Codex, and Claude Code**. It records how the
|
|
5
|
+
[control tiers](../research/control-matrix.md) map to the artifacts the installer emits, so the design
|
|
6
|
+
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
9
|
Examples involving other hosts describe design requirements for future modules;
|
|
10
|
-
the current CLI accepts only the
|
|
10
|
+
the current CLI accepts only the four shipped hosts above.
|
|
11
11
|
|
|
12
12
|
## Principles
|
|
13
13
|
|
|
@@ -44,9 +44,9 @@ already exists, and the installer uses three phases:
|
|
|
44
44
|
Report the conflict surface: existing rules steering toward another web tool; other
|
|
45
45
|
web-capable MCP servers already on the field; array-valued keys the plan must merge
|
|
46
46
|
into rather than replace (`disabledTools`, `permissions.deny`, permissions
|
|
47
|
-
`exclude`, `disabled_tools`); and higher layers (Claude Code managed policy
|
|
48
|
-
enterprise team settings) that
|
|
49
|
-
installer writes.
|
|
47
|
+
`exclude`, `disabled_tools`); and higher layers (Claude Code managed policy — its
|
|
48
|
+
existence is checked by the claude-code module; Devin enterprise team settings) that
|
|
49
|
+
would outrank what the installer writes.
|
|
50
50
|
2. **Merge or snapshot.** Array keys merge with existing entries, recording exactly
|
|
51
51
|
which entries the installer appended; single-value keys (`websearch.provider`, Pi's
|
|
52
52
|
`exposure`) snapshot the prior value before overwriting; files the installer creates
|
|
@@ -71,7 +71,9 @@ already exists, and the installer uses three phases:
|
|
|
71
71
|
competitor, not third-party web MCP servers — those must be excluded too (the
|
|
72
72
|
per-host keys cover them), or routing is not actually forced. Concretely: Pi's
|
|
73
73
|
per-server `enabled` key lets the plan disable detected web-capable competitors
|
|
74
|
-
(each prior value snapshotted for uninstall);
|
|
74
|
+
(each prior value snapshotted for uninstall); Claude Code excludes them the same way
|
|
75
|
+
via server-level `mcp__<server>` deny rules appended to `permissions.deny`; Codex has
|
|
76
|
+
no per-server kill switch,
|
|
75
77
|
so a detected web-capable competitor makes the plan refuse the tier instead of
|
|
76
78
|
promising non-exclusive routing; OpenCode's forced is replacement, which no
|
|
77
79
|
third-party server overrides. Detection classifies a server web-capable from its
|
|
@@ -156,9 +158,9 @@ the artifacts below name the path where they differ.
|
|
|
156
158
|
| Optional | Host config registering the integration: Pi's extension path appends an `npm:<package>` source to `packages` in settings.json; the MCP paths register the server (Pi's MCP entry needs `"exposure": "direct"`; the extension path needs nothing — extension tools are `direct` by Pi's own default) |
|
|
157
159
|
| 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)); the rules name the path's tool ids (`deepseek_web_search` for the extension, `mcp__deepseek__deepseek_web_search` for MCP) |
|
|
158
160
|
| Forced (replacement) | OpenCode plugin options (`setDefaultWebsearch` / `fetchOverrideWebfetch`) |
|
|
159
|
-
| 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; Pi's extension path additionally refuses when a web-capable `packages`/`extensions` source is listed in settings.json (no per-package kill switch exists) |
|
|
161
|
+
| 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`; Claude Code appends server-level `mcp__<server>` deny rules to `permissions.deny` (merging with the user's own entries); Codex, lacking a per-server kill switch, refuses the tier instead; Pi's extension path additionally refuses when a web-capable `packages`/`extensions` source is listed in settings.json (no per-package kill switch exists) |
|
|
160
162
|
| Forced (de-facto) | Nothing beyond the Optional artifacts — no competitor exists |
|
|
161
|
-
| Off | Codex writes the capability's raw tool name into the server entry's `disabled_tools` (host-native: the tool leaves the model's context; the user's own entries in that array are kept); the other MCP entry writes the capability's false-only server-side switch instead (`DEEPSEEK_ENABLE_SEARCH` / `DEEPSEEK_ENABLE_FETCH`); Pi's extension path writes the same switches into the `deepseekWebRetrieval` settings namespace the extension reads at load; both capabilities off refuses to install |
|
|
163
|
+
| Off | Codex writes the capability's raw tool name into the server entry's `disabled_tools` (host-native: the tool leaves the model's context; the user's own entries in that array are kept); Claude Code appends the capability's full tool id (`mcp__deepseek__*`) to `permissions.deny`, the same host-native removal; the other MCP entry writes the capability's false-only server-side switch instead (`DEEPSEEK_ENABLE_SEARCH` / `DEEPSEEK_ENABLE_FETCH`); Pi's extension path writes the same switches into the `deepseekWebRetrieval` settings namespace the extension reads at load; both capabilities off refuses to install |
|
|
162
164
|
|
|
163
165
|
OpenCode additionally appends `permissions` allow entries for exactly the tools it
|
|
164
166
|
registers (`websearch`, `deepseek_fetch`, and `webfetch` when fetch is forced), merged
|
|
@@ -194,10 +196,19 @@ into any existing `permissions` array rather than replacing it.
|
|
|
194
196
|
reverts cannot re-enable a still-excluded competitor.
|
|
195
197
|
- Verify is file-level: after apply it re-reads each written file and asserts every op
|
|
196
198
|
holds (set values in place, appended entries present, rules block present). Higher
|
|
197
|
-
layers
|
|
198
|
-
|
|
199
|
+
layers are a plan-time detect concern; Claude Code documents one (managed policy), and
|
|
200
|
+
the claude-code module reports an existing managed-settings.json instead of failing
|
|
201
|
+
silently. The other shipped hosts document no layer above user config.
|
|
199
202
|
- Only a bare `--apply` enables writes; assigning a value such as `--apply=false`
|
|
200
203
|
is a usage error and writes nothing.
|
|
204
|
+
- `--pin` is opt-in version pinning: the ref written into host config gets the
|
|
205
|
+
running CLI's version appended (`name` becomes `name@<version>`; a ref already
|
|
206
|
+
ending in a version keeps it), so a host resolves that exact release instead of
|
|
207
|
+
the latest publish. Without the flag the ref stays unpinned, byte-identical to
|
|
208
|
+
before; re-running `init --pin` from a newer CLI moves the pin. Ref identity —
|
|
209
|
+
orphan, upgrade, and unexcludable-competitor detection — compares package names
|
|
210
|
+
with the `@version` suffix stripped (`samePackageName` in ownership.ts), so a
|
|
211
|
+
pinned ref still matches the lineage an earlier init registered.
|
|
201
212
|
- File verification precedes the install-record commit. A write or verification
|
|
202
213
|
failure restores the pre-apply files and record and checks the restored values.
|
|
203
214
|
`ApplyError.status` is `rolled_back` only after recovery and new-claim cleanup
|
|
@@ -216,7 +227,7 @@ host-side tool filtering.
|
|
|
216
227
|
|
|
217
228
|
## Hosts without an installer story
|
|
218
229
|
|
|
219
|
-
|
|
230
|
+
Cursor, Devin, GitHub Copilot, and Cline still have no
|
|
220
231
|
host module; their artifacts (from the tier-to-artifact mapping) remain hand-edited
|
|
221
232
|
config until a module lands here. OpenCode's `opencode plugin add` remains available but
|
|
222
233
|
cannot pass options or manage snapshots; `init` supersedes it for tiered installs.
|
package/docs/hosts.jsonc
CHANGED
|
@@ -102,11 +102,15 @@
|
|
|
102
102
|
"nativeSearchProvider": false,
|
|
103
103
|
"nativeFetchOverride": false,
|
|
104
104
|
"paths": ["mcp"],
|
|
105
|
-
"status": "
|
|
105
|
+
"status": "supported",
|
|
106
106
|
"control": {
|
|
107
107
|
"search": { "optional": "yes", "preferred": "yes", "forced": "exclusion", "key": "`permissions.deny: [\"WebSearch\"]` removes the tool from context" },
|
|
108
108
|
"fetch": { "optional": "yes", "preferred": "yes", "forced": "exclusion", "key": "`permissions.deny: [\"WebFetch\"]`, or `CLAUDE_CODE_DISABLE_WEB_FETCH=1`" }
|
|
109
109
|
},
|
|
110
|
+
"adapter": "src/mcp",
|
|
111
|
+
"installer": "src/installer/hosts/claude-code",
|
|
112
|
+
"guide": "docs/agents/claude-code.md",
|
|
113
|
+
"e2eScenario": "claude-code"
|
|
110
114
|
},
|
|
111
115
|
{
|
|
112
116
|
"name": "cursor",
|
package/docs/integration.md
CHANGED
|
@@ -17,7 +17,7 @@ ship built-in web tools. MCP tools can add equivalent tools, but do not replace
|
|
|
17
17
|
| Native tool / fetch override | No | Yes | Host tool API | OpenCode v2 adapter |
|
|
18
18
|
| Custom tool plugin | Yes | Yes | Host plugin API | Cline CLI/SDK; no adapter yet |
|
|
19
19
|
| Extension API | Yes | Yes | Host extension API | Pi adapter (`src/pi/`) |
|
|
20
|
-
| MCP server | Yes | Yes | Host MCP client | Shipped (`src/mcp/`; Pi and
|
|
20
|
+
| MCP server | Yes | Yes | Host MCP client | Shipped (`src/mcp/`; Pi, Codex, and Claude Code guides) |
|
|
21
21
|
| CLI/HTTP wrapper | Yes | Yes | Host can call external tools | Not shipped |
|
|
22
22
|
|
|
23
23
|
MCP is a protocol, not an agent. It is one possible transport for hosts that support MCP
|
|
@@ -35,7 +35,7 @@ Rows are sorted with open-source hosts first, then by host name alphabetically.
|
|
|
35
35
|
| Codex | 0.163.0 | Yes (Apache-2.0) | No | No | MCP server | Supported |
|
|
36
36
|
| OpenCode | 2.0.32 | Yes (MIT) | Yes | Yes | native websearch provider or native tool/fetch override | Supported |
|
|
37
37
|
| Pi | 1.3.0 | Yes (MIT) | No | No | extension API or MCP server | Supported |
|
|
38
|
-
| Claude Code | 2.1.303 | No | No | No | MCP server |
|
|
38
|
+
| Claude Code | 2.1.303 | No | No | No | MCP server | Supported |
|
|
39
39
|
| Cursor | 2026.10.08 | No | No | No | MCP server | No adapter yet |
|
|
40
40
|
| Devin | 3000.11.92 | No | No | No | MCP server | No adapter yet |
|
|
41
41
|
| GitHub Copilot | 1.0.98 | No | No | No | MCP server | No adapter yet |
|
|
@@ -48,7 +48,7 @@ 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
|
-
OpenCode, Pi, and
|
|
51
|
+
OpenCode, Pi, Codex, and Claude Code have supported setup guides and installer host modules. The
|
|
52
52
|
MCP server in `src/mcp/` provides a possible stdio path for the remaining hosts, but
|
|
53
53
|
protocol compatibility alone does not establish a tested host setup. For those rows,
|
|
54
54
|
`No adapter yet` means no supported host-specific adapter or setup guide is shipped.
|
|
@@ -66,8 +66,10 @@ the details: built-in web tools and their kill switches, MCP registration, and r
|
|
|
66
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
|
-
- **Claude Code** — Ships built-in `WebSearch` and `WebFetch` tools.
|
|
70
|
-
|
|
69
|
+
- **Claude Code** — Ships built-in `WebSearch` and `WebFetch` tools. Supported through
|
|
70
|
+
the MCP server; see
|
|
71
|
+
[Claude Code](agents/claude-code.md) and
|
|
72
|
+
[Claude Code in the per-host reference](research/control-matrix.md#claude-code).
|
|
71
73
|
- **Codex** — Ships a built-in `web_search` tool. Supported through the MCP server; see
|
|
72
74
|
[Codex](agents/codex.md) and [Codex in the per-host reference](research/control-matrix.md#codex).
|
|
73
75
|
- **Cursor** — Uses the same `mcp.json` servers as the editor; ships built-in web search
|
|
@@ -94,9 +96,12 @@ For an installation managed by `init`:
|
|
|
94
96
|
needed for uninstall. A global install can still claim shared configuration from a
|
|
95
97
|
particular project, so keep the original working directory for upgrades.
|
|
96
98
|
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`.
|
|
98
|
-
package version, pass
|
|
99
|
-
|
|
99
|
+
guide. For Pi's extension path, use `pi update --extensions`. To pin the host's
|
|
100
|
+
package to the exact version being run, pass `--pin` to init (it writes
|
|
101
|
+
`deepseek-web-retrieval@X.Y.Z` into the registration); upgrading a pinned install
|
|
102
|
+
means re-running init with the newer CLI, since updating the CLI alone does not
|
|
103
|
+
move an independently pinned host package. `--package` still overrides the ref
|
|
104
|
+
entirely.
|
|
100
105
|
|
|
101
106
|
When upgrading from 0.4.0, Pi's default changes from MCP to the native extension.
|
|
102
107
|
Pass `--path mcp` explicitly to retain MCP, or `--path extension` to migrate; the plan
|
|
@@ -116,7 +121,8 @@ Code importing the core's removed `formatFetchContent` helper must migrate to
|
|
|
116
121
|
## Available paths and future hosts
|
|
117
122
|
|
|
118
123
|
- **MCP server** — shipped in `src/mcp/` (the fallback path in the [Pi](agents/pi.md) guide
|
|
119
|
-
and the path in the [Codex](agents/codex.md)
|
|
124
|
+
and the path in the [Codex](agents/codex.md) and
|
|
125
|
+
[Claude Code](agents/claude-code.md) guides); the broadest route for hosts that
|
|
120
126
|
support MCP tools. Protocol compatibility across these hosts is researched in
|
|
121
127
|
[mcp-compatibility.md](research/mcp-compatibility.md).
|
|
122
128
|
- **Native extension adapters** — the Pi extension adapter ships in `src/pi/`; a host whose
|