关于 NetLens
NetLens 是面向需要网页内容与搜索结果的 Agent 的 MCP 服务。它将完整网页转换为清理后的 Markdown,并提供搜索链接,还可提取指定章节或页面大纲。
主要功能
- 01将完整网页提取为干净的 Markdown
- 02使用可选搜索引擎搜索
- 03选择页面章节或大纲
- 04清除广告与页面杂项
- 05返回搜索链接而非摘要
适用场景
- 01读取原生工具无法获取的文章
- 02查找网页后进一步查看内容
- 03从长网页中提取指定章节
MCP 相关
它向 MCP 客户端提供 web_search 和 web_fetch 工具,并支持选择搜索引擎、页面模式及章节。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y netlens-mcpNETLENS_SEARCH_ENGINEDefault search backend: auto, duckduckgo, bing, mojeek, or searxngNETLENS_SEARXNG_URLBase URL of a SearXNG instance to use when engine=searxng (e.g. https://searx.example.org)本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
2收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | integer | 否 | 结果页码,从 1 开始。仅限 SearXNG——抓取的引擎只提供一页,因此会报告为不支持此参数,而不是忽略它。 |
| limit | integer | 否 | 结果数的可选上限;默认返回第一页的全部结果(约 10 条) |
| query | string | 是 | 搜索查询 |
| engine | enum | 否 | 搜索后端。'auto'(默认)在已配置时优先尝试 SearXNG,然后尝试 DuckDuckGo、Mojeek、Bing。'searxng' 需要 NETLENS_SEARXNG_URL。auto | duckduckgo | bing | mojeek | searxng |
| categories | string | 否 | SearXNG 类别筛选器,例如 'it'、'science'、'news'。仅限 SearXNG。 |
| time_range | enum | 否 | 将结果限制为近期内容。仅限 SearXNG。day | week | month | year |
详细介绍
NetLens
用于畅通无阻地阅读网页的 MCP 服务。它使用类似浏览器的请求头直接获取任意 URL——绕过
robots.txt 和简单的机器人拦截——并返回完整页面,以去除广告的干净 Markdown 格式呈现,而非摘要。此外还提供网页搜索,返回真实链接。零依赖:纯 Python 标准库。
专为 AI Agent 打造
AI Agent 经常遇到内置工具无法读取的网页。NetLens 可解决抓取结果为空或无用的三个常见原因:
| 原生网页工具 | NetLens |
|---|---|
遵循 robots.txt,因此被爬虫规则禁止的页面不会返回内容 | 像你亲自打开浏览器一样读取网页——不查询 robots.txt |
被请求头/User-Agent 机器人过滤器拦截(非浏览器客户端收到 403/202) | 通过系统 curl 发送真实的浏览器请求头;通常可将 403 → 200 |
| 返回页面的摘要 | 以 Markdown 格式返回页面的完整内容 |
| 输出中保留广告、Cookie 横幅、导航栏和相关链接等页面元素 | 在本地去除模板内容,让上下文中只包含正文 |
它不会尝试绕过 JavaScript/Cloudflare 挑战页面或 CAPTCHA——这是有意排除在范围之外的功能。如果页面遭到严格拦截,会如实显示 HTTP 状态,而不会伪造结果。
安装
npm(通过 npx):
{
"mcpServers": {
"netlens": {
"command": "npx",
"args": ["-y", "netlens-mcp"]
}
}
}
PyPI(通过 uvx):
{
"mcpServers": {
"netlens": {
"command": "uvx",
"args": ["netlens-mcp"]
}
}
}
将任一配置添加到 MCP 客户端配置中(例如 Claude Code 的 .mcp.json),然后
重启会话以加载工具。
工具
web_search
搜索网页并返回真实的结果链接(标题、URL、摘要),在本地解析——
返回链接,而非摘要。接着使用 web_fetch 阅读搜索结果。
| 参数 | 类型 | 描述 |
|---|---|---|
query | string(必填) | 搜索查询 |
limit | integer | 可选上限;默认返回完整的第一页(约 10 条) |
engine | string | auto(默认)、duckduckgo、bing、mojeek、searxng |
page | integer | 结果页码,从 1 开始。仅适用于 SearXNG |
time_range | string | day、week、month、year。仅适用于 SearXNG |
categories | string | 例如 it、science、news。仅适用于 SearXNG |
结果会报告实际使用的搜索引擎,以及被跳过的引擎发生了什么,因此切换到其他后端的过程一目了然,不会悄无声息:
{
"query": "…",
"engine": "mojeek",
"results": [ … ],
"engines_skipped": [ { "engine": "duckduckgo", "outcome": "HTTP 202" } ]
}
结果是观测到的现象,而非结论——HTTP 202 表示服务器返回了该状态;
仅凭响应无法判断这是限流、标记语言发生变化,还是确实没有匹配结果。配置 SearXNG 后,结果中还会包含直接返回的
answers、infoboxes 和 suggestions。
每次搜索只获取一个结果页(约 10 条),默认返回完整页面,确保不会遗漏位置 9/10 的结果。搜索不支持深度翻页——如果第一页没有答案,请优化查询。
web_fetch
获取任意网页,并以干净的 Markdown 格式返回完整内容。
| 参数 | 类型 | 描述 |
|---|---|---|
url | string(必填) | 要获取的 URL(可省略协议;默认使用 https) |
mode | string | article(仅正文,默认)、full(整个正文)、raw(未经转换的 HTML)、outline(标题结构) |
section | string | 仅返回此标题下的内容,以及其下嵌套的内容 |
links | string | inline(默认)保留链接目标;none 保留链接文本,但删除 URL |
max_chars | integer | 可选的返回字符数上限(截断时会附带说明) |
阅读长页面的部分内容
如果只想查看大型文章的某一部分,文章可能长达数万字。mode="outline" 会返回文章结构,section 则只返回所需部分——一篇大型百科文章全文有 153,000 个字符,大纲有 1,000 个字符,而所需部分有 7,400 个字符。
web_fetch(url=…, mode="outline") → headings with each section's size
web_fetch(url=…, section="Gameplay") → that section and its subsections
在链接密集的页面中,URL 本身会占据大量输出——一篇大型百科文章中约占 40%——因此,只需要正文时,设置 links="none" 可将输出量大致减半。指向同一页面内部的链接始终会以纯文本形式呈现。
如果页面实际上是由客户端渲染的空壳,web_fetch 会明确说明,而不是将空结果作为成功返回:
(注:在 6,856 个 HTML 字符中只找到 10 个可读字符。此页面似乎由 JavaScript 在客户端渲染……)
工作流: 使用 web_search 查找页面,然后使用 web_fetch 阅读。
搜索引擎
搜索引擎通过可插拔、可选择的注册表管理。在 auto 模式下,NetLens 会按顺序尝试引擎,并返回第一个有结果的引擎;因此,如果某个引擎出现速率限制或挑战页面,搜索会继续使用下一个引擎。
| 引擎 | 说明 |
|---|---|
duckduckgo | 默认;使用 html.duckduckgo.com 端点 |
bing | 自动回退 |
mojeek | 独立索引;自动回退 |
searxng | 可自托管/公共的 SearXNG JSON API——设置 NETLENS_SEARXNG_URL |
可在每次调用时通过 engine 参数选择引擎,也可以通过 NETLENS_SEARCH_ENGINE 设置默认引擎。
配置
| 环境变量 | 默认值 | 描述 |
|---|---|---|
NETLENS_SEARCH_ENGINE | auto | 默认搜索后端 |
NETLENS_SEARXNG_URL | — | SearXNG 基础 URL,例如 http://192.168.1.10:8888 |
NETLENS_SEARXNG_TIMEOUT | 8 | 无法访问的 SearXNG 被跳过前等待的秒数 |
NETLENS_USER_AGENT | Chrome UA | 覆盖请求的 User-Agent |
NETLENS_MAX_BYTES | 10485760 | 单次响应的大小上限;超出部分会被截断 |
NETLENS_CACHE_TTL | 300 | 已获取页面的缓存复用时长(秒);0 表示禁用缓存 |
NETLENS_HOST_DELAY | 0.5 | 向同一主机发送请求的最小间隔(秒) |
NETLENS_REQUEST_TIMEOUT | 120 | 单次工具调用的最长等待时间 |
自托管 SearXNG
将 NETLENS_SEARXNG_URL 指向一个已启用 JSON API 的实例(其 settings.yml 中的 search.formats
必须包含 json)。此后,在 auto 模式下会优先尝试该实例,从而避免在常规路径中进行 HTML 抓取及其带来的速率限制。
由于会优先尝试该实例,因此在主机不可用时必须快速失败:连接超时会单独设定上限,以便几秒内跳过无法访问的实例,而不是让每次搜索都陷入等待;跳过情况也会在结果中报告。
工作原理
- 直接抓取。 请求通过系统
curl直接发送到目标网站(TLS、HTTP/2 和压缩效果更好,因此看起来像真实浏览器),如果不可用则回退到urllib。不会使用第三方代理或阅读器。 - 本地转换。 HTML → Markdown 在进程内通过手工编写的
html.parser转换器完成,支持标题、列表、链接(解析相对 URL)、代码 块,以及支持 colspan/rowspan 的 GFM 表格。 - 选择内容,而非删除内容。 NetLens 会选取网页的主要内容区域——优先选择 HTML5 地标(
<main>/<article>/[role=main]),若不存在,则选择相对于链接密度而言包含最多正文内容的子树——并且只转换该区域。由于它是选出最佳区域,而不是删除所有符合某种名称模式的内容,因此提取结果不会悄无声息地变成空页面。不会检查 CSS 类名或 id 名称来判断哪些是内容。 - 按测量结果精简。 在该区域内,会根据链接密度移除主要由链接锚点组成的内容块(导航框、标签云、“此网站更多内容”网格)。非渲染元素(
<script>、<style>等)、明确隐藏的元素,以及第三方广告网络广告位(通过adsbygoogle等供应商名称识别,不会与正文混淆)会被直接移除。 - 遵循响应字符集(从
Content-Type或<meta>获取),因此非 UTF-8 页面不会出现乱码。
从 CLI 使用
该服务也可以作为普通脚本运行,方便在客户端加载前进行测试:
python -m netlens_mcp.server search "http caching best practices"
python -m netlens_mcp.server fetch https://example.com/article
python -m netlens_mcp.server full https://example.com # whole body
python -m netlens_mcp.server raw https://example.com # unconverted HTML
python -m netlens_mcp 会运行 stdio MCP 服务;python -m netlens_mcp.server <cmd> 会运行 CLI。
开发
pip install -e ".[dev]"
python -m pytest # run the test suite
ruff check . # lint
要求
- Python 3.10+(以及系统
curl,现代 Windows/macOS/Linux 均自带;如果不存在,则回退到urllib)
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。