WICHTIG: So verwenden Sie diese Fertigkeit
Diese Datei dient NUR als NAVIGATIONSLEITFADEN. Bevor Sie MCP-Server-Funktionen implementieren, MÜSSEN Sie:
- Diese Übersicht lesen, um zu verstehen, welche Referenzdateien relevant sind.
- IMMER die spezifische(n) Referenzdatei(en) für die von Ihnen implementierten Funktionen lesen.
- Die detaillierten Muster aus diesen Dateien auf Ihre Implementierung anwenden.
Verlassen Sie sich NICHT ausschließlich auf die Kurzreferenz-Beispiele in dieser Datei – sie sind nur minimale Beispiele. Die Referenzdateien enthalten kritische Best Practices, Sicherheitsaspekte und fortgeschrittene Muster.
Best Practices für MCP-Server
Umfassender Leitfaden für die Entwicklung produktionsreifer MCP-Server mit Tools, Ressourcen, Prompts und Widgets unter Verwendung von mcp-use.
⚠️ ZUERST: Neues Projekt oder bestehendes Projekt?
Bevor Sie etwas anderes tun, stellen Sie fest, ob Sie sich in einem bestehenden mcp-use-Projekt befinden.
Erkennung: Überprüfen Sie den Arbeitsbereich auf eine package.json, die "mcp-use" als Abhängigkeit aufführt, ODER eine .ts-Datei, die "mcp-use/server" importiert.
├─ mcp-use-Projekt GEFUNDEN → Nicht gerüsten. Sie sind bereits in einem Projekt.
│ └─ Springen Sie zu "Schnellnavigation" unten, um Funktionen hinzuzufügen.
│
├─ KEIN mcp-use-Projekt (leeres Verzeichnis, nicht verwandtes Projekt oder Neuanfang)
│ └─ Zuerst mit npx create-mcp-use-app gerüsten, dann Funktionen hinzufügen.
│ Siehe "Ein neues Projekt gerüsten" unten.
│
└─ In einem NICHT VERWANDTEN Projekt (z. B. Next.js-App) und der Benutzer möchte einen MCP-Server
└─ Fragen Sie den Benutzer, wo er erstellt werden soll, und gerüsten Sie dann in diesem Verzeichnis.
Nicht innerhalb eines bestehenden, nicht verwandten Projektstamms gerüsten.
Erstellen Sie NIEMALS manuell MCPServer-Boilerplate, package.json oder eine Projektstruktur von Hand. Die CLI richtet TypeScript-Konfiguration, Entwicklungs-Skripte, Inspector-Integration, Hot Reload und Widget-Kompilierung ein, die manuell schwer zu reproduzieren sind.
Ein neues Projekt gerüsten
npx create-mcp-use-app mein-server
cd mein-server
npm run dev
Vollständige Details zum Gerüstbau und CLI-Flags finden Sie unter quickstart.md.
Schnellnavigation
Wählen Sie Ihren Pfad basierend auf dem, was Sie bauen:
🚀 Grundlagen
Wann: Diese IMMER zuerst lesen, wenn Sie in einer neuen Konversation mit der MCP-Arbeit beginnen. Später zur Klärung von Architektur/Konzepten darauf zurückgreifen.
- concepts.md – MCP-Primitive (Tool, Resource, Prompt, Widget) und wann was verwendet wird
- architecture.md – Serverstruktur (Hono-basiert), Middleware-System, server.use() vs. server.app
- quickstart.md – Gerüstbau, Einrichtung und erstes Tool-Beispiel
- deployment.md – Bereitstellung in der Manufact Cloud, Self-Hosting, Docker, Verwaltung von Bereitstellungen
Laden Sie diese, bevor Sie in die Abschnitte zu Tools/Ressourcen/Widgets eintauchen.
🔐 Authentifizierung hinzufügen?
Wann: Schützen Ihres Servers mit OAuth (WorkOS, Supabase oder benutzerdefiniert)
-
- Wann: Erstmaliges Hinzufügen von Auth, Verständnis von
ctx.authoder Auswahl eines Anbieters - Deckt ab:
oauth-Konfiguration, Benutzerkontext-Form, Anbietervergleich, häufige Fehler
- Wann: Erstmaliges Hinzufügen von Auth, Verständnis von
-
- Wann: Verwendung von WorkOS AuthKit zur Authentifizierung
- Deckt ab: Einrichtung, Umgebungsvariablen, DCR vs. vorregistriert, Rollen/Berechtigungen, WorkOS-API-Aufrufe
-
- Wann: Verwendung von Supabase zur Authentifizierung
- Deckt ab: Einrichtung, Umgebungsvariablen, HS256 vs. ES256, RLS-bewusste API-Aufrufe
-
- Wann: Verwendung eines anderen Identitätsanbieters (GitHub, Okta, Azure AD, Google usw.)
- Deckt ab: Benutzerdefinierte Überprüfung, Benutzerinformationsabruf, Anbieterbeispiele
🔧 Server-Backend bauen (Kein UI)?
Wann: Implementieren von MCP-Funktionen (Aktionen, Daten, Vorlagen). Lesen Sie die spezifische Datei für das von Ihnen erstellte Primitive.
-
- Wann: Erstellen von Backend-Aktionen, die die KI aufrufen kann (E-Mail senden, Daten abrufen, Benutzer erstellen)
- Deckt ab: Tool-Definition, Schemata, Annotationen, Kontext, Fehlerbehandlung
-
- Wann: Bereitstellen von schreibgeschützten Daten, die Clients abrufen können (Konfiguration, Benutzerprofile, Dokumentation)
- Deckt ab: Statische Ressourcen, dynamische Ressourcen, parametrisierte Ressourcenvorlagen, URI-Vervollständigung
-
- Wann: Erstellen von wiederverwendbaren Nachrichtenvorlagen für KI-Interaktionen (Code-Review, Zusammenfassung)
- Deckt ab: Prompt-Definition, Parametrisierung, Argumentvervollständigung, Best Practices für Prompts
-
- Wann: Formatieren von Antworten von Tools/Ressourcen (Text, JSON, Markdown, Bilder, Fehler)
- Deckt ab:
text(),object(),markdown(),image(),error(),mix()
🎨 Visuelle Widgets bauen (Interaktives UI)?
Wann: Erstellen von React-basierten visuellen Oberflächen zum Durchsuchen, Vergleichen oder Auswählen von Daten
-
- Wann: Erstellen Ihres ersten Widgets oder Hinzufügen einer Benutzeroberfläche zu einem vorhandenen Tool
- Deckt ab: Widget-Einrichtung,
useWidget()-Hook,isPending-Prüfungen, Props-Handhabung
-
- Wann: Verwalten des UI-Zustands (Auswahlen, Filter, Registerkarten) innerhalb von Widgets
- Deckt ab:
useState,setState, Zustandspersistenz, wann Tool- vs. Widget-Zustand verwendet wird
-
- Wann: Hinzufügen von Schaltflächen, Formularen oder Aufrufen von Tools aus Widgets heraus
- Deckt ab:
useCallTool(), Formularverarbeitung, Aktionsschaltflächen, optimistische Aktualisierungen
-
- Wann: Gestalten von Widgets zur Unterstützung von Themes, responsiven Layouts oder Barrierefreiheit
- Deckt ab:
useWidgetTheme(), Hell-/Dunkelmodus,autoSize, Layoutmuster, CSS-Best Practices
-
- Wann: Erstellen komplexer Widgets mit asynchronen Daten, Fehlergrenzen oder Leistungsoptimierungen
- Deckt ab: Ladezustände, Fehlerbehandlung, Memoization, Code-Splitting
📚 Benötigen Sie vollständige Beispiele?
Wann: Sie möchten vollständige Implementierungen häufiger Anwendungsfälle sehen
- common-patterns.md
- End-to-End-Beispiele: Wetter-App, Aufgabenliste, Rezeptbrowser
- Zeigt: Server-Code + Widget-Code + Best Practices im Kontext
Entscheidungsbaum
Was brauchen Sie?
├─ Neues Projekt von Grund auf
│ └─> quickstart.md (Gerüstbau + Einrichtung)
│
├─ OAuth / Benutzerauthentifizierung
│ └─> authentication/overview.md → anbieterspezifischer Leitfaden
│
├─ Einfache Backend-Aktion (kein UI)
│ └─> Tool verwenden: server/tools.md
│
├─ Schreibgeschützte Daten für Clients
│ └─> Ressource verwenden: server/resources.md
│
├─ Wiederverwendbare Prompt-Vorlage
│ └─> Prompt verwenden: server/prompts.md
│
├─ Visuelles/interaktives UI
│ └─> Widget verwenden: widgets/basics.md
│
└─ In Produktion bereitstellen
└─> deployment.md (Cloud-Deploy, Self-Hosting, Docker)
Kernprinzipien
- Tools für Aktionen – Backend-Operationen mit Eingabe/Ausgabe
- Ressourcen für Daten – Schreibgeschützte Daten, die Clients abrufen können
- Prompts für Vorlagen – Wiederverwendbare Nachrichtenvorlagen
- Widgets für UI – Visuelle Oberflächen, wenn hilfreich
- Zuerst mit Mock-Daten – Schnell prototypisieren, APIs später anbinden
❌ Häufige Fehler
Vermeiden Sie diese Anti-Patterns, die in Produktions-MCP-Servern gefunden wurden:
Tool-Definition
- ❌ Zurückgeben von rohen Objekten anstatt Verwendung von Response-Helfern
- ✅ Verwenden Sie die Helfer
text(),object(),widget(),error()
- ✅ Verwenden Sie die Helfer
- ❌ Überspringen von Zod-Schema
.describe()für jedes Feld- ✅ Fügen Sie Beschreibungen zu allen Schemafeldern hinzu, für ein besseres KI-Verständnis
- ❌ Keine Eingabevalidierung oder -bereinigung
- ✅ Validieren Sie Eingaben mit Zod, bereinigen Sie benutzerbereitgestellte Daten
- ❌ Werfen von Fehlern anstatt Verwendung des
error()-Helfers- ✅ Verwenden Sie
error("Nachricht")für elegante Fehlerantworten
- ✅ Verwenden Sie
Widget-Entwicklung
- ❌ Zugriff auf
propsohne Prüfung vonisPending- ✅ Prüfen Sie immer
if (isPending) return <Loading/>
- ✅ Prüfen Sie immer
- ❌ Widget verwaltet Serverzustand (Filter, Auswahlen)
- ✅ Widgets verwalten ihren eigenen UI-Zustand mit
useState
- ✅ Widgets verwalten ihren eigenen UI-Zustand mit
- ❌ Fehlender
McpUseProvider-Wrapper oderautoSize- ✅ Umschließen Sie die Root-Komponente:
<McpUseProvider autoSize>
- ✅ Umschließen Sie die Root-Komponente:
- ❌ Inline-Stile ohne Theme-Bewusstsein
- ✅ Verwenden Sie
useWidgetTheme()für Hell-/Dunkelmodus-Unterstützung
- ✅ Verwenden Sie
Sicherheit & Produktion
- ❌ Hartcodierte API-Schlüssel oder Geheimnisse im Code
- ✅ Verwenden Sie
process.env.API_KEY, dokumentieren Sie in.env.example
- ✅ Verwenden Sie
- ❌ Keine Fehlerbehandlung in Tool-Handlern
- ✅ In try/catch einschließen, bei Fehler
error()zurückgeben
- ✅ In try/catch einschließen, bei Fehler
- ❌ Teure Operationen ohne Caching
- ✅ API-Aufrufe, Berechnungen mit TTL cachen
- ❌ Fehlende CORS-Konfiguration
- ✅ CORS für Produktionsbereitstellungen konfigurieren
🔒 Goldene Regeln
Meinungsstarke architektonische Richtlinien:
1. Ein Tool = Eine Fähigkeit
Teilen Sie breite Aktionen in fokussierte Tools auf:
- ❌
benutzer-verwalten(zu vage) - ✅
benutzer-erstellen,benutzer-löschen,benutzer-auflisten
2. Vollständige Daten im Voraus zurückgeben
Tool-Aufrufe sind teuer. Vermeiden Sie Lazy-Loading:
- ❌
produkte-auflisten+produkt-details-abrufen(2 Aufrufe) - ✅
produkte-auflistengibt vollständige Daten inklusive Details zurück
3. Widgets verwalten ihren eigenen Zustand
UI-Zustand lebt im Widget, nicht in separaten Tools:
- ❌
element-auswählen-Tool,filter-setzen-Tool - ✅ Widget verwaltet mit
useStateodersetState
4. exposeAsTool standardmäßig auf false
Widgets werden standardmäßig nur als Ressourcen registriert. Verwenden Sie ein benutzerdefiniertes Tool (empfohlen) oder setzen Sie exposeAsTool: true, um ein Widget für das Modell verfügbar zu machen:
// ✅ ALLE 4 SCHRITTE ERFORDERLICH für korrekte Typinferenz:
// Schritt 1: Schema separat definieren
const propsSchema = z.object({
titel: z.string(),
elemente: z.array(z.string()),
});
// Schritt 2: Schema-Variable in Metadaten referenzieren
export const widgetMetadata: WidgetMetadata = {
beschreibung: "...",
props: propsSchema, // ← NICHT inline z.object()
exposeAsTool: false,
};
// Schritt 3: Props-Typ aus Schema-Variable ableiten
type Props = z.infer<typeof propsSchema>;
// Schritt 4: Typisierte Props mit useWidget verwenden
export default function MeinWidget() {
const { props, isPending } = useWidget<Props>(); // ← <Props> hinzufügen
// ...
}
⚠️ Häufiger Fehler: Nur die Schritte 1-2 ausführen, aber 3-4 überspringen (Typensicherheit geht verloren)
5. Nur an Grenzen validieren
- Vertrauen Sie internem Code und Framework-Garantien
- Validieren Sie Benutzereingaben, externe API-Antworten
- Fügen Sie keine Fehlerbehandlung für Szenarien hinzu, die nicht eintreten können
Kurzreferenz
Minimaler Server
import { MCPServer, text } from "mcp-use/server";
import { z } from "zod";
const server = new MCPServer({
name: "mein-server",
title: "Mein Server",
version: "1.0.0",
});
server.tool(
{
name: "begrüßen",
description: "Einen Benutzer begrüßen",
schema: z.object({ name: z.string().describe("Name des Benutzers") }),
},
async ({ name }) => text("Hallo " + name + "!"),
);
server.listen();
Response-Helfer
| Helper | Verwenden, wenn | Beispiel |
|---|---|---|
text() | Einfache String-Antwort | text("Erfolg!") |
object() | Strukturierte Daten | object({ status: "ok" }) |
markdown() | Formatierter Text | markdown("# Titel\nInhalt") |
widget() | Visuelles UI | widget({ props: {...}, output: text(...) }) |
mix() | Mehrere Inhalte | mix(text("Hi"), image(url)) |
error() | Fehlerantworten | error("Fehler beim Abrufen der Daten") |
resource() | Ressourcenreferenzen einbetten | resource("docs://guide", "text/markdown") |