@discourse/mcp schlägt bei Installationen in Unterordnern fehl — Pfade mit führendem Slash entfernen den Site-Unterpfad
TL;DR
Bei Discourse-Instanzen, die unter einem Unterpfad bereitgestellt werden (z. B. https://example.com/forum), kann sich @discourse/mcp nicht verbinden, da bei jedem internen API-Aufruf der Unterpfad entfernt wird und stattdessen die falsche Host-Wurzel angesprochen wird. Dies unterbricht die Site-Validierung und jeden nachfolgenden Tool-Aufruf (search, read_topic usw.), nicht nur die --site-Validierung.
Umgebung
@discourse/mcpv0.2.7 (Stand zum Zeitpunkt des Schreibens)- Node über
npx -y @discourse/mcp@latest - Ziel: Discourse unter
https://<host>/forumgehostet (Installation in Unterordner hinter nginx)
Schritte zur Reproduktion
- Stellen Sie ein Discourse-Forum unter einem Unterpfad bereit, z. B.
https://example.com/forum. Stellen Sie sicher, dasshttps://example.com/forum/about.jsonmit200antwortet. - Führen Sie Folgendes aus:
npx -y @discourse/mcp@latest --site https://example.com/forum --log_level debug - Senden Sie eine beliebige MCP-Anfrage (oder beobachten Sie einfach die Validierung beim Start).
Erwartet
Der Server validiert gegen https://example.com/forum/about.json, und Tools rufen https://example.com/forum/<endpoint> auf.
Tatsächliches Ergebnis
Das Debug-Protokoll zeigt, dass die Anfrage zur Host-Wurzel und nicht zum Unterpfad geht:
DEBUG HTTP GET https://example.com/about.json
DEBUG HTTP GET https://example.com/about.json -> 403 Forbidden
ERROR Failed to validate --site https://example.com/forum: HTTP 403 Forbidden
Das Segment /forum wird stillschweigend entfernt.
Ursache
In dist/http/client.js:42 (und dem entsprechenden Schreibpfad bei :85):
const url = new URL(path, this.base).toString();
Laut der WHATWG-URL-Spezifikation wird ein path-Argument, das mit / beginnt, als absolut behandelt und ersetzt den Pfad der Basis-URL. Im gesamten Codebase werden Pfade mit führendem Slash übergeben, z. B.:
dist/index.js:230—client.get('/about.json')dist/tools/builtin/select_site.js:15—client.get('/about.json')- Alle integrierten Tools folgen demselben
'/...'-Muster.
Ergebnis: new URL('/about.json', 'https://example.com/forum') → https://example.com/about.json. Der Unterordner geht bei jedem Aufruf verloren.
Vorgeschlagene Lösung
Entweder (a) im HTTP-Client normalisieren, indem der führende Slash aus path entfernt wird und sichergestellt wird, dass this.base vor der Auflösung einen abschließenden Slash hat:
const base = this.base.toString().replace(/\/?$/, '/');
const rel = path.replace(/^\//, '');
const url = new URL(rel, base).toString();
…oder (b) alle Aufrufstellen so ändern, dass sie relative Pfade verwenden (ohne führenden Slash). Option (a) ist sicherer – nur ein einziger Änderungspunkt, keine unerwarteten Verhaltensänderungen anderswo.
Umgehungslösung für betroffene Nutzer
Wenn Ihre Discourse-Installation auch eine Subdomain hat, die mit 301 auf den Unterpfad weiterleitet (z. B. forum.example.com → example.com/forum/...), übergeben Sie die Subdomain als --site. Der MCP-HTTP-Client folgt Umleitungen, sodass jeder Aufruf die korrekte Unterpfad-URL auflöst und die Authentifizierung den Sprung übersteht. Auf v0.2.7 wurde dies end-to-end bestätigt (initialize, search usw.).
Wenn keine solche Subdomain existiert, gibt es derzeit keine clientseitige Umgehungslösung – der Fehler muss im Paket behoben werden.