Bug MCP durante l'installazione in una sottocartella

@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/mcp v0.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

  1. Avere un forum Discourse in un sottopercorso, ad es. https://esempio.com/forum. Confermare che https://esempio.com/forum/about.json restituisca 200.
  2. Eseguire:
    npx -y @discourse/mcp@latest --site https://esempio.com/forum --log_level debug
    
  3. 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:230client.get('/about.json')
  • dist/tools/builtin/select_site.js:15client.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.comesempio.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.

1 Mi Piace