Überblick: Die drei Grundprinzipien des MCP-Protokolls
Nel erster Artikel dieser Serie Wir haben das vorgestellt Model Context Protocol (MCP) und seine Host/Client/Server-Architektur. Jetzt ist es an der Zeit, sie im Detail zu analysieren drei Primitive dass ein MCP-Server Folgendes offenlegen kann: Werkzeuge, Ressourcen e Aufforderungen.
Jedes Primitiv spielt eine bestimmte Rolle in der Interaktion zwischen KI und der Außenwelt. Die Unterschiede verstehen, Die Anwendungsfälle und die interne Struktur jedes einzelnen Servers sind entscheidend für die Entwicklung effektiver MCP-Server und gut strukturiert. In diesem Artikel werden wir die Theorie und die Validierungsschemata sehen Zod, JSON-RPC-Payloads und TypeScript-Handler, Analyse konkreter Beispiele aus dem Projekt Tech-MCP.
Was Sie in Diesem Artikel Lernen Werden
- Der Unterschied zwischen Tools, Ressourcen und Eingabeaufforderungen: Rolle, Kontrolle und Anwendungsfälle
- So definieren Sie ein Tool mit Zod-Validierung und asynchronem Handler
- So stellen Sie Ressourcen mit URI-Vorlage und schreibgeschützten Daten bereit
- So erstellen Sie parametrisierte und wiederverwendbare Eingabeaufforderungen
- Das Format der JSON-RPC-Nutzlasten für jedes Grundelement
- Der Lebenszyklus einer MCP-Sitzung von der Entdeckung bis zum Abschluss
- Best Practices für Werkzeugbeschreibungen und Namenskonventionen
Die drei Primitiven im Vergleich
Bevor wir detailliert auf die einzelnen Grundelemente eingehen, ist es hilfreich, sich einen Überblick zu verschaffen ihre grundlegenden Unterschiede. Jedes Grundelement reagiert auf ein bestimmtes Bedürfnis MCP-Ökosystem:
Zusammenfassung der MCP-Primitive
| Primitive | Ruolo | Wer kontrolliert | Effekte Collaterali | Beispiel |
|---|---|---|---|---|
| Tools | Funktionen, die von KI aufgerufen werden können | L'AI decide autonomamente | Ja (kann den Status ändern) | create-sprint, analyze-diff |
| Resources | Dati accessibili in lettura | L'applicazione host | No (read-only) | sprint://{id}, file:///config |
| Prompts | Vorlage predefiniti riutilizzabili | L'utente seleziona | No (generano messaggi) | sprint-review, code-analysis |
Diese Unterscheidung ist wichtig: i Werkzeuge Sie sind das operative Herzstück des Protokolls. le Ressourcen Sie liefern Kontext und Daten, d Aufforderungen Sie treiben die KI voran strukturierte Aufgaben. Schauen wir uns jedes Grundelement im Detail an.
1. Tools: Funktionen, die KI aufrufen kann
I Werkzeuge Sie stellen das Herzstück der MCP-Interaktion dar. Das sind Funktionen, die KI kann Rufen Sie sich während eines Gesprächs dazu auf, konkrete Aktionen in der realen Welt durchzuführen. Im Gegensatz zu einem einfachen API-Aufruf deklariert ein MCP-Tool seine Parameter explizit mit einem typisierten Schema, das es der KI ermöglicht, es zu verstehen Wann e als rufe ihn an.
Grundlegende Merkmale der Tools
- Die KI entscheidet, wann sie aufgerufen wird: Basierend auf dem Kontext der Konversation wählt das Sprachmodell autonom aus, welches Tool aufgerufen werden soll und mit welchen Parametern
- Mit Zod eingegebene Parameter: Jedes Tool deklariert seine Eingaben mit einem Zod-Schema und gewährleistet so eine automatische Validierung zur Laufzeit
- Strukturierte Ergebnisse: Das Ergebnis ist immer ein Array von
contentmit Typtext,imageoresource - Sie können Nebenwirkungen haben: Dateien erstellen, in die Datenbank schreiben, externe APIs aufrufen, Benachrichtigungen senden
- Zusammensetzbar: KI kann mehrere Werkzeuge nacheinander kombinieren, um komplexe Aufgaben zu erledigen
Anatomie eines Tools in TypeScript
Die Registrierung eines Werkzeugs folgt einer präzisen Struktur mit vier Elementen: eindeutiger Name, Beschreibung für die KI, das Zod-Parameterschema und den asynchronen Handler. Hier ist ein Beispiel komplett aus dem Projekt 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)
}]
};
}
);
Warum Zod zur Validierung?
Zod und eine TypeScript-First-Validierungsbibliothek, die umfassende Typsicherheit bietet zur Kompilierungszeit und Validierung zur Laufzeit. Das MCP SDK konvertiert automatisch Zod-Schemas in JSON-Schema, das Format, das KI verwendet, um die Parameter eines Werkzeugs zu verstehen. Das bedeutet, dass Sie durch die Deklaration eines Zod-Schemas Folgendes erhalten: automatische Validierung der Eingaben, Dokumentationserstellung für KI und Typinferenz in TypeScript, alles in einem Definition.
Das Antwortformat eines Tools
Jeder Tool-Handler muss ein Objekt mit einem Array zurückgeben content. Jedes Element
des Arrays hat a type was das Format des Inhalts angibt:
// Risposta testuale (più comune)
return {
content: [{
type: 'text',
text: 'Sprint creato con successo: Sprint-15 (ID: 42)'
}]
};
// Risposta con immagine
return {
content: [{
type: 'image',
data: base64EncodedImage,
mimeType: 'image/png'
}]
};
// Risposta con errore
return {
content: [{
type: 'text',
text: 'Errore: sprint non trovato'
}],
isError: true
};
Werkzeugkategorien im Tech-MCP-Projekt
Im Projekt Tech-MCP, Die über 85 Werkzeuge sind in Funktionskategorien unterteilt, basierend auf der Art der Operation, die sie ausführen:
Klassifizierung von Werkzeugen nach Art der Operation
| Kategorie | Beispiel Tool | Effekte | Beschreibung |
|---|---|---|---|
| Creazione | create-sprint, save-snippet |
Sie schreiben in die Datenbank | Creano nuove entita persistenti |
| Lettura | get-sprint, search-snippets |
Nur lesen | Recuperano dati esistenti |
| Analysen | 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 |
Sie lesen den externen Zustand | Sie überprüfen den Status externer Systeme |
2. Resources: Dati Accessibili in Lettura
Le Ressourcen Sie sind das zweite MCP-Grundelement. Sie stellen Daten dar, die die Anwendung hostet Es kann lesen und der KI als Kontext bereitstellen. Im Gegensatz zu Tools werden Ressourcen nicht aufgerufen direkt von der KI: und der Host-Anwendung (Claude Desktop, Cursor usw.), die entscheidet, wann und was Ressourcenbelastung im Kontext der Konversation.
Grundlegende Eigenschaften von Ressourcen
- Identifiziert durch URI: Jede Ressource hat eine eindeutige Kennung, z
file:///path/to/file,db://schema/tableosprint://{id} - Die Anwendung erfordert sie: Im Gegensatz zu Tools, bei denen die KI entscheidet, ob die Ressourcen und die Host-Anwendung den Zugriff steuern
- Schreibgeschützt: Ressourcen verändern den Zustand des Servers nicht, sie dienen ausschließlich der Bereitstellung von Daten
- Sie unterstützen URI-Vorlage: Für parametrische Ressourcen können Sie Vorlagen wie definieren
sprint://{id} - Expliziter MIME-Typ: Jede Ressource deklariert den Inhaltstyp (
application/json,text/plain, usw.)
Definition einer Ressource mit Vorlage-URI
So definieren Sie eine parametrische Ressource, die die Details eines Sprints offenlegt identifiziert durch Ihre ID:
server.resource(
'sprint://{id}', // URI template
'Get sprint details by ID', // Beschreibung
async (uri) => { // Handler
const id = extractIdFromUri(uri);
const sprint = store.getSprint(id);
if (!sprint) {
throw new Error(`Sprint ${id} not found`);
}
return {
contents: [{
uri: uri.href,
mimeType: 'application/json',
text: JSON.stringify(sprint, null, 2)
}]
};
}
);
Resource Statiche vs Dinamiche
MCP-Ressourcen sind in zwei Kategorien unterteilt: statisch e Dynamik. Statische Ressourcen haben einen festen URI und geben immer Daten vom selben Endpunkt zurück. Dynamische Ressourcen verwenden URI-Vorlagen, um Parameter zu akzeptieren.
// Resource statica: URI fisso, dati globali
server.resource(
'config://app-settings',
'Application configuration settings',
async (uri) => {
return {
contents: [{
uri: uri.href,
mimeType: 'application/json',
text: JSON.stringify(config.getAll())
}]
};
}
);
// Resource dinamica: URI template con parametro
server.resource(
'user://{userId}/profile',
'User profile data',
async (uri) => {
const userId = extractParam(uri, 'userId');
const profile = await db.getProfile(userId);
return {
contents: [{
uri: uri.href,
mimeType: 'application/json',
text: JSON.stringify(profile)
}]
};
}
);
Die JSON-RPC-Nutzlast für Ressourcen
Wenn die Hostanwendung eine Ressource anfordert, verwendet das MCP-Protokoll zwei JSON-RPC-Methoden:
resources/list um verfügbare Ressourcen zu entdecken e resources/read
um seinen Inhalt zu lesen.
// Richiesta: elenco delle resources disponibili
{ "method": "resources/list" }
// Risposta del server
{
"resources": [
{
"uri": "config://app-settings",
"name": "App Settings",
"mimeType": "application/json"
}
],
"resourceVorlages": [
{
"uriVorlage": "sprint://{id}",
"name": "Sprint Details",
"mimeType": "application/json"
}
]
}
// Richiesta: lettura di una resource specifica
{ "method": "resources/read",
"params": { "uri": "sprint://42" } }
// Risposta del server
{
"contents": [{
"uri": "sprint://42",
"mimeType": "application/json",
"text": "{ \"id\": 42, \"name\": \"Sprint-15\" }"
}]
}
Hinweis zum Tech-MCP-Projekt
Im Projekt Tech-MCP, Die Interaktion mit Daten erfolgt hauptsächlich über i Werkzeuge. Die Ressourcen sind für zukünftige Entwicklungen geplant, beispielsweise um Projektkonfigurationen offenzulegen, Datenbankschemata oder API-Dokumentation als schreibgeschützter Kontext für KI.
3. Prompts: Vorlage Predefiniti Riutilizzabili
I Aufforderungen Sie sind das dritte MCP-Grundelement. Sie stellen vordefinierte Vorlagen dar, die als Leitfaden dienen KI bei der Ausführung komplexer und strukturierter Aufgaben. Im Gegensatz zu Tools (bei denen die KI entscheidet) und Ressourcen (wo die Anwendung entscheidet), sind die Eingabeaufforderungen vom Benutzer ausgewählt werden für spezifische Arbeitsabläufe starten.
Grundlegende Merkmale von Eingabeaufforderungen
- Sie treiben die KI voran: Stellen Sie strukturierte Anweisungen bereit, die das Sprachmodell auf ein bestimmtes Ziel ausrichten
- Sie akzeptieren Argumente: Kann mit Benutzereingaben parametriert werden
- Kombinierbar mit Werkzeugen: Eine Eingabeaufforderung kann der KI eine Abfolge von Werkzeugen vorschlagen, die der Reihe nach aufgerufen werden sollen
- Wiederverwendbar: Einmal definiert, können sie in verschiedenen Gesprächen mit unterschiedlichen Parametern verwendet werden
- Vom Benutzer ausgewählt: Der Benutzer wählt aus, welche Eingabeaufforderung aktiviert werden soll, nicht die KI
Definition einer Eingabeaufforderung mit Argumenten
Eine MCP-Eingabeaufforderung wird mit einem Namen, einer Beschreibung, einer Liste von Argumenten und einer Funktion definiert Dadurch werden die Nachrichten generiert, die an die KI gesendet werden sollen:
server.prompt(
'sprint-review', // Nome univoco
'Generate a comprehensive sprint review report', // Beschreibung
[ // 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 ${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 ${format || 'detailed'} con:
- Obiettivi raggiunti vs pianificati
- Velocity e trend rispetto agli sprint precedenti
- Storie completate e non completate
- Raccomandazioni per il prossimo sprint`
}
}]
}))
);
Die JSON-RPC-Nutzlast für Eingabeaufforderungen
Wie bei anderen Grundelementen verwenden Eingabeaufforderungen dedizierte JSON-RPC-Methoden zur Erkennung und Aufruf:
// 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..."
}
}]
}
Fordert das Orchestrate-Tool auf
Die wahre Kraft von Eingabeaufforderungen entfaltet sich, wenn sie zur Orchestrierung komplexer Abläufe verwendet werden von Werkzeugen. Eine gut gestaltete Eingabeaufforderung kann die KI durch einen mehrstufigen Arbeitsablauf führen:
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 ${filePath} (${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`
}
}]
}))
);
Hinweis: Eingabeaufforderungen im Tech-MCP-Projekt
Wie bei den Ressourcen ist das Projekt Tech-MCP Verwendet derzeit i Werkzeuge als Hauptprimitiv. Für die zukünftige Entwicklung sind Eingabeaufforderungen geplant, mit dem Ziel, vordefinierte Workflows für wiederkehrende Szenarien wie Sprint Reviews, Onboarding zu erstellen neuer Entwickler und Analyse der Teamleistung.
Wie KI Werkzeuge auswählt: Die Rolle von Beschreibungen
Wenn sich ein MCP-Server bei einem Client registriert, stellt er die Liste der verfügbaren Tools zur Verfügung
die Methode tools/list. Für jedes Tool erhält die KI drei Schlüsselinformationen:
- Nome: identificativo univoco (es.
create-sprint) - Beschreibung: Text in natürlicher Sprache, der erklärt, was das Tool tut
- Parameterschema: Struktur der Eingabeparameter mit Typen und Beschreibungen
La Beschreibung und das kritischste Element: Eine gut geschriebene Beschreibung ermöglicht die KI zu verstehen Wann das Werkzeug verwenden, Was als Ergebnis erwarten e in welchen Szenarien und es ist angebracht, sich darauf zu berufen.
Best Practices für Werkzeugbeschreibungen
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"
Checkliste für wirksame Beschreibungen
| Elemento | Domanda | Beispiel |
|---|---|---|
| Azione | Was macht das Tool? | "Create a new sprint..." |
| Input | Quali parametri servono? | "...with a name, date range, and goals" |
| Output | Was kommt zurück? | "Returns the created sprint object with id..." |
| Contesto | Wann sollte man es verwenden? | "Use when the user wants to plan a new iteration" |
Der Lebenszyklus einer MCP-Sitzung
Jede MCP-Interaktion folgt einem Lebenszyklus, der in vier Phasen gegliedert ist. Verstehe das Flow ist für die Gestaltung von Servern, die sich in jedem Szenario korrekt verhalten, von entscheidender Bedeutung:
[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
Detail der Phasen
- Initialisierung: Der Client sendet die Protokollversion und ihre Funktionen. Der Server antwortet, indem er angibt, welche Grundelemente er unterstützt (Tools, Ressourcen, Eingabeaufforderungen) und welche seine eigenen sind Funktionen (Benachrichtigungen, Protokollierung usw.).
- Entdeckung: Der Client fragt den Server ab, um alle verfügbaren Grundelemente zu ermitteln. Diese Phase ist von grundlegender Bedeutung, da sie der KI die für die Entscheidung erforderlichen Informationen liefert welche Tools verwendet werden sollen.
- Verwendung: die Betriebsphase, die N-mal während der Sitzung wiederholt wird. Der Kunde kann Tools aufrufen, Ressourcen lesen und Eingabeaufforderungen in beliebiger Reihenfolge und Kombination auslösen.
- Schließung: Der Client signalisiert das Ende der Sitzung. Der Server gibt Ressourcen frei und schließt die Verbindungen.
Parametervalidierung mit Zod: Erweiterte Beispiele
Zod bietet eine breite Palette von Validatoren, mit denen Sie präzise Muster für Parameter definieren können der Werkzeuge. Hier sind einige erweiterte Muster, die im Projekt verwendet werden 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),
};
Interaktion zwischen Primitiven: Ein vollständiges Beispiel
Die drei MCP-Primitive arbeiten nicht isoliert. In einem realen Szenario ein Workflow kann alle drei Grundelemente synergetisch kombinieren:
- Der Benutzer wählt eine Eingabeaufforderung aus: „Sprint Review“ mit Parameter
sprintId: 42 - Die Eingabeaufforderung generiert Anweisungen: Die Nachricht schlägt der KI vor, bestimmte Tools zu verwenden
- L'AI chiama i Tool: invoca
get-sprint,calculate-velocity,get-sprint-stories - Die Anwendung lädt Ressourcen: Als Kontext hinzufügen
config://team-settings - KI generiert den Bericht: Fassen Sie alle gesammelten Daten in einem strukturierten Bericht zusammen
Diese Zusammensetzbarkeit ist eine der Stärken des MCP-Protokolls: Jedes Grundelement trägt dazu bei mit seiner spezifischen Rolle in komplexen und artikulierten Arbeitsabläufen.
Fazit
Die drei MCP-Primitive – Werkzeuge, Ressourcen e Aufforderungen -- bilden das grundlegende Vokabular des Protokolls. Jedes Grundelement hat eine bestimmte Rolle: Tools führen Aktionen aus, Ressourcen stellen Daten bereit, Eingabeaufforderungen leiten die KI bei strukturierten Aufgaben.
Validierung mit Zod garantiert Typsicherheit und automatische Dokumentation, während Der MCP-Sitzungslebenszyklus gewährleistet eine geordnete und vorhersehbare Interaktion zwischen Client und Server. Durch die Zusammensetzbarkeit zwischen Grundelementen können Sie komplexe Arbeitsabläufe erstellen einfache und klar definierte Bausteine.
Im nächsten Artikel werden wir tiefer in die Materie eintauchenMonorepo-Architektur und ich Projektmuster verwendet in Tech-MCP: So organisieren Sie 31 MCP-Server in einem einzigen Repository und verwalten gemeinsame Abhängigkeiten mit Turborepo und pnpm und strukturieren Sie den Code für maximale Wiederverwendbarkeit und Wartbarkeit.
Der vollstaendige Code aller Beispiele ist im Repository verfuegbar Tech-MCP auf GitHub.







