selvin-search-mcp
A local web search MCP server supporting parallel, API, and model-based search modes, integrating Zhipu Web Search API and online models for real-time information retrieval.
README
selvin-search-mcp
Selvin Search MCP 是一个面向 Codex 的本地联网搜索 MCP。它支持三种搜索链路:
| 模式 | 配置 | 搜索是谁做的 | Sources 从哪里来 |
|---|---|---|---|
| 并行搜索模式 | SELVIN_SEARCH_MODE=parallel |
智谱 Web Search API + 支持联网能力的模型同时搜索 | 两条链路返回的来源合并去重 |
| API 搜索模式 | SELVIN_SEARCH_MODE=api |
智谱 Web Search API | 智谱 /web_search 返回的 search_result |
| 模型联网模式 | SELVIN_SEARCH_MODE=model_online |
支持联网能力的模型自己搜索 | 模型回答中的 ## Sources 链接,由 MCP 解析 |
默认推荐 parallel 模式:MCP 会同时启动 API 搜索链路和模型内置联网链路;如果模型内置联网先返回有效内容,MCP 会取消尚未完成的 API 搜索。随后 MCP 会抓取模型内置联网返回的来源页面,解析正文并交给模型做最终整理。api 模式更可控,model_online 模式更依赖模型/平台自己的联网能力。
敏感配置
项目不在代码里保存 API Key,也不在代码里写死具体模型名。运行前创建本地 .env:
cd selvin-search-mcp
cp .env.example .env
.env 已被 .gitignore 忽略,不应提交。仓库只保留 .env.example 作为模板。
配置优先级:
- 系统环境变量
- 项目根目录
.env - 代码内非敏感默认值,例如 provider、search mode 和搜索参数
SELVIN_MODEL 是必填项;不配置模型名时 MCP 会返回配置错误。
模式 A:并行搜索模式
这个模式同时启动两条搜索路线,但模型内置联网链路优先:
用户问题
-> 路线 1:智谱 Web Search API /web_search
-> 路线 2:支持联网的模型 /chat/completions
-> 如果路线 2 先返回有效内容,MCP 取消尚未完成的路线 1
-> 如果路线 1 已经完成并有内容,MCP 同时保留两边结果
-> MCP 要求模型联网回答返回 JSON:answer + sources[{title,url}]
-> 如果路线 2 没有返回精确 URL,MCP 拒绝该路线的联网结果
-> MCP 解析 JSON sources 中的 URL
-> MCP 抓取这些来源页面,抽取正文并归档
-> MCP 合并 API 来源、模型来源和归档正文
-> 用户配置的模型基于归档内容和两边结果做最终整理
-> MCP web_search 返回最终 answer + session_id
-> MCP get_sources 返回合并后的来源列表和抓取状态
.env 示例:
SELVIN_PROVIDER=zhipu
SELVIN_SEARCH_MODE=parallel
SELVIN_API_URL=https://open.bigmodel.cn/api/paas/v4
SELVIN_API_KEY=<your-api-key>
# 或:
# ZHIPU_API_KEY=<your-api-key>
SELVIN_MODEL=<your-model-name>
ZHIPU_SEARCH_ENGINE=search_pro
ZHIPU_SEARCH_COUNT=5
ZHIPU_CONTENT_SIZE=high
ZHIPU_SEARCH_RECENCY_FILTER=noLimit
SELVIN_MAX_TOKENS=2600
SELVIN_API_CANCEL_GRACE_SECONDS=0.5
SELVIN_FETCH_ONLINE_SOURCES=true
SELVIN_FETCH_ONLINE_SOURCE_COUNT=5
SELVIN_FETCH_ONLINE_SOURCE_CHARS=3000
SELVIN_ONLINE_USE_SEARCH_TOOL=true
如果模型内置联网链路使用的是另一个 OpenAI-compatible 平台,可以单独覆盖:
SELVIN_ONLINE_API_URL=<openai-compatible-api-base-url>
SELVIN_ONLINE_API_KEY=<your-online-model-api-key>
SELVIN_ONLINE_MODEL=<online-capable-model-name>
判断是否真的联网:
- API 路线:来源来自智谱
/web_search的search_result - 模型内置路线:智谱/BigModel 默认通过
chat/completions的tools.web_search触发搜索;其他 OpenAI-compatible 平台默认不传该工具,除非显式设置SELVIN_ONLINE_USE_SEARCH_TOOL=true - 模型内置路线必须返回 JSON,格式为
{"answer":"...","sources":[{"title":"...","url":"https://..."}],"error":""} - 如果模型内置路线没有返回精确 URL,MCP 会把它标记为失败,不进入网页抓取和归档
- 模型内置路线返回的 URL 会被 MCP 再访问一次,成功时会写入
archive_status=fetched和archive_content get_sources(session_id)返回的是两边来源合并去重后的列表
模式 B:API 搜索模式
这个模式先调用智谱 /web_search,拿到真实 search_result,再把搜索结果交给你配置的模型总结。
用户问题
-> 智谱 Web Search API /web_search
-> search_result 真实搜索结果
-> 用户配置的模型总结
-> MCP web_search 返回 answer + session_id
-> MCP get_sources 返回 search_result 来源列表
.env 示例:
SELVIN_PROVIDER=zhipu
SELVIN_SEARCH_MODE=api
SELVIN_API_URL=https://open.bigmodel.cn/api/paas/v4
SELVIN_API_KEY=<your-api-key>
# 或:
# ZHIPU_API_KEY=<your-api-key>
SELVIN_MODEL=<your-model-name>
ZHIPU_SEARCH_ENGINE=search_pro
ZHIPU_SEARCH_COUNT=5
ZHIPU_CONTENT_SIZE=high
ZHIPU_SEARCH_RECENCY_FILTER=noLimit
SELVIN_MAX_TOKENS=2600
判断是否真的联网:
web_search.sources_count > 0get_sources(session_id).sources_count与web_search.sources_count一致- 每条来源来自智谱
/web_search的search_result
模式 C:模型联网模式
这个模式不先调用搜索 API,而是直接调用一个支持联网能力的聊天模型。模型需要返回结构化 JSON,MCP 从 JSON 的 sources[].url 中读取来源链接。
用户问题
-> 支持联网的模型 /chat/completions
-> 模型自己搜索并返回 JSON:answer + sources[{title,url}]
-> MCP 从 JSON 中解析 URL
-> MCP 抓取 URL 页面并抽取正文
-> MCP get_sources 返回解析后的来源列表
.env 示例:
SELVIN_PROVIDER=custom
SELVIN_SEARCH_MODE=model_online
SELVIN_API_URL=<openai-compatible-api-base-url>
SELVIN_API_KEY=<your-api-key>
SELVIN_MODEL=<online-capable-model-name>
SELVIN_MAX_TOKENS=2600
注意:
- 这个模式要求你配置的模型/平台真的支持联网搜索。
- 如果模型没有联网能力,它可能只能回答“无法访问实时网络”,或凭记忆回答。
- 如果模型没有按 JSON 返回精确 URL,MCP 会拒绝该路线的结果。
- MCP 会抓取模型返回的 URL 并尝试归档正文,但网页是否允许读取取决于目标网站。
当前已知问题
403 Forbidden
403 Forbidden 表示 MCP 已经访问到目标网站,但网站服务器拒绝返回页面内容。常见原因包括:
- 网站禁止脚本或爬虫访问
- 网站要求完整浏览器环境、Cookie、登录状态或 JavaScript 校验
- 网站限制 User-Agent、IP、地区或访问频率
- URL 指向的页面不存在公开内容,但服务器统一返回 403
当前 MCP 的网页读取方式是普通 HTTP 请求:
httpx GET URL
-> 获取 HTML 或文本
-> 去掉脚本、样式和标签
-> 抽取正文
这种方式遇到 OpenAI、Cloudflare、防爬页面或需要 JS 渲染的页面时,可能只能得到 archive_status=failed 和 archive_error=403 Forbidden,无法写入 archive_content。
后续可增强方向:
- 增加更完整的浏览器请求头,例如
Accept-Language、Referer、压缩支持等 - 增加备用网页读取服务,例如网页转 Markdown 的 reader/proxy
- 增加 Playwright/Chrome 渲染读取,处理需要 JavaScript 或 Cookie 的页面
- 对官方文档类来源增加专门读取器或官方 API 读取器
当 archive_status=failed 时,最终回答应明确标记“来源 URL 存在,但页面正文未归档验证”,不能把模型摘要当作已完全验证的网页事实。
本地运行
uv run --project . selvin-search
Codex 配置模板
当前 README 只提供模板,不会自动修改你的 Codex 项目配置。测试通过后,可以把下面配置加入项目级 Codex 配置:
[mcp_servers.selvin-search]
command = "uv"
args = [
"run",
"--project",
".",
"selvin-search"
]
如果你希望 Codex 不依赖 .env 文件,也可以把环境变量写入 Codex 配置,但不要把真实配置提交到公开仓库:
[mcp_servers.selvin-search.env]
SELVIN_PROVIDER = "zhipu"
SELVIN_SEARCH_MODE = "parallel"
SELVIN_API_URL = "https://open.bigmodel.cn/api/paas/v4"
SELVIN_API_KEY = "<your-api-key>"
SELVIN_MODEL = "<your-model-name>"
ZHIPU_SEARCH_ENGINE = "search_pro"
ZHIPU_SEARCH_COUNT = "5"
ZHIPU_CONTENT_SIZE = "high"
ZHIPU_SEARCH_RECENCY_FILTER = "noLimit"
SELVIN_MAX_TOKENS = "2600"
MCP 工具
web_search
根据 SELVIN_SEARCH_MODE 执行联网搜索。
常用参数:
| 参数 | 说明 |
|---|---|
query |
要搜索的问题 |
platform |
可选,追加到搜索词中用于聚焦平台或来源 |
model |
可选,单次请求覆盖 SELVIN_MODEL |
plan_session_id |
可选,配合规划工具使用;留空表示直接搜索 |
返回字段:
| 字段 | 说明 |
|---|---|
session_id |
后续传给 get_sources |
content |
基于搜索结果或模型联网搜索生成的回答 |
sources_count |
MCP 解析出的来源数量 |
cached |
是否命中本进程缓存 |
get_sources
使用 web_search 返回的 session_id 获取来源列表。
get_config_info
返回当前配置,并做一次连通性测试:
parallel模式:同时请求{SELVIN_API_URL}/web_search和在线模型接口的/modelsapi模式:请求{SELVIN_API_URL}/web_searchmodel_online模式:请求{SELVIN_API_URL}/models
API Key 会被遮罩显示。
switch_model
持久化切换总结模型。更推荐通过 .env 管理模型名;只有需要运行时临时切换时才使用这个工具。
文件与缓存位置
| 类型 | 路径 |
|---|---|
| 项目目录 | 当前仓库根目录 |
| Python 包 | src/selvin_search |
| 本地环境变量 | .env |
| 环境变量模板 | .env.example |
| 配置文件 | ~/.config/selvin-search/config.json |
| 日志目录 | ~/.config/selvin-search/logs |
| 规划会话 | ~/.config/selvin-search/sessions |
快速验证
编译检查:
uv run --project . python -m py_compile \
src/selvin_search/config.py \
src/selvin_search/server.py \
src/selvin_search/providers/zhipu.py \
src/selvin_search/providers/model_online.py
配置读取检查:
uv run --project . python -c \
'from selvin_search.config import config; print(config.provider); print(config.search_mode); print(config.api_url); print(config.model)'
预期输出应显示:
<your-provider>
<parallel|api|model_online>
<your-api-url>
<your-model-name>
如果 .env 未配置 API Key 或模型名,会看到明确的配置错误。
注意事项
parallel模式会合并 API 搜索和模型内置搜索的来源,最终回答由模型再次整理。api模式的 sources 更可控,因为它们来自搜索接口的结构化结果。model_online模式依赖模型和平台自己的联网能力。- 如果中文查询召回为 0,可以换成中英混合查询。
sources_count = 0时,表示本次没有独立联网来源,不应把回答当作已验证结论。
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。