Skip to main content
Glama
JohnnyFoulds

markdown-for-agents-mcp

markdown-for-agents-mcp

npm version npm downloads Node.js codecov License: MIT

Ein MCP (Model Context Protocol)-Server, der URLs mit vollständigem JavaScript-Rendering abruft und sie für KI-Agenten in sauberes, token-effizientes Markdown konvertiert.

Die meisten MCP-Abruf-Tools verwenden einfaches HTTP – sie sehen nur, was ein Server sendet, ohne JavaScript auszuführen. Das funktioniert bei statischen Seiten, liefert aber bei React, Vue, Angular, SPAs und jeder Seite, die Daten dynamisch lädt, stillschweigend leere oder fehlerhafte Inhalte. Dieser Server führt einen echten Chromium-Browser über Playwright aus und rendert daher die vollständige Seite vor der Extraktion – genau den Inhalt, den ein menschlicher Benutzer sehen würde.

Angetrieben von Playwright und der Bibliothek markdown-for-agents. Entfernt Werbung, Navigation und Boilerplate – und liefert bis zu 80 % weniger Token als reines HTML.


Warum Playwright?

Fähigkeit

Einfache HTTP-Fetcher

markdown-for-agents-mcp

Statische HTML-Seiten

React / Vue / Angular Apps

JavaScript-gerenderte Inhalte

Single-Page-App-Routen

Lazy-Loading / Infinite-Scroll

Token-Effizienz vs. rohes HTML

Mittel

Bis zu 80 % weniger

Umgehung von Bot-Erkennung

Keine

UA-Rotation, Webdriver-Spoofing

Beispiel für Token-Reduzierung: Eine typische Nachrichtenseite besteht aus ca. 150 KB rohem HTML (~40.000 Token). Nach dem Playwright-Rendering, der DOM-Bereinigung und der Markdown-Konvertierung wird derselbe Artikel zu ca. 2.000 Token – eine Reduzierung um 95 %.


Inhaltsverzeichnis


Funktionen

  • JavaScript-Rendering — Playwright-gesteuertes Chromium rendert React, Vue, Angular und jede JS-lastige Seite vor der Extraktion

  • Strukturierte Ausgabe — Tools geben typisiertes structuredContent (url, title, markdown, fetchedAt, contentSize) zusammen mit der Textantwort zurück, kompatibel mit MCP SDK 1.11+

  • Intelligente Inhaltsextraktion — Bewertet und wählt den Hauptinhaltsblock aus (main > article > #content > body), wobei Seitenleisten, Navigation und Werbung automatisch verworfen werden

  • Token-Effizienz — Erzeugt kompaktes, LLM-fertiges Markdown; Benchmarks zeigen bis zu 80 % weniger Token als bei rohem HTML

  • Websuche — DuckDuckGo-Suche mit optionalem Abruf und Konvertierung der Top-Ergebnisse

  • LRU-Cache — 50 MB In-Memory-Cache mit 15 Minuten TTL vermeidet redundante Abrufe

  • Domain-Filterung — Integrierte Blockliste für Tracker/Social-Domains; unterstützt Allow-/Blocklisten pro Anfrage und einen Allowlisten-Modus auf Serverebene

  • Batch-Abrufe — Gleichzeitige Multi-URL-Abrufe mit konfigurierbarer Parallelität

  • HTTP-Server-Modus — Ausführung als HTTP-Server (--http [port] oder HTTP_PORT Umgebungsvariable) mit optionaler Bearer-Token-Authentifizierung

  • Proxy-Unterstützung — Übergeben Sie PLAYWRIGHT_PROXY, um Playwright-Datenverkehr über einen Proxy zu leiten

  • Gesundheitsüberwachung — Das health_check-Tool macht Cache- und Abrufmetriken verfügbar

  • Zero-Konfiguration — Chromium wird beim ersten Start automatisch installiert


Installation

npm install -g markdown-for-agents-mcp

Chromium wird automatisch über das postinstall-Skript heruntergeladen. Falls dies fehlschlägt, siehe Fehlerbehebung.

Sie können es auch ohne globale Installation mit npx ausführen:

npx markdown-for-agents-mcp

MCP-Client-Einrichtung

Fügen Sie den Server zu Ihrer MCP-Client-Konfiguration hinzu.

Claude Desktop

Bearbeiten Sie ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) oder %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "markdown": {
      "command": "markdown-mcp"
    }
  }
}

VS Code (Copilot / Continue)

Fügen Sie es unter dem entsprechenden MCP-Erweiterungsschlüssel zu Ihrem Workspace oder Benutzer settings.json hinzu, zum Beispiel:

{
  "mcpServers": {
    "markdown": {
      "command": "markdown-mcp"
    }
  }
}

Cursor / Windsurf / Zed

Jeder Client, der die MCP-Spezifikation implementiert, kann diesen Server verwenden. Der Befehlseinstiegspunkt ist markdown-mcp (verfügbar im PATH nach globaler Installation) oder der vollständige Pfad zu dist/index.js für lokale Builds.

Mit Umgebungsvariablen-Überschreibungen

{
  "mcpServers": {
    "markdown": {
      "command": "markdown-mcp",
      "env": {
        "FETCH_TIMEOUT_MS": "60000",
        "LOG_LEVEL": "DEBUG"
      }
    }
  }
}

HTTP-Server-Modus

Anstelle von stdio können Sie den Server als Standard-HTTP-Endpunkt ausführen – nützlich für geteilte Deployments, Docker oder jeden Client, der den Streamable HTTP-Transport bevorzugt:

# Start on port 3456
markdown-mcp --http 3456

# Or use the env var
HTTP_PORT=3456 markdown-mcp

Der gesamte MCP-Datenverkehr wird unter POST|GET|DELETE /mcp abgewickelt. Um ein Bearer-Token zu erzwingen, setzen Sie MCP_AUTH_TOKEN:

MCP_AUTH_TOKEN=mysecrettoken HTTP_PORT=3456 markdown-mcp

Clients müssen dann bei jeder Anfrage Authorization: Bearer mysecrettoken übergeben.


Verfügbare Tools

fetch_url

Ruft eine einzelne URL mit vollständigem JavaScript-Rendering ab und gibt sauberes Markdown zurück.

Argumente:

Name

Typ

Erforderlich

Beschreibung

url

string

ja

Abzurufende und zu konvertierende URL

timeout

number

nein

Anfrage-Timeout in ms (überschreibt FETCH_TIMEOUT_MS)

Beispiel:

fetch_url(url="https://example.com/blog/post")

Textausgabe (immer vorhanden, abwärtskompatibel):

# Blog Post Title

Source: https://example.com/blog/post

This is the main content of the article, stripped of navigation, ads, and boilerplate.

## Related Section

More content here...

---
*Converted by markdown-for-agents-mcp*

Strukturierte Ausgabe (verfügbar für MCP SDK 1.11+ Clients über structuredContent):

{
  "url": "https://example.com/blog/post",
  "title": "Blog Post Title",
  "markdown": "# Blog Post Title\n\nSource: ...",
  "fetchedAt": "2026-04-06T17:00:00.000Z",
  "contentSize": 2048
}

fetch_urls

Ruft mehrere URLs gleichzeitig ab und gibt kombiniertes Markdown zurück, ein Abschnitt pro URL.

Argumente:

Name

Typ

Erforderlich

Beschreibung

urls

string[]

ja

Abzurufende URLs

timeout

number

nein

Timeout pro Anfrage in ms

Beispiel:

fetch_urls(urls=[
  "https://example.com/post1",
  "https://example.com/post2"
])

Textausgabe:

# Post 1 Title

Source: https://example.com/post1

...

---

# Post 2 Title

Source: https://example.com/post2

...

---

Strukturierte Ausgabe (über structuredContent):

{
  "results": [
    {
      "url": "https://example.com/post1",
      "title": "Post 1 Title",
      "markdown": "...",
      "fetchedAt": "2026-04-06T17:00:00.000Z",
      "contentSize": 1820,
      "success": true
    },
    {
      "url": "https://example.com/post2",
      "title": "Post 2 Title",
      "markdown": "...",
      "fetchedAt": "2026-04-06T17:00:00.000Z",
      "contentSize": 2104,
      "success": true
    }
  ],
  "summary": { "total": 2, "succeeded": 2, "failed": 0 }
}

Die Parallelität wird durch MAX_CONCURRENT_FETCHES gesteuert (Standard: 5).


Durchsucht DuckDuckGo und ruft optional Top-Ergebnisse als Markdown ab. Verwendet einen einfachen HTTP-Endpunkt, um Bot-Erkennung zu vermeiden – kein Playwright für die Suche selbst.

Argumente:

Name

Typ

Erforderlich

Beschreibung

query

string

ja

Suchanfrage

maxResults

number

nein

Maximale Anzahl der zurückzugebenden Ergebnisse (Standard: 10)

allowedDomains

string[]

nein

Nur Ergebnisse von diesen Domains einbeziehen

blockedDomains

string[]

nein

Ergebnisse von diesen Domains ausschließen

fetchResults

boolean

nein

Top-Ergebnisseiten abrufen und in Markdown konvertieren

timeout

number

nein

Anfrage-Timeout in ms

Beispiel — nur Suche:

web_search(
  query="typescript tutorials",
  maxResults=5,
  allowedDomains=["typescriptlang.org", "github.com"]
)

Beispiel — Suche und Abruf:

web_search(
  query="react hooks guide",
  fetchResults=true,
  maxResults=3
)

Textausgabe:

# Web Search Results

## Query: typescript tutorials
**Found 5 results in 1234ms**

### Results:

1. [TypeScript Handbook](https://www.typescriptlang.org/docs/)
   The TypeScript Handbook provides comprehensive documentation...

2. [Best TypeScript Tutorials](https://github.com/danistefanovic/build-your-own-typescript)
   Learn TypeScript by building your own compiler...

Strukturierte Ausgabe (über structuredContent):

{
  "query": "typescript tutorials",
  "results": [
    { "title": "TypeScript Handbook", "url": "https://www.typescriptlang.org/docs/", "snippet": "...", "domain": "typescriptlang.org" }
  ],
  "fetchedContent": [
    { "url": "https://www.typescriptlang.org/docs/", "markdown": "..." }
  ],
  "durationMs": 1234
}

Hinweis: Die Argumente allowedDomains und blockedDomains gelten nur für die Filterung von Suchergebnissen. Die serverseitigen Einstellungen BLOCKLIST_DOMAINS / USE_ALLOWLIST_MODE gelten weiterhin, wenn diese Ergebnisse anschließend abgerufen werden.


download_file

Lädt eine Binärdatei (PDF, Bild, ZIP usw.) von einer URL herunter und speichert sie unter einem lokalen Pfad. Verwendet einen einfachen HTTP-Client – kein Playwright erforderlich. SSRF-Schutz und Domain-Blockliste werden durchgesetzt.

Argumente:

Name

Typ

Erforderlich

Beschreibung

url

string

ja

URL der herunterzuladenden Datei

outputPath

string

ja

Absoluter lokaler Pfad zum Speichern der Datei (übergeordnetes Verzeichnis muss existieren)

Beispiel:

download_file(
  url="https://example.com/report.pdf",
  outputPath="/tmp/report.pdf"
)

Ausgabe:

{
  "savedPath": "/tmp/report.pdf",
  "sizeBytes": 204800,
  "mimeType": "application/pdf",
  "filename": "report.pdf"
}

Hinweis: URLs mit Pfaden wie /download/... sind für dieses Tool zulässig, obwohl sie von fetch_url blockiert werden (um Binär-Download-Ketten zu vermeiden). Verwenden Sie fetch_url für HTML-Seiten – download_file lehnt text/html-Antworten ab.


health_check

Gibt den aktuellen Serverstatus, Cache-Metriken und Abrufstatistiken zurück. Nützlich für Überwachung und Fehlersuche.

Argumente: keine

Beispielausgabe:

{
  "status": "healthy",
  "cache": {
    "hits": 47,
    "misses": 15,
    "currentSize": 12,
    "totalBytes": 4194304,
    "maxBytes": 52428800
  },
  "metrics": {
    "totalFetches": 62,
    "successCount": 59,
    "errorCount": 3,
    "avgDuration": 1840,
    "cacheUtilization": 76
  }
}

CLI-Nutzung

Ein eigenständiges CLI (markdown-cli) ist für die Verwendung außerhalb des MCP-Protokolls enthalten.

Einzelne URL

markdown-cli https://example.com

Mehrere URLs (Batch-Modus)

markdown-cli -b https://example.com https://example.org https://example.net

In Datei speichern

markdown-cli https://example.com/article > article.md

Binärdatei herunterladen

markdown-cli -d -o /tmp/report.pdf https://example.com/report.pdf

Befehlsreferenz

Befehl

Beschreibung

markdown-cli <url>

Ruft eine einzelne URL ab und gibt Markdown aus

markdown-cli -b <url1> <url2> ...

Ruft mehrere URLs im Batch-Modus ab

markdown-cli -d -o <path> <url>

Lädt eine Binärdatei unter einem lokalen Pfad herunter

markdown-cli --help

Hilfe anzeigen


Konfiguration

Alle Einstellungen werden beim Start aus Umgebungsvariablen gelesen und mit Zod validiert. Ungültige Werte führen zu einem Beenden mit Fehlercode ungleich Null und einer beschreibenden Fehlermeldung.

Kopieren Sie .env.example nach .env, um zu beginnen:

cp .env.example .env

Referenz

Variable

Standard

Beschreibung

FETCH_TIMEOUT_MS

30000

Timeout pro Abrufanfrage (ms)

MAX_CONCURRENT_FETCHES

5

Maximale parallele Abrufe bei Batch-Operationen

MAX_REDIRECTS

10

Maximale Redirect-Hops vor Fehler

MAX_CONTENT_LENGTH

100000

Maximale Inhaltsgröße (Zeichen) vor Kürzung

LOG_LEVEL

INFO

DEBUG, INFO, WARN oder ERROR

LOG_FORMAT

text

text (lesbar) oder json (strukturiert)

CACHE_MAX_BYTES

52428800

Maximale LRU-Cache-Größe (50 MB)

CACHE_TTL_MS

900000

Cache-Eintrag TTL (15 Minuten)

USE_ALLOWLIST_MODE

false

Wenn true, sind nur Domains in BLOCKLIST_DOMAINS erlaubt

BLOCKLIST_DOMAINS

(leer)

Kommagetrennte Domains zum Blockieren (oder Erlauben im Allowlisten-Modus)

BLOCKLIST_URL_PATTERNS

(leer)

Kommagetrennte Regex-Muster zum Blockieren nach URL-Pfad

WEB_SEARCH_DEFAULT_TIMEOUT_MS

30000

Standard-Timeout für Suchanfragen (ms)

DOWNLOAD_TIMEOUT_MS

60000

Timeout für Binär-Downloads (ms)

HTTP_PORT

(nicht gesetzt)

Wenn gesetzt, startet ein HTTP-Server auf diesem Port statt stdio

MCP_AUTH_TOKEN

(nicht gesetzt)

Bearer-Token erforderlich für alle HTTP-Anfragen (nur HTTP-Modus)

PLAYWRIGHT_PROXY

(nicht gesetzt)

Proxy-Server-URL für Playwright (z. B. http://proxy.example.com:8080)

PLAYWRIGHT_PROXY_BYPASS

(nicht gesetzt)

Kommagetrennte Domains zur Umgehung des Proxys

Alle Protokolle werden nach stderr geschrieben, um `

-
security - not tested
A
license - permissive license
-
quality - not tested

Latest Blog Posts

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/JohnnyFoulds/markdown-for-agents-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server