先说结论:如果你在 Claude Code 里接了 DeepSeek / Qwen / Kimi 这类第三方 API,但是发现模型不会稳定使用原生 WebSearch / WebFetch,可以试试这个小工具。
项目地址:
- GitHub:github.com/JcDizzy/CC-…
- PyPI:pypi.org/project/cc-…
- License:MIT
我写它的原因很简单:第三方模型接进 Claude Code 后,写代码、读文件、跑命令都还好,但一到“查最新资料”就容易露馅。
比如这些问题,靠模型旧知识很容易答偏:
- 某个库的最新 API 有没有改
- 某个 GitHub issue 有没有类似报错
- 某个 release note 里有没有 breaking change
- Claude Code / MCP / 第三方 API 的接入方式有没有变化
- 一个错误是不是最近版本才出现
所以 cc-web 做的事情就是:给 Claude Code 里的第三方模型补一个本地、只读、带安全边界的 Web 搜索和网页抓取 MCP。
两分钟装好
需要先有 uv / uvx。然后直接运行:
uvx cc-web-mcp init --runner uvx --force
uvx cc-web-mcp doctor
第一条命令会自动做这些事:
- 创建 cc-web 用户配置
- 注册 Claude Code 用户级 stdio MCP
- 写入
~\.claude\CLAUDE.md,提示第三方模型优先走 cc-web - 合并
~\.claude\settings.json的 hook 守卫 - 写入前备份旧配置,避免直接覆盖
第二条命令用来检查本地配置、依赖和网络连通性。看到 OK 基本就可以去 Claude Code 里试了。
它适合谁?
比较适合:
- 你在 Claude Code 里接了 DeepSeek / Qwen / Kimi / 其他第三方模型
- 你发现原生
WebSearch/WebFetch不可用,或者第三方 API 会直接拒绝这些工具调用 - 你希望模型能查官方文档、GitHub issue、release note、报错资料
- 你想要一个轻量、本地、只读、不依赖商业搜索 API 的 Web MCP
不太适合:
- 你只用官方 Claude Code,不接第三方模型
- 你需要高质量商业搜索 API
- 你需要浏览器自动化、JS 渲染、登录态页面抓取
- 你主要想查库文档,这种场景 Context7 可能更合适
- 你需要企业级 SLA、配额、监控和稳定性
工具列表
目前暴露 4 个工具:
research_brief
web_search
fetch_url
health_check
research_brief:优先用这个
这是我最推荐给 agent 用的入口。
它会先搜索,再抓取少量来源的短正文,最后返回一个比较适合模型阅读的资料概览。
适合这种场景:
先查资料 -> 快速理解背景 -> 再决定要不要读某个具体网页
实际用下来,比“先搜一堆链接,再逐个全文抓取”更省上下文,也更符合 coding agent 的工作流。
web_search:只搜索,不抓全文
默认搜索链路:
DuckDuckGo HTML -> Bing CN fallback
这里也说明一下:bing_cn 只是实用 fallback,不是全局搜索的等价替代,所以结果里会带 search_scope_note 提醒模型注意区域偏置。
fetch_url:读具体网页
fetch_url 用来抓取具体 URL,并转换成 Markdown。
支持:
- HTML 转 Markdown
- 纯文本 / Markdown 清洗
- JSON 格式化
- 相对链接转绝对链接
- 长页面分页读取
- 通过搜索结果
ref_id读取网页 - 可选 PDF 文本提取
如果页面太长,它会告诉模型下一段应该从哪里继续读,避免模型一直重复抓同一段。
health_check:排查工具状态
health_check 对应命令行里的:
uvx cc-web-mcp doctor
它会检查依赖、配置、搜索后端状态和网络策略。遇到“模型说工具不可用”时,我一般先让它跑这个。
为什么还要写 CLAUDE.md 和 hook?
一开始我也以为只要提供一个 MCP server 就够了。后来实际接第三方模型时发现,真正麻烦的是:
模型不一定会稳定走对工具。
所以 init 做了两层处理。
1. 写入用户级 CLAUDE.md
位置:
~\.claude\CLAUDE.md
目的很直接:让 DeepSeek / Qwen / Kimi 这类第三方模型从会话开始就知道,需要联网时应该优先使用 cc-web。
这一步很重要。因为有些第三方 API 会在服务端直接拒绝原生 WebSearch,本地 PreToolUse hook 甚至还没机会拦。
2. 写入 PreToolUse hook 守卫
位置:
~\.claude\settings.json
hook 主要负责:
- 默认只允许匹配配置的第三方模型调用 cc-web
- 官方 Claude 默认继续使用原生
WebSearch/WebFetch - 第三方模型误用原生
WebFetch时,提示它改用 cc-web - 如果你确实想让官方 Claude 调用
cc-web fetch_url,也可以显式打开配置
默认配置大概是:
{
"allowed_model_patterns": ["deepseek"],
"search_providers": ["duckduckgo", "bing_cn"],
"allow_fetch_url_for_claude": false,
"block_native_web_for_allowed_models": true
}
如果你还用 Qwen / Kimi,可以把匹配规则改成:
{
"allowed_model_patterns": ["deepseek", "qwen", "kimi"]
}
安全边界
这是给 agent 用的联网工具,所以我不想把它做成“模型想抓什么就抓什么”的裸抓取器。
默认做了这些限制:
- 只允许
http/https - 默认禁止抓取本机、内网、链路本地地址和云 metadata 地址
- 检查 DNS 解析后的 IP,避免公开域名解析到私网
- 检查 30x 重定向后的最终 URL
research_brief抓取搜索结果前会过滤非法 URL- Jina Reader fallback 也会重新做 URL 安全校验
- 即使开启
allow_private_networks,Jina fallback 也不会把内网 URL 发给第三方服务 - 缓存只在非内网模式下启用
- 不执行网页写入操作
- 不尝试绕过验证码、登录墙或 WAF
0.1.7 还把网络策略诊断带到了 fetch_url 返回结果和 health_check 里。这样模型知道到底是 scheme、host、DNS 解析还是重定向触发了策略,不会只看到一个模糊的“抓取失败”。
失败时不会一直硬抓
真实抓网页时,失败很常见:
- 403 / 429
- 登录墙
- 验证码
- WAF
- JS 渲染页面
- 强反爬站点
- 网络超时
cc-web 不会尝试绕过这些限制,而是返回结构化诊断。例如:
{
"error_type": "captcha_or_challenge",
"retryable": false,
"do_not_retry_reason": "Target returned captcha_or_challenge; repeating fetch_url with the same URL is unlikely to help.",
"recommended_next_action": "Use search summaries, official sources, or another accessible source."
}
这样模型不太容易一直重复抓同一个失败页面,而是会换来源、用搜索摘要,或者先跑 health_check。
和 Firecrawl / Tavily / Brave / Context7 的区别
先说结论:cc-web 不是这些工具的替代品。
Firecrawl / Tavily / Brave 更像专业搜索、抓取或网页研究服务,质量和稳定性通常更好,但也更依赖外部 API 或商业服务。
Context7 更适合查某个库的最新文档。
普通 Fetch MCP 更轻,适合只读取网页。
cc-web 的取舍是:
- 默认不依赖商业 API
- 本地可控
- 用
uvx一条命令初始化 - 专门适配 Claude Code + 第三方模型这个场景
- 对国内网络环境做一点 fallback
- 带工具路由、hook 守卫、doctor 诊断和 SSRF 防护
所以它的定位不是“最强网页工具”,而是:
Claude Code 第三方模型后端缺联网能力时,一个本地可控的补丁型工具链。
第一次怎么试?
装好以后,在 Claude Code 里切到第三方模型,然后问一个小范围联网问题:
使用 cc-web 查询 “Claude Code MCP PreToolUse hook permissionDecision”,
先用 research_brief 获取资料概览,再总结当前推荐写法。
如果模型仍然尝试调用原生 WebSearch,先检查 ~\.claude\CLAUDE.md 是否写入成功。
如果模型尝试调用原生 WebFetch 并被 hook 拦截,说明 hook 已经生效,模型应该根据提示改用 cc-web fetch_url。
我个人建议优先让模型调用 research_brief。只有某个来源确实关键时,再用 fetch_url 单独读取完整页面。
当前状态
项目已经整理成标准 Python package:
- PyPI 包名:
cc-web-mcp - 推荐运行方式:
uvx cc-web-mcp ... - console script:
cc-web-mcp - 初始化命令:
init - 诊断命令:
doctor - PDF 提取:可选 extra,
cc-web-mcp[pdf] - License:MIT
- Python:3.11 / 3.12 / 3.13
GitHub Release:
github.com/JcDizzy/CC-…
PyPI:
pypi.org/project/cc-…
后续可能继续做
后续可能继续补:
- 更完整的
web.run兼容层 - 更细的来源质量提示
- 更完整的联网 smoke test
- 更多搜索后端可选项
- 更适合 DeepSeek / Qwen / Kimi 的工具调用提示
- 更清晰的安装 / 更新 / 故障诊断文档
如果你也在用 DeepSeek / Qwen / Kimi 接 Claude Code,并且遇到原生 WebSearch / WebFetch 不可用或不稳定的问题,可以试试看。
也欢迎提 issue,尤其是这些方面:
- Claude Code 工具名兼容问题
- 第三方模型是否会稳定调用
research_brief - DuckDuckGo / Bing CN 在不同网络下的可用性
- 官方文档或 GitHub 页面抓取质量
- hook 误拦截 / 漏拦截
- 反爬诊断误判
- 安全边界问题