MCP Research Friend Server

offiziell

Forschungswerkzeuge, einschließlich einer Sqlite-gestützten Dokumentenablage

Dokumentation

Research Friend

Ein freundlicher Helfer für KI-Assistenten, die Dinge im Web nachschlagen und einen lokalen Recherche-Speicher verwalten müssen.

Research Friend ist ein MCP-Server, der Ihren KI-Tools die Möglichkeit gibt, Webseiten abzurufen und das Internet zu durchsuchen. Im Hintergrund wird ein echter Webbrowser verwendet, sodass es auch mit modernen Websites funktioniert, die stark auf JavaScript angewiesen sind. Es enthält außerdem einen lokalen „Speicher“ zum Ablegen von Dokumenten, Extrahieren von Text und Durchsuchen Ihrer Bibliothek.

Um alle Funktionen nutzen zu können, benötigen Sie einen MCP-Client, der Prompts (üblich) und Sampling (weniger üblich) unterstützt. Wir entwickeln Research Friend zusammen mit Chabeau, das beides unterstützt.

Was kann es?

  • Webseiten abrufen mit einem echten Browser (einschließlich JS-lastiger Seiten)
  • PDFs abrufen und deren Textinhalt extrahieren
  • Das Web durchsuchen via DuckDuckGo oder Google
  • Einen lokalen Speicher für Dokumente pflegen, zum Suchen, Auflisten und Extrahieren

Erste Schritte

Sie benötigen Node.js Version 20 oder neuer, installiert auf Ihrem Computer.

1. Abhängigkeiten installieren

Öffnen Sie ein Terminal in diesem Ordner und führen Sie aus:

npm install

2. Browser-Unterstützung installieren

Research Friend verwendet Playwright, um einen Webbrowser zu steuern. Nach der Installation der Abhängigkeiten müssen Sie den Browser installieren:

npx playwright install chromium

Dies lädt eine Kopie von Chromium herunter, die Playwright verwenden wird. Sie ist getrennt von allen Browsern, die Sie bereits installiert haben.

3. Server starten

node src/index.js

Der Server kommuniziert über stdio (Standardeingabe/-ausgabe), worüber MCP-Clients sich mit ihm verbinden.

Hinzufügen zu Ihrem MCP-Client

Wie Sie Research Friend hinzufügen, hängt davon ab, welchen MCP-Client Sie verwenden. Hier ist ein allgemeines Beispiel, wie die Konfiguration aussehen könnte:

[[mcp_servers]]
id = "research-friend"
command = "node"
args = ["/path/to/mcp-research-friend/src"]
transport = "stdio"

Ersetzen Sie /path/to/mcp-research-friend durch den tatsächlichen Pfad zu diesem Ordner auf Ihrem Computer.

Werkzeuge

Web-Werkzeuge

friendly_web_fetch

Ruft eine Webseite ab und gibt ihren Inhalt zurück. Standardmäßig wird Markdown mit erhaltenen Links zurückgegeben – ideal für LLMs. Verwendet Readability, um den Hauptinhalt zu extrahieren (Navigation, Werbung usw. werden entfernt). Für PDFs, Paginierung oder die Suche innerhalb von Inhalten verwenden Sie stattdessen friendly_web_extract.

Parameter:

  • url (erforderlich) – Die abzurufende Webadresse
  • outputFormat – Ausgabeformat: markdown (Standard), text oder html
  • waitMs – Zusätzliche Wartezeit nach dem Laden der Seite, falls Inhalte langsam erscheinen
  • timeoutMs – Wie lange gewartet werden soll, bevor aufgegeben wird (Standard: 15 Sekunden)
  • maxChars – Maximale Menge an zurückzugebendem Inhalt (Standard: 40.000 Zeichen)
  • includeHtml – Auf true setzen, um auch das rohe HTML zusammen mit dem Inhalt zurückzugeben
  • headless – Auf false setzen, um das Browserfenster zu sehen (nützlich zum Debuggen)

Rückgaben:

  • url – Die angeforderte URL
  • finalUrl – Die URL nach etwaigen Weiterleitungen
  • title – Der Seitentitel
  • content – Der extrahierte Inhalt (im angeforderten Format)
  • html – Rohes HTML (nur wenn includeHtml wahr ist)
  • meta – Seiten-Metadaten (Beschreibung, Autor, Veröffentlichungszeit usw.)
  • fetchedAt – ISO-Zeitstempel, wann die Seite abgerufen wurde
  • truncated – Ob der Inhalt gekürzt wurde, um in maxChars zu passen

friendly_search

Durchsucht das Web und gibt eine Liste von Ergebnissen zurück.

Parameter:

  • query (erforderlich) – Wonach gesucht werden soll
  • engine – Welche Suchmaschine verwendet werden soll (duckduckgo oder google)
  • maxResults – Wie viele Ergebnisse zurückgegeben werden sollen (Standard: 10, Maximum: 50)
  • timeoutMs – Wie lange gewartet werden soll, bevor aufgegeben wird (Standard: 15 Sekunden)
  • headless – Auf false setzen, um das Browserfenster zu sehen

Rückgaben:

  • query – Die verwendete Suchanfrage
  • engine – Welche Suchmaschine verwendet wurde
  • results – Array von Ergebnissen, jedes mit title, url und snippet
  • searchedAt – ISO-Zeitstempel, wann die Suche durchgeführt wurde
  • fallback_result_html – Rohes HTML der Seite (nur enthalten, wenn keine Ergebnisse gefunden wurden)
  • debug_info – Diagnoseinformationen zum Suchversuch

CAPTCHA-Behandlung: Wenn ein CAPTCHA im Headless-Modus erkannt wird, wiederholt das Werkzeug den Versuch automatisch mit einem sichtbaren Browserfenster. Dies gibt Ihnen die Möglichkeit, das CAPTCHA manuell zu lösen. Das Feld debug_info.retried zeigt an, ob dieser Fallback verwendet wurde.

friendly_web_extract

Extrahiert Inhalt von einer URL. Erkennt automatisch, ob die URL auf ein PDF oder eine Webseite verweist, und behandelt beides entsprechend.

Parameter:

  • url (erforderlich) – Die abzurufende URL (PDF oder Webseite)
  • maxChars – Maximale Menge an zurückzugebendem Text (Standard: 40.000 Zeichen)
  • offset – Zeichenposition, ab der begonnen werden soll (Standard: 0). Verwenden Sie dies, um durch große Inhalte zu blättern.
  • search – Suche nach einem Ausdruck und gib Treffer mit umgebendem Kontext anstelle des vollständigen Inhalts zurück
  • contextChars – Zeichen Kontext um jeden Suchtreffer (Standard: 200)
  • waitMs – Zusätzliche Wartezeit nach dem Laden der Seite für dynamische Inhalte (nur Webseiten)
  • timeoutMs – Wie lange gewartet werden soll, bevor aufgegeben wird (Standard: 15 Sekunden, nur Webseiten)
  • headless – Auf false setzen, um das Browserfenster zu sehen (nur Webseiten)

Rückgaben (Normalmodus):

  • url – Die angeforderte URL
  • contentType – Entweder pdf oder html
  • title – Der Seiten-/Dokumenttitel
  • author – Der PDF-Autor (nur PDFs, falls verfügbar)
  • creationDate – Wann das PDF erstellt wurde (nur PDFs, falls verfügbar)
  • pageCount – Anzahl der Seiten (nur PDFs)
  • totalChars – Gesamtzeichen (mit offset zum Paginieren verwenden)
  • offset – Der verwendete Offset
  • content – Der extrahierte Textinhalt
  • fetchedAt – ISO-Zeitstempel
  • truncated – Ob nach diesem Abschnitt noch mehr Inhalt folgt

Rückgaben (Suchmodus):

  • url, contentType, title, totalChars, fetchedAt – Wie oben
  • search – Der verwendete Suchausdruck
  • matchCount – Anzahl der gefundenen Treffer
  • matches – Array von Treffern, jedes mit position, context, prefix und suffix

friendly_web_ask

Ruft eine URL (PDF oder Webseite) ab und lässt ein LLM Fragen dazu beantworten. Erkennt automatisch den Inhaltstyp. Das Dokument wird in einem separaten Kontext verarbeitet, sodass Ihre Hauptkonversation kompakt bleibt.

Parameter:

  • url (erforderlich) – Die abzurufende URL (PDF oder Webseite)
  • ask (erforderlich) – Frage oder Anweisung für das LLM (zusammenfassen, Informationen extrahieren, Fragen beantworten usw.)
  • askMaxInputTokens – Maximale Eingabe-Tokens pro LLM-Aufruf (Standard: 150.000)
  • askMaxOutputTokens – Maximale Ausgabe-Tokens pro LLM-Aufruf (Standard: 4.096)
  • askTimeout – Timeout in Millisekunden (Standard: 300.000 = 5 Minuten)
  • askSplitAndSynthesize – Für große Dokumente: in Abschnitte aufteilen, jeden verarbeiten, dann Ergebnisse synthetisieren (Standard: false). Warnung: verbraucht viele Tokens.
  • waitMs – Zusätzliche Wartezeit nach dem Laden der Seite für dynamische Inhalte (nur Webseiten)
  • timeoutMs – Wie lange gewartet werden soll, bevor aufgegeben wird (Standard: 15 Sekunden, nur Webseiten)
  • headless – Auf false setzen, um das Browserfenster zu sehen (nur Webseiten)

Rückgaben:

  • url – Die angeforderte URL
  • contentType – Entweder pdf oder html
  • title – Der Seiten-/Dokumenttitel
  • totalChars – Gesamtzeichen im Dokument
  • ask – Die gegebene Anweisung
  • answer – Die Antwort des LLM
  • model – Das Modell, das die Antwort generiert hat
  • chunksProcessed – Anzahl der verarbeiteten Abschnitte (1 für kleine Dokumente, mehr bei Verwendung von askSplitAndSynthesize)
  • fetchedAt – ISO-Zeitstempel

Fragemodus verwendet MCP-Sampling, um ein LLM das Dokument mit einer beliebigen Anweisung verarbeiten zu lassen. Dies ist nützlich für:

  • Große Dokumente, die den Kontext überfordern würden
  • Token-Kosten in der Hauptkonversation niedrig zu halten

Wenn askSplitAndSynthesize aktiviert ist, werden Dokumente, die askMaxInputTokens überschreiten, automatisch in überlappende Abschnitte aufgeteilt. Jeder Abschnitt wird separat verarbeitet und die Ergebnisse werden zu einer einzigen kohärenten Antwort synthetisiert. Die endgültige Antwort wird in derselben Sprache wie Ihre Anfrage bereitgestellt, unabhängig von der Sprache des Dokuments.

Dokumentenspeicher

Der Speicher ist eine lokale, durchsuchbare Bibliothek von Dokumenten. Er unterstützt PDFs, HTML-Dateien und Klartext (Markdown/TXT). Wenn Sie ein Dokument hinzufügen, speichert Research Friend die Originaldatei, extrahiert Text (für PDFs/HTML) und speichert Metadaten in einer lokalen Datenbank. Suchvorgänge verwenden im Hintergrund ripgrep für schnellen, ausdrucksbewussten Abgleich.

Speicherort

Der Speicher befindet sich unter ~/.research-friend/:

  • inbox/ – Dateien hier ablegen, um sie zu verarbeiten
  • store/ – Organisierte Dokumentenablage und extrahierter Text
  • stash.db – Metadaten-Datenbank

Unterstützte Dateitypen

  • PDF: .pdf (Text extrahiert)
  • HTML: .html, .htm (Text extrahiert)
  • Markdown: .md, .markdown (als Klartext gespeichert)
  • Text: .txt (als Klartext gespeichert)

Speicher-Werkzeuge

stash_open_inbox

Öffnet den Speicher-Posteingangsordner in Ihrem Dateimanager für einfacheres Drag-and-Drop.

Rückgaben:

  • opened – Ob die Anfrage zum Öffnen des Ordners gesendet wurde
  • inboxPath – Absoluter Pfad zum Posteingang
  • command – Verwendeter Betriebssystembefehl
  • args – Verwendete Befehlsargumente

stash_process_inbox

Verarbeitet Dateien in inbox/, klassifiziert sie in Themen, extrahiert Text und speichert die Ergebnisse. Bei langen Dokumenten verwendet die Klassifizierung Stichprobenabschnitte (Anfang/Mitte/Ende plus einige zufällige Abschnitte), um die Themengenauigkeit zu verbessern.

Rückgaben:

  • processed – Array der erfolgreich verarbeiteten Dateinamen
  • errors – Aufgetretene Fehler
  • documents – Array der erstellten Dokumentdatensätze

reindex_stash

Generiert Zusammenfassungen neu, weist Themen neu zu und aktualisiert die gespeicherten Metadaten für abgelegte Dokumente. Wenn ids weggelassen oder leer ist, werden alle Dokumente neu indiziert.

Parameter:

  • ids – Neu zu indizierende Dokument-IDs (optional)

Rückgaben:

  • reindexed – Neu indizierte Dokument-IDs
  • errors – Aufgetretene Fehler
  • documents – Array der aktualisierten Dokumentdatensätze

stash_list

Listet Dokumente im Speicher auf.

Parameter:

  • topic – Auf ein Thema filtern (optional)
  • limit – Maximale Ergebnisse (Standard: 50)
  • offset – Paginierungs-Offset (Standard: 0)

Rückgaben:

  • typeall oder topic
  • totalDocuments – Gesamtdokumente (nur wenn type all ist)
  • count – Nach Paginierung zurückgegebene Ergebnisse
  • offset – Verwendeter Paginierungs-Offset
  • limit – Verwendetes Paginierungs-Limit
  • topics – Zusammenfassung der bekannten Themen und Dokumentanzahlen
  • documents – Dokumentliste mit Metadaten (enthält isPrimary beim Auflisten eines Themas)

stash_search

Durchsucht Dateinamen und Inhalte im gesamten Speicher. Alle Suchbegriffe müssen vorhanden sein (UND-Logik). Dateinamen-Treffer werden zuerst aufgelistet. Verwenden Sie Anführungszeichen für exakte Ausdrücke.

Parameter:

  • query (erforderlich) – Suchbegriffe. Verwenden Sie Anführungszeichen für Ausdrücke: "sparkling wine"
  • topic – Auf ein Thema filtern (optional)
  • ids – Auf bestimmte Dokument-IDs filtern (optional)
  • limit – Maximale zurückzugebende Dokumente (Standard: 20)
  • offset – Paginierungs-Offset (Standard: 0)
  • maxMatchesPerDoc – Maximale Treffer pro Dokument (Standard: 50)
  • context – Kontextzeilen um jeden Treffer (Standard: 1, max: 5). Steuert sowohl, wie nah Begriffe erscheinen müssen, um zu treffen, als auch, wie viel umgebender Text zurückgegeben wird. Rückgabe:
  • totalMatches – Gesamtzahl der vor der Paginierung gefundenen Dokumente
  • count – Nach der Paginierung zurückgegebene Ergebnisse
  • results – Array von Dokumenten, jeweils mit:
    • id, filename, fileType, summary, charCount, createdAt
    • matchTypefilename, content oder filename+content
    • matches – Array von { line, context } für jede Fundstelle

Verwenden Sie die line-Werte mit stash_extract, um direkt zu den Fundstellen zu springen.

stash_extract

Extrahiert Inhalte aus einem zwischengespeicherten Dokument zum Lesen. Verwenden Sie Zeilennummern aus den stash_search-Ergebnissen, um direkt zu Treffern zu springen.

Parameter:

  • id (erforderlich) – Dokument-ID aus stash_list/stash_search
  • maxChars – Maximale Textmenge, die zurückgegeben wird (Standard: 40.000 Zeichen)
  • offset – Zeichenposition, ab der begonnen wird (schließt sich mit line gegenseitig aus)
  • line – Zeilennummer, ab der begonnen wird (schließt sich mit offset gegenseitig aus)

Rückgabe:

  • id, filename, fileType, summary – Dokument-Metadaten
  • totalChars – Gesamtzahl der Zeichen im Dokument
  • offset – Zeichen-Offset (enthalten, wenn line als Referenz verwendet wird)
  • line – Zeilennummer (nur wenn der Parameter line verwendet wurde)
  • content – Der extrahierte Textinhalt
  • truncated – Ob nach diesem Abschnitt noch mehr Inhalt folgt

stash_ask

Lässt ein LLM Fragen zu einem zwischengespeicherten Dokument beantworten. Das Dokument wird in einem separaten Kontext verarbeitet, sodass Ihre Hauptkonversation kompakt bleibt.

Parameter:

  • id (erforderlich) – Dokument-ID aus stash_list/stash_search
  • ask (erforderlich) – Frage oder Anweisung an das LLM
  • askMaxInputTokens – Maximale Eingabe-Tokens pro LLM-Aufruf (Standard: 150.000)
  • askMaxOutputTokens – Maximale Ausgabe-Tokens pro LLM-Aufruf (Standard: 4.096)
  • askTimeout – Timeout in Millisekunden (Standard: 300.000 = 5 Minuten)
  • askSplitAndSynthesize – Für große Dokumente: in Abschnitte aufteilen, jeden verarbeiten und dann Ergebnisse zusammenführen (Standard: false)

Rückgabe:

  • id, filename, fileType, summary – Dokument-Metadaten
  • totalChars – Gesamtzahl der Zeichen im Dokument
  • ask – Die gegebene Anweisung
  • answer – Die Antwort des LLM
  • model – Das Modell, das die Antwort generiert hat
  • chunksProcessed – Anzahl der verarbeiteten Abschnitte

Typischer Ablauf

  1. Dateien in ~/.research-friend/inbox/ ablegen
  2. stash_process_inbox ausführen
  3. stash_list verwenden, um Themen zu durchsuchen
  4. stash_search verwenden, um relevante Dokumente zu finden
  5. stash_extract verwenden, um ein bestimmtes Dokument zu lesen, oder stash_ask, um Fragen dazu zu stellen

Fehlerbehebung

„Browser unerwartet geschlossen“ oder ähnliche Fehler

Versuchen Sie, den Browser neu zu installieren:

npx playwright install chromium --force

Unter Linux benötigen Sie möglicherweise auch Systemabhängigkeiten:

npx playwright install-deps chromium

Der Server startet nicht

Stellen Sie sicher, dass Sie Node.js 20 oder neuer verwenden:

node --version

Falls Ihre Version älter ist, besuchen Sie nodejs.org, um eine neuere herunterzuladen.

Lizenz

MIT