local-web-mcp
local-web-mcp
Version 0.3.0 · AGPL-3.0
Dieses Werkzeug wurde mit Unterstützung durch KI entwickelt, wurde aber vor dem Upload von einem Menschen geprüft.
Ein MCP-Server, der Claude einen Fallback-Web-Fetcher bereitstellt, der auf deinem eigenen Rechner läuft. Wenn der eingebaute Fetcher blockiert ist, versucht dieser es von deiner IP, deiner Verbindung und optional deiner angemeldeten Sitzung aus.
Ein Werkzeug: fetch_url_locally.
Das Problem, das es löst
Gehostete Fetcher laufen aus IP-Bereichen von Rechenzentren, die viele Websites grundsätzlich ablehnen. Ein lokaler stdio-MCP-Server tut das nicht: Der Client startet den Prozess auf deinem Rechner, also stammen die Anfragen aus deiner normalen Verbindung.
Verifiziert funktionierend auf Websites, die der gehostete Fetcher nicht lesen konnte, darunter CNBC, Politiken und Bloomberg.
Related MCP server: auth-fetch-mcp
Was es nicht ändert
Einen klaren Hinweis wert, weil die Rahmung zu Übertreibungen einlädt.
Die Modellinferenz läuft weiterhin auf den Servern von Anthropic.
Der abgerufene Seitentext wird weiterhin als Werkzeugausgabe an das Modell gesendet. Alles, was über eine angemeldete Sitzung gelesen wird, geht damit mit.
Es ändert, wer mit der Website spricht, nicht wo das Modell läuft.
Die harte Grenze
Kann die Seite ohne Ausführung von JavaScript gelesen werden?
Wenn ja, erledigt dieses Werkzeug das. Wenn nein, führt weder auf Header-, TLS- noch Cookie-Ebene etwas dorthin, und auch noch so viel User-Agent-Feintuning hilft nicht. Websites mit DataDome, Cloudflare Turnstile, PerimeterX und Ähnlichem liefern eine Herausforderung aus, die ausgeführt werden muss, um sie zu bestehen. Verwende dafür ein browserbasiertes Werkzeug oder öffne die Seite selbst.
Das ist eine Grenze, die man kennen sollte, kein Fehler, den es zu beheben gilt.
Bewertungen
Jede Antwort ist gekennzeichnet. Der gefährliche Fall ist kein offensichtlicher 403, sondern eine 200, die nicht die Seite ist: ein Bot-Zwischenfenster, eine Zustimmungsmauer, eine leere client-gerenderte Hülle. Diese werden zusammengefasst, als wären sie der Artikel.
Bewertung | Bedeutung | Was zu tun ist |
| Echte Inhalte | Verwenden |
| Botschutz erkannt | Browser erforderlich, anhalten |
| Direkt abgelehnt (403), meist Bot-Erkennung | Browser erforderlich, anhalten |
| Client-gerenderte Hülle, ohne JS keine Inhalte | Browser erforderlich, anhalten |
| 401, Anmeldewand oder Bezahlwand | Cookies könnten helfen |
| Jeder andere Nicht-2xx-Status (404, 429, 5xx) | Nur bei 429/5xx später erneut versuchen |
| Unter 200 Zeichen extrahiert | Fehlgeschlagenes Lesen, keine leere Seite |
Alles andere als ok bringt eine ausdrückliche Warnung an, die dem Modell sagt,
den Textkörper nicht als Inhalt zu behandeln.
Der Beweis aus dem Textkörper hat Vorrang vor dem Statuscode. Ein Verlag, der
einen Artikel hinter einer Bezahlschranke als HTTP 403 ausliefert, wird als
login_required gemeldet, nicht als blocked, weil der nützliche Rat dort ist,
Cookies zu exportieren, statt zu einem Browser zu greifen.
Die Erkennung zielt auf Anbieter-Infrastruktur statt auf Formulierungen:
Herausforderungsseiten sind lokalisiert, also ist captcha-delivery.com ein
zuverlässiges Signal, wo „Verifying your device" es nicht ist. Anbieter-Cookies
in Antwort-Headern zählen als Beleg, wenn sie mit einem Verweigerungsstatus
einhergehen.
Das Werkzeug
fetch_url_locally(url, max_chars=20000, use_session=true)
Parameter | Typ | Standard | Zweck |
| string | erforderlich | Die Seite, die abgerufen werden soll. Nur |
| integer |
| Obergrenze für zurückgegebenen Text, begrenzt auf 200000. Kürzung wird im Header gemeldet |
| boolean |
| Cookies senden. |
Die Antwort besteht aus einem kurzen Header, gefolgt vom extrahierten Text:
URL: https://example.com/article
Status: 200
Verdict: ok
Title: The headline
Session: authenticated (the user's cookies were sent)
The article text...Session: erscheint nur, wenn tatsächlich Cookies geladen wurden, die für diesen
Host gelten. Eine andere Bewertung als ok fügt eine WARNING:-Zeile hinzu, die
dem Modell sagt, den Textkörper nicht als Inhalt zu behandeln.
Fehler kommen als Fehlermeldung zurück, die die Ursache benennt, zum Beispiel
[blocked_host] Host '192.168.1.5' resolves to a private or internal address
(deutsch: Host '192.168.1.5' löst zu einer privaten oder internen Adresse auf).
Codes: invalid_url, blocked_scheme, blocked_host, dns_failure, timeout,
too_many_redirects, upstream_error, invalid_argument.
Voraussetzungen
Python 3.11+ (verwendet
asyncio.timeout). Mit uv musst du es nicht selbst installieren; uv holt eine geeignete Python-InterpretationClaude Desktop oder Claude Code. Stdio-Server funktionieren nicht im Browser oder in der mobilen App; diese benötigen einen öffentlich erreichbaren HTTPS-Endpunkt.
Installation
Mit uv, das selbst ein geeignetes Python und die Abhängigkeiten holt:
uv --directory /absolute/path/to/local-web-mcp run local-web-mcpFühre das einmal in einem Terminal aus, bevor du den Server registrierst. Der erste Lauf löst die Umgebung auf und baut sie auf, was lange genug dauert, dass ein Client, der den Server kalt startet, aufgeben und den Server als fehlgeschlagen melden könnte, obwohl die Konfiguration korrekt ist.
Es gibt Starting local-web aus und wartet dann auf einen Client auf stdin,
was wie ein funktionierender Server aussieht. Sobald du diese Zeile siehst, ist
die Umgebung gebaut: Drücke Ctrl+C und mach weiter.
Oder mit einer einfachen virtuellen Umgebung:
python3 -m venv .venv
.venv/bin/pip install -r requirements.txtBei Claude Desktop registrieren
Füge zu claude_desktop_config.json hinzu (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"
]
}
}
}Wenn uv nicht im PATH liegt, den der Client sieht, verwende den absoluten Pfad
als command. Das Pendant mit virtueller Umgebung ist:
{
"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-mcpKonfiguration
Alles optional. Jede Einstellung hat einen funktionierenden Standardwert.
Variable | Standard | Zweck |
| nicht gesetzt | Pfad zu einem Cookie-Jar |
| nicht gesetzt | Domains, für die der Jar verwendet werden darf. Immer setzen, wenn du eine Cookie-Datei setzt |
|
| Private, Loopback- und Link-Local-Ziele erlauben |
| leer | Hostnamen, die von der IP-Prüfung ausgenommen sind |
| Chrome-UA | Wird bei jeder Anfrage gesendet |
|
| Spracheinstellung. Websites nutzen sie, um eine Sprache und manchmal eine Regionaledition zu wählen |
|
| Sekunden |
|
| Sekunden |
|
| Harte Obergrenze pro Aufruf |
|
| Obergrenze für den Antworttextkörper |
|
| Redirect-Sprünge, gemeinsam mit Meta-Refreshes |
Der Standard-Accept-Language fragt zuerst Dänisch an. Das ist eine bewusste
Standardwahl statt einer neutralen, also setze LOCALWEB_ACCEPT_LANGUAGE, wenn
du Englisch oder etwas anderes möchtest:
"env": { "LOCALWEB_ACCEPT_LANGUAGE": "en-GB,en;q=0.9" }Sitzungs-Cookies
Weise LOCALWEB_COOKIE_FILE auf einen Export aus einer Browser-Erweiterung.
Der Lader akzeptiert Netscape-cookies.txt-Dateien mit beliebigem Header oder
ohne Header sowie JSON-Exporte der gängigen Erweiterungen. Siehe
cookies.txt.example.
Setze immer LOCALWEB_COOKIE_DOMAINS. Ohne diese Angabe ist der gesamte Jar
aktiv und jeder Abruf kann eine unzusammenhängende Sitzung mitführen. Mit ihr
werden alle Cookies außerhalb dieser Domains bereits beim Laden verworfen, bevor
der Jar einen Client erreicht. Der Abgleich umfasst Subdomains (example.com
deckt www.example.com ab), aber keine Ähnlichkeiten (evil-example.com).
Drei Dinge, die du im Hinterkopf behalten solltest:
Inhalte, die über deine Sitzung gelesen werden, werden als Werkzeugausgabe an das Modell gesendet.
Eine Cookie-Datei ist eine Zugangsdaten-Datei.
chmod 600, und sie ist hier gitignored.Cookies laufen ab. Wenn eine zuvor funktionierende Quelle plötzlich
login_requiredliefert, ist das meist ein veralteter Export und kein verlorener Zugang.
Übergib use_session=false, um zu prüfen, ob eine Seite wirklich öffentlich ist.
Ein lokales Netzwerk erreichen
Private Adressen sind standardmäßig blockiert, und das ist beabsichtigt. Das
Modell wählt URLs teilweise aus Text aus, den es gerade gelesen hat, also kann
eine abgerufene Seite versuchen, es auf 192.168.1.1 zu lenken. Die Blockliste
bedeutet, dass eine Prompt-Injection im Seiteninhalt dies nicht in einen
Netzwerkscanner verwandeln kann.
Bevorzuge eine enge Allowlist gegenüber dem pauschalen Schalter:
"env": { "LOCALWEB_ALLOWLIST": "nas.local,nas" }Sicherheit
Schema auf http und https beschränkt; URLs mit Zugangsdaten werden abgelehnt
Hostname wird aufgelöst und jede zurückgegebene Adresse vor der Anfrage validiert
IPv4-Adressen in IPv6-Schreibweise (
::ffff:10.0.0.1) werden vor der Prüfung entpacktCloud-Metadaten-Endpunkte sind bedingungslos blockiert: Der Hostname wird vor sowohl der Allowlist als auch
ALLOW_PRIVATEaufgelöst, also kann keines von beiden sie öffnenRedirects und Meta-Refreshes werden manuell verfolgt und bei jedem Sprung neu validiert
Cookie-Anzahlen werden protokolliert, niemals Namen, Werte oder Domains
Bekannte Einschränkungen
Kein JavaScript. Die harte Grenze oben.
DNS-Rebinding. Der Hostname wird zur Validierung aufgelöst und dann beim Verbinden erneut aufgelöst. Um diese Lücke zu schließen, muss die Verbindung an die validierte IP gebunden werden. Sinnvoll, bevor man
ALLOW_PRIVATEin einem unsicheren Netzwerk aktiviert.Die Erkennung von Herausforderungen ist signaturbasiert und wird abweichen, wenn Anbieter ihr Markup ändern. Führe
inspect_response.pyaus, wenn eine Bewertung falsch aussieht.Die HTML-zu-Text-Extraktion ist ohne Abhängigkeiten und grob.
trafilaturawäre für ernsthafte Artikelextraktion deutlich besser.
Dateien
Datei | Zweck |
| Der Server |
| Nachsichtiger Cookie-Lader. Erforderlich, wird vom Server importiert |
| Diagnose: gibt aus, was der Fetcher tatsächlich empfängt |
| Bewertungen, Zielvalidierung, Cookie-Laden und -Abgrenzung |
| Blockierte Ziele und ein Live-Abruf über stdio |
| Kommentierte Vorlage für einen Cookie-Jar |
| Paketmetadaten und der Einstiegspunkt |
| Festgeschriebene Abhängigkeitsversionen für reproduzierbare Installationen |
| Laufzeitabhängigkeiten für den Weg mit einfacher venv |
| Schließt venv, Caches und jede Cookie-Datei aus |
| Vollständiger AGPL-3.0-Text |
Eine falsche Bewertung diagnostizieren
uv run python inspect_response.py https://example.com/articleGibt den Status, die interessanten Header, den Anfang des Textkörpers aus und führt dann die eigene Erkennung des Servers dagegen aus. Prüfe das immer, bevor du Erkennungslogik änderst. Ein Browser und dieser Fetcher bekommen häufig völlig unterschiedliche Antworten ausgeliefert. Was du auf dem Bildschirm siehst, ist also kein Beleg dafür, was der Fetcher empfangen hat.
Tests
uv run python unit_test.py
uv run python smoke_test.pyunit_test.py läuft offline und beendet sich bei einem Fehler mit einem Exit-Code ungleich null, sodass es als Pre-Commit-Gate dient. smoke_test.py steuert den Server über stdio und sendet eine Live-Anfrage; es benötigt also eine Netzwerkverbindung. Führen Sie beide im Stammverzeichnis des Repositorys aus.
Beim plain-venv-Weg ersetzen Sie uv run python durch .venv/bin/python.
Lizenz
Copyright (C) 2026 David Lindholm.
GNU Affero General Public License v3.0 oder neuer. Siehe LICENSE.
Dieses Programm wird in der Hoffnung weitergegeben, dass es nützlich sein wird, aber OHNE JEGLICHE GARANTIE; selbst ohne die stillschweigende Garantie der MARKTGÄNGIGKEIT oder der EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
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