deepseek-search
by zou-hong-run
README.md
# kimi-deepseek-search
[](LICENSE)
[](package.json)
[](README.en.md)
**简体中文** | [English](README.en.md)
一个 [Kimi Code CLI](https://www.kimi.com/code/docs/zh/) 插件:把 DeepSeek 原生的 Search / Fetch JSON API 注册为两个 MCP 工具——**网页搜索**和**网页抓取**。
它主要作为内置联网工具的兜底:当 Kimi Code 套餐不覆盖内置 `web_search` 时(例如返回 HTTP 403),Agent 可以改用本插件的工具,而不是反复重试。
**零运行时依赖**,只用 Node 内置的 `fetch`、`readline` 和 `zlib`。
## 功能
- **`web_search`** — 调用 `POST /v1/tools/search`,返回结构化结果:标题、URL、摘要、总结、正文(可选)、站点名与图标、发布时间、权威度、相关度。
- **`web_fetch`** — 调用 `POST /v1/tools/fetch`,把一个网页返回为 Markdown。
- **查询运算符** — `site:`、`-site:`、`-`、`"精确短语"`、`lang:zh,en`、`after:2025-01-01`、`before:2026-06-01`。
- **复用已有凭据** — 自动读取 Kimi Code 已配置的 DeepSeek key,通常无需额外配置。
- **重试** — 对 `408`、`429`、`500`、`502`、`503`、`504` 指数退避重试,尊重 `Retry-After`(上限 8 秒)。
- **可取消** — MCP 的 `notifications/cancelled` 会中止正在进行的请求。
- **有上限的 I/O** — 原始响应上限 8 MiB,解压后上限 16 MiB。
- **协议感知** — 只向协商了 MCP `2025-06-18` 的客户端返回 `structuredContent`。
## 环境要求
- 支持插件的 Kimi Code CLI(`/plugins`)。
- Node.js **18.13+**(推荐 20 或 22)。
- 一个可访问 `/v1/tools/search` 和 `/v1/tools/fetch` 的 DeepSeek API key。搜索与抓取由 DeepSeek 计费,不消耗 Kimi Code 套餐额度。
## 安装
### 从 GitHub 安装
```text
/plugins install https://github.com/zou-hong-run/kimi-code-deepseek-search
```
安装后重新加载:
```text
/reload
```
也可以固定到某个版本,Kimi Code 支持以下 GitHub URL 形式:
```text
/plugins install https://github.com/zou-hong-run/kimi-code-deepseek-search/tree/v1.1.0
/plugins install https://github.com/zou-hong-run/kimi-code-deepseek-search/releases/tag/v1.1.0
/plugins install https://github.com/zou-hong-run/kimi-code-deepseek-search/commit/<sha>
```
### 从本地目录安装
```text
/plugins install C:\path\to\kimi-deepseek-search
```
Kimi Code 会把目录复制到 `$KIMI_CODE_HOME/plugins/managed/deepseek-search/`,并始终从这份托管副本运行。安装后再改源码不会生效,需要重新安装。
### 从 zip 安装
```text
/plugins install https://github.com/zou-hong-run/kimi-code-deepseek-search/archive/refs/heads/main.zip
```
### 验证
```text
/plugins list
/plugins info deepseek-search
```
两个工具会以 `mcp__deepseek-search__web_search` 和 `mcp__deepseek-search__web_fetch` 的名字出现。如果内置搜索可用,Agent 默认会优先用内置的;想强制验证本插件,直接要求它调用 `mcp__deepseek-search__web_search`。
插件清单还会注入一段 system prompt:优先使用内置联网工具,失败时回退到本插件。
## 凭据
每次请求时按以下顺序解析,取第一个非空值:
1. `DEEPSEEK_SEARCH_API_KEY`
2. `DEEPSEEK_API_KEY`
3. `$KIMI_CODE_HOME/config.toml`(默认 `~/.kimi-code/config.toml`)中 `[providers.deepseek]` 表的 `api_key`
key 不会被写入磁盘、打印到日志或缓存:轮换配置或环境变量后,下一次调用立即生效。找不到任何 key 时,工具返回 `WEB_PROVIDER_CREDENTIAL_MISSING`。
## 配置
全部可选,默认值直接适配 DeepSeek 公共 API。
| 环境变量 | 默认值 | 作用 |
| --- | --- | --- |
| `DEEPSEEK_SEARCH_BASE_URL` | `https://api.deepseek.com` | API 基地址,会自动拼接 `/v1/tools/search` 和 `/v1/tools/fetch` |
| `DEEPSEEK_SEARCH_COUNT` | `10` | 调用方未传 `count` 时的默认结果数 |
| `DEEPSEEK_SEARCH_MAX_RETRIES` | `2` | 首次尝试之后的重试次数 |
| `DEEPSEEK_SEARCH_RETRY_DELAY_MS` | `800` | 指数退避的基础延迟 |
| `DEEPSEEK_SEARCH_API_KEY` | — | 最高优先级凭据 |
| `DEEPSEEK_API_KEY` | — | 第二优先级凭据 |
| `KIMI_CODE_HOME` | `~/.kimi-code` | 从这里读取 `config.toml` |
## 工具说明
### `web_search`
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `query` | string | 是 | 1–128 字符,支持上面的查询运算符 |
| `count` | integer | 否 | 1–50,默认 10 |
| `ori_question` | string | 否 | 触发搜索的原始用户问题(≤128 字符),帮助理解意图 |
| `need_content` | boolean | 否 | 同时返回每个网页的 Markdown 正文;正文通常很大 |
| `localization` | string | 否 | 用于偏好本地化结果的 IP 地址(≤64 字符) |
每条结果可能包含 `title`、`url`、`snippet`、`summary`、`content`、`siteName`、`siteIcon`、`date`、`authority`(0–4)、`rerankScore`(0–3)。没有 URL 的条目会被丢弃,重复 URL 会去重。空结果列表表示"没有匹配",不是错误。
### `web_fetch`
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `url` | string | 是 | 绝对的 `http`/`https` URL,≤8192 字符,不能内嵌用户名或密码 |
返回 `{ url, title, content }`,其中 `content` 为 Markdown。
### 错误码
| 错误码 | 含义 |
| --- | --- |
| `WEB_PROVIDER_ERROR` | 参数非法、服务方报错,或响应无法解析 |
| `WEB_PROVIDER_CREDENTIAL_MISSING` | 环境变量和 `config.toml` 里都没有找到 key |
| `WEB_ABORTED` | 请求被客户端取消,或服务正在关闭 |
服务方返回错误信息时,会原样透出。
## 命令行
同一套核心逻辑也打包成两个 CLI,便于脱离 Agent 调试:
```bash
export DEEPSEEK_API_KEY=sk-...
node bin/websearch.mjs "Kimi Code 插件" --count 5
node bin/websearch.mjs "Kimi Code 插件" --json --content
node bin/webfetch.mjs https://www.kimi.com/code/docs/zh/ --json
```
执行 `npm link` 后可以直接使用 `kimi-deepseek-search` 和 `kimi-deepseek-fetch`。`--help` 会列出完整参数;凭据与端点解析规则和 MCP 工具完全一致。
## 开发
```bash
npm test # node:test 测试套件
npm run test:watch # 监听改动并重跑
node lib/server.mjs # 在 stdio 上运行 MCP 服务
```
测试通过 mock `globalThis.fetch` 完成,不需要 key,也不会发起真实网络请求。
目录结构:
```text
kimi-deepseek-search/
kimi.plugin.json # Kimi Code 插件清单(必须位于根目录)
package.json # 元数据、CLI、测试脚本
lib/search.mjs # API 客户端、参数校验、结果映射与渲染
lib/server.mjs # 精简的 JSON-RPC/MCP stdio 服务
bin/websearch.mjs # 搜索 CLI
bin/webfetch.mjs # 抓取 CLI
test/search.test.mjs # node:test 测试套件
```
## 设计说明
- **凭据读取刻意保持窄口径。** 读取 `config.toml` 用的是针对 `[providers.deepseek]` 单个 key 的逐行解析,而不是引入 TOML 依赖;它只需要兼容 Kimi Code 写出的格式。
- **按魔数判断压缩。** 宿主进程可能安装了与 Node 内置 fetch 背后不同版本的 undici dispatcher,跨版本时 `response.json()` 可能拿到仍未解压的字节。按 gzip/zlib 魔数识别,使解码不受这个边界影响。
- **MCP 服务刻意做小。** 只实现 `initialize`、`tools/list`、`tools/call`、`ping`、取消通知,以及按协议版本开关的 `structuredContent`,不引入 SDK。
- **请求并发处理。** 一次慢搜索不会阻塞下一次工具调用。
## 限制
- DeepSeek 的 `/v1/tools/search`、`/v1/tools/fetch` 由服务方维护,可能变更或限流;本插件不做本地爬取或 HTML 解析。
- 返回内容取决于服务方;`authority` 与 `rerankScore` 是服务方信号,不是本地计算的。
- API 用量计入 key 所属的 DeepSeek 账户。
- `web_fetch` 由服务方抓取,插件本身不运行本地 HTTP 客户端。
## 许可证
MIT,见 [LICENSE](LICENSE)。
核心逻辑移植自 [aaronlei/dsh-web-search-diy](https://github.com/aaronlei/dsh-web-search-diy)(MIT),上游版权声明已保留在 `LICENSE` 中。Kimi Code 插件封装、MCP 服务、CLI 以及 DeepSeek Search/Fetch 对接属于新增工作。
---
[English README](README.en.md)
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues