AI & MCP
SSE e Streamable HTTP: come parla un server MCP
Streamable HTTP ha sostituito il trasporto HTTP+SSE: un solo endpoint riceve JSON-RPC in POST e può rispondere con un flusso. Stdio resta per il server locale.
In sintesi
- Il trasporto HTTP+SSE usava due endpoint; Streamable HTTP ne usa uno e risponde JSON o SSE.
- Stdio resta la scelta per un server locale avviato dal client sulla stessa macchina.
- L'endpoint EneUI risponde sempre application/json e non emette Mcp-Session-Id.
Streamable HTTP ha sostituito il trasporto HTTP+SSE: un solo endpoint riceve messaggi JSON-RPC in POST e può rispondere con un flusso SSE. Stdio resta la scelta per un server locale avviato dal client.
Tre trasporti, due generazioni
La prima revisione, 2024-11-05, usava due endpoint: un GET per il flusso e un POST per i messaggi. Streamable HTTP, dalla revisione 2025-03-26, li unisce in un solo percorso.
| Trasporto | Endpoint | Quando | Stato |
|---|---|---|---|
| stdio | stdin e stdout | processo locale | standard |
| HTTP+SSE | GET /sse e POST /messages | client del 2024 | deprecato |
| Streamable HTTP | POST /mcp | server remoto | standard |
Cosa risponde l'endpoint EneUI
curl -s -i https://ui.eneawork.it/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"ping"}'
L'intestazione torna application/json, non text/event-stream, e manca Mcp-Session-Id. La risposta è una sola: {"jsonrpc":"2.0","id":1,"result":{}}.
Una richiesta, una risposta
Il server non tiene stato: ogni POST è indipendente e una notifica senza id chiude con 202 e corpo vuoto. Per un catalogo in sola lettura è sufficiente, e attraversa qualunque proxy senza sorprese.
Il prezzo di questa scelta
Senza flusso aperto il server non può iniziare un messaggio: niente sampling, niente notifica su una resource aggiornata, niente ripresa dopo una disconnessione. Sono tutte funzioni opzionali, ma chi le vuole deve accettare SSE.
Lo stesso percorso per browser e agenti
Un Accept: text/html fa cadere la GET nella pagina /mcp; un Accept: */* riceve il documento JSON con nome, versione, trasporto e i 9 strumenti. La negoziazione avviene nell'intestazione, non su un percorso diverso.
Il catalogo EneUI
Le risposte arrivano dalla stessa origine delle pagine: hero, icone e un blocco reale come SaaS Pricing with Billing Toggle, 1 file e 4 dipendenze di registry, verificato il 1 novembre 2026.
La limitazione
L'endpoint non implementa Mcp-Session-Id né il GET di streaming, quindi non può riprendere una risposta interrotta con Last-Event-ID. Un client che pretende un flusso deve accettare il JSON come risposta completa.
Dove continuare
Il flusso OAuth che accompagna il trasporto è in OAuth per server MCP; il dispatcher è in come costruire un server MCP; il confronto con le API REST è in MCP vs REST. La definizione del protocollo è in che cos'è MCP.
Domande frequenti
Streamable HTTP è obbligatorio in MCP?
No. Un server può usare stdio e basta. Streamable HTTP è il trasporto previsto per un endpoint remoto raggiungibile da più client.
Posso usare ancora HTTP+SSE?
Tecnicamente sì, ma il trasporto è deprecato dalla revisione 2025-03-26. Un client nuovo conviene che parli Streamable HTTP o stdio.
Perché EneUI risponde JSON invece di SSE?
Perché ogni richiesta produce una sola risposta e il JSON attraversa ogni proxy. Un flusso servirebbe solo per messaggi avviati dal server, che qui non esistono.
Cos'è Mcp-Session-Id?
È l'intestazione con cui il server assegna un identificatore di sessione al client. L'endpoint EneUI non la emette: ogni POST è indipendente.
Il browser può aprire /mcp?
Sì, ma riceve la pagina HTML: con Accept text/html la GET cade nell'applicazione, mentre un client che chiede JSON ottiene il documento di scoperta.