Salta al contenuto principale

05 - Creare un Client MCP e Transport HTTP

Implementare un client MCP: transport stdio vs HTTP/SSE, connessione programmatica ai server, gestione sessioni e integrazione custom.

Cosa ne pensi di questo articolo?

In Breve

Implementare un client MCP: transport stdio vs HTTP/SSE, connessione programmatica ai server, gestione sessioni e integrazione custom.

Aggiornamento del 2026-10-30: la sessione HTTP non esiste più nella specifica corrente

In breve: la revisione 2026-07-28 del protocollo ha rimosso le sessioni a livello di protocollo e l'header Mcp-Session-Id. Questo articolo (scritto sulla revisione precedente) descrive ancora il comportamento corretto per client e server fermi a 2025-11-25 o precedenti, che restano diffusi, ma non è più il modello da adottare per nuovi server.

  • Cosa è cambiato: niente handshake initialize; ogni richiesta porta versione del protocollo e capacità del client nel campo _meta, e l'header MCP-Protocol-Version è obbligatorio su ogni POST. Il nuovo RPC server/discover restituisce versioni supportate, capacità e identità del server.
  • Transport: l'endpoint HTTP accetta solo POST. Il GET che apriva lo stream SSE e il DELETE di fine sessione non fanno più parte del protocollo (un server che supporta solo la nuova revisione risponde 405). Le notifiche di cambiamento passano da una richiesta subscriptions/listen. La ripresa degli stream con Last-Event-ID è stata rimossa: se lo stream cade, la richiesta in corso è persa e va riemessa con un nuovo ID.
  • Stato tra una chiamata e l'altra: se serve, il server emette un identificativo esplicito (handle) che il client passa come normale argomento di un tool. Il pattern "mappa sessioni" di questo articolo diventa quindi una tabella di handle gestita dal server.
  • Trade-off: senza sessioni un server si scala orizzontalmente dietro un load balancer senza sticky session, ma lo stato per-client passa a te (handle, scadenza, pulizia). In cambio perdi la ripresa dello stream interrotto.
  • Compatibilità: un client che vuole parlare con entrambe le generazioni prova prima la richiesta moderna e, se riceve un 400 che non è un errore JSON-RPC riconosciuto, ripiega su initialize.
  • SDK TypeScript: al 2026-10-30 le release più recenti elencate nella pagina GitHub sono la 2.4.0 (pacchetti separati @modelcontextprotocol/server, /client, /core) e la 1.32.2 della linea v1 (@modelcontextprotocol/sdk, quella usata negli esempi qui sotto). Prima di migrare consulta la guida di upgrade v1→v2: gli import degli esempi vanno verificati contro il pacchetto che installi.
Caso d'uso: grande impresa, un server MCP davanti a un sistema di ticketing esistente

Chi: il team piattaforma di un'azienda con un gateway API centrale e un sistema di ticketing già in produzione. Compito a mano oggi: ogni assistente (IDE, chat interna) ha il suo connettore scritto ad hoc; la regola N x M dell'articolo 1 vale qui alla lettera. Cosa cambia esattamente: si espone un solo server MCP in sola lettura sull'endpoint HTTP. Con la revisione 2026-07-28 ogni POST porta gli header Mcp-Method e Mcp-Name (nome del tool): il gateway può consentire search_tickets, negare un eventuale close_ticket e applicare limiti di frequenza per tenant senza leggere il corpo della richiesta, e senza sticky session perché le sessioni non esistono più. Il server deve validare l'header Origin (risposta 403 se non valido), e le richieste con header e corpo incoerenti vengono rifiutate con 400 e codice -32020. Cosa va storto: un intermediario che applica policy sugli header deve rifiutare le richieste con versione di protocollo vecchia o assente, altrimenti si fida di header non validati (indicazione della specifica). E soprattutto: il risultato del tool arriva al modello, quindi il limite non è la capacità del protocollo ma quali campi del ticket (nomi di clienti, dati personali) è permesso mandare al fornitore del modello. Filtra i campi nel server, non nel prompt. Costo: non ho una cifra verificata; misura prima quante integrazioni custom mantieni oggi e quante ore l'anno richiedono.

Caso d'uso: piccola impresa o studio senza reparto IT

Un server MCP su STDIO gira come processo locale sul PC di chi lo usa: nessuna porta aperta, nessun gateway, nessun costo di hosting. Per uno studio di 3 persone che vuole far interrogare all'assistente una cartella di preventivi in sola lettura è l'opzione più semplice. Il limite: il contenuto letto passa comunque al modello, quindi per documenti con dati di clienti verifica le condizioni del fornitore prima di collegarlo, e dai al server accesso a una sola cartella, mai alla home.

Fonti (consultate il 2026-10-30): changelog della specifica 2026-07-28, transport Streamable HTTP, release dell'SDK TypeScript.

Introduzione: Dal Server al Client MCP

Negli articoli precedenti abbiamo costruito server MCP che espongono tool, risorse e prompt. Ma chi consuma queste funzionalità? Il Client MCP e il componente software che si connette a uno o più server, scopre i tool disponibili e li invoca per conto di un modello linguistico.

In questo articolo esploreremo come costruire un client MCP programmatico in TypeScript, confronteremo i due principali meccanismi di trasporto (STDIO e Streamable HTTP), analizzeremo la gestione delle sessioni e vedremo come integrare un server MCP in un'applicazione web Express. Tutto il codice e disponibile nel repository Tech-MCP.

Cosa Imparerai in Questo Articolo

  • Come creare un client MCP con l'SDK ufficiale TypeScript
  • Il ciclo tool-use: query, decisione dell'AI, invocazione, risposta
  • Transport STDIO: connessione locale via processo figlio
  • Transport Streamable HTTP: server indipendente accessibile via rete
  • Gestione delle sessioni con session ID e riconnessione
  • Pattern multi-server e InMemoryTransport per testing
  • Sicurezza del transport HTTP: Origin validation, autenticazione Bearer

Setup del Progetto Client

Per creare un client MCP da zero, iniziamo con il setup del progetto TypeScript. L'SDK @modelcontextprotocol/sdk fornisce tutto il necessario per il lato client, mentre @anthropic-ai/sdk permette di integrare Claude come modello decisionale.


mkdir mcp-client && cd mcp-client
npm init -y
npm install @modelcontextprotocol/sdk @anthropic-ai/sdk dotenv
npm install -D typescript @types/node
    

Configura tsconfig.json come nel progetto server e aggiungi gli script al package.json:


{
  "type": "module",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  }
}
    

Crea il file .env con la tua API key Anthropic:


ANTHROPIC_API_KEY=sk-ant-...
    

Client MCP con Transport STDIO

Il transport STDIO e il meccanismo più semplice per connettere un client a un server MCP. Il client lancia il server come processo figlio e comunica tramite standard input/output. Ogni messaggio e un oggetto JSON-RPC separato da newline, mentre stderr resta disponibile per il logging.

Architettura del Client STDIO

Il flusso di una connessione STDIO segue questi passaggi:

  1. Il client crea un StdioClientTransport specificando comando e argomenti del server
  2. Il metodo connect() lancia il processo figlio ed esegue l'handshake initialize / initialized
  3. Il client scopre i tool disponibili con listTools()
  4. A ogni query utente, il client invoca Claude con la lista dei tool e gestisce il ciclo tool-use

Implementazione Completa del Client STDIO

Ecco il codice completo di un client CLI interattivo che usa Claude come modello decisionale:


import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import Anthropic from "@anthropic-ai/sdk";
import { config } from "dotenv";
import * as readline from "node:readline";

config(); // Carica variabili da .env

// Tipo per i tool compatibili con l'API Anthropic
interface AnthropicTool {
  name: string;
  description: string | undefined;
  input_schema: Record<string, unknown>;
}

class McpChatClient {
  private client: Client;
  private anthropic: Anthropic;
  private tools: AnthropicTool[] = [];

  constructor() {
    this.client = new Client({
      name: "mcp-chat-client",
      version: "1.0.0",
    });
    this.anthropic = new Anthropic();
  }

  /**
   * Connessione al server MCP via STDIO.
   * Il client lancia il server come processo figlio.
   */
  async connect(serverCommand: string, serverArgs: string[]): Promise<void> {
    const transport = new StdioClientTransport({
      command: serverCommand,
      args: serverArgs,
    });

    // connect() esegue il lifecycle: initialize -> initialized
    await this.client.connect(transport);

    // Scopri i tool disponibili
    const result = await this.client.listTools();
    this.tools = result.tools.map((tool) => ({
      name: tool.name,
      description: tool.description,
      input_schema: tool.inputSchema as Record<string, unknown>,
    }));

    console.error(
      `Connesso. Tool disponibili: ${this.tools.map((t) => t.name).join(", ")}`
    );
  }

  /**
   * Elabora una query utente con il ciclo tool-use di Claude.
   */
  async chat(userMessage: string): Promise<string> {
    const messages: Anthropic.MessageParam[] = [
      { role: "user", content: userMessage },
    ];

    let response = await this.anthropic.messages.create({
      model: "claude-sonnet-4-20250514",
      max_tokens: 4096,
      messages,
      tools: this.tools as Anthropic.Tool[],
    });

    // Ciclo tool-use: Claude può richiedere più tool in sequenza
    while (response.stop_reason === "tool_use") {
      const assistantContent = response.content;
      messages.push({ role: "assistant", content: assistantContent });

      const toolResults: Anthropic.ToolResultBlockParam[] = [];

      for (const block of assistantContent) {
        if (block.type === "tool_use") {
          console.error(`  -> Invocazione: ${block.name}`);

          // Chiama il tool sul server MCP
          const result = await this.client.callTool({
            name: block.name,
            arguments: block.input as Record<string, unknown>,
          });

          const text = (result.content as Array<{ type: string; text: string }>)
            .map((c) => c.text)
            .join("\n");

          toolResults.push({
            type: "tool_result",
            tool_use_id: block.id,
            content: text,
          });
        }
      }

      messages.push({ role: "user", content: toolResults });

      response = await this.anthropic.messages.create({
        model: "claude-sonnet-4-20250514",
        max_tokens: 4096,
        messages,
        tools: this.tools as Anthropic.Tool[],
      });
    }

    return response.content
      .filter((block): block is Anthropic.TextBlock => block.type === "text")
      .map((block) => block.text)
      .join("\n");
  }

  async disconnect(): Promise<void> {
    await this.client.close();
  }
}
    

Il Flusso Tool-Use in Dettaglio

Il cuore del client MCP e il ciclo tool-use, un meccanismo iterativo che permette all'AI di decidere autonomamente quali tool invocare per rispondere a una query. Ecco il flusso completo:


  Utente          Client             Claude API          Server MCP
    |                |                    |                   |
    | "Aggiungi      |                    |                   |
    |  nota X"       |                    |                   |
    | ────────────>  |                    |                   |
    |                | ── messages ─────> |                   |
    |                |    + tools list    |                   |
    |                |                    |                   |
    |                | <── tool_use ────  |                   |
    |                |    "add-note"      |                   |
    |                |                    |                   |
    |                | ── callTool ────────────────────────>  |
    |                |    "add-note"      |                   |
    |                | <── result ─────────────────────────   |
    |                |                    |                   |
    |                | ── tool_result ──> |                   |
    |                |                    |                   |
    |                | <── text ────────  |                   |
    |                |    "Nota salvata"  |                   |
    | <────────────  |                    |                   |
    | "Nota salvata" |                    |                   |
    

Passaggi Chiave del Ciclo

  1. Il client invia la query utente a Claude insieme alla lista dei tool (nomi, descrizioni, schemi JSON)
  2. Claude analizza la query e decide se usare un tool (risponde con stop_reason: "tool_use")
  3. Il client invoca il tool sul server MCP con client.callTool()
  4. Il risultato torna a Claude come tool_result
  5. Claude può richiedere altri tool o generare la risposta finale (stop_reason: "end_turn")

Transport STDIO vs Streamable HTTP

L'SDK MCP supporta due meccanismi di trasporto fondamentalmente diversi. La scelta tra i due dipende dal caso d'uso, dall'architettura del sistema e dai requisiti di deployment.

Confronto STDIO vs Streamable HTTP

Aspetto STDIO Streamable HTTP
Architettura Il client lancia il server come processo figlio Il server e un servizio indipendente
Connessioni 1:1 (un client per processo) N:1 (molti client, un server)
Deployment Solo locale, stesso host Locale o remoto, qualsiasi rete
Sessioni Implicita (vita del processo) Esplicita (session ID nell'header)
Autenticazione Non necessaria (stesso host) Necessaria (Bearer token, OAuth)
Scalabilità Limitata (un processo per client) Alta (un server, molti client)
Caso d'uso Claude Desktop, IDE, sviluppo locale Microservizi, API condivise, produzione
Complessità setup Minima Richiede server HTTP (Express, Fastify)

In generale, STDIO e la scelta migliore per lo sviluppo locale e l'integrazione con applicazioni desktop come Claude Desktop e Cursor. Streamable HTTP e necessario quando il server deve essere accessibile da più client, da host remoti, o in ambienti di produzione containerizzati.

Server MCP con Transport HTTP (Express)

Per esporre un server MCP via HTTP, l'SDK fornisce StreamableHTTPServerTransport che si integra nativamente con Express. Il server diventa un servizio indipendente che accetta connessioni da qualsiasi client compatibile.

Setup delle Dipendenze


npm install express
npm install -D @types/express
    

Implementazione del Server HTTP


import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport }
  from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import express from "express";
import { randomUUID } from "node:crypto";
import { z } from "zod";

// Crea il server MCP (stessa API di STDIO)
const server = new McpServer({
  name: "notes-http-server",
  version: "1.0.0",
});

// Registra i tool
const notes: Map<string, string> = new Map();

server.tool(
  "add-note",
  "Aggiunge una nuova nota",
  {
    title: z.string(),
    content: z.string(),
  },
  async ({ title, content }) => {
    notes.set(title, content);
    return {
      content: [{ type: "text", text: `Nota "${title}" salvata.` }],
    };
  },
);

// --- Transport HTTP con Express ---
const app = express();
app.use(express.json());

// Crea transport con generatore di sessioni
const transport = new StreamableHTTPServerTransport({
  sessionIdGenerator: () => randomUUID(),
});

// Connetti il server MCP al transport
await server.connect(transport);

// Endpoint MCP: POST (messaggi client -> server)
app.post("/mcp", async (req, res) => {
  await transport.handleRequest(req, res, req.body);
});

// Endpoint MCP: GET (SSE stream server -> client)
app.get("/mcp", async (req, res) => {
  await transport.handleRequest(req, res);
});

// Endpoint MCP: DELETE (terminazione sessione)
app.delete("/mcp", async (req, res) => {
  await transport.handleRequest(req, res);
});

// Health check
app.get("/health", (_req, res) => {
  res.json({ status: "ok", server: "notes-http-server" });
});

const PORT = process.env.PORT ?? 3000;
app.listen(PORT, () => {
  console.log(`Server MCP HTTP su http://localhost:${PORT}/mcp`);
});
    

Endpoint e Protocollo HTTP

Il server espone un singolo path /mcp con tre metodi HTTP, ognuno con una funzione specifica nel protocollo MCP:

  • POST /mcp - Il client invia messaggi JSON-RPC (request, notification, response). Questo e il canale principale per l'invocazione dei tool.
  • GET /mcp - Il client apre un SSE (Server-Sent Events) stream per ricevere notifiche push dal server in tempo reale.
  • DELETE /mcp - Il client termina esplicitamente la sessione, liberando le risorse lato server.

Differenza Fondamentale rispetto a STDIO

Con STDIO, ogni connessione crea un nuovo processo server. Con HTTP, il server si connette al transport una sola volta con server.connect(transport) e gestisce tutte le sessioni concorrentemente. Il sessionIdGenerator assegna un UUID univoco a ogni client che si connette.

Client MCP con Transport HTTP

Per connettersi a un server HTTP, l'SDK fornisce StreamableHTTPClientTransport. L'API del client rimane identica a quella STDIO: una volta stabilità la connessione, listTools(), callTool() e close() funzionano esattamente allo stesso modo.


import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport }
  from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({
  name: "http-client",
  version: "1.0.0",
});

const transport = new StreamableHTTPClientTransport(
  new URL("http://localhost:3000/mcp"),
);

await client.connect(transport);

// Da qui in poi, stessa API di STDIO
const tools = await client.listTools();
console.log("Tool disponibili:", tools.tools.map((t) => t.name));

const result = await client.callTool({
  name: "add-note",
  arguments: { title: "Test", content: "Contenuto di prova" },
});
console.log("Risultato:", result);

await client.close();
    

L'aspetto fondamentale e che il codice applicativo e identico indipendentemente dal transport. La scelta tra STDIO e HTTP e una decisione infrastrutturale, non architetturale: la logica di business del client resta invariata.

Gestione delle Sessioni

La gestione delle sessioni e uno degli aspetti più importanti del transport HTTP. Mentre in STDIO la sessione e implicita (coincide con la vita del processo), in HTTP ogni connessione client riceve un session ID univoco che deve essere incluso in tutte le richieste successive.

Come Funzionano le Sessioni

  1. Il client invia la prima richiesta initialize senza session ID
  2. Il server genera un UUID con sessionIdGenerator e lo restituisce nell'header Mcp-Session-Id
  3. Il client include Mcp-Session-Id in tutte le richieste successive
  4. Il server associa ogni richiesta alla sessione corretta e mantiene lo stato
  5. Alla disconnessione, il client invia DELETE /mcp per terminare la sessione

Il StreamableHTTPClientTransport gestisce automaticamente:

  • L'invio dell'header Mcp-Session-Id dopo l'inizializzazione
  • L'invio dell'header MCP-Protocol-Version in tutte le richieste
  • La riconnessione in caso di sessione scaduta (HTTP 404)

Pattern Stateful: Stato per Sessione

In produzione, ogni sessione può avere il proprio stato isolato. Ecco come implementarlo:


import { randomUUID } from "node:crypto";

// Mappa sessioni -> stato isolato
const sessions = new Map<string, { notes: Map<string, string> }>();

const transport = new StreamableHTTPServerTransport({
  sessionIdGenerator: () => {
    const sessionId = randomUUID();
    sessions.set(sessionId, { notes: new Map() });
    return sessionId;
  },
});
    

Connessione a Server Multipli

Un client MCP può connettersi a più server contemporaneamente, aggregando i tool disponibili in un'unica lista. Questo pattern e fondamentale in architetture complesse dove i tool sono distribuiti su server specializzati.


class MultiServerClient {
  private clients: Map<string, Client> = new Map();
  private allTools: AnthropicTool[] = [];

  async addServer(
    name: string, command: string, args: string[]
  ): Promise<void> {
    const client = new Client({
      name: `client-${name}`,
      version: "1.0.0"
    });
    const transport = new StdioClientTransport({ command, args });
    await client.connect(transport);

    const result = await client.listTools();
    for (const tool of result.tools) {
      this.allTools.push({
        // Prefisso per evitare collisioni di nomi
        name: `${name}__${tool.name}`,
        description: `[${name}] ${tool.description}`,
        input_schema: tool.inputSchema as Record<string, unknown>,
      });
    }

    this.clients.set(name, client);
  }

  async callTool(
    prefixedName: string, args: Record<string, unknown>
  ): Promise<unknown> {
    const [serverName, toolName] = prefixedName.split("__");
    const client = this.clients.get(serverName);
    if (!client) throw new Error(`Server ${serverName} non connesso`);
    return client.callTool({ name: toolName, arguments: args });
  }
}
    

Il prefisso serverName__toolName e essenziale per evitare collisioni quando server diversi espongono tool con lo stesso nome. Claude riceve la lista completa e il client si occupa del routing.

Dual Transport: Supportare STDIO e HTTP

Un server MCP professionale dovrebbe supportare entrambi i transport, decidendo quale usare in base alla configurazione. Questo permette di utilizzare lo stesso codice sia con Claude Desktop (STDIO) che in produzione (HTTP).


import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { StreamableHTTPServerTransport }
  from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import express from "express";
import { randomUUID } from "node:crypto";

function createServer(): McpServer {
  const server = new McpServer({ name: "my-server", version: "1.0.0" });
  // ... registra tool, resource, prompt ...
  return server;
}

// Avvio condizionale basato su variabile d'ambiente
const mode = process.env.MCP_TRANSPORT ?? "stdio";

if (mode === "http") {
  const server = createServer();
  const app = express();
  app.use(express.json());

  const transport = new StreamableHTTPServerTransport({
    sessionIdGenerator: () => randomUUID(),
  });
  await server.connect(transport);

  app.post("/mcp", async (req, res) =>
    await transport.handleRequest(req, res, req.body));
  app.get("/mcp", async (req, res) =>
    await transport.handleRequest(req, res));
  app.delete("/mcp", async (req, res) =>
    await transport.handleRequest(req, res));
  app.get("/health", (_, res) => res.json({ status: "ok" }));

  const port = process.env.PORT ?? 3000;
  app.listen(port, () => console.log(`HTTP su porta ${port}`));
} else {
  const server = createServer();
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Server avviato su STDIO");
}
    

Configurazione del Transport

  • MCP_TRANSPORT=stdio (default) - Per Claude Desktop e IDE locali
  • MCP_TRANSPORT=http PORT=3000 - Per deployment HTTP e microservizi

InMemoryTransport per il Testing

Per i test unitari non serve lanciare processi o server HTTP. L'SDK fornisce InMemoryTransport che collega direttamente client e server in memoria:


import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

async function testInMemory() {
  const server = new McpServer({ name: "test-server", version: "1.0.0" });
  server.tool("ping", "Test ping", {}, async () => ({
    content: [{ type: "text", text: "pong" }],
  }));

  // Crea coppia di transport collegati
  const [clientTransport, serverTransport] =
    InMemoryTransport.createLinkedPair();

  // IMPORTANTE: il server si connette PRIMA del client
  await server.connect(serverTransport);

  const client = new Client({ name: "test-client", version: "1.0.0" });
  await client.connect(clientTransport);

  const result = await client.callTool({ name: "ping", arguments: {} });
  console.log(result);
  // { content: [{ type: "text", text: "pong" }] }

  await client.close();
  await server.close();
}
    

Ordine Critico di Connessione

Con InMemoryTransport, server.connect() deve essere chiamato prima di client.connect(). Il client invia il messaggio initialize immediatamente al connect(), e il server deve gia essere in ascolto per rispondere.

Sicurezza del Transport HTTP

Quando il server MCP e esposto via HTTP, la sicurezza diventa un aspetto critico. Ecco le misure fondamentali da implementare.

Validazione dell'Origin

Per prevenire attacchi di DNS rebinding, valida l'header Origin di ogni richiesta:


app.use((req, res, next) => {
  const origin = req.headers.origin;
  const allowed = [
    "http://localhost:3000",
    "https://myapp.example.com"
  ];
  if (origin && !allowed.includes(origin)) {
    res.status(403).json({ error: "Origin non consentito" });
    return;
  }
  next();
});
    

Binding Locale e Autenticazione Bearer

Per server locali, binda solo su 127.0.0.1. Per server remoti, implementa autenticazione con Bearer token:


// Binding solo locale
app.listen(port, "127.0.0.1", () => {
  console.log(`Server solo su localhost:${port}`);
});

// Autenticazione per server remoti
app.use("/mcp", (req, res, next) => {
  const auth = req.headers.authorization;
  if (!auth?.startsWith("Bearer ")) {
    res.status(401).json({ error: "Token mancante" });
    return;
  }
  const token = auth.slice(7);
  if (!isValidToken(token)) {
    res.status(403).json({ error: "Token non valido" });
    return;
  }
  next();
});
    

Riepilogo

In questo articolo abbiamo esplorato in profondità il lato client del protocollo MCP e i due meccanismi di trasporto fondamentali. Ecco i concetti chiave:

  1. Un client MCP si connette a uno o più server, scopre i tool e li invoca per conto di un modello linguistico
  2. Il ciclo tool-use permette all'AI di decidere autonomamente quali tool chiamare, con il client che funge da intermediario
  3. STDIO e ideale per lo sviluppo locale e le integrazioni desktop (Claude Desktop, Cursor)
  4. Streamable HTTP e necessario per server remoti, connessioni multiple e ambienti di produzione
  5. La gestione delle sessioni con session ID garantisce l'isolamento dello stato tra client diversi
  6. Il pattern dual transport permette di supportare entrambe le modalità con lo stesso codice
  7. InMemoryTransport semplifica il testing senza processi o server HTTP

Nel prossimo articolo approfondiremo i Pacchetti Condivisi del monorepo Tech-MCP: il pacchetto Core con utility comuni, l'EventBus per la comunicazione inter-server e i moduli di accesso al database. Vedremo come strutturare codice riutilizzabile in un monorepo TypeScript professionale.

Il codice completo di tutti gli esempi e disponibile nel repository Tech-MCP su GitHub.

Prova Questi Strumenti

Strumenti gratuiti correlati a questo argomento.

Commenti

Caricamento commenti...

Accedi per commentare

Discuti questo articolo nella community

Unisciti al gruppo Telegram per discutere con altri sviluppatori, fare domande e condividere le tue esperienze.

Ti è piaciuto questo articolo?

Esplora altri contenuti sul blog o scopri i miei progetti