Creo applicazioni web moderne e strumenti digitali personalizzati per aiutare le attività a crescere attraverso l'innovazione tecnologica. La mia passione è unire informatica ed economia per generare valore reale.
La mia passione per l'informatica è nata tra i banchi dell'Istituto Tecnico Commerciale di Maglie, dove ho scoperto il potere della programmazione e il fascino di creare soluzioni digitali. Fin da subito, ho capito che l'informatica non era solo codice, ma uno strumento straordinario per trasformare idee in realtà.
Durante gli studi superiori in Sistemi Informativi Aziendali, ho iniziato a intrecciare informatica ed economia, comprendendo come la tecnologia possa essere il motore della crescita per qualsiasi attività. Questa visione mi ha accompagnato all'Università degli Studi di Bari, dove ho conseguito la Laurea in Informatica, approfondendo le mie competenze tecniche e la mia passione per lo sviluppo software.
Oggi metto questa esperienza al servizio di imprese, professionisti e startup, creando soluzioni digitali su misura che automatizzano processi, ottimizzano risorse e aprono nuove opportunità di business. Perché la vera innovazione inizia quando la tecnologia incontra le esigenze reali delle persone.
Le Mie Competenze
Analisi Dati & Modelli Previsionali
Trasformo i dati in insights strategici con analisi approfondite e modelli predittivi per decisioni informate
Automazione Processi
Creo strumenti personalizzati che automatizzano operazioni ripetitive e liberano tempo per attività a valore aggiunto
Sistemi Custom
Sviluppo sistemi software su misura, dalle integrazioni tra piattaforme alle dashboard personalizzate
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
Democratizzare la Tecnologia
La mia missione è rendere l'informatica accessibile a tutti: dalle piccole imprese locali alle startup innovative, fino ai professionisti che vogliono digitalizzare la propria attività. Ogni realtà merita di sfruttare le potenzialità del digitale.
Unire Informatica ed Economia
Non è solo questione di scrivere codice: è capire come la tecnologia possa generare valore reale. Intrecciando competenze informatiche e visione economica, aiuto le attività a crescere, ottimizzare processi e raggiungere nuovi traguardi di efficienza e redditività.
Creare Soluzioni su Misura
Ogni attività è unica, e così devono esserlo le soluzioni. Sviluppo strumenti personalizzati che rispondono alle esigenze specifiche di ciascun cliente, automatizzando processi ripetitivi e liberando tempo per ciò che conta davvero: far crescere il business.
Trasforma la Tua Attività con la Tecnologia
Che tu gestisca un negozio, uno studio professionale o un'azienda, posso aiutarti a sfruttare le potenzialità dell'informatica per lavorare meglio, più velocemente e in modo più intelligente.
Il mio percorso accademico e le tecnologie che padroneggio
Certificazioni Professionali
8 certificazioni conseguite
Nuovo
Visualizza
Reinvention With Agentic AI Learning Program
Anthropic
Dicembre 2024
Nuovo
Visualizza
Agentic AI Fluency
Anthropic
Dicembre 2024
Nuovo
Visualizza
AI Fluency for Students
Anthropic
Dicembre 2024
Nuovo
Visualizza
AI Fluency: Framework and Foundations
Anthropic
Dicembre 2024
Nuovo
Visualizza
Claude with the Anthropic API
Anthropic
Dicembre 2024
Visualizza
Master SQL
RoadMap.sh
Novembre 2024
Visualizza
Oracle Certified Foundations Associate
Oracle
Ottobre 2024
Visualizza
People Leadership Credential
Connect
Settembre 2024
Linguaggi & Tecnologie
Java
Python
JavaScript
Angular
React
TypeScript
SQL
PHP
CSS/SCSS
Node.js
Docker
Git
💼
12/2024 - Presente
Custom Software Engineering Analyst
Accenture
Bari, Puglia, Italia · Ibrida
Analisi e sviluppo di sistemi informatici attraverso l'utilizzo di Java e Quarkus in Health and Public Sector. Formazione continua su tecnologie moderne per la creazione di soluzioni software personalizzate ed efficienti e sugli agenti.
💼
06/2022 - 12/2024
Analista software e Back End Developer Associate Consultant
Links Management and Technology SpA
Esperienza nell'analisi di sistemi software as-is e flussi ETL utilizzando PowerCenter. Formazione completata su Spring Boot per lo sviluppo di applicazioni backend moderne e scalabili. Sviluppatore Backend specializzato in Spring Boot, con esperienza in progettazione di database, analisi, sviluppo e testing dei task assegnati.
💼
02/2021 - 10/2021
Programmatore software
Adesso.it (prima era WebScience srl)
Esperienza nell'analisi AS-IS e TO-BE, evoluzioni SEO ed evoluzioni website per migliorare le performance e l'engagement degli utenti.
🎓
2018 - 2025
Laurea in Informatica
Università degli Studi di Bari Aldo Moro
Bachelor's degree in Computer Science, focusing on software engineering, algorithms, and modern development practices.
📚
2013 - 2018
Diploma - Sistemi Informativi Aziendali
Istituto Tecnico Commerciale di Maglie
Technical diploma specializing in Business Information Systems, combining IT knowledge with business management.
Contattami
Hai un progetto in mente? Parliamone! Compila il form qui sotto e ti risponderò al più presto.
* Campi obbligatori. I tuoi dati saranno utilizzati solo per rispondere alla tua richiesta.
Panoramica: Le Tre Primitive del Protocollo MCP
Nel primo articolo di questa serie
abbiamo introdotto il Model Context Protocol (MCP) e la sua architettura Host/Client/Server.
Ora e il momento di analizzare nel dettaglio le tre primitive che un server MCP può esporre:
Tools, Resources e Prompts.
Ogni primitiva ha un ruolo distinto nell'interazione tra AI e mondo esterno. Comprendere le differenze,
i casi d'uso e la struttura interna di ciascuna e fondamentale per progettare server MCP efficaci
e ben strutturati. In questo articolo vedremo la teoria, gli schemi di validazione con Zod,
i payload JSON-RPC e gli handler TypeScript, analizzando esempi concreti dal progetto
Tech-MCP.
Cosa Imparerai in Questo Articolo
La differenza tra Tools, Resources e Prompts: ruolo, controllo e casi d'uso
Come definire un Tool con validazione Zod e handler asincrono
Come esporre Resources con URI template e dati read-only
Come creare Prompts parametrizzati e riutilizzabili
Il formato dei payload JSON-RPC per ogni primitiva
Il ciclo di vita di una sessione MCP dalla discovery alla chiusura
Best practice per le descrizioni dei tool e la naming convention
Le Tre Primitive a Confronto
Prima di entrare nel dettaglio di ciascuna primitiva, e utile avere una visione d'insieme
delle loro differenze fondamentali. Ogni primitiva risponde a un'esigenza specifica
nell'ecosistema MCP:
Riepilogo delle Primitive MCP
Primitiva
Ruolo
Chi Controlla
Effetti Collaterali
Esempio
Tools
Funzioni invocabili dall'AI
L'AI decide autonomamente
Si (possono modificare stato)
create-sprint, analyze-diff
Resources
Dati accessibili in lettura
L'applicazione host
No (read-only)
sprint://{id}, file:///config
Prompts
Template predefiniti riutilizzabili
L'utente seleziona
No (generano messaggi)
sprint-review, code-analysis
Questa distinzione e importante: i Tools sono il cuore operativo del protocollo,
le Resources forniscono contesto e dati, i Prompts guidano l'AI in
task strutturati. Vediamo ciascuna primitiva nel dettaglio.
1. Tools: Funzioni che l'AI Può Invocare
I Tools rappresentano il cuore dell'interazione MCP. Sono funzioni che l'AI può
chiamare autonomamente durante una conversazione per eseguire azioni concrete nel mondo reale.
A differenza di una semplice chiamata API, un tool MCP dichiara esplicitamente i suoi parametri
con uno schema tipizzato, permettendo all'AI di capire quando e come invocarlo.
Caratteristiche Fondamentali dei Tools
L'AI decide quando chiamarli: basandosi sul contesto della conversazione, il modello linguistico sceglie autonomamente quale tool invocare e con quali parametri
Parametri tipizzati con Zod: ogni tool dichiara i suoi input con uno schema Zod, garantendo validazione automatica a runtime
Risultati strutturati: il risultato e sempre un array di content con tipo text, image o resource
Possono avere effetti collaterali: creare file, scrivere nel database, chiamare API esterne, inviare notifiche
Composabili: l'AI può combinare più tool in sequenza per completare task complessi
Anatomia di un Tool in TypeScript
La registrazione di un tool segue una struttura precisa con quattro elementi: nome univoco,
descrizione per l'AI, schema dei parametri Zod e handler asincrono. Ecco un esempio
completo dal progetto Tech-MCP:
import { z } from 'zod';
server.tool(
'create-sprint', // Nome univoco del tool
'Create a new sprint with a name, date range, and goals. ' +
'Returns the created sprint object with id, status, and dates. ' +
'Use this when the user wants to start planning a new iteration.',
{ // Schema parametri (Zod)
name: z.string().describe('Sprint name, e.g. Sprint-15'),
startDate: z.string().describe('Start date in ISO format'),
endDate: z.string().describe('End date in ISO format'),
goals: z.array(z.string()).describe('List of sprint goals'),
},
async ({ name, startDate, endDate, goals }) => { // Handler
const sprint = store.createSprint({
name,
startDate,
endDate,
goals
});
return {
content: [{
type: 'text',
text: JSON.stringify(sprint, null, 2)
}]
};
}
);
perchè Zod per la Validazione?
Zod e una libreria di validazione TypeScript-first che offre type-safety completa
a compile-time e validazione a runtime. L'SDK MCP converte automaticamente gli schemi Zod
in JSON Schema, il formato che l'AI usa per comprendere i parametri di un tool.
Questo significa che dichiarando uno schema Zod si ottiene: validazione automatica degli input,
generazione della documentazione per l'AI e type inference in TypeScript, tutto in un'unica
definizione.
Il Formato della Risposta di un Tool
Ogni tool handler deve ritornare un oggetto con un array content. Ogni elemento
dell'array ha un type che indica il formato del contenuto:
Nel progetto Tech-MCP,
gli 85+ tool sono organizzati in categorie funzionali in base al tipo di operazione che eseguono:
Classificazione dei Tool per Tipo di Operazione
Categoria
Esempio Tool
Effetti
Descrizione
Creazione
create-sprint, save-snippet
Scrivono nel database
Creano nuove entità persistenti
Lettura
get-sprint, search-snippets
Solo lettura
Recuperano dati esistenti
Analisi
analyze-diff, find-bottlenecks
Nessun side effect
Elaborano input e generano insight
Generazione
generate-unit-tests, generate-compose
Producono output
Generano codice, configurazioni, template
Monitoraggio
list-pipelines, get-budget-status
Leggono stato esterno
Verificano lo stato di sistemi esterni
2. Resources: Dati Accessibili in Lettura
Le Resources sono la seconda primitiva MCP. Rappresentano dati che l'applicazione host
può leggere e fornire come contesto all'AI. A differenza dei Tool, le Resources non vengono chiamate
direttamente dall'AI: e l'applicazione host (Claude Desktop, Cursor, ecc.) che decide quando e quali
risorse caricare nel contesto della conversazione.
Caratteristiche Fondamentali delle Resources
Identificate da URI: ogni resource ha un identificatore univoco, come file:///path/to/file, db://schema/table o sprint://{id}
L'applicazione le richiede: a differenza dei tool dove l'AI decide, per le resources e l'applicazione host a controllare l'accesso
Read-only: le resources non modificano lo stato del server, servono esclusivamente a fornire dati
Supportano URI Template: per risorse parametriche si possono definire template come sprint://{id}
MIME type esplicito: ogni resource dichiara il tipo di contenuto (application/json, text/plain, ecc.)
Definizione di una Resource con URI Template
Ecco come si definisce una resource parametrica che espone i dettagli di uno sprint
identificato tramite il suo ID:
server.resource(
'sprint://{id}', // URI template
'Get sprint details by ID', // Descrizione
async (uri) => { // Handler
const id = extractIdFromUri(uri);
const sprint = store.getSprint(id);
if (!sprint) {
throw new Error(`Sprint
Le resources MCP si dividono in due categorie: statiche e dinamiche.
Le resources statiche hanno un URI fisso e restituiscono sempre dati dallo stesso endpoint.
Le resources dinamiche usano URI template per accettare parametri.
Quando l'applicazione host richiede una resource, il protocollo MCP usa due metodi JSON-RPC:
resources/list per scoprire le risorse disponibili e resources/read
per leggerne il contenuto.
Nel progetto Tech-MCP,
l'interazione con i dati avviene principalmente attraverso i Tools.
Le Resources sono previste per sviluppi futuri, ad esempio per esporre configurazioni di progetto,
schemi di database o documentazione API come contesto read-only per l'AI.
3. Prompts: Template Predefiniti Riutilizzabili
I Prompts sono la terza primitiva MCP. Rappresentano template predefiniti che guidano
l'AI nell'esecuzione di task complessi e strutturati. A differenza dei tool (dove l'AI decide) e delle
resources (dove l'applicazione decide), i prompts sono selezionati dall'utente per
avviare flussi di lavoro specifici.
Caratteristiche Fondamentali dei Prompts
Guidano l'AI: forniscono istruzioni strutturate che indirizzano il modello linguistico verso un obiettivo specifico
Accettano argomenti: possono essere parametrizzati con input dell'utente
Combinabili con i tool: un prompt può suggerire all'AI una sequenza di tool da chiamare in ordine
Riutilizzabili: una volta definiti, possono essere usati in conversazioni diverse con parametri diversi
Selezionati dall'utente: l'utente sceglie quale prompt attivare, non l'AI
Definizione di un Prompt con Argomenti
Un prompt MCP si definisce con un nome, una descrizione, una lista di argomenti e una funzione
che genera i messaggi da inviare all'AI:
server.prompt(
'sprint-review', // Nome univoco
'Generate a comprehensive sprint review report', // Descrizione
[ // Argomenti
{
name: 'sprintId',
description: 'ID of the sprint to review',
required: true
},
{
name: 'format',
description: 'Output format: summary, detailed, or metrics-only',
required: false
}
],
async ({ sprintId, format }) => ({ // Handler
messages: [{
role: 'user',
content: {
type: 'text',
text: `Analizza lo sprint #123;sprintId} con i seguenti passaggi:
1. Usa il tool get-sprint per recuperare i dati dello sprint
2. Usa calculate-velocity per calcolare la velocity del team
3. Usa get-sprint-stories per l'elenco delle storie completate
4. Genera un report in formato #123;format || 'detailed'} con:
- Obiettivi raggiunti vs pianificati
- Velocity e trend rispetto agli sprint precedenti
- Storie completate e non completate
- Raccomandazioni per il prossimo sprint`
}
}]
}))
);
Il Payload JSON-RPC per i Prompts
Come per le altre primitive, i prompts utilizzano metodi JSON-RPC dedicati per discovery
e invocazione:
// Discovery: elenco dei prompts disponibili
{ "method": "prompts/list" }
// Risposta del server
{
"prompts": [
{
"name": "sprint-review",
"description": "Generate a comprehensive sprint review report",
"arguments": [
{
"name": "sprintId",
"description": "ID of the sprint to review",
"required": true
},
{
"name": "format",
"description": "Output format: summary, detailed, or metrics-only",
"required": false
}
]
}
]
}
// Invocazione di un prompt
{ "method": "prompts/get",
"params": {
"name": "sprint-review",
"arguments": { "sprintId": "42", "format": "detailed" }
}
}
// Risposta: messaggi generati dal prompt
{
"messages": [{
"role": "user",
"content": {
"type": "text",
"text": "Analizza lo sprint 42 con i seguenti passaggi..."
}
}]
}
Prompt che Orchestrano Tool
Il vero potere dei prompts emerge quando vengono usati per orchestrare sequenze complesse
di tool. Un prompt ben progettato può guidare l'AI attraverso un flusso di lavoro multi-step:
server.prompt(
'full-code-review',
'Perform a comprehensive code review workflow',
[
{ name: 'filePath', description: 'Path to the file to review', required: true },
{ name: 'language', description: 'Programming language', required: true }
],
async ({ filePath, language }) => ({
messages: [{
role: 'user',
content: {
type: 'text',
text: `Esegui una code review completa del file #123;filePath} (#123;language}):
STEP 1 - Analisi statica:
Usa analyze-diff per identificare problemi nel codice
STEP 2 - Generazione test:
Usa generate-unit-tests per creare test per le funzioni trovate
STEP 3 - Verifica stile:
Controlla che il codice segua le convenzioni del progetto
STEP 4 - Report finale:
Genera un report con: problemi trovati, test suggeriti,
miglioramenti proposti, severity di ogni issue`
}
}]
}))
);
Nota: Prompts nel Progetto Tech-MCP
Come per le Resources, il progetto Tech-MCP
utilizza attualmente i Tools come primitiva principale. I Prompts sono previsti per sviluppi futuri,
con l'obiettivo di creare workflow predefiniti per scenari ricorrenti come sprint review, onboarding
di nuovi sviluppatori e analisi di performance del team.
Come l'AI Sceglie i Tool: Il Ruolo delle Descrizioni
Quando un server MCP si registra con un client, espone la lista dei tool disponibili tramite
il metodo tools/list. Per ogni tool, l'AI riceve tre informazioni chiave:
Nome: identificativo univoco (es. create-sprint)
Descrizione: testo in linguaggio naturale che spiega cosa fa il tool
Schema parametri: struttura dei parametri di input con tipi e descrizioni
La descrizione e l'elemento più critico: una descrizione ben scritta permette all'AI
di capire quando usare il tool, cosa aspettarsi come risultato e in quali
scenari e appropriato invocarlo.
Best Practice per le Descrizioni dei Tool
OTTIMO (spiega cosa fa, cosa ritorna, quando usarlo):
"Create a new sprint with a name, date range, and goals.
Returns the created sprint object with id, name, dates, status.
Use this when the user wants to start planning a new iteration."
BUONO (spiega cosa fa e gli input):
"Create a new sprint with a name, date range, and goals"
VAGO (l'AI potrebbe non capire quando usarlo):
"Sprint creation tool"
Checklist per Descrizioni Efficaci
Elemento
Domanda
Esempio
Azione
Cosa fa il tool?
"Create a new sprint..."
Input
Quali parametri servono?
"...with a name, date range, and goals"
Output
Cosa ritorna?
"Returns the created sprint object with id..."
Contesto
Quando usarlo?
"Use when the user wants to plan a new iteration"
Il Ciclo di Vita di una Sessione MCP
Ogni interazione MCP segue un ciclo di vita strutturato in quattro fasi. Comprendere questo
flusso e essenziale per progettare server che si comportano correttamente in ogni scenario:
[1] INIZIALIZZAZIONE
Client --> Server: initialize (versione protocollo, capabilities)
Server --> Client: capabilities (tool list, resource templates, prompts)
[2] DISCOVERY
Client --> Server: tools/list
Server --> Client: [{ name, description, inputSchema }, ...]
Client --> Server: resources/list
Server --> Client: [{ uri, name, mimeType }, ...]
Client --> Server: prompts/list
Server --> Client: [{ name, description, arguments }, ...]
[3] UTILIZZO (ripetuto N volte durante la sessione)
Client --> Server: tools/call { name, arguments }
Server --> Client: { content: [...] }
Client --> Server: resources/read { uri }
Server --> Client: { contents: [...] }
Client --> Server: prompts/get { name, arguments }
Server --> Client: { messages: [...] }
[4] CHIUSURA
Client --> Server: close
Dettaglio delle Fasi
Inizializzazione: il client invia la versione del protocollo e le proprie capabilities.
Il server risponde dichiarando quali primitive supporta (tools, resources, prompts) e le proprie
capabilities (notifiche, logging, ecc.).
Discovery: il client interroga il server per scoprire tutte le primitive disponibili.
Questa fase e fondamentale perchè fornisce all'AI le informazioni necessarie per decidere
quali tool utilizzare.
Utilizzo: la fase operativa, ripetuta N volte durante la sessione. Il client
può invocare tool, leggere resources e attivare prompts in qualsiasi ordine e combinazione.
Chiusura: il client segnala la fine della sessione. Il server rilascia le risorse
e chiude le connessioni.
Validazione dei Parametri con Zod: Esempi Avanzati
Zod offre una vasta gamma di validatori che permettono di definire schemi precisi per i parametri
dei tool. Ecco alcuni pattern avanzati utilizzati nel progetto
Tech-MCP:
import { z } from 'zod';
// Schema con enum e valori opzionali
const createTaskSchema = {
title: z.string().min(1).max(200)
.describe('Task title'),
priority: z.enum(['low', 'medium', 'high', 'critical'])
.describe('Task priority level'),
assignee: z.string().optional()
.describe('Username of the assignee'),
labels: z.array(z.string()).default([])
.describe('List of labels to apply'),
estimate: z.number().positive().optional()
.describe('Estimated hours to complete'),
};
// Schema con oggetti nested
const deployConfigSchema = {
environment: z.enum(['staging', 'production']),
version: z.string().regex(/^\d+\.\d+\.\d+$/),
options: z.object({
rollback: z.boolean().default(true),
healthCheck: z.boolean().default(true),
notifySlack: z.boolean().default(false),
}).optional(),
};
// Schema con union types
const searchSchema = {
query: z.string().min(1),
scope: z.union([
z.literal('code'),
z.literal('docs'),
z.literal('issues'),
z.literal('all'),
]).default('all'),
limit: z.number().int().min(1).max(100).default(20),
};
Interazione tra le Primitive: Un Esempio Completo
Le tre primitive MCP non operano in isolamento. In uno scenario reale, un flusso di lavoro
può combinare tutte e tre le primitive in modo sinergico:
L'utente seleziona un Prompt: "Sprint Review" con parametro sprintId: 42
Il Prompt genera istruzioni: il messaggio suggerisce all'AI di usare specifici tool
L'AI chiama i Tool: invoca get-sprint, calculate-velocity, get-sprint-stories
L'applicazione carica Resources: aggiunge come contesto config://team-settings
L'AI genera il report: combina tutti i dati raccolti in un report strutturato
Questa composabilità e uno dei punti di forza del protocollo MCP: ogni primitiva contribuisce
con il suo ruolo specifico a flussi di lavoro complessi e articolati.
Conclusioni
Le tre primitive MCP -- Tools, Resources e Prompts --
costituiscono il vocabolario fondamentale del protocollo. Ogni primitiva ha un ruolo distinto:
i Tool eseguono azioni, le Resources forniscono dati, i Prompts guidano l'AI in task strutturati.
La validazione con Zod garantisce type-safety e documentazione automatica, mentre
il ciclo di vita della sessione MCP assicura un'interazione ordinata e prevedibile tra client e server.
La composabilità tra le primitive permette di costruire flussi di lavoro complessi partendo da
building block semplici e ben definiti.
Nel prossimo articolo approfondiremo l'architettura monorepo e i pattern di progetto
utilizzati in Tech-MCP:
come organizzare 31 server MCP in un singolo repository, gestire le dipendenze condivise con Turborepo
e pnpm, e strutturare il codice per massima riutilizzabilita e manutenibilità.
Il codice completo di tutti gli esempi e disponibile nel repository
Tech-MCP su GitHub.