Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Implementare un MCP Server e integrare strumenti e dati

Come implementare un MCP (Model Context Protoco) Server e integrare strumenti e dati per le nostre applicazioni AI
Come implementare un MCP (Model Context Protoco) Server e integrare strumenti e dati per le nostre applicazioni AI
Link copiato negli appunti

In questa lezione iniziamo a costruire concretamente un MCP Server, cioè una componente fondamentale dell’ecosistema Model Context Protocol. Dopo aver compreso l’architettura, la comunicazione JSON-RPC e i principi di sicurezza e consenso, siamo finalmente in grado di vedere come un server MCP espone strumenti e dati a un modello linguistico in modo standardizzato, controllato e riutilizzabile. L’obiettivo è di comprendere come progettiamo un’interfaccia tra mondo dei modelli e mondo dei sistemi reali, come database, API e servizi locali.

Progettazione di un MCP Server

Quando implementiamo un MCP Server, partiamo sempre da un principio fondamentale, ovvero che tutto ciò che esponiamo deve essere descrivibile, invocabile e controllabile tramite il protocollo JSON-RPC. Questo significa che ogni "tool" non è altro che una funzione dichiarata, con input e output ben definiti, accessibile attraverso una chiamata standardizzata.

Per rendere il concetto concreto, immaginiamo di voler costruire un piccolo MCP Server che espone due strumenti: uno per ottenere la temperatura di una città e uno per sommare due numeri. Nonostante la semplicità, questo esempio ci permette di coprire l’intero ciclo di vita di un tool MCP: registrazione, discovery ed esecuzione.

Implementazione di un MCP Server con Node.js

Scegliamo Node.js per la sua semplicità e diffusione, ma lo stesso concetto sarebbe identico in Python, Go o altri linguaggi.

Iniziamo creando un server HTTP che riceve richieste JSON-RPC. Non stiamo ancora introducendo dipendenze MCP ufficiali, ma stiamo simulando il comportamento standard del protocollo.

import express from "express";
const app = express();
app.use(express.json());
// Database simulato per la temperatura
const weatherDB = {
  rome: 22,
  milan: 18,
  naples: 26
};
// Dispatcher JSON-RPC
app.post("/mcp", (req, res) => {
  const { id, method, params } = req.body;
  if (method === "tools/list") {
    return res.json({
      jsonrpc: "2.0",
      id,
      result: {
        tools: [
          {
            name: "get_temperature",
            description: "Restituisce la temperatura di una città",
            inputSchema: {
              type: "object",
              properties: {
                city: { type: "string" }
              },
              required: ["city"]
            }
          },
          {
            name: "add_numbers",
            description: "Somma due numeri interi",
            inputSchema: {
              type: "object",
              properties: {
                a: { type: "number" },
                b: { type: "number" }
              },
              required: ["a", "b"]
            }
          }
        ]
      }
    });
  }
  if (method === "tools/call") {
    const { name, arguments: args } = params;
    if (name === "get_temperature") {
      const city = args.city.toLowerCase();
      const temp = weatherDB[city] ?? null;
      return res.json({
        jsonrpc: "2.0",
        id,
        result: {
          content: temp !== null
            ? `La temperatura a ${city} è ${temp}°C`
            : `Dati non disponibili per ${city}`
        }
      });
    }
    if (name === "add_numbers") {
      const result = args.a + args.b;
      return res.json({
        jsonrpc: "2.0",
        id,
        result: {
          content: `Risultato: ${result}`
        }
      });
    }
  }
  return res.status(404).json({
    jsonrpc: "2.0",
    id,
    error: {
      code: -32601,
      message: "Metodo non supportato"
    }
  });
});
app.listen(3000, () => {
  console.log("MCP Server in esecuzione su http://localhost:3000/mcp");
});

Chiamata ed esecuzione

La chiamata tools/list rappresenta il momento in cui il client MCP interroga il server per capire quali strumenti sono disponibili. Questo passaggio è cruciale perché consente ai modelli di adattarsi dinamicamente alle capacità del sistema, senza hardcoding.

La chiamata tools/call invece rappresenta l’esecuzione effettiva. Qui il modello (tramite il client MCP) invia il nome dello strumento e i parametri, e il server restituisce un risultato strutturato.

Questa separazione tra scoperta ed esecuzione è uno degli elementi che rende MCP un protocollo robusto e scalabile.

Simulazione di una richiesta MCP

Per capire meglio il flusso, immaginiamo una richiesta JSON-RPC inviata al nostro server per ottenere la temperatura di Roma.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_temperature",
    "arguments": {
      "city": "Rome"
    }
  }
}

La risposta del server sarà:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": "La temperatura a rome è 22°C"
  }
}

Questo formato standardizzato consente a qualsiasi client MCP di interpretare la risposta senza ambiguità, indipendentemente dall’implementazione interna del server.

Integrazione con dati reali e servizi esterni

Un MCP Server reale raramente lavora su dati statici come nel nostro esempio. Più spesso, siamo chiamati a integrare API esterne, database o sistemi aziendali.

Immaginiamo di voler sostituire il nostro dizionario statico con una chiamata a un servizio meteo esterno. In questo caso, il tool get_temperature diventerebbe una funzione asincrona che interroga una API REST.

async function fetchTemperature(city) {
  const response = await fetch(`https://api.weather.example.com/${city}`);
  const data = await response.json();
  return data.temperature;
}

All’interno del nostro handler MCP, possiamo quindi integrare questa funzione trasformando il tool in un vero punto di accesso a dati esterni in tempo reale. In questo passaggio, il server non si limita più a restituire valori predefiniti, ma diventa responsabile di orchestrare la chiamata verso l’API, gestire eventuali errori e normalizzare la risposta in un formato coerente con il protocollo.

if (name === "get_temperature") {
  const city = args.city.toLowerCase();
  const temp = await fetchTemperature(city);
  return res.json({
    jsonrpc: "2.0",
    id,
    result: {
      content: 'La temperatura a ${city} è ${temp}°C'
    }
  });
}

Conclusioni

Nel momento in cui passiamo da un’implementazione dimostrativa a un utilizzo reale, emerge con chiarezza un aspetto fondamentale: un MCP Server non può essere considerato soltanto come un semplice esecutore di funzioni, ma deve essere progettato tenendo conto dello stato e della scalabilità del sistema nel suo complesso. Nel nostro esempio abbiamo lavorato in un contesto completamente stateless, dove ogni richiesta è indipendente e non esiste memoria tra una chiamata e l’altra.

Questo approccio è utile per comprendere i meccanismi di base del protocollo, ma nella pratica i tool MCP interagiscono molto spesso con sessioni utente, contesti applicativi o dati temporanei che devono essere preservati nel tempo. Pensiamo, ad esempio, a un sistema che gestisce conversazioni multi-turno, oppure a un flusso operativo che richiede più passaggi consecutivi: in questi casi diventa necessario introdurre un livello di gestione dello stato.

Per risolvere questa esigenza, possiamo integrare componenti come sistemi di caching o database persistenti. Tecnologie come Redis consentono di mantenere uno stato leggero e veloce tra richieste successive, mentre database relazionali o NoSQL permettono di gestire informazioni strutturate e durature. È importante sottolineare che questa scelta non è imposta dal protocollo MCP: al contrario, MCP rimane volutamente agnostico rispetto alla gestione dello stato, lasciando a noi la libertà di definire l’architettura più adatta al contesto applicativo.

Questa flessibilità è uno dei punti di forza del protocollo, perché consente di adattarlo tanto a microservizi leggeri quanto a sistemi enterprise complessi. Nella prossima lezione entreremo nel mondo delle applicazioni reali, esplorando integrazioni avanzate e best practice.

Se vuoi aggiornamenti su Implementare un MCP Server e integrare strumenti e dati inserisci la tua email nel box qui sotto:

Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.

Ti consigliamo anche