Resources e Prompts
Introduzione
Oltre ai tool, MCP espone due primitive aggiuntive: Resources per fornire dati contestuali e Prompts per template di interazione. Insieme ai tool, formano le tre colonne del protocollo.
+-------------------------------------------------------------------+
| PRIMITIVE MCP |
+-------------------------------------------------------------------+
| |
| TOOLS RESOURCES PROMPTS |
| Controllati dal Controllate dalla Controllati |
| modello AI applicazione host dall'utente |
| |
| Il modello decide L'app decide quando L'utente seleziona |
| quando invocarli caricare i dati un template |
| |
| Azioni attive Dati passivi Interazioni guidate |
| (eseguono codice) (forniscono contesto) (strutturano prompt) |
+-------------------------------------------------------------------+
Resources
Le risorse sono sorgenti di dati identificate da URI. A differenza dei tool (che eseguono azioni), le risorse forniscono informazioni che arricchiscono il contesto dell'AI.
Registrare una Risorsa Statica
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
const server = new McpServer({
name: "docs-server",
version: "1.0.0",
});
// Risorsa statica: contenuto fisso
server.resource(
"readme", // Nome
"file:///project/README.md", // URI univoco
{ mimeType: "text/markdown" }, // Metadata
async () => ({
contents: [
{
uri: "file:///project/README.md",
mimeType: "text/markdown",
text: "# Il Mio Progetto\n\nDescrizione del progetto...",
},
],
}),
);
Il client accede alla risorsa con resources/read specificando l'URI.
Registrare Resource Templates
I template permettono risorse parametrizzate con URI pattern (RFC 6570):
// Resource template: contenuto dinamico basato su parametro
server.resource(
"note-by-title",
new ResourceTemplate("notes://{title}", { list: undefined }),
{ mimeType: "text/plain" },
async (uri, { title }) => {
const content = notes.get(title as string);
if (!content) {
throw new Error(`Nota "${title}" non trovata`);
}
return {
contents: [
{
uri: uri.href,
mimeType: "text/plain",
text: content,
},
],
};
},
);
Con list: undefined, il template non appare nella lista delle risorse. Per elencare le istanze disponibili:
server.resource(
"note-by-title",
new ResourceTemplate("notes://{title}", {
list: async () => {
// Ritorna le risorse attualmente disponibili
return {
resources: Array.from(notes.keys()).map((title) => ({
uri: `notes://${encodeURIComponent(title)}`,
name: title,
mimeType: "text/plain",
})),
};
},
}),
async (uri, { title }) => {
const content = notes.get(title as string);
return {
contents: [{
uri: uri.href,
mimeType: "text/plain",
text: content ?? "Non trovata",
}],
};
},
);
Tipi di Contenuto
Le risorse supportano contenuto testuale e binario:
// Contenuto testuale
{
uri: "file:///config.json",
mimeType: "application/json",
text: '{"key": "value"}'
}
// Contenuto binario (base64)
{
uri: "file:///logo.png",
mimeType: "image/png",
blob: "iVBORw0KGgoAAAANSUhEUg..." // base64
}
Subscription alle Risorse
Se una risorsa cambia nel tempo, il server puo' notificare i client:
// Nella capability declaration, abilita subscribe
// Il server emette notifiche quando i dati cambiano:
server.notification({
method: "notifications/resources/updated",
params: { uri: "notes://my-note" },
});
Prompts
I prompt sono template riutilizzabili che strutturano interazioni con il modello. Tipicamente esposti come slash commands nell'interfaccia utente.
Registrare un Prompt Semplice
server.prompt(
"summarize-notes", // Nome (diventa /summarize-notes)
"Riassumi tutte le note salvate", // Descrizione
async () => ({
messages: [
{
role: "user",
content: {
type: "text",
text: `Ecco le mie note. Fai un riassunto conciso:\n\n${
Array.from(notes.entries())
.map(([title, content]) => `## ${title}\n${content}`)
.join("\n\n")
}`,
},
},
],
}),
);
Prompt con Argomenti
server.prompt(
"review-note",
"Revisiona e migliora una nota specifica",
[
{
name: "title",
description: "Titolo della nota da revisionare",
required: true,
},
{
name: "style",
description: "Stile desiderato: formale, informale, tecnico",
required: false,
},
],
async ({ title, style }) => {
const content = notes.get(title);
if (!content) {
throw new Error(`Nota "${title}" non trovata`);
}
const styleHint = style ? ` Usa uno stile ${style}.` : "";
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `Revisiona e migliora questa nota.${styleHint}\n\n# ${title}\n\n${content}`,
},
},
],
};
},
);
Prompt Multi-Messaggio
I prompt possono includere messaggi con ruoli diversi per creare contesti ricchi:
server.prompt(
"debug-session",
"Avvia una sessione di debug guidata",
[
{
name: "error",
description: "Il messaggio di errore da analizzare",
required: true,
},
],
async ({ error }) => ({
messages: [
{
role: "user",
content: {
type: "text",
text: `Ho questo errore: ${error}`,
},
},
{
role: "assistant",
content: {
type: "text",
text: "Capisco il problema. Analizziamo passo per passo. Per prima cosa, "
+ "dimmi in quale contesto si verifica l'errore.",
},
},
{
role: "user",
content: {
type: "text",
text: "Si verifica durante l'esecuzione dei test.",
},
},
],
}),
);
Prompt con Risorse Embedded
Un prompt puo' includere risorse inline come contesto:
server.prompt(
"analyze-project",
"Analizza la struttura del progetto",
async () => ({
messages: [
{
role: "user",
content: {
type: "resource",
resource: {
uri: "file:///project/package.json",
mimeType: "application/json",
text: JSON.stringify(packageJson, null, 2),
},
},
},
{
role: "user",
content: {
type: "text",
text: "Analizza questa configurazione e suggerisci miglioramenti.",
},
},
],
}),
);
Tool vs Resource vs Prompt: Quando Usare Cosa
Regola pratica: se il modello deve decidere quando e come usarlo, e' un Tool. Se l'applicazione carica i dati in background, e' una Resource. Se l'utente seleziona un'azione predefinita, e' un Prompt.
Riepilogo
In questo capitolo hai imparato:
- Come registrare risorse statiche e parametrizzate con URI template
- La differenza tra contenuto testuale e binario nelle risorse
- Come creare prompt semplici, con argomenti e multi-messaggio
- Come incorporare risorse nei prompt
- Quando usare tool, resource o prompt
Prossimo: Transport HTTP e Deployment