Se sviluppi backend, le REST API sono il tuo pane quotidiano. Costruiamo endpoint, definiamo contratti chiari con OpenAPI/Swagger e lasciamo che i client (frontend, app mobile o altri microservizi) li consumino. È un paradigma deterministico: il client sa esattamente cosa chiamare, quando chiamarlo e come interpretare la risposta.
Ma cosa succede quando il “client” non è un’applicazione strutturata, ma un LLM o un agente autonomo che deve decidere dinamicamente quali azioni compiere per risolvere un problema?
È qui che entra in gioco il Model Context Protocol (MCP). Non sostituisce REST, ma risolve un problema diverso: esporre dati e funzionalità in un formato nativamente comprensibile per i modelli di intelligenza artificiale, permettendo la scoperta dinamica e l’esecuzione contestuale tramite JSON-RPC (spesso su stdio o SSE).
Vediamo la differenza in pratica usando C#.
1. L’approccio tradizionale: REST con ASP.NET Core Minimal APIs
In uno scenario classico, creiamo un endpoint per esporre i dati di un cliente. È rigido, tipizzato e progettato per essere consumato da un frontend o da un sistema di integrazione.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Endpoint REST deterministico
app.MapGet("/api/customers/{id:int}", async (int id, AppDbContext db) =>
{
var customer = await db.Customers.FindAsync(id);
if (customer is null)
return Results.NotFound(new { Error = "Cliente non trovato" });
return Results.Ok(customer);
})
.WithName("GetCustomer")
.WithOpenApi(operation => new(operation) {
Summary = "Recupera i dettagli di un cliente",
Description = "Restituisce i dati anagrafici di un cliente dato il suo ID univoco."
});
app.Run();
Come viene consumato: Il frontend effettua una chiamata HTTP GET a /api/customers/42. Deve conoscere l’URL, i parametri richiesti e gestire i codici di stato HTTP (200, 404, ecc.). Se vogliamo che un LLM usi questa API, dobbiamo passargli lo schema OpenAPI, fargli generare la request HTTP corretta, e parsare il JSON di ritorno.
2. L’approccio Agentico: Model Context Protocol (MCP) in C#
Con l’MCP, non esponiamo un “endpoint HTTP”, ma registriamo un Tool all’interno di un server MCP. Il server si mette in ascolto (ad esempio tramite standard input/output o Server-Sent Events) e comunica direttamente con l’host AI (come Claude Desktop, cursor, o un orchestratore custom).
Ecco come appare l’implementazione concettuale di un server MCP in .NET che espone la stessa funzionalità:
using Mcp.Core;
using Mcp.Server;
// Inizializzazione del Server MCP
var server = new McpServer("CustomerManagementServer", "1.0.0");
// Registrazione di un "Tool" che l'IA può scoprire ed eseguire
server.AddTool(
name: "get_customer_details",
description: "Recupera i dati anagrafici e lo storico ordini di un cliente. Usalo quando devi rispondere a domande su uno specifico cliente.",
inputSchema: new
{
type = "object",
properties = new
{
id = new { type = "integer", description = "L'ID univoco del cliente" }
},
required = new[] { "id" }
},
handler: async (arguments, CancellationToken ct) =>
{
// Estrazione dei parametri passati dall'LLM
int id = arguments.GetProperty("id").GetInt32();
var customer = await db.Customers.FindAsync(id);
if (customer is null)
{
return new ToolResult
{
IsError = true,
Content = [ new TextContent { Text = $"Nessun cliente trovato con ID {id}." } ]
};
}
// Il risultato viene restituito in formato testo/markdown che l'LLM sa interpretare
var jsonResult = JsonSerializer.Serialize(customer);
return new ToolResult
{
Content = [ new TextContent { Text = jsonResult } ]
};
}
);
// Il server si mette in ascolto (es. tramite stdio per esecuzioni locali o script)
await server.StartStdioAsync();
Le differenze fondamentali nell’implementazione
- Il Trasporto:
- REST: Viaggia su HTTP/HTTPS.
- MCP: Viaggia spesso su
stdio(per i processi locali, ottimo per gli agenti che girano sulla stessa macchina) oSSE(Server-Sent Events) per le connessioni remote, usando JSON-RPC. Non c’è l’overhead del routing HTTP tradizionale.
- Lo Scopo della Descrizione:
- REST: La descrizione Swagger serve allo sviluppatore umano per scrivere il client.
- MCP: La proprietà
descriptionnel Tool è vitale. È il prompt che dice all’LLM quando e perché usare questo strumento. Se la descrizione è ambigua, l’agente non chiamerà il tool.
- Gestione degli Errori:
- REST: Usi i codici di stato HTTP (400, 404, 500).
- MCP: Restituisci
IsError = truecon un testo esplicativo (“Cliente non trovato”). L’LLM leggerà questo errore e potrà decidere autonomamente di ritentare con un parametro diverso o di informare l’utente.
- Resources vs Tools:
- Nell’esempio sopra abbiamo creato un Tool (un’azione con parametri). MCP permette anche di esporre Resources (es.
uri: file:///logs/system.log), che l’LLM può leggere per ottenere contesto senza dover invocare funzioni, cosa che in REST richiederebbe un endpoint dedicato.
- Nell’esempio sopra abbiamo creato un Tool (un’azione con parametri). MCP permette anche di esporre Resources (es.
Il verdetto per i sistemi moderni
Se stai architettando un’applicazione web o un sistema aziendale, continuerai a scrivere REST API o gRPC.
Ma nel momento in cui devi integrare un framework multi-agente, invece di scrivere wrapper complessi attorno alle tue API REST per fare function calling manuale, costruire un Server MCP dedicato al tuo dominio (magari un microservizio .NET separato che incapsula la business logic) è la strada più pulita, standard e scalabile.