@discourse/mcp fallisce nelle installazioni in sottocartelle: i percorsi con barra iniziale rimuovono il sottopercorso del sito
TL;DR
Su istanze di Discourse montate in un sottopercorso (ad es. https://esempio.com/forum), @discourse/mcp non riesce a connettersi perché ogni chiamata API interna rimuove il sottopercorso, colpendo la radice errata dell’host. Questo compromette la validazione del sito e ogni successiva chiamata agli strumenti (search, read_topic, ecc.), non solo la validazione di --site.
Ambiente
@discourse/mcpv0.2.7 (ultima versione al momento della scrittura)- Node tramite
npx -y @discourse/mcp@latest - Target: Discourse ospitato su
https://<host>/forum(installazione in sottocartella dietro nginx)
Passaggi per riprodurre il problema
- Avere un forum Discourse in un sottopercorso, ad es.
https://esempio.com/forum. Confermare chehttps://esempio.com/forum/about.jsonrestituisca200. - Eseguire:
npx -y @discourse/mcp@latest --site https://esempio.com/forum --log_level debug - Inviare una qualsiasi richiesta MCP (o semplicemente osservare la validazione all’avvio).
Comportamento atteso
Il server valida contro https://esempio.com/forum/about.json e gli strumenti chiamano https://esempio.com/forum/<endpoint>.
Comportamento effettivo
Il log di debug mostra che la richiesta viene inviata alla radice dell’host, non al sottopercorso:
DEBUG HTTP GET https://esempio.com/about.json
DEBUG HTTP GET https://esempio.com/about.json -> 403 Forbidden
ERROR Failed to validate --site https://esempio.com/forum: HTTP 403 Forbidden
Il segmento /forum viene rimosso silenziosamente.
Causa principale
In dist/http/client.js:42 (e nel corrispondente percorso di scrittura a :85):
const url = new URL(path, this.base).toString();
Secondo le specifiche WHATWG URL, un argomento path che inizia con / viene trattato come assoluto e sostituisce il pathname dell’URL di base. In tutto il codice, i percorsi vengono passati con una barra iniziale, ad es.:
dist/index.js:230—client.get('/about.json')dist/tools/builtin/select_site.js:15—client.get('/about.json')- Tutti gli strumenti integrati seguono lo stesso pattern
'/...'.
Risultato: new URL('/about.json', 'https://esempio.com/forum') → https://esempio.com/about.json. Il sottocartella viene perso in ogni chiamata.
Soluzione suggerita
O (a) normalizzare nel client HTTP rimuovendo la barra iniziale da path e assicurandosi che this.base abbia una barra finale prima della risoluzione:
const base = this.base.toString().replace(/\/?$/, '/');
const rel = path.replace(/^\//, '');
const url = new URL(rel, base).toString();
…o (b) modificare tutti i punti di chiamata per utilizzare percorsi relativi (senza barra iniziale). L’opzione (a) è più sicura: punto unico di modifica, senza comportamenti inaspettati altrove.
Soluzione temporanea per gli utenti interessati
Se la tua installazione di Discourse ha anche un sottodominio che esegue un reindirizzamento 301 verso il sottopercorso (ad es. forum.esempio.com → esempio.com/forum/...), passa il sottodominio come --site. Il client HTTP di MCP segue i reindirizzamenti, quindi ogni chiamata si risolve nell’URL corretto del sottopercorso e l’autenticazione sopravvive al passaggio. Verificato funzionante end-to-end (initialize, search, ecc.) su v0.2.7.
Se non esiste un tale sottodominio, al momento non ci sono soluzioni temporanee lato client: il bug deve essere corretto nel pacchetto.