Skip to main content
Glama
krahnikblis

librechat-search-mcp

by krahnikblis

librechat-search-mcp

Dieses Projekt ermöglicht ein „All-Message-Gedächtnis“, indem es die Search messages-Funktion von LibreChat auf MCP-Tools für proaktive oder bedarfsgesteuerte Nutzung erweitert.

Related MCP server: Claw Recall

Zusammenfassung

Ein eingeschränkter, LibreChat-spezifischer MCP-Server, der auf dem generischen meilisearch-mcp basiert, um den von LibreChat indizierten Nachrichtenverlauf zu durchsuchen. Er soll die native memory-Funktion/-Fähigkeit ergänzen und dabei Kosten und Kontextverlust sparen, wenn zusätzlich die optionale memory.agent von LibreChat deaktiviert wird. Er nutzt Streamable HTTP, gehostet in einem eigenen Container im Docker-Compose-Netzwerk von LibreChat – also NICHT für Nicht-Docker-Hosting-/Deployment-Setups implementiert –, leitet den effektiven Benutzer aus dem Pro-Request-User-Id-Header von LibreChat ab und wendet den Benutzerfilter serverseitig an. Zusätzliche Filter nach der Suche helfen, die Ergebnisse einzugrenzen, bevor sie an den Agenten zurückgegeben werden. Der Server ist bewusst so ausgelegt, dass diese Fähigkeiten auf den Umfang von Benutzern und Admins beschränkt bleiben, die sie bereits haben, und weist bewusst auf potenzielle Risiken hin, wo Datenschutz eine Rolle spielt. Er ist in erster Linie für Szenarien gedacht, in denen den Benutzern ausdrücklich „keine Erwartung an Privatsphäre“ kommuniziert wird.

Motivation

Die in LibreChat integrierte Memory-Funktion ist brauchbar für ein notizblockartiges Kontextgedächtnis, hat aber einige Kosten und Nebenwirkungen:

  • Kleinere Modelle (z. B. Gemma-4-12B) interpretieren die Erinnerungen in neuen Chats als wichtigen Prompt-Kontext, was zu merkwürdigen Übertragungen aus anderen Unterhaltungen führt.

  • Erinnerungen werden vom standardmäßigen LibreChat-Memory-Agenten vollständig überschrieben, nicht angehängt/kombiniert, wodurch bewusst erstellte Erinnerungen verloren gehen.

  • Der automatische Memory-Agent läuft bei jeder Benutzernachricht und verdoppelt die Eingabe-Token-Kosten (ja, du verwendest wahrscheinlich ein günstigeres Modell für deinen Memory-Agenten ...).

  • Cache-Schreibkosten – mein Auslöser, dieses Projekt endlich zu bauen: Jedes Mal, wenn der Memory-Agent eine Erinnerung anpasst, wird der gesamte Unterhaltungs-Cache neu geschrieben (bei Verwendung des OpenAI-Cachings), weil die Erinnerungen in die ersten Objekte des Threadverlaufs eingefügt werden.

    • Einige GPT-5.6-Terra-Unterhaltungen haben mich bis zu 3 US-Dollar pro Stück gekostet, und bei der Überprüfung meiner nutzung entdeckte ich, dass die unnötig wiederholten Cache-Writes der größte Faktor waren.

Gleichzeitig wollte ich, dass meine Agenten stärker den Gesamtverlauf im Blick haben, so wie ChatGPT das kann. Da ich einfach in das Search messages-Feld von LibreChat tippen kann, dachte ich mir: „Warum kann man dem Agenten diese Fähigkeit nicht geben?“ Über vollständige Nachrichten stehen viel reichhaltigere Informationen zur Verfügung als über die von günstigen Agenten zusammengefassten Erinnerungen, und mit etwas rekursiver Suche könnte man viele Verbindungen zwischen viele Unterhaltungen herstellen. Meine private Implementierung zeigt das bereits; die Umsetzung bei der Arbeit innerhalb meiner Gruppe bleibt noch abzuwarten …

MCP-Tools

Der Server stellt LibreChat-spezifische Versionen der schreibgeschützten Tools des Upstream-Projekts meilisearch-mcp bereuf und verwirft dessen Schreib-Tools.

  • search_messages: die indizierten Nachrichten des Aufrufers proaktiv auf Kontinuität hin durchsuchen; optional eingrenzen über bekannte Unterhaltungs-ID, Absender und Ergebnislimit. Gibt Nachrichten-ID, Unterhaltungs-ID, Absender und Text zurück.

  • search_conversations: die indizierten Unterhaltungen des Aufrufers proaktiv nach Titel durchsuchen; gibt Unterhaltungs-ID, Titel und Tags für Folgen von Nachrichten.

  • admin_search_messages: explizit angeforderte, autorisierte Suche über die Nachrichten eines bestimmten Benutzers; gibt den Zielbenutzer plus die dokumentierten Nachrichtenfelder zurück.

  • admin_search_conversations: explizit angeforderte, autorisierte Suche über die Unterhaltungen eines bestimmten Benutzers der Titel; gibt den Zielbenutzer plus Unterhaltungs-ID, Titel und Tags zurück.

  • health-check: den konfigurierten Meilisearch-Verfügbarkeitsstatus lesen.

  • get-version: die Meilisearch-Versionsinformationen lesen.

  • get-stats: die Datenbankweiten Meilisearch-Statistiken lesen.

  • get-health-status: strukturierten Gesundheits- und Indexstatus lesen.

  • get-system-info: Meilisearch-Systeminformationen lesen.

  • get-index-metrics: die Metriken für einen bekannten Index lesen (indexUid erforderlich).

    • NOCH NICHT IMPLEMENTIERT – gibt in Standard-LibreChat-Setups einen Fehler zurück. Die zurückgegebene fieldDistribution könnte für die künftige Erstellung eines thematischen Graphen für vernetzte Nachrichtensuchen nützlich sein, aber in LibreChats neuester Meili-Version ist dieses Feature experimentell und muss aktiviert/erstellt werden.

Benutzerkreis

Normale Suchen sind durch den Dienst anfrage- und aufrufergebunden und akzeptieren keine BenutzerZielnen oder einen rohen Filter. Administrative Suchen erfordern eine Autorisierung durch den Dienst und normalerweise einen Zielbenutzer; bei fehlgeschlagener Autorisierung nicht erneut versuchen oder herumprobieren. Die aktuelle Implementierung meldet einen generischen Suchfehler. Alle Tools sind schreibbegrenzt und geben nur die oben dokumentierten Felder zurück.

Anfragebezogenes Tool-Verhalten

Was mir von Anfang an nicht klar war: Wie sich die Anfragebezogenheit (d. h. die Verwendung von Nachrichten- oder Unterhaltungs-IDs im MCP-Header) auf die UX auswirkt. Der MCP-Server ist insgesamt für die Auswahl sichtbar, aber seine Tools sind es nicht – das heißt, du kannst die Admin-Tools für einen benutzungsorientierter Agenten nicht abwählen (allerdings gibt es eine gewisse Dynamik, wie dieser Server seine Tools je nach Benutzerzugehörigkeit präsentiert). Im Idealfall könnten wir Serververbindungs-Kopien getrennt von den Tool-Header konfigurieren. Ich verfolge die verschiedenen MCP-Bugs/PRs in LibreChat, um besser zu verstehen, welche Anpassungen ich für eine bessere Eigenbarkeit vornehmen kann.

Bekannte Probleme

Im aktuellen Projekt:

  • Logs sind zu primitiv für Fehlersuche (Anfrageparameter und Antwortmetriken hinzufügen; optional Fehler als JSON ablegen)

  • Tool-Fehler sind nichtssagend (anfangs beabsichtigt, für mehr Datenschutz; der Agent braucht mehr Kontext zur Selbstkorrektur

  • Verwendung von search_messages mit conversationId-Filter schlägt gelegentlich fehl? (könnte mit Verbindung/Threading/Async zusammenhängen; TODO: conversationId als filterbares Feld ergänzen)

  • get-index-metrics verlangt eine experimentelle Funktionsaktivierung (TODO: testen und erkunden)

  • Dokumentation und Code enthalten Alten/Dev-Artefakte und Inkonsistenzen

  • Die Benutzer-ID für gezielte Admin-Suchen ist schwer zu bekommen (TODO: PeoplePicker-API untersuchen, um auf Handle oder Name+Initiale abzubilden)

Integration/Aktivierungseffekte:

  • Tool-Auswahl nicht möglich (wegen anfragebezogener Header)

  • Schneller Tool-Einsatz in einem Unter-Agenten erzeugt Fehlerantworten (Threading und async Funktionen benötigen eine genauere Betrachtung)

  • Wiederholtes Suchen/Besprechen historischer Themen verwässert diese in künftigen Suchen

  • Garupierung von Unterhaltungen ist umständlich und potenziell token-teuer (TODO: Funktion oder Feature ergänzen, die unterhaltungszusammenführende Statistiken über Nachrichtensuchen liefert)

  • Seltene Suchszenarien teuren (TODO: serverseitige Gruppierung, Stichwort-/Themengraph, Multi-Such-Union/Intersection/Exclude-Operationen, Dedup, Sortierung)

Sicherheitsmodell

Für dieses Tool gilt die Grundannahme, dass die LibreChat-Betriebsinstanz Single-Tenant und mit einer einzigen Richtlinie betrieben wird und keine sicherheitspezifischen Modelle oder Provider implementiert!

Die Tools besitzen eine einfache Benutzer-Zugangssperre und einen potenziell großen Admin-Bereich:

  • Normale Tools: search_messages und search_conversations durchsuchen immer nur den Benutzer des Auftrifers. Das Modell kann weder user noch den einen rohen Meilisearch-Filter angeben.

  • Admin-Tools: admin_search_messages und admin_search_conversations erfordern, dass der User-Id des Aufrufers exakt mit einem Eintrag in MEIME_MCP_ADMINS übereinstimmt. Das Ziel-user ist erforderlich, außer es ist MEILI_MCP_ADMIN_SCOPE_ALL=USER=true.

  • Der MCP-Dienst erhält einen eingeschränkten, schreibgeschützten Meilisearch-Schlüssel über MEILI_MCP_KEY; verwende dem Meilisearch-Master-Key niemals oder gib ihn niemals weiter.

  • Die Ergebnisse sind schema-beschränkt. Normale Ergebnisse enthalten nur messageId, conversationId, sender und text; Unterhaltungsergebnisse nur conversationId, title und tags. Admin-Auswertungen enthalten zusätzlich den ausgewählten user.

  • Fehlende, leere oder fehlerhafte Identität schlägt abweisend fehl. Autorisierungsfehler sind unterschiedlich generisch und Geheimnisse werden nie zurückgegeben.

Der abgerufene Text ist exakt der Text, den LibreChat indiziert hat. Je nach Indexer und Bereitstellung können darunter Assistenzausgaben, nuancesartige Texte oder Tool-Spuren sein. Dieser MCP-Server kann Inhalte nicht wiedergewinnen, die LibreChat nicht in einem Index hat; unberücksichtigen Sie Suchergebnisse als potenziell sensible Audit-Daten.

SIEHE SECURITY.md FÜR WEITERE VORSICHTSMASSNAHMEN UND WARNUNGEN!!!

Verantwortungsvoller Umgang

Ich informiere meine Benutzer im Unternehmen bereits, dass ich und die IT-SecOps die Fähigkeit einer Daten-/Verlaufseinsicht haben – „keine Erwartung an Privatsphäre“. Ich gehe davon aus, du würdest das in deiner Bereitstellung ähnlich handhaben, wenn es da für dich zutrifft – oder dieses Tool nicht in einem Szenario implementierst, in dem es Richtlinien verletzen könnte. Dieses Tool macht es mir nur leichter weiterzugeben, was ich deutlich tun kann (gegenüber MongoDB-Tools oder Meili-CLI), und gleichzeitig den Verlauf von Anbieter Anbieter verfügbar zu machen / Modell Modell Agenten zu Agenten. In meinen Betriebsinsätze noch kein Problem – noch –, weil ich keine privaten Modelle für sichere Inhalte implementiert habe.

LibreChat-Setup

Kopiere oder überführe diese example-Dateien in das ComposeProjekt von LibreChat und trage deine konkreten Schlüssel/IDs/Konfigurationen ein:

  • librechat-search-mcp/librechat.yaml.example: Führe mcpSettings und mcpServers in die bestehende librechat.yaml-Datei می. Beachte, dass Header-Zuommungen wie {{LIBRECHAT_USER_}]}} meiner Seite nicht verändert werden dürfen; LibreChat ersetzt sie pro Anfrage – sie gehören zum Sicherheitsmodell und zur Filterfunktion.

    • Empfohlen, wenn du meiner Motivation für deine Betrieb zustimmst: Deaktiviere in librechat.yaml den Memory-Agenten so lange, bis zukünftigen LibreChat-Versionen die Auswirkungen auf Token-Kosten und Verlaufs-Pollution ändern.

    • Hinweis: Neuere LibreChat-Änderungen haben das Memory-Tool-Verhalten auf eine explizite Opt-in-Einstellung unter endpoints.agents.capabilities umgestellt – fügt dort „memory“ hinzu, wenn du möchtest, dass der Agent auf Targeting Erinnerungen schreiben kann.

  • librechat-search-mcp/docker-compose.override.on : Führe den librechat-search-mcp-Dienst in das bestehende Composer-Code ein. Er ist nur intern zugänglich: Er hat expose: 8000, keine ports und ist im default Compose-Netzwerk.

  • librechat-search-mcp/.env.example: Füge diese Schlüssel deiner wichtigsten Haupt-.env-. Hinzu und ersetze nur die markierten Platzhalter. Ich empfehle, sie direkt unter dem aktuellen Abschnitt Search wäre.

Die MCP-URL ist http://librechat-search-mcp:8000/mcp. Der MCP-sichtbare Servername bleibt chat-search, damit ist für Menschen verständlich ist. Wenn der E-Instanz private MCP-Ziele blockiert, behalte die Einträge allowedAddresses/allowedDomains aus librechat.yaml.example. VORSCHTIG: Ein Nicht-”empty ” domain whitelist can affect other MCP servers, same intentional merge.

MEILI_HOST_PORT=7700 ist die Host-/Compose-Bridge-Variable, die von der umliegenden LibreChat-Betriebs des verwendet wird. Der MCP-Container selbst muss die Compose-Service-URL http://meilisearch:${MEILI_HOST_PORT} verwenden (den Beispiel das überraschende generiert); LibreChats bestehende sichere MEILI_HOST=http://0.0.0.0:7700 ist eine gesonderte, nach außen gerichtete Einstellung und sollte nicht leichtfertig gewechselt werden.

Eigene (Admin-)Benutzer-ID zur Klarstellung finden

Die Benutzer-IDs für MEILI_MCP_ADMINS kannst du mit jeder der folgenden Methoden herausfinden (in Reihenfolge nach der üblichen Ausführlichkeit):

  • in der Browser-UI:

  1. Öffnen Sie die Inspektor-/Entwicklertools (Strg+Umschalt+I) und wählen Sie den Tab „Netzwerk“ aus;

  2. Wählen Sie in der Konversationsliste des Chat-Verlaufs eine frühere Konversation aus (möglicherweise müssen Sie eine ältere auswählen, die sich nicht im Browser-Cache befindet);

  3. Der erste im Netzwerk-Tab aufgezeichnete API-Aufruf lädt die Konversationskopfzeilendaten in den Untertab Response, der Folgendes enthält:

    • user - dieser Wert ist Ihre ID (dieses Feld wird verwendet, um Suchen innerhalb des Servers zu filtern, oder als Parameter target-user für die admin_-Tools) - kopieren Sie diesen (und bitten Sie andere von Ihnen gewählte Administratoren/Berechtigte, Ihnen denselben Wert zu nennen) in die .env-Datei- als MEILI_MCP_ADMINS [nur mit Kommas getrennte Liste];

    • conversationId - dies ist dieselbe ID, die in den Parametern für die search_-MCP-Tools verwendet wird, und es ist bemerkenswert, dass sie mit der URL der Konversation übereinstimmt: http://localhost:3080/c/{conversationId};

  4. bemerkenswert an der Funktionsweise dieses Projekts - der 3. API-Aufruf enthält die Nachrichtenliste dieser Konversation, ähnlich wie die Struktur, mit der Meilisearch sie indexiert; dieses Projekt verwendet die folgenden Schlüssel:

    • conversationId - wird von diesem Projekt verwendet, um Ergebnisse der Suche im aktuellen Chat standardmäßig auszuschließen oder Treffer auf gezielte Nachrichten zu filtern

    • sender - „User“ oder Anzeigename des Agents

    • text - der Inhalt der Nachricht

    • zukünftige Forschungsüberlegungen für die gewünschte Funktionalität:

      • endpoint (oder in einem gezielteren Maße model) könnte zusammen mit einer Einstellung MEILI_MCP_CONSTRAIN_ENDPOINT=true als Filter verwendet werden (wenn private Modelle/Agenten von öffentlichen Provider-Modellen getrennt sind), um den Nachrichtensuchriff über Endpunkte zu unterbinden

      • parentMessageId ist bereits als Ergebnisfilter während der Tool-Nutzung über die dynamische Variable {{LIBRECHAT_BODY_PARENTMESSAGEID}} von LibreChat im Header des MCP-Transports integriert; ich habe vor, die Suchindizes daraufhin zu untersuchen, um eine gezielte Vorher/Nachher-Pufferung von Nachrichten um Suchtreffer zu erreichen, Ergebnisse deterministisch zu ordnen und Nachrichtenketten als Graphen darzustellen

      • content enthält Gedanken/Begründungen von Tool-Aufrufen (ich kann mich nicht erinnern, das im indexierten Inhalt zu sehen, wahrscheinlich aus gutem Grund – ein Nutzer, der den Nachrichtenverlauf durchsucht, erwartet vermutlich Treffer, bei denen der Titel oder der Nachrichtentext übereinstimmt, nicht datei- oder agenteninterne Interna)

      • attachments enthält Ergebnisse von Tool-Aufrufen (und möglicherweise RAG- und/oder hochgeladene Dateiinhalte) – ähnlich wie bei content erwarte ich nicht, dass dies indexiert wird

      • createdAt könnte als deterministischer zeitlicher Ordnungs- oder sogar Filterschlüssel verwendet werden (Meili liefert Treffer bereits in scheinbar zeitlicher Reihenfolge, dies könnte aber auch durch die Relevanzbewertung beeinflusst werden) – dies ist möglicherweise auch über die Meili-Indexdokument-Metadaten (den Zeitpunkt der Erstellung/Aktualisierung des Index) erreichbar, wenn auch mit einem leicht anderen Wert; sobald eine Neuindizierung durchgeführt wird, könnte dieser jedoch seinen gesamten Wert verlieren.

  • LibreChat-Container-Logs (docker compose logs api) unmittelbar nachdem Sie (als Admin-Benutzer) eine Aktion aus der LibreChat-Oberfläche ausführen (VORSICHT: nicht ratsam, wenn Sie viele gleichzeitige Benutzer haben und die Log-Ergebnisse nicht getrennt werden können, da hier KEINE Benutzernamen genannt werden)

  • die Tabelle users in Mongo Express untersuchen (wenn Sie das separat eingerichtet haben, ist die Nutzung der Benutzeroberfläche etwas einfacher)

  • die Tabelle users in der MongoDB untersuchen (für die folgenden Termin gilt unter Bash und PowerShell Entsprechendes; führen Sie die dafür sind vom LibreChat-Verzeichnis oder dem Verzeichnis aus, in dem sich Ihre docker-compose.yml befindet):

# open a shell terminal within the MongoDB container - this assumes the default LibreChat service name `mongodb`:
docker compose exec mongodb sh

# open a database shell terminal within the container's shell:
mongosh

# switch to the database used by LibreChat (see all with `show databases`):
use LibreChat

# display target user by `role` attribute == "ADMIN" (LibreChat also stores `email` and `username` which may be present/null depending on registration method):
db.users.find({role: "ADMIN"}).forEach(printjson)
# Alternatively, display the entire users collection (be careful with this if you have many users):
db.users.find().forEach(printjson)
# the hash string in the first key of returned JSONs is the `user` ID - assuming you've found yourself/chosen admins, grab just this hash value from the `ObjectId` construct:
# {
#   _id: ObjectId('derp7bfe19e9268da678derp'), #### <- in this dummy example, derp7bfe19e9268da678derp is my user ID to add to MEILI_MCP_ADMINS ####
#   name: 'krahnik blis',
#   username: 'krahnik',
#   email: 'krahnik@emailmenot.derp',
#   ...

# quit the mongosh terminal
quit

# exit the mongodb container shell terminal
exit

Generieren eines schreibgeschützten, berechtigten Schlüssels für den MCP-Server

Verwenden Sie NICHT den MEILI_MASTER_KEY von LibreChat als Ihren MEILI_MCP_KEY!

Das Repository enthält plattformübergreifende Helfer, um den API-Schlüssel in einem Befehl zu generieren und zu validieren. Sie greifen dabei auf den meilisearch-Container zu (der also laufen muss), erzeugen einen berechtigten Schlüssel, gebe den Schlüssel standardmäßig aus oder schreiben ihn optional ein eine lokale Datei und ändern nie die primäre .env von LibreChat. Die Datei-Ausgabemethode ist optional wird nur angenommen, wenn die Datei nicht bereits existiert und auch nur, wenn --force/-Force angegeben wird; erzeugte *.local.env-Dateien sind git-ignoriert und werden auf Plattformen, die dies unterstützen, mit restriktiven Berechtigungen angelegt.

Führen Sie vom LibreChat-Verzeichnis aus (nachdem Sie dieses Repo mit git clone hineingeklont haben):

bash:

# ensure the script is executable:
chmod +x librechat-search-mcp/scripts/generate-restricted-key.sh

# run the script in terminal mode:
./librechat-search-mcp/scripts/generate-restricted-key.sh
# OR, run it in file-output mode:
./librechat-search-mcp/scripts/generate-restricted-key.sh --output .librechat-search-mcp.local.env

PowerShell:

# run the script in terminal mode:
powershell.exe -ExecutionPolicy Bypass -File .\librechat-search-mcp\scripts\generate-restricted-key.ps1
# OR, run it in file-output mode:
powershell.exe -ExecutionPolicy Bypass -File .\librechat-search-mcp\scripts\generate-restricted-key.ps1 -Output .librechat-search-mcp.local.env

Die Ausgabe des Skripts enthält Validierungsstests für die Endpunktberechtigungen und eine Dummy-Löschprobe, um die Schreibgeschützten Berechtigungen zu gewährleisten; der schreibgeschützte, berechtigte Schlüssel wird am Ende ausgegeben oder in die Datei Ihrer Wahl geschrieben.

Das Skript enthält Prüfungen und Meldungen, die ich beim Debuggen verwendet habe. Ich habe sie für meinen need künftigen Seelenfrieden: du kannst sie auch so lassen:

[info] Working directory: /path/to/LibreChat
[info] Environment file: .env
[info] Meilisearch container: meilisearch
[info] Messages index: messages
[info] Conversations index: convos
[warning] MEILI_HOST used 0.0.0.0; using loopback for in-container requests.
[info] MEILI_HOST from .env: http://0.0.0.0:7700
[info] API URL used inside chat-meilisearch: http://127.0.0.1:7700
[info] MEILI_MASTER_KEY length: 32
[info] MEILI_MASTER_KEY SHA-256: d3907119a65e489d0202derp0ac65216a44derpb43bd8be71b7dderpb158ac67
[info] Testing Meilisearch connectivity from inside the container.
PASS  /health -> HTTP 200
[info] Testing the MEILI_MASTER_KEY read from .env.
PASS  .env master key accepted by /version
[info] Key contract payload: {"description":"LibreChat MCP search and read-only diagnostics","actions":["search","stats.get","metrics.get","indexes.get","settings.get","version"],"indexes":["messages","convos"],"expiresAt":null}
[info] Creating restricted key in chat-meilisearch.
[info] Restricted key created successfully.
[info] Generated key length: 64
[info] Validating read-only key contract.
PASS  /health -> HTTP 200
PASS  /version -> HTTP 200
PASS  /stats -> HTTP 200
FAIL  /metrics -> HTTP 400
		{"message":"Getting metrics requires enabling the `metrics` experimental feature. See https://github.com/meilisearch/product/discussions/625","code":"feature_not_enabled","type":"invalid_request","link":"https://docs.meilisearch.com/errors#feature_not_enabled"}
PASS  /indexes -> HTTP 200
PASS  /indexes/messages/settings -> HTTP 200
PASS  /indexes/convos/settings -> HTTP 200
[info] Testing that document deletion is rejected.
PASS  DELETE /indexes/messages/documents/__mcp_read_only_probe__ -> HTTP 403

Restricted key was created, but one or more validation checks failed:
- /metrics returned HTTP 400

The key will still be returned below. Do not deploy it until the failures are understood.
394ederp18e6299f7fddderpbb485b77be7bb1d0906b29ade8derpebaf65de43

^ in diesem Dummy-Beispiel ist 394ederp18e6299f7fdd8bb485b77be7bb1d0906b29ade8faf65de43 der Schlüssel, der als MEILI_MCP_KEY in der .env-Datei von LibreChat zu verwenden ist.

Erwartete FAIL-Meldung

Derzeit würde der /metrics-Endpunkt erwartungsgemäß fehlschlagen, da dies in der von LibreChat verwendeten Meilisearch-Version noch eine experimentelle Funktion ist; ich erforsche einen möglichen Nutzen und werde dieses Repository mit Aktivierungsanweisungen/-skripten aktualisieren, falls sich etwas Brauchbares ergibt. Dies bedeutet, dass das Tool get_index_metrics den in der obigen Beispiel-Skriptausgabe gezeigten Fehler zurückgibt, sofern Sie das Feature nicht selbst aktivieren.

Folgendes crus Sie manuell durchführen, was in den Skripten generate-restricted-key enthalten ist, falls Sie Ihre Implementierung angepasst haben oder Fehler auftreten (oder um die Skripte in aller Ausführlichkeit zu sehen):

Erstellen Sie einen dedizierten, schreibgeschützten Schlüssel für diesen Dienst. Sein exakt Aktionsvertrag:

  • search

  • stats.get

  • metrics.get

  • indexes.get

  • settings.get

  • version

Begrenzen Sie den Schlüssel auf die zwei konfigurierten Indizes (messages und convos oder Ihre konfigurierten Namen). Der globale Health-Endpunkt wird separat geprüft und erfordert keine schreibfähige Rolle. Setzen Sie expiresAt nur auf null, wenn ein nicht ablaufender Betriebschlüssel beabsichtigt ist, und speichern Sie den zurückgegebenen Schlüssel ausschließlich in MEILI_MCP_KEY.

Erstellen Sie den Schlüssel von einem Terminal im Container chat-meilisearch(docker export)/meilisearch(docker compose exec) aus, NICHT vom MCP-Container. Der Master-Schlüssel unten ist ein Platzhalter in der Befehlsverlauf und darf nicht in Prompts, Logs oder dieses Repository eingefügt werden:

curl -fsS -X POST "http://127.0.0.1:7700/keys" \
-H "Authorization: Bearer $MEILI_MASTER_KEY" \
-H "Content-Type: application/json" \
--data '{"description":"LibreChat MCP search and read-only diagnostics","actions":["search","stats.get","metrics.get","indexes.get","settings.get","version"],"indexes":["messages","convos"],"expiresAt":null}'

Fügen Sie keine documents.*, indexes.create, indexes.delete, settings.*-Schreibaktionen, keys.*, tasks.cancel oder * hinzu. Setzen Sie MEILI_MCP_KEY niemals gleich MEILI_MASTER_KEY.

Verifizieren Sie den Vertrag vor dem Einsatz des Schlüssels mit den folgenden Nur-Lese-Sonden. Sie müssen alle HTTP 200 zurückgeben (das JSON wird absichtlich verworfen):

auth=(-H "Authorization: Bearer $MEILI_MCP_KEY" -H "Accept: application/json")
for path in /health /version /stats /metrics /indexes /indexes/messages/settings /indexes/convos/settings; do
code=$(curl -sS -o /dev/null -w '%{http_code}' "${auth[@]}" "http://127.0.0.1:7700/$path")
test "$code" = 200 || { printf 'unexpected %s: HTTP %s\n' "$path" "$code" >&2; exit 1; }
done

Verifizieren Sie dann, dass eine harmlose Löschsonde abgelehnt wird. Verwenden Sie eine Sentinal-Dokument-ID, die nicht vorhanden ist; setzen Sie hier keine echte Dokument-ID ein:

code=$(curl -sS -o /dev/null -w '%{http_code}' -X DELETE \
"${auth[@]}" "http://127.0.0.1:7700/indexes/messages/documents/__mcp_read_only_probe__")
case "$code" in 401|403) ;; *) printf 'write permission was not rejected: HTTP %s\n' "$code" >&2; exit 1;; esac

Dieselbe Schlüssel wird von den MCP-Such- und Diagnosepfaden verwendet. Wenn irgendein Nur-Lese-Probe 401/403 zurückgibt, korrigieren Sie den Aktionskontrakt oder den Index-Scope des Schlüssels; verwenden Sie nicht den Master-Schlüssel oder erweiterte Berechtigungen, solange Schreibvorgänge nicht abgelehnt werden.

Zuviele Schlüssel und deren Löschung

VORSICHT: Mehrmaliges Ausführen des obigen Skripts könnte/der obigen Befehle erzeugt mehrere verwaiste Schlüssel in Meilisearch. Ich empfehle, das nicht zu tun. Aber wenn du es getan hast,

  • Entweder Sie legen eine Umgebungsvariable im Container mit Ihrem Master-Schlüssel an, oder Sie ersetzen die folgenden Instanzen von $MEILI_MASTER_KEY durch Ihren echten Schlüssel

  • Zuerst im Terminal innerhalb des primären Meilisearch-Containers alle Schlüssel auflisten: curl -sS -H "Authorization: Bearer $MEILI_MASTER_KEY" "http://127.0.0.1:7700/keys"

  • Suchen Sie die Schlüssel, die vom Erstellungsskript dieses Projekts gekennzeichnet wurden; das description heißt "LibreChat MCP search and read-only diagnostics"

  • Wählen Sie die Schlüssel aus, die nicht der gewünschte behalten werden sollen, und notieren Sie sich deren uids

  • Führen Sie für jeden zu löschenden Schlüssel aus (ersetzen Sie KEY_UID durch Ihren echten Wert): curl -sS -X DELETE -H "Authorization: Bearer $MEILI_MASTER_KEY" "http://127.0.0.1:7700/keys/KEY_UID"

Vollständige Befehlsfolge zur Einrichtung

Führen Sie die folgenden Befehle nacheinander interaktiv aus (otfte Windows-Benutzer können den cat/nano-Zeugs weglassen und Notepad/IDE verwenden):

cd LibreChat

# this creates the folder librechat-search-mcp WITHIN the LibreChat Compose scope:
git clone https://github.com/krahnikblis/librechat-search-mcp.git

# assuming the baseline LibreChat Compose services are already running, this creates & tests the restricted API key to set manually into the LibreChat .env MEILI_MCP_KEY:
# see above/README page for details and/or PowerShell equivalent commands
# either write to a local file:
./librechat-search-mcp/scripts/generate-restricted-key.sh --output .librechat-search-mcp.local.env
# OR print to the terminal:
./librechat-search-mcp/scripts/generate-restricted-key.sh

# print the example to copy as template:
cat librechat-search-mcp/.env.example
# copy or merge the example MEILI_MCP_ variables, including the key generated in the prior step into .env:
nano .env

# print the example to copy as template:
cat librechat-search-mcp/docker-compose.override.yml.example
# copy or merge the example configurations from the example into docker-compose.override.yml
nano docker-compose.override.yml

# print the example to copy as template:
cat librechat-search-mcp/librechat.yaml.example
# copy or merge the MCP [and optional agent capabilities and memory agent changes] configurations into librechat.yaml:
nano librechat.yaml

# validate config:
docker compose config

# stop existing services to recreate the LibreChat container with the MCP settings:
docker compose down

# build the image:
docker compose build librechat-search-mcp

# start all Compose services together:
docker compose up -d

# check logs for the new service:
docker compose logs --tail=100 librechat-search-mcp

Wenn alles gut gelaufen ist, wird dieser MCP in Ihrer LibreChat-Oberfläche verfügbar sein!

Umgebung und Indexvertrag

Erforderlich:

MEILI_MCP_KEY=<restricted-search-key>
MEILI_MCP_ADMINS=<admin,list>

Wichtige Werte in .env:

MEILI_HOST_PORT=7700
MEILI_MCP_PORT=8000
MEILI_MCP_MESSAGES_INDEX=messages
MEILI_MCP_CONVOS_INDEX=convos
MEILI_MCP_DEFAULT_LIMIT=5
MEILI_MCP_MAX_LIMIT=25
MEILI_MCP_ADMIN_SCOPE_ALL_USERS=false
MEILI_MCP_LOG_HOST_DIR=<local/log/path>

Beide Indizes müssen ein filterbares Attribut user enthalten (das bereits durch das LibreChat-Design vorhanden ist). Der von LibreChat erzeugte Nachrichten-Index hat kein filterbares conversationId; dieses und andere Parameter für die MCP-Suchtools werden serverseitig verarbeitet, bevor sie dem Aufrufer zurückgegeben werden.

Protokoll-Mount und -Persistenz

The container writes structured JSON-lines logs to /var/log/librechat-search-mcp. The Compose example binds that directory to ${MEILI_MCP_LOG_HOST_DIR}; its default is ./librechat-search-mcp/logs relative to the parent LibreChat Compose project. Log files are named librechat-search-mcp-YYYY-MM-DD.log, so recreating the container does not remove existing host logs. Keep this host directory private and back up or rotate it according to your deployment policy. To use the parent project's conventional log directory instead, set MEILI_MCP_LOG_HOST_DIR=./logs in the local .env; do not commit that populated file or generated logs.

Führen Sie den Schreib-Lese-Kontrakt-Check aus dem librechat-search-mcp-Container aus:

bash/PowerShell:

# The image's WORKDIR is /app and Compose injects MEILI_HOST plus the
# restricted MEILI_MCP_KEY into the service.
# the script was copied into the container as part of image build
docker compose exec -T -w /app librechat-search-mcp python scripts/check_index_contract.py

Das Skript ist im Image unter /app/scripts/check_index_contract.py hinterund wird. Es prüft Health, Indexnamen, Primärschlüssel, Filterbarkeit und sortierbare Attribute, ohne Einstellungen zu verändern oder den Schlüssel auszugeben. Exit-Status 0 und JSON "status": "pass" bedeutet, der Kontrakt ist bestanden; ein Nichtzero-Exit-Status bedeutet „Der gemeldete Health-Indexeinstellungen- oder Pflichtfilter-Check ist fehlgeschlagen. “ Es ist eine Diagnose, kein MCP-Bereitschaftsprobe. /health bestätigt nur, dass der MCP-Prozess lebt.

Aufrufer-Prompts und erwartetes Verhalten

Starten eine neue LibreChat-Konversation nach der Konfiguration und den laufenden Containern (z.B. in der MCP-Sidebar der UI, im Agent Builder und/oder im Dropdown MCP Server der Chatbox), damit das Modell die aktuelle Tool-Listen entdeckt. Tool-Beschreibungen sind so geschrieben, dass die standardmäßige Suche proaktive Nutzung fördert, während die admin_-Varianten „vom Benutzer initiiert zuerst verwendend“ erhalten. Ich werde diese Anweisungen in zukünftigen Updates wahrscheinlich noch justieren – ich habe bereits viel Nutzung, die entweder unnötig oder zu breit war...

HINWEIS: Kleine lokale Modelle müssen häufig den Namen des Tools unterscheidlich.

Normale Suche - explizite Anweisung:

Use search_conversations with query "deployment" and limit 3. Return only conversationId, title, and tags.
Use search_messages with query "deployment" and limit 3. Return only messageId, conversationId, sender, and text.

Beabsichtigte proaktive Nutzung der normalen Suche:

Hey remember that time we went wild designing a giant robotic grackle? I have some ideas about how to combine it with the ornithopter we discussed last week...

Der Agent soll proaktiv eine Suche mit einer suchabfrage wie zum Tulen „grackle ornithopter“ ausführen, und welche Sie passende Nachrichten aus mehreren Konversationen sehen.

Absichtliches Such-Agenten-Design:

Die Tool-Beschreibung selbst ausreichend allein mit Generischenatz und Tool-Beschreibungen, aber der eigentliche Spaß besteht im Aufbau eines spezifischen Agents und/oder eines informativen SKILL.md zur Formung eines merkwürdiges Verhaltens. Da die Ergebnisse dieser Tools vollständige Nachrichten sind, könnten die Token-Kosten dennoch erheblich sein; welche I probably an success.

Gezielter Admin-Audit (nur von einem erlaubten Konto aus):

Auf meiner To-do-Liste steht, die LibreChat-PeoplePicker-API zu recherchieren und zu sehen, wie beziehungsweise ob sie im Compose-Netzwerk verfügbar ist – idealerweise könnte ein Admin einen Benutzer über Handle oder Vornamen benennen, und wenn PeoplePicker aktiviert ist, könnte der Agent die interne ID nachschlagen (oder vielleicht den Agenten umgehen und die Nachschlage mit gezielter Filterung/Fehlerbehandlung direkt im Server ausführen, also etwa „2 ‚Sallys‘ gefunden: Meinten Sie Sally X. oder Sally Y.?“, ohne dem Agenten die E-Mail-Adresse oder den vollständigen Namen zu nennen)...

Use admin_search_messages for target user "<target-user-id>" with query "deployment" and limit 3.

Vorgesehener Admin-Umfang (Debugging, Prompt-/Konversationsoptimierung, kollektive Aufmerksamkeit)

What are our team members saying overall about our company's brand presense in the FIFA World Cup?
Let's review <target-user-id>'s conversation <conversationId> - what initial prompt and context would have elicited the final answer more directly?

Grenzprüfungen:

Try to search another user's messages by supplying a user argument and a raw filter. Do not bypass the tool schema; report whether the request was rejected and do not return cross-user results.
Find messages before and after this hit using createdAt, reconstruct surrounding messages through MongoDB, and sort by timestamp.

Letzteres wird nicht unterstützt: Dieses Projekt fügt keine Zeitstempel-Sortierung, kein Vorher-/Nachher-Abrufen, keine MongoDB/API-Suche, keine Rekonstruktion umgebender Nachrichten und keine beliebige Sortierung hinzu. Absender- und Konversationsfilter sind begrenzte Nachfilter, sodass weniger als das angeforderte Limit gültig ist und die ursprüngliche Meilisearch-Trefferreihenfolge erhalten bleibt.

Überprüfung

Lokale Prüfungen (aus dem Ordner dieses Projekts unter LibreChat):

python -m pytest tests/test_monitoring.py tests/test_m2_contract.py tests/test_m2_authorization.py tests/test_m1_search.py tests/test_server.py -q
python -m compileall -q src scripts tests
git diff --check

Deployment-Prüfungen erfordern weiterhin einen laufenden LibreChat/Meilisearch-Stack: überprüfen Sie die Tool-Erkennung in neuen Sitzungen, den User-Id-Header, die Berechtigungen eingeschränkter Schlüssel, den Index-Vertrag, keine Veröffentlichung von Host-Ports und gleichzeitige Anfragen von zwei Benutzern. Behandeln Sie lokale Unit-Tests nicht als Beleg für das Verhalten der realen Aufrufer.

Bereitstellung und Fehlerbehebung

  • Siehe docs/deployment.md für die unterstützte Docker-Compose-Grenze, die sichere Konfigurationsreihenfolge, Dienstidentitäten und den container_name-Trade-off.

  • Siehe docs/troubleshooting.md für häufige Fehler bei Compose, Schlüsselerzeugung, Netzwerk, MCP-Erkennung, Index und Protokollierung.

  • Siehe SECURITY.md, bevor Sie den Dienst aktivieren. Sie behandelt indexierte Inhalte, die Offenlegung gegenüber KI-Anbietern, Identität und Admin-Umfang, Logs/Aufbewahrung, eingeschränkte Schlüssel, Vertrauensgrenzen und das, was dieses Projekt nicht garantiert.

Entwicklung

Entwicklungs-, Planungs-, Audit- und interne Entscheidungsaufzeichnungen werden bewusst außerhalb des Produktions-Repositorys in workspace/project-context/librechat-search-mcp/development-records/ geführt.

Ich meine, wenn jemand beitragen möchte, eröffnet einfach eine Diskussion oder ein Issue oder was auch immer; ich könnte einen Contributing-Abschnitt hinzufügen und lernen, wie PRs funktionieren … aber wirklich ist das nur mein eigenes Hobby-Projekt, von dem ich weiß, dass es auch bei der Arbeit großen Wert haben wird, und der einfachste Weg von hier nach dort ist die Veröffentlichung auf GitHub. Das heißt: Ich baue gern Dinge und löse Probleme, aber ich übernehme keine Verpflichtung, mich mit all den Anliegen anderer zu beschäftigen, und werde wahrscheinlich das priorisieren, was entweder großartige Feature-Fähigkeiten freischaltet oder Lücken schließt.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables semantic search across conversation archives via MCP, allowing AI clients to retrieve relevant past conversations using vector embeddings and text fallback.
    0
    4
    ISC
  • A
    license
    Not graded
    quality
    F
    maintenance
    Persistent, searchable memory for AI agents. Enables agents to recover context after compaction by searching indexed conversations, emails, and files via MCP tools.
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to perform web searches with full content retrieval and multi-engine provenance, including trust scoring and local corpus persistence, via MCP integration.
    4
    2
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only

  • Multi-engine search for AI agents. Trust scoring, local corpus, MCP-native. Self-hostable, BYOK.

  • Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.

View all MCP Connectors

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/krahnikblis/librechat-search-mcp'

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