# SSE and Streamable HTTP: how an MCP server talks

Streamable HTTP replaced HTTP+SSE: one endpoint takes JSON-RPC over POST and may answer with a stream. Here is what this server really does.

> Page: https://ui.eneawork.it/blog/mcp-transport-sse-vs-http
> Markdown: https://ui.eneawork.it/blog/mcp-transport-sse-vs-http.md

*2026-11-01*

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.

Il catalogo EneUI conta 111.985 componenti, 1.556 blocchi e 12.808 icone da 1.472 librerie, letti da /api/stats il 1 novembre 2026. L'endpoint /mcp dichiara protocolVersion 2025-06-18 e transport streamable-http. La prova del 1 novembre 2026, con Accept: application/json, text/event-stream, ha restituito application/json, nessuna intestazione Mcp-Session-Id e Cache-Control: no-store.

## 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.

## 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.

## FAQ

### 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.
