Standardizzazione delle integrazioni di IA con Model Context Protocol (MCP)
Una guida pratica alla creazione e alla messa in sicurezza di server MCP personalizzati per connettere in modo sicuro i dati aziendali agli agenti di sviluppo di IA.

Collegare i modelli linguistici di grandi dimensioni (LLM) a fonti di dati e sistemi interni è storicamente un'attività frammentata e ad-hoc. Ogni progetto di ingegneria dell'IA inizia solitamente con la scrittura di wrapper API personalizzati, la mappatura di schemi JSON o la scrittura di codice di integrazione proprietario all'interno dei runtime dell'orchestratore per gestire le chiamate ai tool.
Se si passa da OpenAI ad Anthropic, o se i programmatori passano da un IDE assistito dall'IA a un altro, spesso è necessario riscrivere l'intero layer di integrazione.
Questa frizione è il motivo per cui il Model Context Protocol (MCP), uno standard aperto promosso da Anthropic, ha rapidamente guadagnato terreno. Proprio come il Language Server Protocol (LSP) ha standardizzato il modo in cui i compilatori comunicano con gli editor di codice, l'MCP standardizza il modo in cui i modelli di IA comunicano con le fonti di dati e gli strumenti di sviluppo.
Ecco una guida pratica alla creazione, alla strutturazione e alla protezione di un server MCP personalizzato per esporre in sicurezza i dati aziendali ai propri agenti di sviluppo.
L'architettura: disaccoppiamento di client e server
Il principio fondamentale del design di MCP è il disaccoppiamento. Invece di cablare le integrazioni API direttamente nel runtime di un agente, l'MCP introduce un'architettura client-server:
[ AI Agent / IDE ] (MCP Client)
│
│ (JSON-RPC 2.0 over Stdio or SSE)
▼
[ Custom MCP Server ]
│
├─► Secure Database (PostgreSQL / BigQuery)
├─► Internal Microservices
└─► Local Development Tools- Client MCP: Il coordinatore (ad esempio, Cursor, Windsurf o un orchestratore LangChain personalizzato). Gestisce il ragionamento del LLM, mantiene il contesto dell'utente e avvia le richieste dei tool.
- Server MCP: Un processo o servizio leggero che espone tre primitive principali:
- Prompts: Modelli riutilizzabili per guidare le interazioni del modello.
- Resources: Fonti di dati in sola lettura (contenuto di file, righe di database, risposte API).
- Tools: Funzioni eseguibili che possono eseguire operazioni o chiamare API esterne.
Creare un server MCP personalizzato in TypeScript
Creiamo un server MCP pronto per la produzione utilizzando Node.js e l'SDK TypeScript ufficiale. Questo server esporrà uno strumento sicuro per cercare record in un database interno (ad esempio, candidati o casi di studio) con una validazione rigorosa degli argomenti a runtime.
1. Inizializzazione del progetto
Per prima cosa, configura un progetto TypeScript e installa le dipendenze necessarie:
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install --save-dev typescript @types/node
npx tsc --init2. Implementazione del server
Di seguito è riportato il codice per un server MCP sicuro basato su stdio. Registriamo uno strumento di ricerca e usiamo zod per imporre una validazione rigorosa dello schema sui payload in entrata:
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
// 1. Initialize the MCP Server
const server = new Server(
{
name: "enterprise-search-service",
version: "1.0.0",
},
{
capabilities: {
tools: {}, // Advertise tool capabilities to the client
},
}
);
// 2. Define the Search Schema using Zod
const CandidateSearchSchema = z.object({
query: z.string().min(2),
limit: z.number().optional().default(5),
department: z.enum(["Engineering", "Design", "Product", "Sales"]).optional(),
});
// 3. Register Available Tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "search_candidates",
description: "Search internal database for candidates matching specific skills and departments.",
inputSchema: {
type: "object",
properties: {
query: { type: "string", description: "Search term or required skill" },
limit: { type: "number", description: "Maximum records to return" },
department: { type: "string", enum: ["Engineering", "Design", "Product", "Sales"] },
},
required: ["query"],
},
},
],
};
});
// Mock database resolver
async function queryDatabase(query: string, limit: number, dept?: string) {
// Real implementation would connect to Cloud SQL / BigQuery
return [
{ id: 101, name: "Sarah Connor", role: "Staff Platform Engineer", tags: ["Kubernetes", "Go", "MACH"] },
{ id: 102, name: "Marcus Wright", role: "Solutions Architect", tags: ["Next.js", "React", "AI Agents"] }
];
}
// 4. Handle Tool Executions
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name !== "search_candidates") {
throw new Error(`Tool ${request.params.name} not found`);
}
try {
// Validate the arguments at runtime
const args = CandidateSearchSchema.parse(request.params.arguments);
// Fetch secure records
const results = await queryDatabase(args.query, args.limit, args.department);
return {
content: [
{
type: "text",
text: JSON.stringify(results, null, 2),
},
],
};
} catch (error: any) {
return {
content: [
{
type: "text",
text: `Error validating arguments: ${error.message}`,
},
],
isError: true,
};
}
});
// 5. Start Server Transport (stdio is standard for local IDE integrations)
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Enterprise Search MCP Server running on stdio");Consolidare la sicurezza per l'uso aziendale
Sebbene la scrittura del codice TypeScript sia lineare, esporre i dati aziendali interni di produzione ai LLM richiede rigide misure di sicurezza operative. I modelli di IA sono soggetti ad allucinazioni, iniezioni di prompt e cicli di esecuzione dei tool non intenzionali.
Ecco i quattro pilastri della sicurezza aziendale MCP:
1. Validazione dello schema e sanitizzazione degli input
Non fidarsi mai degli argomenti generati da un LLM. Validare sempre i parametri utilizzando librerie come Zod, e igienizzare le stringhe per prevenire rischi nei database:
- Utilizzare query parametrizzate o ORM per prevenire la SQL Injection.
- Validare i percorsi delle directory per prevenire exploit di directory traversal se il tool legge file locali.
2. Autenticazione e passaggio del contesto OAuth
Quando si esegue in una rete aziendale, è necessario verificare il livello di autorizzazione dell'utente che utilizza l'agente.
- Esporre MCP tramite Server-Sent Events (SSE) invece di stdio. Ciò consente di eseguire il server MCP come microservizio indipendente protetto da un API Gateway.
- Inoltrare il token di identità dell'utente (JWT) nelle intestazioni della richiesta, consentendo al server MCP di applicare la sicurezza a livello di riga (RLS) nel database di destinazione.
3. Controllo con intervento umano (HITL)
Esporre strumenti di sola lettura (come search_candidates) è a basso rischio. Tuttavia, esporre strumenti di scrittura (come update_records o deploy_service) è pericoloso.
- Implementare approvazioni esplicite per le azioni di scrittura. Il client MCP dovrebbe intercettare le richieste di scrittura e mostrare al programmatore un diff con le modifiche che l'agente desidera applicare.
[ Agent Tool Request ] ──► [ Security Middleware ] ──► (Diff Check / UI Popup)
│
┌──────────────────────────────────────────┘
▼
[ User Approves? ] ──(Yes)──► [ Execute Write on Server ]4. Limitazione della frequenza e barriere
Gli agenti possono entrare in cicli di ragionamento ricorsivo in cui chiamano uno strumento decine di volte in pochi secondi, generando carichi pesanti sul database o costi di token elevati.
- Imporre limiti di frequenza (rate limiting) delle richieste per sessione.
- Limitare la dimensione massima dei payload dei risultati per evitare il sovraccarico di token.
Sviluppi futuri: Esporre i sistemi legacy come primitive di IA
La forza del Model Context Protocol risiede nel trasformare le vecchie interfacce software in capacità pulite e rilevabili.
Racchiudendo database interni, script di deployment e API in un layer MCP standardizzato, ci si assicura che qualsiasi strumento di IA (sia esso un editor come Cursor, un assistente di terminale o un agente di deployment autonomo) possa interagire con la logica di business in modo sicuro, prevedibile e senza costi di traduzione aggiuntivi.