关于 DeepSeek Search Everywhere
DeepSeek Search Everywhere 是供 AI Agent 使用的 MCP 服务,通过 DeepSeek Search & Fetch API 提供网页搜索、页面抓取和研究功能。它在 API 外增加去重、可配置的内容上限、缓存和请求限速。
主要功能
- 01搜索网页并返回页面正文
- 02单个或批量抓取 URL
- 03生成多查询引用研究报告
- 04按 Schema 提取结构化数据
- 05结果去重与内容预算控制
- 06缓存和端点级限速
适用场景
- 01一次调用搜索来源并读取页面正文
- 02为研究问题收集并抓取来源
- 03从多个查询角度生成引用报告
- 04从网页提取结构化字段
MCP 相关
通过默认的 stdio 或可选的 Bearer 令牌保护型 Streamable HTTP,向 MCP 客户端提供 7 个工具。HTTP 模式必须配置 Bearer 令牌。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
6收录的工具列表 · 更新于 1 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| lang | any | 否 | |
| count | integer | 否 | |
| query | string | 是 | |
| dedupe | boolean | 否 | |
| refresh | boolean | 否 | |
| rewrite | boolean | 否 | |
| need_content | boolean | 否 | |
| ori_question | any | 否 | |
| summary_chars | any | 否 | |
| max_total_chars | integer | 否 | |
| strip_boilerplate | boolean | 否 | |
| max_chars_per_result | integer | 否 |
详细介绍
DeepSeek Search Everywhere MCP
一个 MCP 服务,通过官方 DeepSeek Search & Fetch API,为 AI Agent 提供网页搜索、页面抓取和多来源研究功能。
它是对该 API 的轻量、审慎封装:结果会去重,内容长度限制在你设定的预算内,重复调用会由内存缓存提供服务,外发调用则由本地速率限制器控制节奏。 默认使用 stdio,提供 7 个工具,也可选择启用受承载令牌保护的流式 HTTP。
这是一个标准 MCP 服务,因此适用于任何兼容 MCP 的 AI 客户端或 Agent:Claude Code、 Claude Desktop、Google Antigravity、Cursor、Windsurf、VS Code(GitHub Copilot)、Gemini CLI、Codex CLI、Zed、 opencode 等。本地客户端通过 stdio 启动服务;远程或共享配置可通过 HTTP 连接。
与 DeepSeek 无关联。这是一个由社区独立维护的项目。
功能
- 一次请求即可搜索并获取内容:
need_content会将页面文本直接内联返回,因此通常无需针对每条结果再进行一次抓取。 - 批量抓取和研究:
deepseek_fetch_many可并发抓取最多 10 个 URL;deepseek_research会一次性收集来源:先进行一次搜索,再直接抓取搜索结果中缺少内容的页面。它不会迭代或总结。 - 深度研究和结构化提取:
deepseek_deep_research会将主题拆分为子查询,并综合生成带引用的简报报告;deepseek_extract会提取符合架构或字段要求、经过验证的结构化 JSON。 - 结果清理:按规范 URL 以及标题/站点去重,为单条结果和总内容设置字符数预算,并取消 Markdown 转义。
- 可选择通过
deepseek-flash将查询改写为英文(禁用思考模式),也可使用显式lang运算符处理非英语查询。 - 缓存和限制器:带单航班机制的 TTL + LRU 缓存、按端点设置的令牌桶,以及用于绕过缓存的
refresh。 - 默认安全:静态 SSRF 检查、机密信息脱敏、不收集遥测数据。请参阅安全。
要求
- Python 3.11 或更高版本
- 从 DeepSeek 平台获取的 DeepSeek API 密钥(
DEEPSEEK_API_KEY)
安装
该服务已发布到 PyPI,并列入官方 MCP Registry,
名称为 io.github.radoxtech/deepseek-search-everywhere-mcp。
# Run without installing (uv)
uvx deepseek-search-everywhere-mcp
# Or install with pip
pip install deepseek-search-everywhere-mcp
HTTP 传输需要 http extra(它会安装 uvicorn):
pip install "deepseek-search-everywhere-mcp[http]"
要运行 main 中最新的未发布代码,或运行源码检出版本:
uvx --from git+https://github.com/radoxtech/deepseek-search-everywhere-mcp deepseek-search-everywhere-mcp
git clone https://github.com/radoxtech/deepseek-search-everywhere-mcp.git
cd deepseek-search-everywhere-mcp
pip install -e ".[http]"
检查密钥和网络连接是否正常(打印余额后退出):
export DEEPSEEK_API_KEY=sk-...
deepseek-search-everywhere-mcp --check
快速开始
以下示例均使用 stdio。请将 sk-... 替换为你的密钥。
该服务不依赖特定客户端:以下示例涵盖常见客户端,其他任何 MCP 客户端 (Antigravity、Cursor、Windsurf、VS Code、Gemini CLI、Codex CLI、Zed 等)也都可以在自己的 MCP 配置格式中使用相同的 命令、参数和环境变量。
Claude Code
claude mcp add deepseek-search-everywhere -e DEEPSEEK_API_KEY=sk-... -- \
uvx deepseek-search-everywhere-mcp
Claude Desktop
编辑 claude_desktop_config.json(Settings,Developer,Edit Config):
{
"mcpServers": {
"deepseek-search-everywhere": {
"command": "uvx",
"args": ["deepseek-search-everywhere-mcp"],
"env": { "DEEPSEEK_API_KEY": "sk-..." }
}
}
}
opencode
在 opencode.json 中:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"deepseek-search-everywhere": {
"type": "local",
"command": ["uvx", "deepseek-search-everywhere-mcp"],
"environment": { "DEEPSEEK_API_KEY": "{env:DEEPSEEK_API_KEY}" },
"enabled": true
}
}
}
任意 stdio 客户端
大多数客户端(包括 Antigravity、Cursor 和 Windsurf)都使用 mcpServers JSON 配置块。使用 Claude Desktop 示例中的 uvx
形式;如果已安装该软件包,也可以将客户端指向控制台脚本:
{
"mcpServers": {
"deepseek-search-everywhere": {
"command": "deepseek-search-everywhere-mcp",
"env": { "DEEPSEEK_API_KEY": "sk-..." }
}
}
}
python -m deepseek_search_everywhere_mcp 与之等效。
Streamable HTTP
适用于通过 HTTP 连接的客户端。始终需要 bearer 令牌;没有令牌时,服务会拒绝启动。
pip install "deepseek-search-everywhere-mcp[http]"
export DEEPSEEK_API_KEY=sk-...
export MCP_BEARER_TOKEN="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
deepseek-search-everywhere-mcp --transport streamable-http # http://127.0.0.1:8000/mcp
选项:--host(默认值 127.0.0.1)、--port(默认值 8000)、--path(默认值 /mcp)。令牌仅从环境变量中读取,绝不会从命令行读取。服务以无状态模式运行,并以 JSON 响应
(不使用 SSE 流)。客户端配置:
{
"mcpServers": {
"deepseek-search-everywhere": {
"url": "http://127.0.0.1:8000/mcp",
"headers": { "Authorization": "Bearer <MCP_BEARER_TOKEN>" }
}
}
}
Claude Code:claude mcp add --transport http deepseek-search-everywhere http://127.0.0.1:8000/mcp --header "Authorization: Bearer $MCP_BEARER_TOKEN"。
服务使用纯 HTTP;如果绑定地址超出回环范围,请在其前面配置 TLS(参见 SECURITY.md)。
Docker
GitHub Container Registry(ghcr.io)上提供官方容器镜像:
docker pull ghcr.io/radoxtech/deepseek-search-everywhere-mcp:latest
Stdio 模式(Claude Desktop、Cursor、本地 IDE):
{
"mcpServers": {
"deepseek-search-everywhere": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "DEEPSEEK_API_KEY=sk-...",
"ghcr.io/radoxtech/deepseek-search-everywhere-mcp:latest"
]
}
}
}
远程 HTTP 托管(Docker Compose、VPS、n8n、Dify、云端 Agent):
docker run -d --name deepseek-mcp -p 8000:8000 \
-e DEEPSEEK_API_KEY="sk-..." \
-e MCP_BEARER_TOKEN="your-secret-token" \
ghcr.io/radoxtech/deepseek-search-everywhere-mcp:latest \
--transport streamable-http --host 0.0.0.0 --port 8000
容器以无特权的非 root 用户(UID 10001)运行,依赖项与主机隔离。
工具
| 工具 | 用途 | 参数(默认值) |
|---|---|---|
deepseek_search | 搜索网络;返回内嵌的页面文本(默认),或摘要片段和元数据 | query、count=5(1-50)、ori_question、need_content=True、lang、max_chars_per_result=4000、max_total_chars=30000、dedupe=True、rewrite=False、after、before、include_domains、exclude_domains、refresh=False、summary_chars、strip_boilerplate=True |
deepseek_fetch | 将一个已知 URL 获取为 Markdown(支持词汇匹配摘要提取和分节阅读) | url、clean=True、max_chars=20000、query、section、max_snippets=3、refresh=False、strip_boilerplate=True |
deepseek_fetch_many | 并发获取 1-10 个 URL(一次最多处理 5 个) | urls、max_chars_per_url=4000、max_total_chars=20000、clean=True、query、refresh=False、strip_boilerplate=True |
deepseek_research | 单轮来源收集:搜索并获取内容,自动抓取内容过少的页面(少于 200 字符)。不迭代,不生成摘要 | question、max_pages=5(1-50)、per_page_chars=6000、total_chars=30000、after、before、include_domains、exclude_domains、lang、rewrite=False、dedupe=True、refresh=False、strip_boilerplate=True |
deepseek_deep_research | 从多个角度研究主题;拆分子查询、收集来源并综合生成带引文的报告 | topic、max_queries=3(2-4)、max_pages_per_query=3(1-5)、lang、dedupe=True、refresh=False、strip_boilerplate=True |
deepseek_extract | 从网页中提取符合目标字段或架构的结构化 JSON | url、fields=None、schema=None、instruction=None、clean=True、max_chars=40000、refresh=False、strip_boilerplate=True |
deepseek_check_balance | 账户余额和会话指标(上游查询、缓存命中、估算费用) | 无 |
参数说明:
query和question限制为 128 个字符,并支持site:、-site:、"phrase"、lang:、after:和before:。ori_question(最多 128 个字符)是自然语言问题,可提升排序效果。after、before、include_domains和exclude_domains是搜索工具的显式筛选参数。include_domains会转换为以空格分隔的site:运算符,exclude_domains会转换为-site:,日期则会转换为after:YYYY-MM-DD/before:YYYY-MM-DD。筛选条件和查询会一起进行预算限制,以确保不超过 DeepSeek 的 128 个字符限制。deepseek_fetch和deepseek_fetch_many中的query使用 BM25-lite 评分引擎提取排名靠前的相关摘录,不会调用大模型。section(从 1 开始的索引)支持分段阅读长文档,并提供has_more和total_sections分页元数据。两者都在内存中对缓存页面进行操作。deepseek_deep_research通过deepseek-flash将主题拆解为 2-4 个子查询,并发搜索,合并并去重候选来源,然后生成带编号方括号引用([1]、[2])的综合报告,最多使用 6 个来源 / 24,000 个字符。如果接近综合报告的截止时间,会平稳地改为返回已收集的来源。deepseek_extract使用deepseek-flash提取符合fields: list[str]或schema: dict的结构化 JSON,无需将完整页面文本载入客户端上下文。未找到的请求字段会填为null;没有可读文本的页面会快速失败,且不消耗大模型令牌。deepseek_check_balance(以及旧版别名deepseek_balance)包含一个session区块,提供运行时长、处理的查询总数、缓存命中率、估算成本和节省金额(按每次请求 $0.00075 计算)。lang是显式语言运算符,例如es、de、ja或pt-BR。如果未设置,非英语查询的结果可能包含多种语言;对于命名实体,请比较设置和不设置lang的结果。- 使用
dedupe=True时,搜索会向上游多请求一些结果(max(2, ceil(count * 0.5)),最多 50 条),去重后再截取到count条,因此即使索引返回重复项,仍能获得count条结果。 使用dedupe=False时则恰好请求count条。 - 未设置
need_content时,每条搜索结果会附带简短的summary,而非页面文本。摘要长度上限为summary_chars(默认值为 400),且不会超过max_chars_per_result;设为summary_chars=0时不返回摘要。启用内容后,只有未返回内容的结果才会用summary代替,此时summary_chars的默认值为max_chars_per_result。摘要计入max_total_chars。 rewrite=True(deepseek_research中也适用)会先使用deepseek-flash将查询翻译成英语,再进行搜索。设置了lang时会跳过翻译;如果翻译失败,则静默回退到原查询。clean=True(抓取工具和搜索内容)会移除所有 ASCII 标点字符前的反斜杠转义 (\(、\-、\[、\/、\#……)。围栏代码块和行内代码片段不会被修改。- 搜索结果(内容、
snippet、summary,以及deepseek_research来源)还会解码 JSON 字符串转义,前提是搜索索引返回的页面文本仍经过 JSON 转义(Kr\u00f3tkie会变为Krótkie,<\/p>会变为</p>);代码中的内容除外。摘要和片段中不带属性的简单 HTML 标签(<p>、<br>、</h2>……)会替换为空格。 strip_boilerplate=True(仅限关键字参数,适用于所有返回页面内容的工具)会移除已知的网站界面文本。无论 Reddit 线程使用何种语言,DeepSeek 返回的 Reddit 线程界面都会本地化为中文,包括评论排序菜单(排序方式:、最佳、新……)、# 评论区域标题、归档帖子横幅、[已删除]作者行和注册页脚。规则按网站区分(目前仅适用于 Reddit,匹配reddit.com及其子域名),且只会移除完全由已知标签组成的行,因此用户文本(包括中文)和代码块都会保留。一条适用于所有网站的规则:如果内容开头是 Cookie 同意(CMP)对话框(“Informacje o prywatności”、“We value your privacy”、“Wir verwenden Cookies”……),且以已知同意提示语开头的首行之后还出现了对话框控件(“Accept all”、“Zarządzaj preferencjami zgody”……),则会移除该对话框。移除会在第一条不属于对话框的行处停止,因此下方文本不会被改动,关于隐私的文章也会保留。如果抓取的页面只有横幅,则content为空,并会附带说明。该处理在clean之后、字符数上限之前运行,因此预算按清理后的文本计算;不会更改缓存。strip_boilerplate=False会原样返回抓取到的内容。deepseek_fetch_many会跳过空条目;对于重复 URL(规范化 URL 相同),只抓取一次;保持输入顺序;并将失败的 URL 作为ok: false的条目返回,而不是导致整个批次失败。所有抓取共用 120 s 截止时间;届时仍在等待的 URL 会标记为deadline_exceeded。每个页面最多获取min(max_chars_per_url, max_total_chars // number of URLs)个字符。deepseek_research是单次来源收集,不是 Agent:它只进行一次搜索和若干补漏抓取,不会优化查询或再次搜索,也不会生成摘要。它接受与搜索相同的lang、rewrite和dedupe选项;返回数据封装中的query_used会显示实际发送的查询。除非设置rewrite=True,否则不会生成摘要,也不会调用模型:它会返回来源,供调用方综合。 每个来源包含title、url、date和site(如果上游未提供,两者均为 null)、date_source、authority和rerank_score,因此无需打开来源即可查看过时或偏题的内容。deepseek_research用于初步调查,寻找候选来源。它没有质量筛选,因此结果可能包含低质量或二手页面(学生论文、聚合站、标题党内容)。引用事实前,请在一手来源中核实。若要查找一手来源,请用英语询问原始研究(例如“X 的原始研究,期刊论文”),并使用site:搜索波兰语或其他本地来源 (site:cbos.pl ...)。authority会原样传递上游索引返回的值。其含义没有文档说明,也不代表可信度(学生 PDF 和参考数据库可能得分相同),因此请勿用它来评判或筛选来源。 调用示例:
deepseek_search(query="rust async runtime comparison", count=5)
deepseek_search(query="gobierno de España presupuestos 2026", lang="es", need_content=False)
deepseek_fetch(url="https://docs.rs/tokio/latest/tokio/", max_chars=15000)
deepseek_fetch_many(urls=["https://example.com/a", "https://example.com/b"], max_total_chars=12000)
deepseek_research(question="how does HTTP/3 connection migration work", max_pages=4)
deepseek_deep_research(topic="comparing Raft vs Paxos consensus mechanisms in distributed systems")
deepseek_extract(url="https://news.ycombinator.com", fields=["top_story", "points", "author"])
deepseek_check_balance()
响应封装
每个工具都会返回一个带有 ok 的 JSON 对象。
| 字段 | 适用范围 | 含义 |
|---|---|---|
ok | 全部 | 成功时为 true,失败时为 false |
cached | 除 balance 外的所有工具;也适用于 deepseek_fetch_many 中的每个条目和 deepseek_research 中的每个来源 | 响应来自内存缓存时为 true。对于 deepseek_fetch_many 和 deepseek_research,只有未发出上游请求且至少有一个响应来自缓存时才为 true |
cached_count | deepseek_fetch_many、deepseek_research | 此次调用中由缓存提供的响应数量 |
requests_used | deepseek_fetch_many、deepseek_research | 实际发出的上游请求数(缓存命中不计费) |
elapsed_ms | 全部,包括错误 | 工具调用耗时(毫秒,使用单调时钟);缓存命中会报告其自身接近零的耗时 |
notes | 所有成功响应封装 | 人类可读的备注:去重数量、改写已应用或失败、已应用 lang、截断提示(“部分页面内容已截断,以符合字符预算。”) |
error | 失败时 | { "code", "message", "status"? };若存在上游 HTTP 状态码,则 status 为该状态码 |
partial | deepseek_fetch_many、deepseek_research | 部分条目或来源失败时为 true;每个失败项都带有自己的 error。顶层 ok 仍为 true,因此请检查 partial |
failed_count | deepseek_fetch_many、deepseek_research | 失败的条目或来源数量 |
搜索结果包含 title(如果上游标题为空,则为不带 www. 的 URL 主机名;若标题在 - 两侧重复,例如 Reddit 的 X - X,则合并为 X)、url、date、authority(0–4,-1 表示未知;这是上游字段,不代表可信度评分)、rerank_score、site、snippet,
以及在可用时包含 chars 或 summary 的 content。如果上游未提供 date,则使用标题或文本前 600 个字符中找到的 YYYY-MM-DD 日期(有效日历日期,年份介于 1990 年至次年)。如果没有此类日期,则完整的英文或波兰语月份名称与年份相邻时(September 2025、
wrzesień 2025、PubMed 格式的 2025 September),取该月第一天;若同时写有日,则取该日(15 września 2025、
September 15, 2025);波兰语月份名称会匹配主格和属格形式,缩写和单独的年份会被忽略;搜索结果和研究来源中的 date_source 均为 "upstream"、"content" 或 null(无日期)。deepseek_fetch 返回 url、title、content、chars、
truncated。deepseek_deep_research 返回 topic、subqueries、report(带有方括号引用 [1]、[2])、
synthesized 和 sources。deepseek_extract 返回 url、title 和 data(符合请求字段或架构的提取 JSON)。所有工具返回的 chars 始终等于所返回 content 的长度。
错误代码
| 代码 | 含义 |
|---|---|
missing_api_key | DEEPSEEK_API_KEY 或备用文件中没有密钥 |
ssrf_blocked | URL 在本地被拒绝:内部主机、字面私有地址/环回地址或嵌入式凭据 |
bad_url、invalid_url、empty_url、url_too_long | URL 格式错误或过长 |
empty_query、query_too_long、bad_count、bad_lang、bad_request | 参数无效 |
rate_limited_local | 在最长等待时间内未能获取本地速率限制令牌 |
response_too_large | 上游响应正文超过大小上限(搜索为 8 MiB,抓取为 32 MiB) |
deadline_exceeded | 批次项目未能在共享批次截止时间前完成 |
timeout、network_error、request_failed、invalid_json | 传输层错误 |
internal_error | 抓取批次项目时发生意外异常 |
other / http_error | 上游 API 错误保留 DeepSeek 提供的代码(或使用 http_error),并设置 error.status |
响应大小和成本
在 2026-10-28 使用每个工具的默认参数,通过在线 API 测得的每种模式单次响应的序列化 JSON 大小(紧凑 JSON,UTF-8 字节):
| 调用 | 大小 |
|---|---|
deepseek_search,count=3,need_content=false(默认 summary_chars) | 3.7 KB |
deepseek_search,count=3,need_content=false,summary_chars=0 | 2.3 KB |
deepseek_search,count=3,need_content=true(默认) | 15.1 KB |
deepseek_fetch,一个文档页面(默认 max_chars) | 20.9 KB |
deepseek_fetch_many,3 个文档页面 | 13.3 KB |
deepseek_research,max_pages=3 | 20.1 KB |
这些只是单次样本,不是保证值:大小会随查询和返回的页面而变化,且受 max_chars_per_result、max_total_chars 及其他字符预算限制,而非固定数量限制。
成本:DeepSeek 按每次成功请求而非每个返回结果对 Search 和 Fetch 计费,因此 count 不会改变单次调用的价格。当前价格、计费规则和限制请参阅 DeepSeek Search & Fetch 指南;这些内容可能会发生变化,本项目不会跟踪更新。需要多次上游请求的工具调用(例如 deepseek_research 获取搜索内容缺失的页面,或 deepseek_fetch_many)会按每次请求计费;rewrite=true 还会使用 deepseek-flash 令牌。缓存命中不计费。
缓存和速率限制
缓存和速率限制器位于服务进程中,不会在进程之间共享。
| 搜索 | 获取 | 查询改写 | |
|---|---|---|---|
| 缓存 TTL | 5 min | 30 min | 24 h |
| 条目数限制 | 128 | 128 | 1024 |
| 大小限制 | 16 MiB | 32 MiB | 1 MiB |
| 速率限制(持续速率 / 突发量) | 10 / s,20 | 5 / s,10 | 不限 |
- 只有成功且非空的响应会被缓存。错误永远不会被缓存。
- 相同的并发调用会共用一次上游请求(single-flight);只有发起请求的调用会消耗一个速率限制令牌,且这些调用都不会报告
cached: true。 refresh=true会跳过本次调用的缓存读取,并替换已存储的条目。dedupe会改变上游请求(搜索会多获取结果),因此dedupe=true和dedupe=false的调用不会共用缓存条目。- 缓存命中和改写调用不消耗速率限制令牌。每次逻辑调用消耗一个令牌,包括重试。
- 如果获取令牌需要等待超过 5 s,该调用会立即以
rate_limited_local失败,而不会无限期排队。 - 瞬时故障(HTTP 429 和网关 5xx)会重试一次。
DEEPSEEK_MCP_CACHE=0会禁用所有缓存。
配置
| 变量 | 必需 | 用途 |
|---|---|---|
DEEPSEEK_API_KEY | 是 | DeepSeek 平台密钥 |
DEEPSEEK_BASE_URL | 否 | API 基础 URL(默认 https://api.deepseek.com) |
MCP_BEARER_TOKEN | 仅 HTTP | 客户端必须通过 Authorization: Bearer ... 发送的令牌 |
DEEPSEEK_MCP_CACHE | 否 | 1(默认)或 0,用于禁用缓存 |
DEEPSEEK_MCP_LOG_LEVEL | 否 | 服务、MCP SDK 和 uvicorn 的 stderr 日志级别:DEBUG、INFO、WARNING(默认)、ERROR、CRITICAL |
DEEPSEEK_AUTH_JSON | 否 | 用作密钥备用来源的 JSON 文件路径(参见安全) |
.env.example 列出了相同的变量。服务本身不会读取 .env 文件;请导出这些变量,或将其设置在 MCP 客户端的 env 中。
安全
完整的政策和报告说明:SECURITY.md。
- 仅进行静态 SSRF 检查。 在访问缓存、限流器或网络之前,会先验证 URL:
非 http(s) 协议、内部主机名、字面形式的私有/环回/链路本地地址,以及包含嵌入式凭据的 URL,都会返回
ssrf_blocked。服务不会解析 DNS,实际抓取由 DeepSeek 执行,因此这并不构成网络隔离。 - 密钥处理。 密钥仅会通过
Authorization标头发送到配置的 API 基础 URL。错误消息和备注中会对密钥、Bearer 令牌及类似机密进行脱敏。 - HTTP 传输要求每个请求都携带 Bearer 令牌(使用恒定时间比较,绝不记录日志)。
- 无遥测。 唯一的出站目标是 DeepSeek API。
- 旧版 opencode 回退机制。 如果未设置
DEEPSEEK_API_KEY,服务会从~/.local/share/opencode/auth.json({"deepseek": {"key": "..."}})或DEEPSEEK_AUTH_JSON指定的文件中读取密钥。此机制仅供 opencode 用户使用;建议使用环境变量。 - 工具输入(查询、URL)会发送给 DeepSeek 以完成任务。请勿在其中传入机密。
限制
deepseek_fetch对 PDF 和 Reddit 返回 HTTP 404,并且在某些网站上会超时。请改用deepseek_search,并输入页面标题或带site:限定的查询。- Fetch 只返回标题和内容:不包含最终 URL、状态码或发布日期。
- Fetch 的延迟来自 DeepSeek 的页面渲染,而非此服务:已渲染的页面约 0.5 秒即可返回,其他页面需要 3–10 秒;缺失页面(HTTP 404)仍需 3–5 秒才会由 DeepSeek 报告。404 不会重试。
deepseek_fetch_many一次最多并行执行 5 次抓取,因此批次耗时约等于最慢页面的耗时;提交较大的批次时请考虑这一点。 - 仅支持搜索和抓取。不支持站点映射或爬取,也不支持异步任务;仅支持一个提供方(DeepSeek)。
- 缓存和限流器按进程隔离;运行多个服务进程会使有效速率成倍增加。
- 本地速率限制采用保守的默认值,不能替代 DeepSeek 自身的配额。
- HTTP 传输采用普通 HTTP、无状态且仅支持 JSON;不支持 OAuth,也没有 SSE 流。
开发
git clone https://github.com/radoxtech/deepseek-search-everywhere-mcp.git
cd deepseek-search-everywhere-mcp
python -m venv .venv && . .venv/bin/activate
pip install -e ".[test,lint,http]" build twine
pytest -q # offline suite; no network, no key needed
ruff check . # lint
python -m build # sdist + wheel in dist/
python -m twine check dist/* # validate package metadata
离线测试会清除 DEEPSEEK_* 变量,并将密钥回退路径指向一个不存在的文件,因此无法访问网络。CI 会在 Python 3.11、3.12 和 3.13 上运行 lint、测试和构建。
有关贡献工作流和提交规范,请参阅 CONTRIBUTING.md。
实时测试
实时测试套件会端到端调用真实的 DeepSeek API,并使用 deepseek-flash 作为大模型评审器,对结果是否相关且能否回答问题进行评分。默认运行时会排除该测试套件;没有密钥时会自动跳过;完整运行的费用最多也只有几美分(此外还会调用 deepseek-flash 进行评审)。
cp .env.example .env # then put your key in DEEPSEEK_API_KEY=
set -a && . ./.env && set +a # export the variables; tests do not read .env themselves
pytest -m live
运行后会打印评审分数和理由。.env 已加入 Git 忽略列表;切勿提交该文件。
发布
版本遵循 Semantic Versioning,并根据
Conventional Commits 使用
release-please 自动发布。所有操作均在
.github/workflows/release.yml 中执行:
- 每次推送到
main时,都会运行 release-please。它会创建(或更新)一个发布 PR,在pyproject.toml、server.json和.release-please-manifest.json中更新版本号,并在CHANGELOG.md开头添加一个章节。遵循标准的 Semantic Versioning:fix会增加补丁版本号,feat会增加次版本号,而 破坏性变更(feat!:)会增加主版本号;feat、fix、perf、refactor、docs和deps会显示在变更日志中。 - 合并发布 PR 后,release-please 会创建
vX.Y.Z标签并创建 GitHub Release。 - 随后,同一次工作流运行会构建带标签的提交,检查标签是否与
pyproject.toml和server.json中的版本一致,运行twine check和干净 wheel 冒烟测试,通过 Trusted Publishing(OIDC,无需令牌)发布到 PyPI,将构件附加到 GitHub Release,并更新 MCP Registry。
发布操作在同一工作流中进行,因为使用 GITHUB_TOKEN 创建的标签和 PR 不会触发其他工作流。
手动备用方案:更新 pyproject.toml、server.json 和 .release-please-manifest.json 中的版本号
(tests/test_version_sync.py 会检查前两个文件中的版本是否一致),更新 CHANGELOG.md,然后提交并推送标签。工作流随后会自行发布并创建 GitHub Release。
git tag -a v2.0.0 -m "v2.0.0" && git push origin v2.0.0
bash scripts/smoke_package.sh # optional local check: build, install into a clean venv, run the CLI
手动运行工作流(workflow_dispatch)会构建并验证软件包,且只会发布到 TestPyPI。
一次性仓库设置:
- Settings、Actions、General:启用 “Allow GitHub Actions to create and approve pull requests”,以便 release-please 创建 PR。
- Settings、Environments:创建
pypi环境(手动运行时还需创建testpypi);在此处添加必需的 审核者,即可对每次 PyPI 发布进行把关。 - 在 PyPI(以及 TestPyPI)上,为此仓库添加一个可信发布者,工作流设为
release.yml,环境设为pypi(在 TestPyPI 上设为testpypi)。
手动发布到 MCP Registry
server.json 为 MCP Registry 描述 PyPI 软件包。README 中包含一条
mcp-name 注释,Registry 会用它来验证软件包所有权。发布工作流会自动执行此操作;如需手动发布:
python scripts/validate_server_json.py # structural checks; also runs `mcp-publisher validate` if installed
mcp-publisher login github # the io.github.radoxtech namespace requires GitHub authentication
mcp-publisher publish
先发布到 PyPI:Registry 会检查软件包版本是否存在。release-please 会确保 pyproject.toml
和 server.json 中的版本保持同步;如果两者不一致,tests/test_version_sync.py 会失败。
变更日志
请参阅 CHANGELOG.md 了解发布说明。
许可证
MIT。与 DeepSeek 无关联。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。