1. localhost — è solo per te, non per ChatGPT
Partiamo dal principale “dissonanza cognitiva” del modulo. Apri http://localhost:3000 nel browser, tutto funziona, Next.js è a posto, il widget viene renderizzato. Sembra logico: “Visto che ho un URL, diamolo semplicemente a ChatGPT”.
Il problema è che localhost non è “il dominio magico della mia macchina su Internet”. È un nome speciale che punta sempre alla stessa macchina su cui gira il browser o il client. Il tuo laptop parla con se stesso. I server di OpenAI, dove gira ChatGPT, sanno anch’essi rivolgersi a localhost… ma al loro — dentro il data center. E il tuo Next.js è felicemente nascosto dietro il router di casa, il NAT e, forse, una VPN aziendale.
In questa lezione:
- capiremo perché localhost non è accessibile a ChatGPT;
- configureremo un tunnel HTTPS tramite cloudflared da localhost:3000 a un URL pubblico;
- collegheremo questo URL in ChatGPT Dev Mode;
- verificheremo la catena “codice → tunnel → ChatGPT” con una semplice modifica al widget e parleremo delle trappole tipiche.
Ne derivano due fatti semplici:
- ChatGPT non sa dove si trova il tuo laptop.
- Anche se lo sapesse, non può comunque raggiungerlo direttamente — le connessioni in ingresso sono chiuse.
Inoltre, ChatGPT lavora solo con endpoint HTTPS pubblici (punti di ingresso): serve un dominio “normale” e un certificato TLS. Per ragioni di sicurezza i server di OpenAI non effettuano chiamate verso indirizzi HTTP arbitrari senza crittografia, quindi serve proprio un dominio HTTPS con certificato valido. Esporre semplicemente http://my-external-IP:3000 non è un’opzione.
Quindi serve un intermediario — un servizio che:
- vive su Internet con un normale dominio HTTPS;
- può inoltrare in modo sicuro le richieste da quel dominio al tuo localhost:3000.
Questo è il tunnel HTTPS.
2. Cos’è un tunnel HTTPS: modello intuitivo
Senza paroloni: un tunnel è un servizio che ti dà un URL pubblico temporaneo (o permanente) e inoltra tutte le richieste da lì verso la tua porta locale. In termini di rete è, di fatto, un reverse proxy che mantiene una connessione in uscita verso il cloud.
Un’analogia intuitiva: sei dietro una porta chiusa (il router di casa), e il tunnel è un corriere che sta fuori con un cartello “tutta la posta qui”, entra ogni tanto da un ingresso di servizio e ti consegna le lettere in mano.
Il percorso della richiesta è, più o essenzialmente, questo:
sequenceDiagram
participant ChatGPT as ChatGPT (cloud)
participant Tunnel as Tunnel HTTPS
(Cloudflare / ngrok)
participant Dev as Il tuo server di sviluppo
(localhost:3000)
ChatGPT->>Tunnel: Richiesta HTTPS a https://xyz.trycloudflare.com
Tunnel->>Dev: Richiesta HTTP a http://localhost:3000
Dev-->>Tunnel: Risposta di Next.js
Tunnel-->>ChatGPT: Risposta HTTPS
I punti chiave sono questi.
Primo, l’iniziatore della connessione verso il servizio di tunneling sei tu. L’utility (cloudflared, ngrok ecc.) stabilisce da sola una connessione in uscita verso il cloud. Questo è quasi sempre consentito anche dietro NAT/firewall.
Secondo, il servizio di tunneling ti fornisce un dominio HTTPS con certificato valido, quindi niente TLS autofirmato da configurare a mano.
Terzo, per ChatGPT la tua App appare come un normale servizio web con dominio HTTPS. Non “sa” che poi il traffico finisce sul laptop di qualcuno.
3. Quali tunnel esistono e cosa useremo nel corso
Nel mondo dello sviluppo web ci sono diverse soluzioni popolari per questo compito:
- ngrok — il classico del settore, per lungo tempo è stato lo standard de facto su “come esporre il locale all’esterno”.
- Cloudflare Tunnel (cloudflared) — soluzione moderna e gratuita di Cloudflare, fornisce un dominio del tipo *.trycloudflare.com anche senza registrazione; volendo puoi associare anche un tuo dominio.
- LocalTunnel — minima magia, semplice pacchetto npm che fornisce un URL HTTPS temporaneo come https://something.loca.lt.
Tutti risolvono lo stesso problema: dare al server locale un dominio HTTPS pubblico, adatto a ChatGPT.
Per il corso vogliamo evitare dispersioni, quindi come strumento “principale” useremo Cloudflare Tunnel con l’utility cloudflared. Motivi semplici: non richiede registrazione per i tunnel rapidi, fornisce un HTTPS valido, si avvia facilmente con un solo comando.
Detto questo, se sei già fan di ngrok — nessun problema. I comandi saranno un po’ diversi, ma il concetto è identico: ngrok http 3000 invece di cloudflared tunnel --url http://localhost:3000.
Per orientarti meglio, riassumiamo gli strumenti in una piccola tabella.
| Strumento | Richiede registrazione? | Formato URL | Punti di forza principali | Punti deboli principali |
|---|---|---|---|---|
| Cloudflare Tunnel | No | |
Avvio rapido, HTTPS valido | L'URL cambia a ogni avvio |
| ngrok | Sì | |
Documentazione enorme, ecosistema | Anche l'URL gratuito cambia |
| LocalTunnel | No | |
Installazione via npm, minima magia | Domini instabili, meno funzionalità |
In questa lezione ci concentreremo su Cloudflare Tunnel nella modalità “tunnel rapido usa e getta”. È più che sufficiente per “far fare amicizia” al tuo Next.js con ChatGPT in Dev Mode.
4. Verifichiamo che il Next.js locale sia attivo
Prima di esporre qualcosa tramite tunnel, è necessario assicurarsi che il server locale funzioni davvero. Altrimenti farai il debug del tunnel quando il problema è solo che Next.js non è in esecuzione.
Promemoria dell’ordine standard:
# dalla root del progetto con il template Apps SDK
npm install # se non l'hai ancora fatto
npm run dev # avvio del server di sviluppo Next.js
Di default Next.js 16 si avvierà su http://localhost:3000 (se la porta non è occupata). Nel terminale vedrai qualcosa del tipo:
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
Apri nel browser http://localhost:3000 e verifica che la pagina del template si apra. Questa è la tua “laboratorio locale”. Se qui qualcosa non funziona (errore di build, TypeScript segnala problemi, porta occupata) — prima risolvi, poi passa al tunnel.
5. Avviamo Cloudflare Tunnel: da localhost a un HTTPS pubblico
Passiamo alla parte più interessante — facciamo in modo che chiunque su Internet (incluso ChatGPT) possa aprire il tuo Next.js via un URL HTTPS.
Installazione di cloudflared
Il metodo di installazione dipende dal sistema operativo. Il modo più semplice per macOS è tramite Homebrew:
brew install cloudflare/cloudflare/cloudflared
Su Windows e Linux puoi scaricare il binario pronto o usare il gestore pacchetti consigliato dalla documentazione Cloudflare (i link sono nei materiali aggiuntivi del modulo).
Puoi verificare l’installazione con il comando:
cloudflared --version
Se l’utilità non viene trovata, controlla il PATH o riavvia il terminale.
Tunnel rapido usa e getta
Il nostro obiettivo ora è un tunnel minimo funzionante, senza account, domini o configurazioni complesse. Per questo cloudflared ha la modalità quick tunnel, che fornisce un URL sul dominio trycloudflare.com.
Con npm run dev in esecuzione, esegui in un secondo terminale:
cloudflared tunnel --url http://localhost:3000
Ricorda una regola semplice: HTTPS — fuori, HTTP — dentro. cloudflared ti fornisce esternamente un dominio HTTPS, ma verso il tuo localhost:3000 parla in semplice HTTP.
Dopo un breve log vedrai una riga simile a:
INF +-------------------------------------------------------------+
INF | Your quick Tunnel has been created! |
INF | https://giftgenius-1234.trycloudflare.com |
INF +-------------------------------------------------------------+
Questo https://giftgenius-1234.trycloudflare.com è il nuovo indirizzo pubblico della tua applicazione locale. Il tunnel riceve richieste HTTPS su questo dominio e le inoltra a http://localhost:3000.
Due aspetti importanti.
Primo, il terminale con cloudflared deve rimanere aperto finché il tunnel serve. Appena lo chiudi (o premi Ctrl+C), il tunnel cade e l’URL smette di funzionare.
Secondo, a ogni avvio del quick tunnel l’URL potrebbe essere nuovo. Per lo sviluppo didattico va bene: l’obiettivo di questo modulo è semplicemente dare a ChatGPT accesso al tuo Next.js locale tramite un qualsiasi indirizzo HTTPS funzionante. Ma significa che in ChatGPT Dev Mode a volte dovrai aggiornare l’URL. Nel modulo 7 torneremo sul tema dei tunnel e imposteremo un vero dominio dev stabile, così da non inseguire gli indirizzi.
Verifichiamo il tunnel come un normale sito
Prima di collegare il tutto a ChatGPT, verifichiamo che il tunnel sia effettivamente raggiungibile da Internet.
- Apri l’https://...trycloudflare.com ottenuto nel browser.
- Dovresti vedere la stessa UI che su http://localhost:3000.
- Nella console dove gira npm run dev, vedrai nuove richieste — cioè Next.js sta davvero servendo accessi esterni.
Se la pagina non si apre o mostra un errore, verifica prima di tutto:
- se è in esecuzione npm run dev;
- se hai indicato correttamente l’URL locale all’avvio del tunnel (http://localhost:3000, non https:// e non la porta 3001);
- se qualcosa blocca le connessioni in uscita (raro, ma può succedere in reti aziendali molto restrittive).
6. Inoltriamo questo URL nel Dev Mode di ChatGPT
Ora abbiamo tutto per collegare la catena:
ChatGPT (cloud) → il tuo tunnel HTTPS → Next.js locale.
La parte di interfaccia del Dev Mode l’hai già vista nella lezione precedente; ora ripetiamo la stessa cosa ma con un vero URL HTTPS, non solo teorico.
In ChatGPT la sequenza generale è questa.
Apri ChatGPT nel browser e vai nella sezione per sviluppatori (di solito qualcosa come “Developer”, “Apps”, “My apps” — i nomi specifici possono cambiare con gli aggiornamenti dell’interfaccia).
Crea una nuova app o modifica un’app di sviluppo già esistente, se l’hai già creata.
Nel campo dove va inserito l’URL della tua App, indica l’indirizzo radice del tunnel, ad esempio:
https://giftgenius-1234.trycloudflare.com/mcp
Il punto di ingresso è il nostro /route/mcp.ts. Al collegamento, ChatGPT partirà da lì e poi recupererà tutte le informazioni necessarie. Nel README del template potrebbe essere indicato un altro percorso, se le app sono multiple; per ora considera che l’URL radice del tunnel + /mcp è ciò che ti serve.
Salva la configurazione dell’app. A questo punto ChatGPT effettua alcune richieste alla tua applicazione attraverso il tunnel:
- legge il manifest dell’App (metadati, strumenti ecc.);
- verifica la disponibilità dell’endpoint MCP;
- ottiene l’elenco di tutti i tools e delle risorse;
- mette in cache il codice HTML di tutti i widget(!)
Se tutto va bene, vedrai la tua app nella lista delle Dev‑Apps. Se qualcosa è rotto (manifest non valido, server non risponde, tunnel caduto), ChatGPT mostrerà un errore del tipo “App unavailable” o simile.
Importante: lo stesso URL HTTPS del tunnel verrà usato da ChatGPT sia per invocare gli strumenti (MCP), sia per caricare il widget e gli asset statici. Nel prossimo paragrafo vediamo separatamente questi due ruoli.
7. Come passano ora le richieste: due ruoli del tuo tunnel
È importante capire chiaramente cosa fa ChatGPT con questo URL. Nell’architettura di Apps SDK ci sono due principali punti di ingresso: l’endpoint MCP e il widget UI.
In forma semplificata la catena è così:
flowchart LR
ChatGPT["ChatGPT (modello)"]
subgraph Internet
Tunnel[Tunnel HTTPS
giftgenius-1234.trycloudflare.com]
end
Local["Server di sviluppo Next.js http://localhost:3000"]
ChatGPT -- Richieste HTTP(S) a /mcp --> Tunnel
ChatGPT -- Caricamento iframe /widget --> Tunnel
Tunnel --> Local
Il tunnel ha di fatto due ruoli principali:
- Ruolo 1: endpoint MCP (strumenti). Quando il modello decide di chiamare uno strumento (tool), effettua un HTTP POST all’endpoint MCP (nel template è la route app/mcp/route.ts in Next.js) sullo stesso dominio del tunnel.
- Ruolo 2: widget UI e statici. Quando il modello decide di mostrare un widget, incorpora un iframe con il tuo URL (di solito /widget o ciò che è indicato nel manifest), e anche questo caricamento passa attraverso il tunnel.
Il tunnel non è “per una sola cosa”: è un’unica porta verso la tua App locale: UI, MCP, statici — tutto transita dallo stesso dominio HTTPS pubblico.
8. Pratica: verifichiamo la catena “codice → tunnel → ChatGPT”
Per essere certi che tutto funzioni davvero, e non solo sui diagrammi, svolgi uno scenario pratico minimo.
Primo, avvia npm run dev e verifica che http://localhost:3000 si apra nel browser.
Secondo, avvia cloudflared tunnel --url http://localhost:3000 e ottieni un URL HTTPS pubblico. Provalo in un altro browser o anche su un altro dispositivo (ad esempio, sul telefono tramite rete mobile) — in questo modo ti assicuri che le richieste passino su Internet e non rimangano sulla tua macchina.
Terzo, apri ChatGPT, passa al Dev Mode e verifica che la tua App sia collegata a questo URL. Nel Composer della chat di ChatGPT seleziona la tua App, inizia un dialogo e vedi se ChatGPT inserisce il widget e carica la tua UI.
Per vedere chiaramente che è proprio il tuo codice, modifica qualcosa di molto semplice nel widget, ad esempio il titolo:
// app/widget/page.tsx (esempio)
'use client';
export default function GiftGeniusWidget() {
return <h1>GiftGenius attraverso il tunnel 🚇</h1>;
}
Dopo aver salvato il file:
- Attendi che Next.js completi il fast refresh,
- Vai nella sezione di ChatGPT dove hai aggiunto la tua applicazione e aggiorna (refresh) la pagina.
- Apri/aggiorna la sessione con l’App in ChatGPT
- Scrivi una nuova richiesta a ChatGPT chiedendo di visualizzare il tuo widget
- Assicurati che il nuovo testo del titolo sia visibile già dentro ChatGPT.
Questo è il piccolo “momento della verità”: hai appena modificato il codice sulla tua macchina e il cambiamento si è riflesso nell’interfaccia cloud di ChatGPT tramite il tunnel.
9. Un po’ di sicurezza e “cosa esattamente hai esposto”
Qualsiasi tunnel non è un giocattolo, ma un vero ingresso pubblico alla tua macchina. Nel nostro scenario didattico esponiamo solo localhost:3000, dove gira l’applicazione Next.js. Questo è relativamente sicuro se:
- questa porta non è usata per altro;
- non hai una “app-mostro” che include per qualche motivo un pannello admin del DB, phpMyAdmin e altri quattro servizi demo.
Un paio di regole pratiche.
Il tunnel è uno strumento di sviluppo, non un ambiente di produzione. Lo usiamo consapevolmente in Dev Mode, non per utenti reali e certamente non per ricevere pagamenti.
Evita di eseguire su questa stessa porta (3000) pannelli amministrativi, database senza password e simili. Tutto ciò che risponde su questa porta diventa visibile da Internet finché il tunnel è attivo.
Non diffondere il tuo URL trycloudflare.com ovunque. Sì, la probabilità che qualcuno inizi a scannerizzarlo mentre stai facendo un progetto didattico è bassa. Ma l’abitudine “il link al server di sviluppo lo mandiamo in giro” in produzione può costare caro.
Più avanti, quando parleremo di Vercel e dell’ambiente di produzione, useremo un hosting serio con domini stabili e sicurezza da produzione, e il tunnel rimarrà uno strumento esclusivamente da dev.
10. Errori tipici con avvio locale e tunnel
Dunque, abbiamo un Next.js locale attivo, un tunnel HTTPS funzionante e il Dev Mode collegato in ChatGPT. Infine — alcuni errori tipici che quasi tutti incontrano nelle prime iterazioni, e come diagnosticarli rapidamente.
Errore n. 1: tentativo di usare http://localhost:3000 direttamente in ChatGPT.
A volte chi inizia copia semplicemente questo URL nella configurazione del Dev Mode e si sorprende che ChatGPT dica di non riuscire a raggiungere l’App. Ricordo: localhost è “io stesso” per chi effettua la richiesta. Per ChatGPT è il server di OpenAI, non il tuo laptop. Non vedrai log particolari sulla tua macchina, perché le richieste non ci arrivano proprio.
Errore n. 2: avvio del tunnel verso una porta inesistente o errata.
Scenario frequente: tempo fa eseguivi npm run dev sulla porta 3000, il server è già caduto, ma per abitudine nel secondo terminale lanci cloudflared tunnel --url http://localhost:3000. Cloudflare ti dà un bel dominio HTTPS, ma all’apertura — errore. Diagnosi semplice: il server locale non è attivo. Controlla sempre prima http://localhost:3000 nel browser, e solo dopo accendi il tunnel.
Errore n. 3: confusione tra http:// e https:// all’avvio del tunnel.
Il tunnel ti fornisce da sé l’HTTPS all’esterno, ma verso il server locale deve parlare in HTTP, ad esempio http://localhost:3000. Cercare di indicare https://localhost:3000 porta spesso a strani errori TLS interni o semplicemente all’indisponibilità. Ricorda la regola: HTTPS — fuori, HTTP — dentro.
Errore n. 4: terminale con il tunnel chiuso durante i test attivi in ChatGPT.
Altro caso classico: tutto è configurato, l’App funziona in ChatGPT, poi chiudi per sbaglio la finestra del terminale con cloudflared. Dopo 10 minuti torni in ChatGPT — e vedi “App unavailable”. Il motivo è semplice: l’URL è rimasto nelle impostazioni dell’App, ma il tunnel è spento. Ricorda la regola: finché testi l’App in Dev Mode, deve rimanere vivo un terminale con il tunnel.
Errore n. 5: usare inconsapevolmente un nuovo URL dopo il riavvio del tunnel.
In modalità quick tunnel Cloudflare ad ogni avvio assegna un nuovo *.trycloudflare.com. Se hai fermato e riavviato cloudflared, ma in ChatGPT è rimasto indicato il vecchio URL, ChatGPT continuerà a provarci e otterrà timeout o un servizio di qualcun altro. Quando l’URL del tunnel cambia, aggiornalo sempre nelle impostazioni del Dev Mode. Più avanti parleremo di come ottenere un dominio dev stabile, così da non inseguire gli URL.
Errore n. 6: esporre servizi superflui o rischiosi sulla stessa porta.
Talvolta gli sviluppatori, per comodità, eseguono sulla porta 3000 non solo Next.js, ma anche “strumenti di servizio”: pannello di debug, API sperimentali senza autenticazione, ecc. Appena inoltri questa porta tramite tunnel, tutte queste cose diventano accessibili dall’esterno. Per un progetto didattico forse non succede nulla di grave, ma questa abitudine nei progetti reali aumenta il rischio di leak e intrusioni. Tieni sempre a mente: tutto ciò che risponde sulla porta indicata nel tunnel è esposto a Internet.
GO TO FULL VERSION