Skip to main content
Glama

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: chrome-bridge

它不改变什么

值得直说,因为这种框架容易让人夸大其词。

  • 模型推理仍然在 Anthropic 的服务器上运行。

  • 抓取到的页面文本仍然作为工具输出发送给模型。通过已验证会话读取到的任何内容都会一并发送。

  • 它改变的是谁与网站对话,而不是模型在哪里运行。

硬性边界

页面能否在不执行 JavaScript 的情况下被读取?

如果可以,本工具就能处理。如果不行,那么无论从 header、TLS 还是 cookie 层面都无法突破,调整 User-Agent 也无济于事。使用 DataDome、Cloudflare Turnstile、PerimeterX 等类似服务的网站会提供一个必须执行才能通过的验证挑战。对于这些网站,请使用基于浏览器的工具,或自行打开页面。

这是一个需要了解的边界,而不是需要修复的 bug。

判定结果

每个响应都有标注。危险的情况不是明显的 403,而是返回 200 但并非页面本身:机器人拦截页、同意横幅、空白的客户端渲染外壳。这些内容会被当作文章一样被总结。

判定

含义

应对方法

ok

真实内容

使用它

challenge

检测到机器人保护

需要浏览器,停止

blocked

直接拒绝(403),通常是机器人检测

需要浏览器,停止

js_required

客户端渲染外壳,没有 JS 就没有内容

需要浏览器,停止

login_required

401、登录墙或订阅墙

cookie 可能会有帮助

http_error

任何其他非 2xx 状态(404、429、5xx)

仅对 429/5xx 稍后重试

empty

提取的字符少于 200

读取失败,而非空页面

除 ok 以外的任何结果都会附加一条明确警告,告诉模型不要把正文当作内容。

正文证据优先于状态码。如果某个发布商以 HTTP 403 提供付费墙文章,那么应报告为 login_required 而非 blocked,因为此时有用的建议是导出 cookie,而不是改用浏览器。

检测匹配的是供应商基础设施,而不是文字措辞:验证页面是本地化的,因此 captcha-delivery.com 是可靠信号,而“正在验证您的设备”不是。当响应头中出现供应商 cookie 且伴随拒绝状态时,也会作为证据。

工具

fetch_url_locally(url, max_chars=20000, use_session=true)

参数

类型

默认值

用途

url

string

必填

要抓取的页面。仅支持 http 和 https

max_chars

integer

20000

返回文本的上限,最大限制为 200000。截断会在 header 中报告

use_session

boolean

true

发送 cookie。传 false 可测试页面是否真正公开

回复是一段简短的 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

配置

全部可选。每个设置都有可用的默认值。

变量

默认值

用途

LOCALWEB_COOKIE_FILE

未设置

cookie jar 的路径

LOCALWEB_COOKIE_DOMAINS

未设置

jar 可被使用的域名。只要设置 cookie 文件,就应设置此项

LOCALWEB_ALLOW_PRIVATE

false

允许私有、回环和链路本地目标

LOCALWEB_ALLOWLIST

空

不受 IP 检查约束的主机名

LOCALWEB_USER_AGENT

Chrome UA

随每个请求发送

LOCALWEB_ACCEPT_LANGUAGE

da,en-GB;q=0.9,en;q=0.8

语言偏好。网站据此选择语言,有时也会选择地区版本

LOCALWEB_CONNECT_TIMEOUT

5

秒

LOCALWEB_READ_TIMEOUT

20

秒

LOCALWEB_TOTAL_TIMEOUT

40

每次调用的硬性上限

LOCALWEB_MAX_BYTES

3000000

响应体大小上限

LOCALWEB_MAX_REDIRECTS

5

重定向跳数,与 meta refresh 共享

默认的 Accept-Language 首先请求丹麦语。这是一个有意选择的默认值,而非中性默认值,因此如果你想要英语或其他语言,请设置 LOCALWEB_ACCEPT_LANGUAGE:

"env": { "LOCALWEB_ACCEPT_LANGUAGE": "en-GB,en;q=0.9" }

将 LOCALWEB_COOKIE_FILE 指向浏览器扩展的导出文件。加载器接受带任意文件头或不带文件头的 Netscape cookies.txt,以及常见扩展的 JSON 导出。参见 cookies.txt.example。

务必设置 LOCALWEB_COOKIE_DOMAINS。 否则整个 jar 都会生效,任何抓取都可能携带无关会话。设置后,位于这些域名之外的每个 cookie 都会在加载时、在 jar 到达客户端之前被丢弃。匹配涵盖子域名(example.com 覆盖 www.example.com),但不包括近似域名(evil-example.com)。

有三点需要牢记:

  1. 通过你的会话读取的内容会作为工具输出发送给模型。

  2. cookie 文件是凭证文件。执行 chmod 600,并且本仓库已将其加入 .gitignore。

  3. 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 会明显更好。

文件

文件

用途

local_web_mcp.py

服务器

cookies.py

容错的 cookie 加载器。必需,由服务器导入

inspect_response.py

诊断工具:转储抓取器实际接收到的内容

unit_test.py

判定、目标验证、cookie 加载与作用域

smoke_test.py

被阻止的目标和一次实时抓取,通过 stdio 运行

cookies.txt.example

带注释的 cookie jar 模板

pyproject.toml

包元数据和 local-web-mcp 入口点

uv.lock

固定依赖版本,确保可复现安装

requirements.txt

普通 venv 路线的运行时依赖

.gitignore

排除 venv、缓存和任何 cookie 文件

LICENSE

完整的 AGPL-3.0 文本

诊断错误的判定

uv run python inspect_response.py https://example.com/article

打印状态、感兴趣的响应头、正文开头,然后针对其运行服务器自身的检测。在修改检测逻辑之前,务必先检查此输出。 浏览器和此抓取器经常被返回完全不同的响应,因此你在屏幕上看到的内容并不能证明抓取器实际收到了什么。

测试

uv run python unit_test.py
uv run python smoke_test.py

unit_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。

本程序的分发是希望它会有用,但不提供任何担保;甚至不提供适销性或对特定用途的适用性的默示担保。

Available Tools

1 tool
fetch_url_locallyFetch a URL from the user's machineA
Read-only

Fetch a web page over the user's own internet connection and return its readable text.

USE THIS WHEN the built-in web fetch has already been tried and: it returned an error, 403, or 429; it returned a Cloudflare or captcha interstitial; it returned a cookie/consent wall or a near-empty page; the source is geo-restricted; the source sits behind the user's institutional access or paid subscription; or the URL is on the user's local network.

DO NOT use it as the first attempt for ordinary public pages -- the built-in fetcher is faster and does not use the user's bandwidth.

The response carries a verdict line. If the verdict is not 'ok', the body is an interstitial rather than the article and must not be summarised as though it were the content.

NameRequiredDescriptionDefault
urlYes
max_charsNo
use_sessionNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Clearly discloses that the response includes a verdict line that must be checked, and warns that a non-'ok' verdict means the body is an interstitial and must not be summarized as content. This is valuable behavioral context beyond the readOnlyHint annotation, and it directly prevents a likely misuse.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized for the complexity, with the core purpose front-loaded and usage conditions clearly structured. It earns its length by giving concrete error cases and a safety caveat; it is not overly verbose, though it could be slightly tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity and the fact that there is an output schema, the description is complete for an agent to call it correctly: it knows when to use it, what to expect in the response, and how to avoid misinterpreting interstitials. No critical operational detail is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate; it does not mention individual parameters like max_chars or use_session, but the core parameter 'url' is fully implied ('Fetch a web page...'). The behavioral verdict warning adds context that indirectly helps the agent interpret the output, but explicit parameter-level guidance is still missing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action ('Fetch a web page over the user's own internet connection') and an explicit resource ('user's own... URL'), and it differentiates itself by emphasizing the local-network/user-machine execution path versus the built-in fetcher. It is unambiguous about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides extensive when-to-use criteria: use only after built-in fetch fails with errors, interstitials, geo-restrictions, etc., and explicitly says DO NOT use as first attempt for ordinary pages. This is exactly the kind of conditional routing guidance an agent needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.3.0
    • First observedfetch_url_locally

TDQS

A4.6/5.0

Scored across 1 tool

Disambiguation5/5

There is only one tool, so there is no possibility of confusing it with another tool. Its purpose is clearly described and scoped.

Naming Consistency5/5

The single tool name follows a clear, descriptive snake_case convention. With only one tool, there are no inconsistent patterns to evaluate.

Tool Count3/5

A single tool is borderline for a server, but it may be justified for a narrowly-focused fallback fetch utility. It feels thin compared to broader MCP servers, but not absurdly so.

Completeness4/5

The tool completely covers its stated purpose of fetching pages locally and returning readable text. Minor gaps exist around request customization or response metadata, but no core workflow dead ends are apparent.

Maintenance

ActivityStale
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables Claude to browse the web and make GET/POST/PUT requests with a real Chrome TLS/HTTP2 fingerprint to avoid anti-bot detection, supporting persistent cookie sessions and optional proxies.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides a direct bridge between Claude and an authenticated Chrome session, enabling fetch requests with session cookies and JavaScript execution within live web pages.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude and other MCP clients to read, extract, crawl, and export data from open browser tabs and specified URLs locally, including logged-in sessions, structured page data, contacts, images, sitemaps, and Shopify catalogues.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to drive the user's real, already-logged-in Chrome browser locally, so they can read and navigate pages, click, type, fill forms, take screenshots, and inspect cookies, tabs, console, and network traffic without headless browsers or remote-debugging ports.
    1 npm
    ISC