# MCP 2.0 diventa stateless: cosa cambia con la specifica 2026-07-28

_Niente più handshake né sessioni nel protocollo, richieste che bastano a sé stesse, MRTR, Tasks ed estensioni facoltative. Cosa cambia per chi ha già un server MCP e come preparare la migrazione._

Fonte: https://andreapirazzini.it/blog/mcp-2-0-stateless-cosa-cambia · Andrea Pirazzini · 4 agosto 2026

## In breve

- La revisione 2026-07-28 di MCP elimina l'handshake initialize e l'header Mcp-Session-Id: ogni richiesta porta con sé versione e capacità.
- Se un tool deve chiedere qualcosa all'utente usa MRTR: la chiamata si ripete con uno stato opaco che il server deve proteggere con una firma.
- Tasks, MCP Apps e l'autorizzazione gestita dall'azienda sono estensioni ufficiali ma spente di default: client e server devono attivarle entrambi.
- Roots, Sampling e Logging sono deprecati e non spariranno prima di una revisione del 28 luglio 2027; deprecata anche la registrazione dinamica dei client.
- "MCP 2.0" è un soprannome: 2.0 è la versione del nuovo SDK C# di Microsoft, mentre il protocollo si identifica con la data.

## Perché se ne parla

Il 28 luglio 2026 è uscita una nuova revisione del Model Context Protocol, la più radicale da quando esiste. Sparisce la "stretta di mano" iniziale, sparisce la sessione legata alla connessione, e su Streamable HTTP ogni chiamata diventa una singola POST che contiene tutto il necessario per essere capita. In più arrivano strumenti nuovi per chiedere dati all'utente a metà lavoro, per le operazioni lunghe e per mostrare interfacce dentro la chat.

In giro la trovate come "MCP 2.0", ma il nome ufficiale è la data: **2026-07-28**. Il 2.0 appartiene alla nuova versione principale dell'SDK C# pubblicato da Microsoft, ed è diventato per comodità il soprannome del salto di generazione.

MCP, per chi arriva ora, è lo standard aperto con cui un'applicazione di intelligenza artificiale si collega a strumenti, dati e flussi di lavoro: una presa universale, che Claude, ChatGPT, Visual Studio Code e parecchi altri programmi sanno usare. Dall'altra parte un server MCP espone file, database, API o operazioni del gestionale (il quadro generale è nella guida su [cosa sono gli agenti AI](https://andreapirazzini.it/guide/agenti-ai-cosa-sono-esempi)).

![Schema a tre colonne: a sinistra le applicazioni AI (interfacce di chat, editor di codice, altre app), al centro MCP come protocollo standard, a destra dati e file, strumenti di sviluppo e di produttività, con frecce nei due sensi](https://xfzvzyxtnexwldhdjrdj.supabase.co/storage/v1/object/public/blog-media/posts/e261dcc3-eb84-420e-a9ce-6ac27362921d/cdbc0417-2b00-4f71-8dd6-10b14da24a83.webp)
*Lo schema ufficiale di MCP: da una parte le applicazioni AI, dall’altra dati e strumenti, in mezzo un solo protocollo che li mette in comunicazione. Immagine: documentazione Model Context Protocol.*

È la quinta release della specifica, e arriva su un ecosistema cresciuto in fretta. I numeri qui sotto sono di Anthropic: misurano la crescita, non sono un censimento indipendente.

- **400M** download al mese degli SDK MCP (quattro volte l'inizio dell'anno)
- **950+** server nella directory dei connettori di Claude
- **12 mesi** minimo tra deprecazione e rimozione di una funzione

_Fonte: Anthropic e specifica MCP 2026-07-28_

## Prima e dopo, in una tabella

| Aspetto | Prima | Con la 2026-07-28 |
| --- | --- | --- |
| Avvio | initialize seguito da initialized | Nessun handshake obbligatorio |
| Sessione HTTP | Header Mcp-Session-Id | Tolta dal protocollo |
| Versione e capacità | Concordate una volta all'inizio | In _meta a ogni richiesta |
| Scoperta delle funzioni | Dentro l'inizializzazione | server/discover: obbligatorio per il server, facoltativo per il client |
| Bilanciamento del carico | Sticky session o archivio condiviso | Round-robin e serverless senza trucchi |
| Domande all'utente | Richieste dal server al client | MRTR, con un requestState opaco |
| Lavori lunghi | Tasks sperimentale | Estensione Tasks, facoltativa |

## Richieste che bastano a sé stesse

### Come funzionava prima

Una connessione Streamable HTTP cominciava con un piccolo rito: il client mandava `initialize`, poi `notifications/initialized`. Il server poteva assegnare un identificativo nell'header `Mcp-Session-Id`, che il client doveva ripresentare a ogni chiamata.

Con più istanze dietro un bilanciatore, la richiesta doveva tornare proprio all'istanza che "si ricordava" di voi (le _sticky session_), oppure tutte dovevano condividere un archivio delle sessioni. Come un ristorante dove solo il cameriere che ha preso l'ordinazione sa cosa avete chiesto.

### Come funziona adesso

Handshake e sessioni escono dal protocollo. Nel campo `_meta` ogni richiesta porta la versione del protocollo, ciò che il client sa fare e, come buona pratica, il nome del software che la manda; il server risponde allo stesso modo. L'ordinazione ora è scritta sul foglietto, e qualunque cameriere può leggerla: qualsiasi istanza compatibile risponde a qualsiasi chiamata, e serverless, esecuzione sull'edge e bilanciamento a rotazione diventano scelte naturali.

**mcp@2026-07-28: transport**

**Prima**

```
> POST /mcp  method=initialize
Mcp-Session-Id: 1868a90c
POST /mcp  tools/call + session id
```

*Si apre una sessione, e solo dopo si chiamano i tool.*

**Con la 2026-07-28**

```
> POST /mcp  MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call  ·  Mcp-Name: search
resultType: complete
```

*Nessuna sessione: la chiamata porta con sé tutto quello che serve.*

*Dall’handshake alla chiamata che basta a sé stessa: prima si negoziava una sessione, ora ogni POST dichiara da sé versione e metodo. Sequenza ricostruita dal changelog e dalla specifica Streamable HTTP.*

### Senza stato non vuol dire senza memoria

"Stateless" riguarda il protocollo, non la vostra applicazione. Un server può ancora ricordare un carrello o un flusso di approvazione, purché lo faccia alla luce del sole: crea un identificativo (per esempio `basketId`, `workflowId` o `browserId`) e il modello lo ripassa come un argomento qualsiasi.

```json
{
  "name": "aggiungi_al_carrello",
  "arguments": { "basketId": "b-7f3a", "prodotto": "POLTRONA-BLU", "quantita": 1 }
}
```

I nomi sono d'esempio. Il punto è che lo stato non si nasconde più nel trasporto: sta negli argomenti, dove si vede e si controlla.

## HTTP leggibile anche da chi sta in mezzo

Streamable HTTP usa un unico endpoint che riceve POST. Ora ogni richiesta dichiara negli header versione (`MCP-Protocol-Version`) e metodo (`Mcp-Method`), più `Mcp-Name` quando riguarda un elemento con un nome, come un tool; alcuni parametri possono finire anche in header `Mcp-Param-*`. Con valori d'esempio:

```http
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: crea_preventivo
```

Così gateway, firewall applicativi (WAF), bilanciatori e monitoraggio possono instradare o classificare il traffico leggendo l'etichetta, senza aprire il pacco JSON-RPC. Fa fede comunque il corpo: se non coincide con gli header, il server risponde con l'errore `HeaderMismatch`.

Altre due novità:

- **Cache.** I risultati memorizzabili di tool, prompt e risorse possono indicare `ttlMs` (per quanto valgono) e `cacheScope` (cache pubblica o privata).
- **SSE non è morto.** Spariscono il vecchio endpoint GET e la ripresa con `Last-Event-ID`, ma la risposta a una POST può ancora arrivare in streaming SSE, legata a quella sola richiesta. Per le notifiche continue c'è il nuovo `subscriptions/listen`.

## MRTR: chiedere qualcosa all'utente senza una linea aperta

Senza sessione, come fa un tool a chiedere una conferma o un dato mancante a metà lavoro? La specifica risponde con **MRTR**, _Multi Round-Trip Requests_: richieste che si completano in più giri.

```text
Client → tools/call (id 41)
Server ← resultType: "input_required" con inputRequests e/o requestState
Client   soddisfa le richieste: elicitation, sampling o elenco delle roots
Client → stessa chiamata con un nuovo id (42) + inputResponses + requestState
Server ← risultato finale
```

La risposta del server contiene `resultType: "input_required"` e porta con sé la mappa `inputRequests` con le domande, un `requestState` opaco (un blocco di dati che il client non interpreta e si limita a restituire) oppure entrambi: non possono mancare tutti e due. Il client raccoglie le risposte e rimanda la stessa chiamata, questa volta con un ID JSON-RPC diverso. La continuità viaggia nel messaggio, nessuna istanza deve ricordare niente.

![Diagramma di sequenza tra client e server: la chiamata close_support_ticket riceve input_required con inputRequests e requestState, il client risolve gli input e ripete la chiamata con inputResponses e requestState, il server risponde complete](https://xfzvzyxtnexwldhdjrdj.supabase.co/storage/v1/object/public/blog-media/posts/e261dcc3-eb84-420e-a9ce-6ac27362921d/df1515f6-2144-4688-a745-7790924bd05b.webp)
*Lo stesso giro nel diagramma di Microsoft, con un tool che deve chiudere un ticket di assistenza. Immagine: Microsoft .NET Blog.*

### Il punto delicato: requestState

La specifica lo tratta come un dato che un attaccante può manipolare, perché passa dalle mani del client. Quando decide permessi o regole di business va blindato contro le modifiche, con una firma HMAC o una cifratura autenticata AEAD, e conviene che contenga l'utente (il _principal_), una scadenza breve e il legame con la richiesta di partenza. Per le operazioni da eseguire una volta sola serve anche un controllo lato server contro il _replay_.

**mcp@2026-07-28: mrtr**

**Prima chiamata**

```
> tools/call close_support_ticket
resultType: input_required
inputRequests + protected requestState
```

*Al tool mancano dei dati: invece del risultato, risponde chiedendoli.*

**Seconda chiamata**

```
> tools/call + inputResponses + requestState
resultType: complete
new JSON-RPC id · independent request
```

*Il client ha raccolto le risposte e ripete la chiamata come richiesta nuova.*

*Il requestState esce dal server, passa per le mani del client e rientra con la seconda chiamata: ecco perché va firmato. Schema basato sul modello MRTR della specifica.*

> **Attenzione:** Un requestState non firmato è un buono sconto scritto a penna: chiunque può correggerne l'importo.

## Tasks: lavori lunghi senza connessione aperta

MRTR gestisce più scambi dentro la stessa operazione. **Tasks** serve per lavori che durano secondi o ore, o che aspettano un'approvazione. Fa parte delle estensioni ufficiali, quindi il nucleo non la impone.

Il server restituisce `resultType: "task"` con un `taskId`, lo stato iniziale, una validità (TTL) e l'intervallo consigliato per ricontrollare. Poi:

```text
tasks/get     a che punto è il lavoro?
tasks/update  invia una risposta, se il task ne chiede una a metà strada
tasks/cancel  annulla il lavoro
```

Gli stati sono cinque: `working`, `input_required`, `completed`, `failed`, `cancelled`. L'identificativo è durevole, quindi il client può scollegarsi e riprendere più tardi, ma la durata va costruita: Microsoft avverte che l'archivio in memoria dell'SDK C# va bene solo in sviluppo, e con più istanze o riavvii serve uno storage condiviso e persistente. Cioè un database in più da gestire.

## Le estensioni, e dove funzionano davvero

La release dà una forma ufficiale alle funzioni opzionali: identificativi con il proprio spazio dei nomi, negoziazione delle capacità, repository separati. Le estensioni ufficiali sono quattro:

- **MCP Apps**: HTML interattivo (moduli, dashboard, grafici, player) mostrato dentro i client compatibili;
- **Tasks**: esecuzione asincrona con identificativi durevoli;
- **OAuth Client Credentials**: autenticazione tra macchine;
- **Enterprise-Managed Authorization**: accessi governati dal sistema di identità aziendale.

Sono spente di default e funzionano solo se entrambe le parti le dichiarano. La tabella ufficiale elenca MCP Apps già attive in Claude, ChatGPT, VS Code Copilot e diversi altri, mentre per le estensioni di autorizzazione il quadro è molto più disomogeneo. Ufficiale non vuol dire disponibile ovunque.

## OAuth più severo, ma non fa il lavoro al posto vostro

L'autorizzazione resta facoltativa. Chi la implementa su HTTP segue OAuth 2.1 e gli standard di scoperta e protezione delle risorse: i server protetti pubblicano i _Protected Resource Metadata_, i client supportano la scoperta OAuth e OpenID Connect, usano PKCE e legano ogni token alla risorsa MCP giusta.

La novità principale riguarda l'emittente. Se la risposta contiene `iss`, il client lo verifica rispetto all'emittente che ha registrato, e solo dopo scambia il codice; le credenziali si archiviano per emittente e non si riusano con server di autorizzazione diversi. Si chiudono così gli attacchi di tipo _mix-up_ e _confused deputy_, ma a ogni richiesta il server deve comunque controllare identità, ruolo, organizzazione e permessi dell'utente.

L'estensione **Enterprise-Managed Authorization** mette al centro il provider di identità aziendale, come Okta o Microsoft Entra: l'IT approva i connettori, applica regole per gruppi e revoca accessi senza che ogni dipendente autorizzi a mano ogni server. È la base più credibile per un'azienda strutturata, a patto che client, server di autorizzazione e provider di identità la implementino davvero.

## Cosa viene deprecato, e con che tempi

Roots, Sampling e Logging funzionano ancora ma sono _deprecated_: le implementazioni nuove non dovrebbero usarli.

| Funzione deprecata | Cosa usare al suo posto |
| --- | --- |
| Roots | Percorsi e cartelle passati come parametri o URI |
| Sampling | Il server chiama direttamente il provider del modello |
| Logging | Log e tracce su stderr o OpenTelemetry |
| Dynamic Client Registration | Client ID Metadata Documents |

Tra deprecazione e rimozione passano almeno dodici mesi: Roots, Sampling e Logging potranno sparire solo in una revisione pubblicata dal 28 luglio 2027 in poi. I valori `includeContext: "thisServer"` e `"allServers"`, deprecati già dalla revisione 2025-11-25, se ne andranno insieme a Sampling.

Fa eccezione il vecchio trasporto HTTP+SSE, deprecato prima che la regola esistesse: potrà essere rimosso tre mesi dopo che la proposta SEP-2596 sarà diventata _Final_, senza aspettare l'anno. Chi lo usa dovrebbe passare a Streamable HTTP.

**Quanto preavviso prima della rimozione** — Mesi minimi tra deprecazione e possibile rimozione

| Voce | Mesi di preavviso |
| --- | --- |
| Roots, Sampling e Logging | 12 mesi |
| Vecchio trasporto HTTP+SSE | 3 mesi |

_Fonte: specifica MCP 2026-07-28_

## Agent Skills: utili, ma fuori dal protocollo

La documentazione della 2026-07-28 include una guida per costruire server con le **Agent Skills**: pacchetti di istruzioni (un file SKILL.md più riferimenti) che aiutano un agente di programmazione a scegliere deployment, struttura dei tool, autenticazione e pacchettizzazione. Il plugin di riferimento `mcp-server-dev` ne contiene tre: `build-mcp-server`, `build-mcp-app` e `build-mcpb`. Fanno risparmiare tempo a chi sviluppa, ma non sono una funzione del protocollo e non vanno nella lista delle cose da migrare.

## L'SDK C# 2.0 e il supporto in Claude

Con l'SDK C# 2.0 Microsoft rende stateless il comportamento predefinito del trasporto HTTP e sposta Apps e Tasks in pacchetti da aggiungere solo se servono. Le API stabili della versione 1 continuano a compilare, l'SDK sa ricadere sulle implementazioni precedenti e le deprecazioni producono avvisi, non errori. Fa eccezione la vecchia Tasks sperimentale, incompatibile con il nuovo disegno.

![Immagine viola di annuncio con la scritta Announcing v2.0 of the official MCP C# SDK e le parole Stateless-first, HTTP-native, Multi Round-Trip Requests](https://xfzvzyxtnexwldhdjrdj.supabase.co/storage/v1/object/public/blog-media/posts/e261dcc3-eb84-420e-a9ce-6ac27362921d/9ca9c9d9-7025-4b9b-aef6-f1f2e78db54f.webp)
*L’immagine con cui Microsoft ha presentato la versione 2.0 dell’SDK C# ufficiale, allineata alla specifica 2026-07-28. Immagine: Microsoft .NET Blog.*

Ma i ripieghi di un SDK non rendono compatibile tutto il resto: avvio, risultati e richieste dal server al client cambiano in modo incompatibile, e in un ambiente misto va provata ogni coppia di client e server.

Anthropic sta distribuendo il supporto in Claude gradualmente. Insieme alla release ha annunciato MCP Apps, l'autorizzazione gestita dall'azienda, dashboard di osservabilità e, in anteprima di ricerca, gli **MCP tunnels**, per raggiungere server in reti private senza un endpoint pubblico. Sono funzioni di Claude, non requisiti del protocollo.

## La migrazione in nove passi

Se avete già server MCP in funzione, procederei così:

1. **Inventario**: handshake, Mcp-Session-Id, stream su GET, vecchia Tasks, Roots, Sampling, Logging.
2. **Richieste autosufficienti**: versione, capacità e dati del client in `_meta`, header coerenti con il corpo.
3. **Stato esplicito**: identificativi firmati o persistenti passati ai tool, al posto delle sessioni implicite.
4. **Scoperta e ripieghi**: `server/discover`, errori di versione, test tra revisioni.
5. **MRTR** al posto delle richieste avviate dal server, con requestState protetto da manomissioni e replay.
6. **Tasks** per i lavori lunghi: archivio durevole, TTL, polling, annullamento, input intermedi.
7. **Gateway e monitoraggio**: instradamento sugli header, tracciamento OpenTelemetry, collegamento tra le richieste della stessa operazione.
8. **Test OAuth da rifare**: emittente, destinatario del token, resource indicator, allargamento degli scope, revoca.
9. **Rilascio in canary**: poco traffico sul percorso nuovo, misurando errori e latenza prima di spegnere il vecchio.

**migration@mcp: preflight**

**Protocollo**

```
✓ inventory initialize / Mcp-Session-Id / GET stream
✓ per-request _meta + standard HTTP headers
✓ server/discover + version fallback
```

*Togliere tutto ciò che dà per scontata una sessione.*

**Sicurezza**

```
✓ HMAC or AEAD for requestState
✓ issuer + audience + resource indicator
✓ OpenTelemetry correlation across retries
```

*Verificare stato e identità a ogni singola richiesta.*

**Operazioni**

```
✓ persistent task store + TTL + cancel
✓ mixed client/server compatibility tests
deploy canary → observe → retire legacy
```

*Task che sopravvivono ai riavvii e un rilascio graduale.*

*I nove controlli prima di migrare, divisi in tre gruppi. Elenco ricavato dalla specifica, dalla guida di Microsoft e dalle indicazioni di migrazione di AAIF e CometAPI.*

Se il server tocca gestionali o dati dei clienti, è anche l'occasione per rivedere permessi e tracciabilità: lavoro da [sistemi AI su misura](https://andreapirazzini.it/servizi/sistemi-ai-su-misura).

## Cosa non sappiamo ancora

L'adozione sarà graduale: le tabelle delle estensioni le cura la community e possono restare indietro, Anthropic parla di distribuzione progressiva, gli SDK non hanno tutti gli stessi ripieghi. Vanno ancora misurati sul campo il costo operativo di Tasks, il supporto a MRTR nei client, l'interoperabilità OAuth tra provider di identità e server, la qualità del monitoraggio da un capo all'altro.

E togliere la sessione non riduce il rischio da sé. Adesso una singola operazione può spezzarsi in tante richieste e protrarsi per ore: sapere quali server sono attivi, autorizzare ogni singola richiesta e collegare i pezzi dello stesso task conta più di prima.

## Il mio parere

Con la 2026-07-28 MCP smette di assomigliare a una telefonata, dove entrambi devono restare in linea, e si avvicina a un normale servizio web moderno. Nucleo senza stato, header leggibili, cache, MRTR e Tasks risolvono problemi che chi ha messo MCP in produzione conosce bene, e le estensioni evitano di gonfiare il nucleo con funzioni che servono solo ad alcuni.

Il conto è una migrazione vera: alcune API spariscono, altre cambiano forma, e la compatibilità dipende dall'SDK. Sulla direzione e sul metodo il mio giudizio è molto positivo; diventerà pieno quando il supporto dei client e delle estensioni aziendali sarà più uniforme. Nel frattempo, nessuna fretta: ma sapere da subito quanto i vostri server dipendono da sessioni e funzioni deprecate costa poco e vi evita sorprese.

[Prenota una call](https://andreapirazzini.it/prenota)

## Domande frequenti

**"MCP 2.0" è il nome ufficiale?**

No. La specifica si chiama con la data, 2026-07-28. "2.0" è la versione principale dell'SDK C# di Microsoft, diventata il soprannome informale della revisione.

**MCP è diventato completamente stateless?**

Il nucleo sì. Le applicazioni però possono conservare stato con identificativi espliciti, e Tasks richiede un archivio durevole.

**SSE è stato eliminato?**

No. Sono stati tolti il vecchio endpoint GET e la ripresa con Last-Event-ID. La risposta a una singola POST può ancora arrivare in streaming SSE, e per le notifiche continue c'è subscriptions/listen.

**Devo riscrivere subito i miei server?**

Non per forza, ma conviene fare subito l'inventario di sessioni e funzioni deprecate: la vecchia Tasks e le richieste avviate dal server richiedono comunque interventi mirati.

**Le Agent Skills fanno parte del protocollo?**

No. Sono istruzioni per agenti di programmazione, usate dalla documentazione per costruire più in fretta server, Apps e pacchetti MCP.

**La nuova autorizzazione rende MCP sicuro da sola?**

No. OAuth, verifica dell'emittente e legame del token alla risorsa sono più rigorosi, ma restano a vostro carico validazione dei token, permessi per operazione, protezione di requestState, controlli sul replay e monitoraggio.
