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.
- package/CHANGELOG.md +187 -1
- package/README.md +13 -9
- package/dist/cli.js +4228 -178
- package/docs/adr/0001-refuse-drift-between-plan-and-apply.md +29 -0
- package/docs/agents/codex.md +193 -0
- package/docs/agents/domain.md +51 -0
- package/docs/agents/issue-tracker.md +45 -0
- package/docs/{opencode-v2.md → agents/opencode-v2.md} +30 -7
- package/docs/{pi.md → agents/pi.md} +35 -7
- package/docs/agents/triage-labels.md +15 -0
- package/docs/design/installer-design.md +184 -0
- package/docs/hosts.jsonc +59 -33
- package/docs/integration.md +45 -52
- package/docs/research/control-matrix.md +257 -0
- package/docs/{mcp-compatibility.md → research/mcp-compatibility.md} +39 -108
- package/package.json +5 -3
- package/src/core/auth.ts +1 -1
- package/src/core/client.ts +42 -249
- package/src/core/constants.ts +5 -0
- package/src/core/descriptions.ts +19 -0
- package/src/core/format.ts +31 -1
- package/src/core/jsonc.ts +16 -0
- package/src/core/options.ts +2 -3
- package/src/core/search.ts +5 -7
- package/src/core/transport.ts +253 -0
- package/src/core/types.ts +13 -11
- package/src/installer/apply.ts +176 -0
- package/src/installer/cli.ts +215 -0
- package/src/installer/detect.ts +85 -0
- package/src/installer/formats/index.ts +58 -0
- package/src/installer/formats/json.ts +151 -0
- package/src/installer/formats/rules.ts +62 -0
- package/src/installer/formats/toml.ts +163 -0
- package/src/installer/formats/value.ts +57 -0
- package/src/installer/hosts/codex.ts +128 -0
- package/src/installer/hosts/index.ts +134 -0
- package/src/installer/hosts/opencode.ts +118 -0
- package/src/installer/hosts/pi.ts +115 -0
- package/src/installer/hosts/shared.ts +31 -0
- package/src/installer/paths.ts +18 -0
- package/src/installer/render.ts +62 -0
- package/src/installer/revert.ts +61 -0
- package/src/installer/rulesContent.ts +32 -0
- package/src/installer/state.ts +63 -0
- package/src/installer/types.ts +126 -0
- package/src/installer/uninstall.ts +33 -0
- package/src/mcp/auth.ts +2 -1
- package/src/mcp/cli.ts +21 -5
- package/src/mcp/config.ts +70 -27
- package/src/mcp/server.ts +81 -65
- package/src/opencode/auth.ts +3 -2
- package/src/opencode/plugin.ts +93 -56
- package/src/mcp/format.ts +0 -31
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Control levels across hosts
|
|
2
|
+
|
|
3
|
+
This note answers one question: for each host in the [support matrix](../integration.md), how
|
|
4
|
+
strongly can a user steer when the DeepSeek tools are called — optionally available,
|
|
5
|
+
preferentially used, or forcibly routed — independently for search and fetch? It is also
|
|
6
|
+
the per-host reference for setup facts: MCP registration, rules files, built-in web
|
|
7
|
+
competitors, and their kill switches. [integration.md](../integration.md) keeps the mechanism
|
|
8
|
+
taxonomy and host-support matrix; [mcp-compatibility.md](mcp-compatibility.md) keeps the
|
|
9
|
+
protocol research and its evidence.
|
|
10
|
+
|
|
11
|
+
**Research baseline:** 2026-10-20, using the same version locks as
|
|
12
|
+
[hosts.jsonc](../hosts.jsonc), the single source of truth for host facts. Open-source rows are
|
|
13
|
+
verified at exact git tags, npm tarballs, or binary analysis; proprietary rows from official
|
|
14
|
+
docs and changelogs at the locked versions. Version mentions inside the per-host sections
|
|
15
|
+
and the generated `key` strings are research-provenance anchors verified at the lock, not
|
|
16
|
+
restatements of it; they are re-verified on a baseline bump (see the drift list at the end).
|
|
17
|
+
The matrix below is generated — edit
|
|
18
|
+
hosts.jsonc, then run `bun run docs:matrix`.
|
|
19
|
+
|
|
20
|
+
## Tiers
|
|
21
|
+
|
|
22
|
+
| Tier | Meaning | Determinism |
|
|
23
|
+
| --- | --- | --- |
|
|
24
|
+
| Optional | Tools are declared to the model with no preference guidance; the model picks freely among available tools. | None |
|
|
25
|
+
| Preferred | Prompt-level rules (instruction files, system-prompt additions) steer the model toward the tools. | Probabilistic |
|
|
26
|
+
| Forced | Routing is deterministic **relative to the built-in competitor**; other web-capable MCP servers or a higher configuration layer can still break it (reading notes below). Three flavors: **replacement** (the built-in tool's implementation is swapped), **exclusion** (the built-in competitor is denied or disabled so the DeepSeek path is the only one), **de-facto** (the host ships no built-in web tool). | Deterministic (conditional) |
|
|
27
|
+
|
|
28
|
+
## Matrix
|
|
29
|
+
|
|
30
|
+
<!-- generated: control-matrix — edit docs/hosts.jsonc, then run `bun run docs:matrix` -->
|
|
31
|
+
|
|
32
|
+
| Host | Capability | Optional | Preferred | Forced | Mechanism |
|
|
33
|
+
| --- | --- | --- | --- | --- | --- |
|
|
34
|
+
| Cline | Search | Yes | Yes | Yes | De-facto — no built-in web-search tool at 0.0.13 (binary-verified) |
|
|
35
|
+
| Cline | Fetch | Yes | Yes | Yes | Exclusion — `disabledTools` in `~/.cline/data/settings/global-settings.json` |
|
|
36
|
+
| Codex | Search | Yes | Yes | Yes | Exclusion — `web_search = "disabled"` (top-level config.toml) |
|
|
37
|
+
| Codex | Fetch | Yes | Yes | Yes | De-facto — no built-in fetch tool at 0.163.0 |
|
|
38
|
+
| OpenCode | Search | n/a | n/a | Yes | Replacement — `websearch.provider: "deepseek"` or plugin `setDefaultWebsearch` |
|
|
39
|
+
| OpenCode | Fetch | Yes | Yes | Yes | Replacement — `fetchOverrideWebfetch: true` |
|
|
40
|
+
| Pi | Search | Yes | Yes | Yes | De-facto — no built-in web tool at 1.3.0 (source-verified) |
|
|
41
|
+
| Pi | Fetch | Yes | Yes | Yes | De-facto — no built-in web tool at 1.3.0 (source-verified) |
|
|
42
|
+
| Claude Code | Search | Yes | Yes | Yes | Exclusion — `permissions.deny: ["WebSearch"]` removes the tool from context |
|
|
43
|
+
| Claude Code | Fetch | Yes | Yes | Yes | Exclusion — `permissions.deny: ["WebFetch"]`, or `CLAUDE_CODE_DISABLE_WEB_FETCH=1` |
|
|
44
|
+
| Cursor | Search | Yes | Yes | No | — |
|
|
45
|
+
| Cursor | Fetch | Yes | Yes | Yes | Exclusion — `permissions.deny: ["WebFetch(*)"]` |
|
|
46
|
+
| Devin | Search | Yes | Yes | Yes | Exclusion — `disabled_tools` / `permissions.deny` in config.json |
|
|
47
|
+
| Devin | Fetch | Yes | Yes | Yes | Exclusion — `disabled_tools` / `permissions.deny` in config.json |
|
|
48
|
+
| GitHub Copilot | Search | Yes | Yes | Yes | Exclusion — `githubMcpTools` settings (competitor ships via the bundled GitHub MCP server) |
|
|
49
|
+
| GitHub Copilot | Fetch | Yes | Yes | Yes | Exclusion — `--deny-tool web_fetch` / `--excluded-tools` (session flags) |
|
|
50
|
+
|
|
51
|
+
<!-- /generated: control-matrix -->
|
|
52
|
+
|
|
53
|
+
Reading notes:
|
|
54
|
+
|
|
55
|
+
- `n/a` marks a structurally unreachable tier, not missing research: OpenCode's search
|
|
56
|
+
provider is host-level config, not a model-selectable tool, so the model never chooses
|
|
57
|
+
between engines — the only choice is replacement on or off.
|
|
58
|
+
- A `De-facto` Forced flavor needs no config: the host ships no built-in competitor, so the
|
|
59
|
+
registered tools are the only web path.
|
|
60
|
+
- Cursor's search row is the one Forced-tier gap in the matrix: no documented deny token
|
|
61
|
+
exists for its built-in web search.
|
|
62
|
+
- An `Exclusion` flavor forces routing **relative to the built-in competitor only**. If
|
|
63
|
+
other web-capable MCP servers are already registered, they stay on the field and
|
|
64
|
+
routing is not forced until they are excluded too; higher configuration layers
|
|
65
|
+
(managed, enterprise, system) can also outrank the kill switch. Install-time handling
|
|
66
|
+
of both conditions is specified in the
|
|
67
|
+
[installer design](../design/installer-design.md).
|
|
68
|
+
|
|
69
|
+
## Per-host reference
|
|
70
|
+
|
|
71
|
+
One section per host, in hosts.jsonc order. Each carries what an install needs beyond the
|
|
72
|
+
matrix: the built-in competitors, their kill switches, how the MCP server is registered,
|
|
73
|
+
and which rules files steer preference. The `init` CLI implements these tiers for
|
|
74
|
+
OpenCode, Pi, and Codex (see [installer design](../design/installer-design.md)). Config
|
|
75
|
+
paths imply the available scopes; keys locked to a single scope are enumerated in the
|
|
76
|
+
[installer design](../design/installer-design.md#scope).
|
|
77
|
+
|
|
78
|
+
### Cline
|
|
79
|
+
|
|
80
|
+
- **Positioning** — VSCode-extension agent with an experimental lightweight CLI (`clite`,
|
|
81
|
+
built on the Cline SDKs). Apache-2.0. MCP plus CLI/SDK custom tools; neither replaces the
|
|
82
|
+
built-in `fetch_web_content`. Current docs.cline.bot describes the newer 3.x `cline`
|
|
83
|
+
binary — the lock is 0.0.13 `clite`, and everything here is verified against that binary.
|
|
84
|
+
- **Built-in web tools** — `fetch_web_content` (fetch a URL and analyze it with a prompt);
|
|
85
|
+
no built-in web search (the binary's `web_search` strings are Bedrock provider tool
|
|
86
|
+
versions). Kill switch: `"disabledTools": ["fetch_web_content"]` in
|
|
87
|
+
`~/.cline/data/settings/global-settings.json` (path overridable via
|
|
88
|
+
`CLINE_GLOBAL_SETTINGS_PATH`); a disabled tool is dropped from the available set.
|
|
89
|
+
`--yolo` mode also deactivates web fetch.
|
|
90
|
+
- **MCP registration** — `~/.cline/settings/cline_mcp_settings.json`
|
|
91
|
+
(`CLINE_MCP_SETTINGS_PATH`), written by the `clite mcp` wizard in a nested form:
|
|
92
|
+
`mcpServers.<name>.transport` with `type` (`stdio` | `sse` | `streamableHttp`) plus
|
|
93
|
+
`command`/`args`/`env`, `disabled`, and `autoApprove`. Negotiates `2024-11-05` — the
|
|
94
|
+
protocol floor of the matrix; treat it as text-content-blocks-only.
|
|
95
|
+
- **Rules** — `.clinerules` (file or directory) and `.cline/rules/` plus `AGENTS.md` at
|
|
96
|
+
project scope; `~/.cline/rules` and `~/Documents/Cline/Rules` at user scope — all
|
|
97
|
+
verified inside the 0.0.13 binary.
|
|
98
|
+
|
|
99
|
+
### Codex
|
|
100
|
+
|
|
101
|
+
- **Positioning** — OpenAI's official Rust CLI. Apache-2.0. MCP is the only integration
|
|
102
|
+
path.
|
|
103
|
+
- **Built-in web tools** — a native Responses `web_search` tool. The default mode is
|
|
104
|
+
`cached` (an OpenAI-maintained index, no external web access — the competitor exists
|
|
105
|
+
silently by default); `live` requires opt-in (`--search`, `web_search = "live"`, or a
|
|
106
|
+
full-access sandbox). No built-in fetch tool. Kill switch: top-level
|
|
107
|
+
`web_search = "disabled"` in `~/.codex/config.toml`. Trap: the `[tools] web_search =
|
|
108
|
+
<bool>` form parses but discards the value at 0.163.0 — a silent no-op
|
|
109
|
+
([config source at rust-v0.163.0](https://github.com/openai/codex/blob/rust-v0.163.0/codex-rs/config/src/config_toml.rs)).
|
|
110
|
+
- **MCP registration** — `~/.codex/config.toml` `[mcp_servers.<name>]`: stdio
|
|
111
|
+
`command`/`args`/`env`/`env_vars`; `startup_timeout_sec` (10 s), `tool_timeout_sec`
|
|
112
|
+
(60 s); `enabled_tools`/`disabled_tools`, per-tool approval modes, and output limits.
|
|
113
|
+
stdio children do not inherit the parent environment (only `HOME`, `PATH`, and explicit
|
|
114
|
+
`env`), so `DEEPSEEK_API_KEY` must be passed explicitly. When a tool result has
|
|
115
|
+
`structuredContent`, Codex replaces the content blocks with the serialized JSON. No SSE.
|
|
116
|
+
- **Rules** — `~/.codex/AGENTS.md` (with `AGENTS.override.md` preferred) at user scope;
|
|
117
|
+
every `AGENTS.md` from the project root down to the cwd, concatenated root→cwd.
|
|
118
|
+
Extensible via `project_doc_fallback_filenames` and `developer_instructions`
|
|
119
|
+
([agents_md.rs at rust-v0.163.0](https://github.com/openai/codex/blob/rust-v0.163.0/codex-rs/core/src/agents_md.rs)).
|
|
120
|
+
|
|
121
|
+
### OpenCode
|
|
122
|
+
|
|
123
|
+
- **Positioning** — the only host with both a native websearch provider and a native fetch
|
|
124
|
+
override; the shipped adapter uses them, not MCP. See [OpenCode v2](../agents/opencode-v2.md).
|
|
125
|
+
- **Built-in web tools** — `websearch` (bundled providers: exa, firecrawl, parallel,
|
|
126
|
+
tavily, tinyfish, or `"random"`) and `webfetch`. `"websearch": false` removes the search
|
|
127
|
+
tool from model requests entirely; `webfetch` has no disable config key at 2.0.32 — the
|
|
128
|
+
deterministic paths are a permissions deny (`action: "webfetch"`) or a plugin
|
|
129
|
+
tool-transform removal, the latter being what `fetchOverrideWebfetch` does.
|
|
130
|
+
- **MCP registration** — out of scope for this host: the shipped path is the plugin
|
|
131
|
+
adapter, and OpenCode's MCP support is not part of it.
|
|
132
|
+
- **Rules** — `AGENTS.md` only (no CLAUDE.md fallback in v2): global
|
|
133
|
+
`~/.config/opencode/AGENTS.md`, then project files from the workspace toward home,
|
|
134
|
+
nested files injected when the agent reads into that subtree. The `instructions` config
|
|
135
|
+
key adds files, globs, or URLs ([docs](https://opencode.ai/v2/docs/instructions)).
|
|
136
|
+
|
|
137
|
+
### Pi
|
|
138
|
+
|
|
139
|
+
- **Positioning** — minimal, fully customizable agent (earendil-works). MIT. MCP server
|
|
140
|
+
plus a TypeScript extension API. See [Pi](../agents/pi.md).
|
|
141
|
+
- **Built-in web tools** — none at 1.3.0. The built-in set is exactly `bash, edit, find,
|
|
142
|
+
grep, ls, powershell, read, write` (default-active: `read, bash, edit, write`); web
|
|
143
|
+
search/fetch arrive via MCP or extensions
|
|
144
|
+
([tools index at v1.3.0](https://github.com/earendil-works/pi/blob/v1.3.0/packages/coding-agent/src/core/tools/index.ts)).
|
|
145
|
+
- **MCP registration** — `~/.pi/agent/mcp.json` or `.pi/mcp.json`: stdio
|
|
146
|
+
`command`/`args`/`env`/`cwd`, HTTP `url`/`headers`, plus `timeout`, `enabled`,
|
|
147
|
+
`exposure`. MCP tools are hidden from the model by default
|
|
148
|
+
(`exposure: "codemode"`); `"exposure": "direct"` declares them like built-ins — the
|
|
149
|
+
prerequisite for every tier. SSE is rejected. Text results over 20 KB are
|
|
150
|
+
middle-truncated with the full text saved to a file, and the per-request default
|
|
151
|
+
timeout is 60 s. Pi is content-first for the model, with a `structuredContent`
|
|
152
|
+
fallback used only when a result has no content blocks — the one open-source host that
|
|
153
|
+
touches `structuredContent` at all — and a re-declared (not validated) tool
|
|
154
|
+
`outputSchema`.
|
|
155
|
+
- **Rules** — `AGENTS.md`/`CLAUDE.md` context files from the agent dir, the working
|
|
156
|
+
directory, and its parents; `SYSTEM.md` replaces the system prompt and `APPEND_SYSTEM.md`
|
|
157
|
+
adds to it; extensions can replace the whole prompt via `before_agent_start`
|
|
158
|
+
([configuration.md at v1.3.0](https://github.com/earendil-works/pi/blob/v1.3.0/packages/coding-agent/docs/configuration.md)).
|
|
159
|
+
|
|
160
|
+
### Claude Code
|
|
161
|
+
|
|
162
|
+
- **Positioning** — Anthropic's official CLI. Proprietary. MCP adds tools; built-ins are
|
|
163
|
+
not replaceable.
|
|
164
|
+
- **Built-in web tools** — `WebSearch` and `WebFetch`. Kill switch: bare deny rules —
|
|
165
|
+
`"permissions": {"deny": ["WebSearch", "WebFetch"]}` — remove the tools from the model's
|
|
166
|
+
context entirely; deny outranks allow at every settings level and cannot be carved out.
|
|
167
|
+
`--disallowedTools` is the flag form. `CLAUDE_CODE_DISABLE_WEB_FETCH=1` (2.1.285+) kills
|
|
168
|
+
WebFetch only; there is no env equivalent for WebSearch
|
|
169
|
+
([tools](https://code.claude.com/docs/en/tools),
|
|
170
|
+
[permissions](https://code.claude.com/docs/en/permissions)).
|
|
171
|
+
- **MCP registration** — `.mcp.json` (`mcpServers` with `command`/`args`/`env`, or
|
|
172
|
+
`type: "http"` + `url`); `${VAR}` expansion in `command`/`args`/`env`/`url`/`headers`.
|
|
173
|
+
Tool permission rules use `mcp__<server>__<tool>`. Tool descriptions are capped at 4,096
|
|
174
|
+
chars (2.1.296+) and tool output at 25k tokens by default (`MAX_MCP_OUTPUT_TOKENS`),
|
|
175
|
+
with oversized text saved to a file; 16 MiB message cap on HTTP transports.
|
|
176
|
+
- **Rules** — `CLAUDE.md` hierarchy (managed → user `~/.claude/CLAUDE.md` → project →
|
|
177
|
+
`CLAUDE.local.md`) with `@import`; `AGENTS.md` is read instead only when no CLAUDE.md
|
|
178
|
+
exists anywhere above the cwd (since 2.1.277)
|
|
179
|
+
([memory](https://code.claude.com/docs/en/memory)).
|
|
180
|
+
|
|
181
|
+
### Cursor
|
|
182
|
+
|
|
183
|
+
- **Positioning** — AI-first editor plus a same-family CLI. Proprietary. MCP is the CLI
|
|
184
|
+
path.
|
|
185
|
+
- **Built-in web tools** — web search and `WebFetch`. Fetch kill switch:
|
|
186
|
+
`"permissions.deny": ["WebFetch(*)"]` in `~/.cursor/cli-config.json` (global) or
|
|
187
|
+
`.cursor/cli.json` (project — only `permissions` is project-configurable); deny wins
|
|
188
|
+
over allow. Web search has no documented deny token; the only control is
|
|
189
|
+
`autoAcceptWebSearch` (a per-call approval prompt, not a hard deny). This is the
|
|
190
|
+
matrix's one Forced-tier gap
|
|
191
|
+
([CLI permissions](https://cursor.com/docs/cli/reference/permissions),
|
|
192
|
+
[changelog](https://cursor.com/docs/cli/changelog)).
|
|
193
|
+
- **MCP registration** — the same `mcp.json` servers as the editor (`.cursor/mcp.json` or
|
|
194
|
+
`~/.cursor/mcp.json`): `command`/`args`/`env` for stdio, `url`/`headers` for remote;
|
|
195
|
+
`${env:NAME}` interpolation. MCP tools prompt for approval; `--approve-mcps` bypasses,
|
|
196
|
+
and global-scope servers have been auto-approved since April 2026.
|
|
197
|
+
- **Rules** — `.cursor/rules/*.mdc` (with `description`/`globs`/`alwaysApply` frontmatter —
|
|
198
|
+
a plain `.md` file there is ignored), `AGENTS.md` at the root and in subdirectories, and
|
|
199
|
+
`CLAUDE.md`; "The CLI agent supports the same rules system as the editor"
|
|
200
|
+
([CLI using](https://cursor.com/docs/cli/using)).
|
|
201
|
+
|
|
202
|
+
### Devin
|
|
203
|
+
|
|
204
|
+
- **Positioning** — Cognition's autonomous-agent CLI. Proprietary. Plugins bundle skills,
|
|
205
|
+
rules, hooks, and MCP servers — not arbitrary custom tools — so MCP is the tool path.
|
|
206
|
+
- **Built-in web tools** — `web_search` (v2026.5.6-1) and `webfetch` (v2026.5.26-0). Kill
|
|
207
|
+
switch: `"disabled_tools": ["webfetch", "web_search"]` in user `config.json`, and
|
|
208
|
+
`web_search` is accepted as a tool name in `permissions.deny`/`ask`/`allow` (both
|
|
209
|
+
changelog-documented at v3000.10.21, not yet on the reference pages); PreToolUse hooks
|
|
210
|
+
block calls by exiting with code 2; an enterprise "Enable Web Search" team setting
|
|
211
|
+
exists ([changelog](https://docs.devin.ai/cli/changelog)).
|
|
212
|
+
- **MCP registration** — `.devin/mcp_config.local.json` (default),
|
|
213
|
+
`.devin/mcp_config.json`, or `~/.config/devin/mcp_config.json`, all with the same
|
|
214
|
+
`mcpServers` shape; `devin mcp add <name> -- <cmd>` / `<URL>`. MCP tools prompt for
|
|
215
|
+
approval by default; `mcp__server__tool` allow/deny patterns in `permissions`.
|
|
216
|
+
- **Rules** — `AGENTS.md` (root, nested, and global `~/.config/devin/AGENTS.md`),
|
|
217
|
+
`AGENTS.local.md`, `.devin/rules/*.md` with `trigger` frontmatter,
|
|
218
|
+
`.devin/global_rules.md`, and plugin-shipped rules; imports other tools' rules via
|
|
219
|
+
`read_config_from` ([rules](https://docs.devin.ai/cli/extensibility/rules)).
|
|
220
|
+
|
|
221
|
+
### GitHub Copilot
|
|
222
|
+
|
|
223
|
+
- **Positioning** — GitHub's official CLI. Proprietary. MCP servers, optionally bundled in
|
|
224
|
+
plugins.
|
|
225
|
+
- **Built-in web tools** — `web_fetch` (since 0.0.374) and `web_search` via the bundled
|
|
226
|
+
GitHub MCP server (which exposes only that tool since 1.0.57). Kill switch, session
|
|
227
|
+
scoped: `--deny-tool web_fetch,web_search` or `--excluded-tools` — the docs' own example
|
|
228
|
+
for avoiding web search entirely; deny wins even under `--allow-all`. Persistent:
|
|
229
|
+
`web_search` via `githubMcpToolsets`/`githubMcpTools` settings, and
|
|
230
|
+
`network.allowOutbound: false` blocks fetch egress at the network layer; a persistent
|
|
231
|
+
key for the built-in `web_fetch` itself is unconfirmed at 1.0.98
|
|
232
|
+
([allowing tools](https://docs.github.com/en/copilot/how-tos/copilot-cli/use-copilot-cli/allowing-tools),
|
|
233
|
+
[changelog](https://github.com/github/copilot-cli/blob/main/changelog.md)).
|
|
234
|
+
- **MCP registration** — `~/.copilot/mcp-config.json` or project `.mcp.json`; stdio
|
|
235
|
+
entries use `"type": "local"` plus `command`/`args`/`env`; a per-server `tools` list
|
|
236
|
+
gates which tools are exposed — per-tool control at registration time.
|
|
237
|
+
- **Rules** — `~/.copilot/copilot-instructions.md` (user),
|
|
238
|
+
`.github/copilot-instructions.md` (repo) and `.github/instructions/**/*.instructions.md`
|
|
239
|
+
(path-scoped via `applyTo` globs); `AGENTS.md`/`CLAUDE.md` discovery (changelog-dated
|
|
240
|
+
≤1.0.86; `GEMINI.md` could not be dated to the lock);
|
|
241
|
+
`COPILOT_CUSTOM_INSTRUCTIONS_DIRS` adds directories
|
|
242
|
+
([custom instructions](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-custom-instructions)).
|
|
243
|
+
|
|
244
|
+
## Cross-cutting observations
|
|
245
|
+
|
|
246
|
+
- **AGENTS.md is the de-facto rules standard.** Seven of the eight hosts read it
|
|
247
|
+
natively (Codex, Cline, Cursor, Devin, Copilot, Pi, OpenCode); Claude Code reads it as
|
|
248
|
+
a fallback. One rules file works nearly everywhere; the exception: OpenCode v2 has no
|
|
249
|
+
CLAUDE.md fallback.
|
|
250
|
+
- **Replacement is exclusive to native extension points** — only OpenCode. Exclusion is
|
|
251
|
+
the general forced path on MCP hosts. The two structural limits: OpenCode search has no
|
|
252
|
+
middle tier, and Cursor search cannot be forced at all.
|
|
253
|
+
- **Version drift to re-verify on the next baseline pass:** Cline's docs describe the 3.x
|
|
254
|
+
`cline` binary while the lock is 0.0.13 `clite`; Codex's config docs have moved and
|
|
255
|
+
describe a newer release; Copilot's `GEMINI.md` support could not be changelog-dated to
|
|
256
|
+
≤1.0.98. Protocol-revision evidence for every host lives in
|
|
257
|
+
[mcp-compatibility.md](mcp-compatibility.md).
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# MCP compatibility across hosts
|
|
2
2
|
|
|
3
|
-
This note answers one question for the
|
|
4
|
-
[support matrix](integration.md) speak the same MCP protocol standard? Short answer: they all
|
|
3
|
+
This note answers one question for the shipped MCP server: do the hosts in the
|
|
4
|
+
[support matrix](../integration.md) speak the same MCP protocol standard? Short answer: they all
|
|
5
5
|
speak MCP, but not the same revision. MCP has split into two eras, hosts negotiate different
|
|
6
6
|
revisions, and one dual-era server covers them all.
|
|
7
7
|
|
|
8
|
-
The
|
|
9
|
-
`2024-11-05` (Cline), `2025-06-18` (Codex
|
|
8
|
+
The seven MCP-capable hosts in the matrix span **four different negotiated revisions**:
|
|
9
|
+
`2024-11-05` (Cline), `2025-06-18` (Codex), `2025-11-25` (Pi), and
|
|
10
10
|
`2026-07-28` (Claude Code, Devin, GitHub Copilot) — plus Cursor, whose revision no primary
|
|
11
11
|
source pins. OpenCode is out of scope here: its shipped integration is the
|
|
12
|
-
[native plugin adapter](opencode-v2.md), not MCP.
|
|
12
|
+
[native plugin adapter](../agents/opencode-v2.md), not MCP.
|
|
13
13
|
|
|
14
14
|
**Research baseline:** 2026-10-19, using the same version locks as the host support matrix in
|
|
15
|
-
[integration.md](integration.md). Claims are cited to primary sources: the MCP specification,
|
|
15
|
+
[integration.md](../integration.md). Claims are cited to primary sources: the MCP specification,
|
|
16
16
|
official host docs and changelogs, npm registry manifests, and host source code at the locked
|
|
17
17
|
versions.
|
|
18
18
|
|
|
@@ -74,87 +74,28 @@ Two release lines of the official TypeScript SDK ([docs](https://github.com/mode
|
|
|
74
74
|
|
|
75
75
|
## What each host supports
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
`type` (`stdio` | `sse` | `streamableHttp`), `command`/`args`/`env` or `url`/`headers`, plus
|
|
100
|
-
`disabled` and `autoApprove`. Current docs describe a newer, flatter layout than the locked
|
|
101
|
-
binary. The client declares no capabilities and requests `2024-11-05` — the protocol floor
|
|
102
|
-
of the whole matrix; treat it as text-content-blocks-only.
|
|
103
|
-
- **Codex** — Rust client on the official rmcp crate. Config: `~/.codex/config.toml`
|
|
104
|
-
`[mcp_servers.<name>]` — stdio `command`/`args`/`env`/`env_vars`; HTTP `url`,
|
|
105
|
-
`bearer_token_env_var`, `http_headers`; `startup_timeout_sec` (10s), `tool_timeout_sec`
|
|
106
|
-
(60s), `enabled_tools`/`disabled_tools`, per-tool approval modes and output limits.
|
|
107
|
-
**stdio children do not inherit the parent environment** — only `HOME`, `PATH`, and a few
|
|
108
|
-
system vars plus explicitly configured `env`, so `DEEPSEEK_API_KEY` must be passed
|
|
109
|
-
explicitly. When a tool result has `structuredContent`, Codex replaces the content blocks
|
|
110
|
-
with the serialized JSON. No SSE support.
|
|
111
|
-
- **Continue** — Config: `~/.continue/config.yaml` `mcpServers` list — `name`, `type`
|
|
112
|
-
(`stdio` | `sse` | `streamable-http`), `command`/`args`/`env`/`cwd` or `url`/`apiKey`/
|
|
113
|
-
`requestOptions`; `${{ secrets.NAME }}` interpolation; headless mode fails if any MCP
|
|
114
|
-
server fails to connect. **Tool names are exposed raw, without a server prefix**, and
|
|
115
|
-
matching is first-found across servers — avoid generic names like `search`.
|
|
116
|
-
`structuredContent` is never read; content blocks are JSON-stringified for the model.
|
|
117
|
-
- **Gemini** — Config: `mcpServers` in `~/.gemini/settings.json` or `.gemini/settings.json` —
|
|
118
|
-
`command`/`args`/`env`/`cwd`, or `url` with `type: "http" | "sse"` (at 0.64.0 a bare `url`
|
|
119
|
-
defaults to Streamable HTTP), `headers`, `timeout`, `includeTools`/`excludeTools`; `env`
|
|
120
|
-
values expand `$VAR`/`${VAR}`. Tools get an `mcp_{server}_{tool}` name truncated at 63
|
|
121
|
-
chars, and underscores in the server name break its FQN parsing — keep the server name
|
|
122
|
-
short and underscore-free. Reads only `content` blocks; `structuredContent` is ignored.
|
|
123
|
-
- **Pi** — Config: `~/.pi/agent/mcp.json` or `.pi/mcp.json` — stdio `command`/`args`/`env`/
|
|
124
|
-
`cwd`, HTTP `url`/`headers`, plus `timeout`, `enabled`, `exposure`. **MCP tools are hidden
|
|
125
|
-
from the model by default (`exposure: "codemode"`) — set `exposure: "direct"`** so the
|
|
126
|
-
search/fetch tools are declared. SSE is explicitly rejected. Text results over 20 KB are
|
|
127
|
-
middle-truncated with the full text saved to a file. Pi is the one open-source host that
|
|
128
|
-
uses `structuredContent` and tool `outputSchema`.
|
|
129
|
-
|
|
130
|
-
### Proprietary hosts
|
|
131
|
-
|
|
132
|
-
All four locked versions happen to be the latest stable releases at the research date, so
|
|
133
|
-
current docs and changelogs apply to them directly. Notes relevant to a two-tool DeepSeek
|
|
134
|
-
search/fetch server:
|
|
135
|
-
|
|
136
|
-
- **Claude Code** — [MCP docs](https://code.claude.com/docs/en/mcp),
|
|
137
|
-
[changelog](https://raw.githubusercontent.com/anthropics/claude-code/main/CHANGELOG.md).
|
|
138
|
-
Config: `.mcp.json` (`mcpServers` with `command`/`args`/`env`, or `type: "http"` + `url`).
|
|
139
|
-
Env expansion `${VAR}` works in `command`/`args`/`env`/`url`/`headers`. Tool permission
|
|
140
|
-
rules `mcp__<server>__<tool>`; tool descriptions capped at 4,096 chars (2.1.296+); tool
|
|
141
|
-
output capped at 25k tokens by default (`MAX_MCP_OUTPUT_TOKENS`), oversized text saved to a
|
|
142
|
-
file; 16 MiB message cap on HTTP transports.
|
|
143
|
-
- **Cursor** — [MCP docs](https://cursor.com/docs/mcp),
|
|
144
|
-
[CLI MCP](https://cursor.com/docs/cli/mcp). Config: `.cursor/mcp.json` or
|
|
145
|
-
`~/.cursor/mcp.json`; `command`/`args`/`env` for stdio (docs mark `type` as required),
|
|
146
|
-
`url`/`headers` for remote; `${env:NAME}` interpolation. MCP tools need approval; the CLI
|
|
147
|
-
has `--approve-mcps`, global-scope servers have been auto-approved since April 2026.
|
|
148
|
-
- **Devin** — [MCP config](https://docs.devin.ai/cli/extensibility/mcp/configuration),
|
|
149
|
-
[changelog](https://docs.devin.ai/cli/changelog). Config: `.devin/mcp_config.local.json`
|
|
150
|
-
(default), `.devin/mcp_config.json`, or `~/.config/devin/mcp_config.json`; same
|
|
151
|
-
`mcpServers` shape; `devin mcp add <name> -- <cmd>` / `<URL>`. MCP tools prompt for
|
|
152
|
-
approval by default, with `mcp__server__tool` allow/deny patterns in `permissions`.
|
|
153
|
-
- **GitHub Copilot** — [MCP docs](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers),
|
|
154
|
-
[repo](https://github.com/github/copilot-cli). Config: `~/.copilot/mcp-config.json` or
|
|
155
|
-
project `.mcp.json`; stdio entries use `"type": "local"` plus `command`/`args`/`env`; a
|
|
156
|
-
per-server `tools` list gates which tools are exposed; runtime flags
|
|
157
|
-
`--allow-tool`/`--deny-tool` accept `MCP_SERVER_NAME(tool)`.
|
|
77
|
+
Host versions are locked in [`docs/hosts.jsonc`](../hosts.jsonc), the single source of truth for
|
|
78
|
+
host facts; each row below was verified against that lock on the research baseline.
|
|
79
|
+
|
|
80
|
+
| Host | Negotiated revision | Transports | Evidence |
|
|
81
|
+
| --- | --- | --- | --- |
|
|
82
|
+
| Cline | `2024-11-05` | stdio, Streamable HTTP, SSE | Custom client (no official SDK); `protocolVersion "2024-11-05"` extracted from the platform binary; source repo not public |
|
|
83
|
+
| Codex | `2025-06-18`; `mcp_2026_07_28` feature flag opts into `2026-07-28` | stdio, Streamable HTTP (no SSE) | Git tag `rust-v0.163.0`: rmcp 3.5.1 pinned; initialize sends `V_2025_06_18` |
|
|
84
|
+
| Pi | `2025-11-25` | stdio, Streamable HTTP (SSE rejected) | Git tag: own `@earendil-works/pi-mcp` client, `LATEST_PROTOCOL_VERSION "2025-11-25"` |
|
|
85
|
+
| Claude Code | `2026-07-28` by default (`MCP_PROTOCOL_NEGOTIATION=legacy` opt-out) | stdio, Streamable HTTP, SSE, ws | Changelog 2.1.296+: "negotiate MCP protocol version 2026-07-28 by default"; docs: TS SDK 2.0 runtime |
|
|
86
|
+
| Cursor | Unpinnable from primary sources (docs show ≥ `2025-06-18` features) | stdio, Streamable HTTP, SSE | Docs feature set only; no revision stated in docs or changelog |
|
|
87
|
+
| Devin | `2026-07-28` | stdio, Streamable HTTP (SSE fallback), SSE | Changelog for the locked release itself: "Support for MCP protocol revision 2026-07-28" |
|
|
88
|
+
| GitHub Copilot | `2026-07-28` | stdio (`type: "local"`), Streamable HTTP, SSE | Changelog 1.0.81: "Ship MCP 2026-07-28 support to CLI, SDK, IDE, and in-memory clients" |
|
|
89
|
+
|
|
90
|
+
All seven support stdio and Streamable HTTP; legacy SSE is never required (and Codex
|
|
91
|
+
and Pi reject it). Verification methodology and provenance follow the
|
|
92
|
+
[per-host reference](control-matrix.md#per-host-reference); the Evidence column cites per-row
|
|
93
|
+
sources and Sources lists the file-level links.
|
|
94
|
+
|
|
95
|
+
Registration paths, config shapes, approval surfaces, and per-host quirks live in the
|
|
96
|
+
[per-host reference](control-matrix.md#per-host-reference) of the control-matrix note; they
|
|
97
|
+
are setup facts, not protocol facts. The table above carries the protocol evidence, and
|
|
98
|
+
source-level links follow in Sources.
|
|
158
99
|
|
|
159
100
|
## One server for all hosts
|
|
160
101
|
|
|
@@ -164,12 +105,14 @@ differences:
|
|
|
164
105
|
|
|
165
106
|
1. **Tools only, text-first results.** Expose the retrieval as two tools via the `tools`
|
|
166
107
|
capability; do not rely on resources, prompts, sampling, elicitation, or roots — the
|
|
167
|
-
hosts' client capabilities are inconsistent (Codex has elicitation only;
|
|
168
|
-
|
|
108
|
+
hosts' client capabilities are inconsistent (Codex has elicitation only; Pi serves
|
|
109
|
+
roots). Always return readable
|
|
169
110
|
text in `content` blocks, and mirror the same data in `structuredContent` for
|
|
170
111
|
`2025-06-18`+ clients — the spec's own backwards-compat SHOULD. This split matters in
|
|
171
|
-
practice: Codex *replaces* content with `structuredContent` when present
|
|
172
|
-
|
|
112
|
+
practice: Codex *replaces* content with `structuredContent` when present; Cline reads
|
|
113
|
+
text content only; Pi is
|
|
114
|
+
content-first, falling back to `structuredContent` only when a result has no content
|
|
115
|
+
blocks (verified in `tools.ts` at v1.3.0).
|
|
173
116
|
2. **stdio is the universal transport.** Every host in the matrix launches stdio servers
|
|
174
117
|
with the same conceptual JSON (`mcpServers` → `command`/`args`/`env`), differing only in
|
|
175
118
|
file location and cosmetic field names. stdio needs no OAuth and no URL config, and the
|
|
@@ -185,15 +128,11 @@ differences:
|
|
|
185
128
|
different `type` strings: `http`, `streamable-http`, `streamableHttp`), and OAuth 2.1
|
|
186
129
|
resource-server behavior (RFC 9728 metadata) then applies; prefer pre-registered clients
|
|
187
130
|
over the now-deprecated Dynamic Client Registration.
|
|
188
|
-
5. **Host quirks to design around.**
|
|
189
|
-
`deepseek_fetch`)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
cap and fetch output bounded (Claude Code caps tool output at 25k tokens by default; Pi
|
|
194
|
-
truncates text over 20 KB). Document per-host approval: `mcp__deepseek__*` rules (Claude
|
|
195
|
-
Code, Devin), `tools` lists and `--allow-tool` (Copilot), `--approve-mcps` (Cursor),
|
|
196
|
-
`autoApprove` (Cline), `exposure: "direct"` (Pi).
|
|
131
|
+
5. **Host quirks to design around.** Tool naming (`deepseek_web_search`,
|
|
132
|
+
`deepseek_fetch`) already reflects the quirk catalog in the
|
|
133
|
+
[per-host reference](control-matrix.md#per-host-reference) — name collisions and
|
|
134
|
+
truncation, environment passing, output caps, and per-host approval surfaces; consult
|
|
135
|
+
it per host rather than this summary.
|
|
197
136
|
|
|
198
137
|
## Sources
|
|
199
138
|
|
|
@@ -215,20 +154,12 @@ differences:
|
|
|
215
154
|
|
|
216
155
|
### Hosts
|
|
217
156
|
|
|
218
|
-
- Gemini CLI: [v0.64.0 tag](https://github.com/google-gemini/gemini-cli/tree/v0.64.0) —
|
|
219
|
-
[package.json (SDK 1.23.0 pin)](https://github.com/google-gemini/gemini-cli/blob/v0.64.0/packages/core/package.json),
|
|
220
|
-
[mcp-client.ts](https://github.com/google-gemini/gemini-cli/blob/v0.64.0/packages/core/src/tools/mcp-client.ts),
|
|
221
|
-
[mcp-tool.ts (name handling, result rendering)](https://github.com/google-gemini/gemini-cli/blob/v0.64.0/packages/core/src/tools/mcp-tool.ts),
|
|
222
|
-
[npm 0.64.0](https://registry.npmjs.org/@google/gemini-cli)
|
|
223
157
|
- Codex: [rust-v0.163.0 tag](https://github.com/openai/codex/tree/rust-v0.163.0) —
|
|
224
158
|
[Cargo.toml (rmcp pin)](https://github.com/openai/codex/blob/rust-v0.163.0/codex-rs/Cargo.toml),
|
|
225
159
|
[rmcp_client.rs (initialize params)](https://github.com/openai/codex/blob/rust-v0.163.0/codex-rs/codex-mcp/src/rmcp_client.rs),
|
|
226
160
|
[mcp_types.rs (config keys)](https://github.com/openai/codex/blob/rust-v0.163.0/codex-rs/config/src/mcp_types.rs),
|
|
227
161
|
[utils.rs (stdio env allowlist)](https://github.com/openai/codex/blob/rust-v0.163.0/codex-rs/rmcp-client/src/utils.rs),
|
|
228
162
|
[rust-sdk protocol constants at the pinned rev](https://github.com/modelcontextprotocol/rust-sdk/blob/4048ac40e958fb1a7d614617a2ae8d26666ee2fa/crates/rmcp/src/model.rs)
|
|
229
|
-
- Continue: [1.5.47 npm tarball](https://registry.npmjs.org/@continuedev/cli/-/cli-1.5.47.tgz)
|
|
230
|
-
(MCPService.ts, mcpTransports.ts, bundled SDK protocol constants; no git tag exists),
|
|
231
|
-
[current docs](https://docs.continue.dev/customize/deep-dives/mcp)
|
|
232
163
|
- Pi: [v1.3.0 tag](https://github.com/earendil-works/pi/tree/v1.3.0) —
|
|
233
164
|
[pi-mcp protocol types](https://github.com/earendil-works/pi/blob/v1.3.0/packages/mcp/src/protocol/types.ts),
|
|
234
165
|
[MCP docs at the tag](https://github.com/earendil-works/pi/blob/v1.3.0/packages/coding-agent/docs/mcp.md),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "deepseek-web-retrieval",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"description": "Token-efficient DeepSeek Search and Fetch for coding agents, starting with OpenCode v2.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"./mcp": "./src/mcp/server.ts"
|
|
27
27
|
},
|
|
28
28
|
"bin": {
|
|
29
|
-
"deepseek-web-retrieval": "
|
|
29
|
+
"deepseek-web-retrieval": "dist/cli.js"
|
|
30
30
|
},
|
|
31
31
|
"files": [
|
|
32
32
|
"index.ts",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"test:e2e": "bun run test/e2e/run.ts",
|
|
47
47
|
"docs:matrix": "bun run scripts/render-matrix.ts",
|
|
48
48
|
"test:coverage": "bun test --coverage",
|
|
49
|
-
"check": "bun run typecheck && bun run build && bun test"
|
|
49
|
+
"check": "bun run typecheck && bun run docs:matrix --check && bun run build && bun test"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"@opencode/plugin": "^2.0.32"
|
|
@@ -64,6 +64,8 @@
|
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"@modelcontextprotocol/server": "^2.3.1",
|
|
67
|
+
"jsonc-parser": "^3.3.1",
|
|
68
|
+
"smol-toml": "^1.9.1",
|
|
67
69
|
"zod": "^4"
|
|
68
70
|
}
|
|
69
71
|
}
|
package/src/core/auth.ts
CHANGED