local-web-mcp
local-web-mcp
Version 0.3.0 · AGPL-3.0
这个工具在 AI 的支持下开发,但上传前已经过人工评估。
一个 MCP 服务器,为 Claude 提供一个运行在你自己机器上的备用网页抓取器。当内置抓取器被阻止时,它会从你的 IP、你的连接,以及(可选)你已登录的会话尝试请求。
一个工具:fetch_url_locally。
它解决的问题
托管抓取器从数据中心 IP 段发起请求,许多网站会直接拒绝。本地 stdio MCP 服务器不会这样:客户端会在你的机器上启动进程,因此请求来自你的普通连接。
已验证可在托管抓取器无法读取的网站上工作,包括 CNBC、Politiken 和 Bloomberg。
Related MCP server: auth-fetch-mcp
它不改变什么
值得直说,因为这种框架容易让人夸大其词。
模型推理仍然在 Anthropic 的服务器上运行。
抓取到的页面文本仍然作为工具输出发送给模型。通过已验证会话读取到的任何内容都会一并发送。
它改变的是谁与网站对话,而不是模型在哪里运行。
硬性边界
页面能否在不执行 JavaScript 的情况下被读取?
如果可以,本工具就能处理。如果不行,那么无论从 header、TLS 还是 cookie 层面都无法突破,调整 User-Agent 也无济于事。使用 DataDome、Cloudflare Turnstile、PerimeterX 等类似服务的网站会提供一个必须执行才能通过的验证挑战。对于这些网站,请使用基于浏览器的工具,或自行打开页面。
这是一个需要了解的边界,而不是需要修复的 bug。
判定结果
每个响应都有标注。危险的情况不是明显的 403,而是返回 200 但并非页面本身:机器人拦截页、同意横幅、空白的客户端渲染外壳。这些内容会被当作文章一样被总结。
判定 | 含义 | 应对方法 |
| 真实内容 | 使用它 |
| 检测到机器人保护 | 需要浏览器,停止 |
| 直接拒绝(403),通常是机器人检测 | 需要浏览器,停止 |
| 客户端渲染外壳,没有 JS 就没有内容 | 需要浏览器,停止 |
| 401、登录墙或订阅墙 | cookie 可能会有帮助 |
| 任何其他非 2xx 状态(404、429、5xx) | 仅对 429/5xx 稍后重试 |
| 提取的字符少于 200 | 读取失败,而非空页面 |
除 ok 以外的任何结果都会附加一条明确警告,告诉模型不要把正文当作内容。
正文证据优先于状态码。如果某个发布商以 HTTP 403 提供付费墙文章,那么应报告为 login_required 而非 blocked,因为此时有用的建议是导出 cookie,而不是改用浏览器。
检测匹配的是供应商基础设施,而不是文字措辞:验证页面是本地化的,因此 captcha-delivery.com 是可靠信号,而“正在验证您的设备”不是。当响应头中出现供应商 cookie 且伴随拒绝状态时,也会作为证据。
工具
fetch_url_locally(url, max_chars=20000, use_session=true)
参数 | 类型 | 默认值 | 用途 |
| string | 必填 | 要抓取的页面。仅支持 |
| integer |
| 返回文本的上限,最大限制为 200000。截断会在 header 中报告 |
| boolean |
| 发送 cookie。传 |
回复是一段简短的 header,后跟提取出的文本:
URL: https://example.com/article
Status: 200
Verdict: ok
Title: The headline
Session: authenticated (the user's cookies were sent)
The article text...Session: 仅在 cookie 确实已加载且作用域限定于该主机时出现。判定不是 ok 时,会添加一行 WARNING:,告诉模型不要把正文当作内容。
失败会以错误形式返回并说明原因,例如 [blocked_host] Host '192.168.1.5' resolves to a private or internal address。错误码:invalid_url、blocked_scheme、blocked_host、dns_failure、timeout、too_many_redirects、upstream_error、invalid_argument。
环境要求
Python 3.11+(使用
asyncio.timeout)。使用 uv 时你无需自行安装;uv 会获取合适的解释器Claude Desktop 或 Claude Code。Stdio 服务器在浏览器或移动应用中无法工作,这两者需要公开可访问的 HTTPS 端点。
安装
使用 uv(它会自行获取合适的 Python 和依赖):
uv --directory /absolute/path/to/local-web-mcp run local-web-mcp在注册服务器之前,请先在终端中运行一次。 首次运行会解析并构建环境,耗时较长,客户端冷启动时可能会放弃并报告服务器失败,即使配置是正确的。
它会打印 Starting local-web,然后等待客户端在 stdin 上连接,这就是服务器正常工作的表现。看到这行输出后,环境即已构建完成:按 Ctrl+C 继续。
或者使用普通的虚拟环境:
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt注册到 Claude Desktop
添加到 claude_desktop_config.json(macOS:~/Library/Application Support/Claude/,Linux:~/.config/Claude/):
{
"mcpServers": {
"local-web": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/local-web-mcp",
"run",
"local-web-mcp"
]
}
}
}如果客户端可见的 PATH 中没有 uv,请使用其绝对路径作为 command。虚拟环境对应的配置为:
{
"mcpServers": {
"local-web": {
"command": "/absolute/path/to/.venv/bin/python",
"args": ["/absolute/path/to/local_web_mcp.py"]
}
}
}Claude Code:
claude mcp add local-web -- uv --directory /absolute/path/to/local-web-mcp run local-web-mcp配置
全部可选。每个设置都有可用的默认值。
变量 | 默认值 | 用途 |
| 未设置 | cookie jar 的路径 |
| 未设置 | jar 可被使用的域名。只要设置 cookie 文件,就应设置此项 |
|
| 允许私有、回环和链路本地目标 |
| 空 | 不受 IP 检查约束的主机名 |
| Chrome UA | 随每个请求发送 |
|
| 语言偏好。网站据此选择语言,有时也会选择地区版本 |
|
| 秒 |
|
| 秒 |
|
| 每次调用的硬性上限 |
|
| 响应体大小上限 |
|
| 重定向跳数,与 meta refresh 共享 |
默认的 Accept-Language 首先请求丹麦语。这是一个有意选择的默认值,而非中性默认值,因此如果你想要英语或其他语言,请设置 LOCALWEB_ACCEPT_LANGUAGE:
"env": { "LOCALWEB_ACCEPT_LANGUAGE": "en-GB,en;q=0.9" }会话 Cookie
将 LOCALWEB_COOKIE_FILE 指向浏览器扩展的导出文件。加载器接受带任意文件头或不带文件头的 Netscape cookies.txt,以及常见扩展的 JSON 导出。参见 cookies.txt.example。
务必设置 LOCALWEB_COOKIE_DOMAINS。 否则整个 jar 都会生效,任何抓取都可能携带无关会话。设置后,位于这些域名之外的每个 cookie 都会在加载时、在 jar 到达客户端之前被丢弃。匹配涵盖子域名(example.com 覆盖 www.example.com),但不包括近似域名(evil-example.com)。
有三点需要牢记:
通过你的会话读取的内容会作为工具输出发送给模型。
cookie 文件是凭证文件。执行
chmod 600,并且本仓库已将其加入 .gitignore。cookie 会过期。之前能正常使用的来源现在返回
login_required,通常是导出已过期,而不是访问权限丢失。
传入 use_session=false 可检查页面是否真正公开。
访问本地网络
私有地址默认被阻止,而且是故意如此。模型选择 URL 的部分依据是它刚读到的文本,因此被抓取的页面可能试图将其引向 192.168.1.1。阻止列表意味着页面内容中的提示注入无法将本工具变成网络扫描器。
优先使用窄范围的白名单,而不是一刀切的开关:
"env": { "LOCALWEB_ALLOWLIST": "nas.local,nas" }安全
协议仅限 http 和 https;携带凭据的 URL 会被拒绝
请求前解析主机名,并验证每一个返回的地址
检查前先解包 IPv6 映射的 IPv4(
::ffff:10.0.0.1)云元数据端点被无条件阻止:主机名会在白名单和
ALLOW_PRIVATE之前解析,因此二者都无法打开这些端点手动跟随重定向和 meta refresh,并在每一跳重新验证
记录 cookie 数量,绝不记录名称、值或域名
已知限制
不支持 JavaScript。 即上文所述硬性边界。
DNS 重绑定。 主机名会先为验证解析一次,然后在连接时再次解析。要弥合这一缺口,需要将连接固定到已验证的 IP。在不受信任的网络中启用
ALLOW_PRIVATE之前,值得先解决这一点。验证挑战检测基于签名,会随着供应商修改标记而逐渐过时。如果判定结果看起来不对,请运行
inspect_response.py。HTML 转文本提取不依赖第三方库,且较为粗糙。 对于严肃的文章提取,
trafilatura会明显更好。
文件
文件 | 用途 |
| 服务器 |
| 容错的 cookie 加载器。必需,由服务器导入 |
| 诊断工具:转储抓取器实际接收到的内容 |
| 判定、目标验证、cookie 加载与作用域 |
| 被阻止的目标和一次实时抓取,通过 stdio 运行 |
| 带注释的 cookie jar 模板 |
| 包元数据和 |
| 固定依赖版本,确保可复现安装 |
| 普通 venv 路线的运行时依赖 |
| 排除 venv、缓存和任何 cookie 文件 |
| 完整的 AGPL-3.0 文本 |
诊断错误的判定
uv run python inspect_response.py https://example.com/article打印状态、感兴趣的响应头、正文开头,然后针对其运行服务器自身的检测。在修改检测逻辑之前,务必先检查此输出。 浏览器和此抓取器经常被返回完全不同的响应,因此你在屏幕上看到的内容并不能证明抓取器实际收到了什么。
测试
uv run python unit_test.py
uv run python smoke_test.pyunit_test.py 离线运行,失败时返回非零退出码,因此可以用作 pre-commit 门禁。smoke_test.py 通过 stdio 驱动服务器,并发出一次真实请求,因此需要网络连接。从仓库根目录运行这两个脚本。
在纯 venv 方案中,用 .venv/bin/python 替换 uv run python。
许可证
版权所有 (C) 2026 David Lindholm。
GNU Affero General Public License v3.0 or later。参见 LICENSE。
本程序的分发是希望它会有用,但不提供任何担保;甚至不提供适销性或对特定用途的适用性的默示担保。
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceFetches content from authenticated web pages by driving your signed-in Chrome/Edge browser via DevTools Protocol, automatically handling login redirects and reusing sessions across domains.8MIT
- AlicenseAqualityAmaintenanceEnables AI assistants to access content from authenticated web pages by opening a real browser for manual login and session capture. It saves browser profiles locally so users only need to log in once per service for future automated access.46935MIT
- AlicenseAqualityDmaintenanceEnables AI agents to control the user's Chrome or Firefox browser, leveraging existing sessions for tasks requiring authentication and user handoff.181715MIT
- FlicenseNot gradedqualityCmaintenanceUnlimited, session-authenticated web search and fetch for AI tools using your own browser. Supports authenticated/paywalled pages without API keys.
Related MCP Connectors
Reliable web access for AI agents: smart HTTP, rotating proxies, and full-browser rendering.
Stealth web browser for agents: search, fetch, click, download and type in persistent MCP sessions.
Provides cloud browser automation capabilities using Stagehand and Browserbase, enabling LLMs to i…
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/davidwlindholm/local-web-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server