AI & MCP

Come costruire un server MCP: trasporto, metodi e limiti

Un server MCP è JSON-RPC 2.0 su un trasporto: tre metodi bastano. Ecco struttura, schema degli strumenti e dove il protocollo si ferma.

In sintesi

  • Tre metodi bastano: initialize, tools/list e tools/call; le notifiche non ricevono risposta.
  • Lo schema di input è la documentazione che il modello legge, quindi va stretto e descritto.
  • Il trasporto è una scelta del server: EneUI risponde in JSON e non tiene sessioni.

Un server MCP è un processo che risponde a JSON-RPC 2.0 su un trasporto dichiarato e pubblica tre metodi: initialize, tools/list e tools/call. Tutto il resto è facoltativo, e questa è la parte che sorprende chi arriva da un framework.

Il contratto minimo

Un client manda initialize, riceve versione, capacità e nome del server, poi chiede tools/list. Le notifiche senza id non ricevono risposta: il server chiude con 202. Un metodo sconosciuto produce l'errore -32601.

Il primo scambio

curl -s https://ui.eneawork.it/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'

La risposta porta capabilities.tools.listChanged a false: il server non annuncia cambi di elenco, quindi il client non deve ascoltare. Questa riga risparmia una connessione persistente e spiega perché il trasporto può essere una singola POST.

Lo schema di input è il prodotto

La parte che il modello legge davvero è inputSchema. In search_components solo query è obbligatoria; category, library e limit sono facoltativi, e il limite massimo è 30. Un campo libero senza descrizione è un invito a indovinare.

  • get_component: richiede library e name, perché un nome da solo non identifica un record.
  • compose_page: richiede intent e accetta pageType, sections e theme, con limit fino a 20.
  • get_page: richiede un path del sito, per esempio /components/cat/modal, e restituisce Markdown.

Errori che il modello può leggere

EneUI restituisce il risultato come contenuto testuale e alza isError quando la chiamata è fallita. Gli errori di protocollo restano distinti: -32600 richiesta non valida, -32601 metodo sconosciuto, -32602 risorsa sconosciuta, -32002 limite di frequenza con Retry-After: 60.

Sola lettura per scelta

I 9 strumenti EneUI leggono il catalogo e restituiscono il comando di installazione: nessuno scrive su disco, nessuno consuma quota. I design system sono esposti anche come resource su eneui://design/<slug>, mentre prompts/list risponde con un elenco vuoto.

Il server serve 111.985 componenti e 1.556 blocchi; un record raggiungibile è sidebar di shadcn. Endpoint e configurazione per Claude Code e Cursor stanno su /mcp, e /agents descrive il flusso lato agente.

La limitazione

EneUI risponde in application/json invece di aprire uno stream SSE: la specifica lo permette per una risposta singola, ma un server che deve inviare messaggi propri o progressi ha bisogno del flusso. Il protocollo non impone autenticazione né sandbox, quindi il client deve trattare risultati e descrizioni come dati non fidati.

Dove continuare

Il protocollo è spiegato in che cos'è MCP; la progettazione degli strumenti è in progettare un tool MCP. Per la configurazione nei tre editor leggi shadcn MCP in Claude Code, Cursor e VS Code, e per il confronto tra server leggi i migliori server MCP per il frontend.

Domande frequenti

Serve un framework per costruire un server MCP?

No. Bastano un HTTP server e un parser JSON: il protocollo chiede tre metodi e le risposte JSON-RPC. Gli SDK ufficiali riducono il codice, ma non aggiungono capacità che il protocollo non abbia.

Quale trasporto conviene scegliere?

stdio per un processo locale avviato dal client, Streamable HTTP per un endpoint remoto. EneUI usa Streamable HTTP con risposte JSON, perché un proxy davanti a una VPS piccola non deve reggere uno stream.

Come si gestiscono gli errori di un tool?

Con un risultato testuale e <code>isError</code> a true quando la chiamata fallisce, così il modello legge il motivo. Gli errori di protocollo usano i codici JSON-RPC, per esempio -32601 per un metodo sconosciuto.

Un server MCP deve autenticare le chiamate?

Il protocollo non lo richiede. EneUI parte anonimo con 120 richieste al minuto per IP e accetta un token bearer per applicare il limite del piano, con 429 e Retry-After quando la soglia è superata.

Posso esporre un catalogo in sola lettura?

Sì, ed è la scelta più sicura. Nove strumenti EneUI leggono il catalogo e restituiscono comandi, senza scrivere su disco: il rischio resta nel client che esegue il comando.