In questa terza lezione approfondiamo uno degli aspetti più importanti del Model Context Protocol (MCP), ovvero il meccanismo di comunicazione tra i suoi componenti e il processo attraverso cui i modelli scoprono e utilizzano gli strumenti disponibili. Dopo aver analizzato nella lezione precedente l’architettura composta da Host, Client e Server, è importante comprendere come questi elementi dialogano tra loro in modo strutturato, affidabile e standardizzato. Il fulcro di questa comunicazione è rappresentato dal protocollo JSON-RPC, che consente di definire un linguaggio comune tra sistemi eterogenei. Grazie a questo approccio, il modello linguistico non interagisce con gli strumenti in modo arbitrario, ma segue regole precise che rendono ogni richiesta tracciabile, interpretabile e verificabile.
MCP e protocollo JSON-RPC
Il protocollo JSON-RPC rappresenta la base su cui si fonda la comunicazione in MCP. Si tratta di un protocollo leggero per l’esecuzione di chiamate remote, basato su messaggi strutturati in formato JSON. La sua semplicità è uno dei suoi principali punti di forza, perché consente di implementare interazioni complesse mantenendo una struttura chiara e leggibile. Nel contesto di MCP, JSON-RPC viene utilizzato per standardizzare il modo in cui il Client invia richieste ai Server e riceve risposte.
Ogni interazione segue uno schema preciso, che include un identificativo della richiesta, il metodo da invocare e i parametri necessari per l’esecuzione. Questo approccio garantisce coerenza e interoperabilità, permettendo a sistemi sviluppati in linguaggi diversi di comunicare senza ambiguità. Inoltre, la natura strutturata dei messaggi facilita il debugging, il logging e il monitoraggio delle operazioni.
Struttura delle richieste e delle risposte
Per comprendere meglio il funzionamento della comunicazione, è utile analizzare la struttura delle richieste e delle risposte in JSON-RPC anche attraverso esempi concreti, che ci permettono di vedere come questi concetti si traducono operativamente all’interno di un sistema MCP.
Ogni richiesta contiene informazioni essenziali che permettono al Server di interpretare correttamente l’azione da eseguire. La richiesta include un identificativo univoco che consente di associare la risposta alla richiesta originale, un nome di metodo che rappresenta l’azione da eseguire e un insieme di parametri che descrivono i dati necessari per l’operazione.
Ad esempio, immaginiamo che il modello debba ottenere il meteo aggiornato di una città. Il Client MCP potrebbe inviare una richiesta strutturata come la seguente:
{
"jsonrpc": "2.0",
"id": 1,
"method": "getWeather",
"params": {
"city": "Roma"
}
}
In questo caso possiamo osservare chiaramente tutti gli elementi fondamentali. Il campo "jsonrpc" specifica la versione del protocollo utilizzato, "id" identifica in modo univoco la richiesta, "method" indica l’azione da eseguire e "params" contiene i dati necessari, in questo caso il nome della città.
Il Server, una volta ricevuta la richiesta, la elabora e restituisce una risposta che può contenere il risultato dell’operazione oppure un errore. Se tutto va a buon fine, la risposta potrebbe essere strutturata in questo modo:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"temperature": 22,
"condition": "soleggiato"
}
}
Qui vediamo che l’identificativo "id" corrisponde a quello della richiesta, permettendo al Client di associare correttamente la risposta. Il campo "result" contiene i dati restituiti dal Server, che il modello potrà utilizzare per costruire una risposta coerente per l’utente.
Nel caso in cui qualcosa non vada a buon fine, il Server restituisce invece un errore strutturato. Ad esempio, se il parametro richiesto è mancante o non valido, la risposta potrebbe essere:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32602,
"message": "Parametri non validi"
}
}
Questo approccio rende esplicita la gestione degli errori e consente al sistema di reagire in modo appropriato, ad esempio correggendo la richiesta o informando l'utente.
Il concetto di Tool Discovery in MCP
Uno degli elementi più innovativi di MCP è il concetto di tool discovery, ovvero la capacità del modello di scoprire dinamicamente gli strumenti disponibili. A differenza di sistemi tradizionali, in cui le integrazioni sono spesso statiche e predefinite, MCP introduce un meccanismo che consente al modello di interrogare il Server per conoscere quali strumenti può utilizzare.
Questo processo avviene attraverso chiamate specifiche che permettono al Client di ottenere una descrizione delle funzionalità esposte dal Server. Il modello può quindi analizzare queste informazioni e decidere quali strumenti utilizzare in base al contesto della richiesta. Il tool discovery rappresenta un passo fondamentale verso la creazione di sistemi adattivi, in cui le capacità del modello non sono fissate a priori, ma possono evolversi dinamicamente in base agli strumenti disponibili.
Affinché il tool discovery sia efficace, è necessario che gli strumenti siano descritti in modo chiaro e strutturato. Ogni tool deve includere informazioni che permettano al modello di comprenderne lo scopo, i parametri richiesti e il tipo di risultato restituito. Questa descrizione non è solo tecnica, ma anche semantica. Il modello utilizza queste informazioni per interpretare quando e come utilizzare uno strumento. Una descrizione ben progettata aumenta significativamente la probabilità che il modello scelga lo strumento corretto e lo utilizzi in modo appropriato.
Quando il Client MCP vuole sapere quali strumenti sono disponibili, invia una richiesta JSON-RPC specifica al Server, tipicamente utilizzando un metodo come tools/list.
{
"jsonrpc": "2.0",
"id": 100,
"method": "tools/list"
}
Questa richiesta non contiene parametri complessi, perché l'obiettivo è semplicemente ottenere l'elenco dei tool disponibili in quel momento. Il Server risponde fornendo una lista strutturata di strumenti, ciascuno con una descrizione chiara:
{
"jsonrpc": "2.0",
"id": 100,
"result": {
"tools": [
{
"name": "getWeather",
"description": "Recupera il meteo attuale per una città",
"inputSchema": {
"type": "object",
"properties": {
"city": {
"type": "string"
}
},
"required": ["city"]
}
},
{
"name": "calculateSum",
"description": "Calcola la somma di due numeri",
"inputSchema": {
"type": "object",
"properties": {
"a": { "type": "number" },
"b": { "type": "number" }
},
"required": ["a", "b"]
}
}
]
}
}
In questa risposta vediamo tre elementi fondamentali:
- Il nome del tool, che identifica univocamente la funzione.
- La descrizione, che aiuta il modello a capire quando usarlo.
- Lo schema di input, che definisce i parametri richiesti e il loro formato.
Una volta ricevuta questa risposta, il modello analizza le informazioni disponibili. Se l'utente chiede ad esempio "che tempo fa a Napoli?", il modello può associare questa richiesta al tool getWeather, grazie alla descrizione semantica.
Conclusioni
In questa lezione abbiamo analizzato in dettaglio il funzionamento della comunicazione all’interno del Model Context Protocol, concentrandoci sul ruolo del JSON-RPC e sul processo di tool discovery. Abbiamo visto come questi elementi permettano al modello di interagire con strumenti esterni in modo strutturato, affidabile e dinamico. Nella prossima lezione approfondiremo i temi della sicurezza, analizzando come controllare e regolamentare l’accesso agli strumenti e ai dati.
Se vuoi aggiornamenti su Comunicazione e Tool Discovery nel protocollo MCP (JSON-RPC) inserisci la tua email nel box qui sotto: