Ergänze einen MCP-Server, wenn ein Anwendungsfall deines Plug-ins Live-Daten, Authentifizierung, kontrollierte Aktionen oder Code erfordert, der auf einer von dir betriebenen Infrastruktur ausgeführt wird. Der Server definiert die Werkzeuge, die ChatGPT und Codex zur Verfügung stehen. Er muss keine eigene Benutzeroberfläche zurückgeben.
Gehe von den unterstützten Zielen in deiner Übersicht der Anwendungsfälle aus. Jedes Werkzeug sollte dabei helfen, ein klar erkennbares Nutzungsziel zu erreichen, und nur die Daten und Aktionen bereitstellen, die dafür erforderlich sind.
Entwickle zuerst die Werkzeuge. Sobald der Server ohne eigene Benutzeroberfläche funktioniert, kannst du den MCP-Server um eine Benutzeroberfläche ergänzen, wenn Arbeitsabläufe visuelle Interaktion erfordern.
Ein Software Development Kit für MCP auswählen
Die offiziellen Software Development Kits bieten Hilfsfunktionen für Schemas, Servergrundgerüste und den Transport über Streamable HTTP:
- TypeScript SDK,
veröffentlicht als
@modelcontextprotocol/sdk. - Python SDK, veröffentlicht
als
mcp.
Installiere das SDK, das zu deinem Server-Stack passt:
# TypeScript
npm install @modelcontextprotocol/sdk zod
# Python
pip install mcp
Den Server erstellen
Erstelle einen MCP-Server mit einem stabilen Namen und einer stabilen Version:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
const server = new McpServer({
name: "acme-projects",
version: "1.0.0",
});
MCP-Server können bei der Initialisierung auch ein
Feld instructions
zurückgeben. ChatGPT und Codex verwenden diese Anweisungen zusätzlich
zu den Metadaten der Werkzeuge.
Verwende Serveranweisungen für Vorgaben, die werkzeugübergreifend gelten, etwa erforderliche Aufrufreihenfolgen oder gemeinsame Ratenlimits. Platziere die wichtigsten Details in den ersten 512 Zeichen. Wiederhole nicht jede Werkzeugbeschreibung und versuche nicht, die Persönlichkeit des Modells zu ändern.
const server = new McpServer(
{ name: "acme-projects", version: "1.0.0" },
{
instructions:
"Before updating a project, call get_project to confirm its ID and current status.",
}
);
Werkzeuge anhand von Nutzungszielen definieren
Erstelle für jede eigenständige Aktion, die das Plug-in unterstützen muss, ein Werkzeug. Bevorzuge
gezielte Operationen wie list_projects, get_project und
update_project gegenüber einem einzigen Werkzeug mit vielen voneinander unabhängigen Modi.
Jedes Werkzeug benötigt:
- Einen Namen, der die Aktion beschreibt, und einen verständlichen Titel.
- Eine Beschreibung, die erklärt, wann es verwendet werden sollte.
- Ein explizites Eingabeschema.
- Ein Ausgabeschema, wenn das Werkzeug strukturierte Daten zurückgibt.
- Korrekte Sicherheitsannotationen.
- Einen Handler, der die Anfrage autorisiert und die Operation ausführt.
Das Modell entscheidet anhand dieser Metadaten, ob und wie es das Werkzeug aufruft. Betrachte Namen, Beschreibungen, Schemas und Annotationen als Teil des Verhaltens, das Nutzende bei deinem Plug-in erleben.
import { z } from "zod";
server.registerTool(
"list_projects",
{
title: "List projects",
description:
"Use this when the user wants to find or review projects in their Acme workspace.",
inputSchema: {
status: z.enum(["active", "archived"]).optional(),
},
outputSchema: {
projects: z.array(
z.object({
id: z.string(),
name: z.string(),
status: z.string(),
})
),
},
annotations: {
readOnlyHint: true,
openWorldHint: false,
destructiveHint: false,
},
},
async ({ status }) => {
const projects = await listProjects({ status });
return {
structuredContent: { projects },
content: [
{
type: "text",
text: `Found ${projects.length} projects.`,
},
],
};
}
);
Nützliche Ergebnisse ohne Benutzeroberfläche zurückgeben
Das Ergebnis eines Werkzeugs kann Folgendes enthalten:
structuredContent: kompakte Daten, die das Modell prüfen und bei späteren Aufrufen verwenden kann.content: Text oder andere MCP-Inhalte, die dem Modell helfen, den Nutzenden zu antworten._meta: clientspezifische Daten, die für das Modell nicht sichtbar sind.
Gib genügend Informationen zurück, damit das Modell den Ablauf ohne eine Komponente abschließen kann. Verwende in strukturierten Ergebnissen stabile Kennungen, damit später aufgerufene Werkzeuge auf dieselben Datensätze verweisen können.
Gib keine Geheimnisse, Zugriffstoken oder unnötigen personenbezogenen Daten
in Werkzeugergebnissen zurück. Betrachte _meta als für das Modell unsichtbar, aber nicht als Ersatz
für Autorisierung oder sichere Speicherung.
Skills vom MCP-Server importieren
Konfiguriere den MCP-Server so, dass er Skills bereitstellt, wenn du deren Anweisungen und ergänzende Dateien zusammen mit dem Server versionieren und bereitstellen möchtest. Bei der Einreichung des Plug-ins importiert Werkzeuge scannen einen statischen Snapshot dieser Skills in den Entwurf.
OpenAI unterstützt derzeit einen begrenzten, statischen Teilumfang des Entwurfs der Skills-Erweiterung SEP-2640. Dieser Vorschlag ist noch nicht Teil der stabilen MCP-Spezifikation.
Die Unterstützung der Erweiterung bekannt geben
Deklariere io.modelcontextprotocol/skills in den Funktionen, die der Server
bei der Initialisierung angibt:
{
"capabilities": {
"extensions": {
"io.modelcontextprotocol/skills": {}
}
}
}
Die Deklaration muss unter capabilities.extensions stehen. OpenAI erkennt
die frühere Deklaration unter experimental nicht an.
Die Skills und ihre Ressourcen auflisten
Unterstütze die paginierte Methode skills/list. Jeder Eintrag muss Folgendes enthalten:
- Ein Feld
uri, das auf dieSKILL.mddes Skills verweist. frontmattermit sämtlichen Einträgen aus dem geparsten Frontmatter vonSKILL.md. Nimm auch die Einträgenameunddescriptionauf.- Eine vollständige Liste
resources, dieSKILL.mdund jede ergänzende Datei enthält. - Einen SHA-256-Hashwert für jede Ressource im Format
sha256:<64 lowercase hexadecimal characters>.
Verwende die URI-Konvention skill://. Das Verzeichnis, das SKILL.md enthält, muss
denselben Namen wie der Skill haben. Zum Beispiel:
{
"skills": [
{
"uri": "skill://dice-roller/tabletop-dice/SKILL.md",
"frontmatter": {
"name": "tabletop-dice",
"description": "Roll one or more dice and report each result and the total."
},
"resources": [
{
"uri": "skill://dice-roller/tabletop-dice/SKILL.md",
"digest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
},
{
"uri": "skill://dice-roller/tabletop-dice/references/notation.md",
"digest": "sha256:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
}
]
}
],
"nextCursor": "optional-next-page-cursor"
}
Die Hashwerte im Beispiel zeigen das erforderliche Format. Berechne bei einer Textressource den Hashwert
der UTF-8-Bytes von content.text. Dekodiere bei einer Blob-Ressource
content.blob aus Base64 und berechne anschließend den Hashwert der dekodierten Bytes.
Unterstütze außerdem skills/get für jede aufgeführte URI einer SKILL.md. Gib ein Objekt skill
mit derselben vollständigen Eintragsstruktur wie bei skills/list zurück.
Verwende diese Anfrageparameter:
- Akzeptiere bei der ersten Anfrage an
skills/listein leeres Objekt ({}). - Akzeptiere bei jeder weiteren Anfrage an
skills/listden zurückgegebenen Cursor, beispielsweise{ "cursor": "next-page-cursor" }. - Akzeptiere bei
skills/getdie Katalog-URI, beispielsweise{ "uri": "skill://dice-roller/tabletop-dice/SKILL.md" }.
Jede aufgeführte Ressource zurückgeben
Unterstütze resources/read für jede URI im Manifest. Gib genau ein
Inhaltselement zurück, dessen URI mit der Anfrage übereinstimmt. OpenAI akzeptiert UTF-8-Text oder
einen Base64-kodierten Blob.
Beim Import prüft OpenAI Folgendes:
- OpenAI kann jede aufgeführte Ressource abrufen und ihren Hashwert bestätigen.
- Das Frontmatter der abgerufenen
SKILL.mdstimmt exakt mit dem Katalogeintrag überein. - Ressourcenpfade sind sicher, eindeutig und frei von Normalisierungskonflikten.
- Der vollständige Skill hält die Importlimits ein.
Der Importer akzeptiert bis zu fünf Skills mit eindeutigen Namen, verteilt auf 10 Katalogseiten. Jeder Skill kann bis zu 100 Dateien enthalten. Dabei gelten diese Größenlimits:
| Inhalt | Limit |
|---|---|
SKILL.md | 256 KiB |
| Jede ergänzende Datei | 1 MiB |
| Alle Ressourcen eines Skills | 5 MiB |
| Generierte Skill-Archive pro Scan | 8 MiB |
Die Größenbeschränkung für alle Archive zusammen schließt den zusätzlichen Speicherbedarf des ZIP-Formats ein.
Wenn ein Eintrag die Validierung nicht besteht oder einen Grenzwert überschreitet, gibt Werkzeuge scannen weiterhin die Werkzeuge des Servers zurück, aktualisiert aber nicht die importierten Skills im Entwurf. Behebe das Problem auf dem Server und scanne erneut.
Aus MCP importierte Skills sind Momentaufnahmen zum Zeitpunkt der Einreichung und keine zur Laufzeit aktualisierten Ressourcen. Führe nach einer Änderung an einem Skill erneut Werkzeuge scannen aus, überprüfe die importierten Skills und reiche eine neue Plug-in-Version ein. Den vollständigen Ablauf findest du unter Plug-ins einreichen.
Anfragen authentifizieren und autorisieren
Füge eine Authentifizierung hinzu, wenn ein Werkzeug private Daten liest oder im Auftrag einer Person handelt. Erzwinge auf dem MCP-Server für jede Anfrage eine Autorisierung. Verlasse dich niemals darauf, dass das Modell entscheidet, ob eine Person zugriffsberechtigt ist.
Informationen zu OAuth-Discovery, Sicherheitsschemas und Autorisierungsaufforderungen findest du unter Nutzende authentifizieren.
Um die Nutzung mehrerer Konten zu verbessern, stelle ein authentifizierungspflichtiges
Profilwerkzeug ohne Schreibzugriff bereit und kennzeichne es mit _meta["openai/profile"]: true.
OpenAI nutzt die Profilinformationen, um verbundene Konten konsistent zu identifizieren
und Nutzenden die Unterscheidung zu erleichtern. Ermittle das Profil anhand der validierten
Anmeldedaten der Anfrage und beschränke jeden Werkzeugaufruf auf diese Anmeldedaten. Nutzende können
auch ohne Profilwerkzeug mehrere Konten verbinden. Unter
Mehrere Konten unterstützen findest du
das Schema und ein Implementierungsbeispiel.
Werkzeugannotationen und Elizitation
Lege Annotationen entsprechend dem tatsächlichen Verhalten fest:
readOnlyHint:truenur dann, wenn das Werkzeug keinen Zustand ändern kann.destructiveHint:true, wenn ein Werkzeug Folgen haben kann, die sich nicht oder nur schwer rückgängig machen lassen.openWorldHint:true, wenn ein Werkzeug auf das öffentliche Internet oder einen nicht fest begrenzten Kreis externer Ressourcen zugreift, auch durch Aktionen ohne Schreibzugriff wie die Websuche. Für ein Werkzeug, das auf ein abgegrenztes privates Konto oder einen Workspace beschränkt ist, kann dieser Wert auffalsegesetzt werden, selbst wenn der Dienst extern gehostet wird.
Annotationen helfen ChatGPT und Codex, angemessen mit Bestätigungen und Sicherheitsfragen umzugehen. Sie ersetzen weder Autorisierung noch Validierung oder Bestätigungen auf deinem Server.
Verwende MCP-Elizitation, wenn der Server strukturierte Informationen benötigt, die beim ursprünglichen Werkzeugaufruf nicht übergeben wurden. Frage dabei nur Informationen ab, die Nutzende vernünftigerweise bereitstellen können. Verwende Elizitation nicht, um Geheimnisse zu erfassen oder die reguläre Authentifizierung zu umgehen.
Kompatibilität mit Unternehmenswissen
Unternehmenswissen kann Werkzeuge deines MCP-Servers ohne Schreibzugriff nutzen.
Damit ein Plug-in als Quelle für Unternehmenswissen infrage kommt, implementiere die standardisierten
Eingabeschemas der Werkzeuge search und fetch und kennzeichne andere Werkzeuge ohne Schreibzugriff mit
readOnlyHint: true.
Gib für Quellen, die das Modell zitieren soll, absolute URLs zurück, die Nutzende öffnen können.
Belasse interne Dokumentkennungen im Feld id des Ergebnisses. Informationen zu den erforderlichen
Schemas und Ergebnisstrukturen findest du unter
MCP-Server für ChatGPT und API-Integrationen entwickeln.
Lokal ausführen und testen
Stelle einen Endpunkt für Streamable HTTP bereit, üblicherweise unter /mcp, und überprüfe ihn anschließend mit
MCP Inspector:
npx @modelcontextprotocol/inspector
Wähle in der Inspector-Oberfläche Streamable HTTP aus und gib
http://localhost:3000/mcp ein.
Führe mit dem Inspector folgende Prüfungen durch:
- Vergewissere dich, dass die Initialisierung erfolgreich ist.
- Überprüfe die Serveranweisungen und die Liste der angebotenen Werkzeuge.
- Rufe jedes Werkzeug mit repräsentativen und ungültigen Eingaben auf.
- Überprüfe Schemas, Ergebnisse, Fehler und Annotationen.
- Vergewissere dich, dass die Autorisierung für private Daten und Schreibaktionen erzwungen wird.
Verbinde den Server anschließend im Entwicklermodus mit ChatGPT. Teste die direkten und indirekten Anfragen, die Ausnahmefälle sowie die Anfragen außerhalb des vorgesehenen Umfangs aus deiner Anwendungsfallübersicht.
Endpunkt bereitstellen
Um dein Plug-in zur Veröffentlichung einzureichen, stelle den MCP-Server unter einem stabilen, öffentlich erreichbaren HTTPS-Endpunkt bereit. Mit einem sicheren MCP-Tunnel kannst du einen privaten MCP-Server im Entwicklermodus verbinden. Das erfüllt jedoch nicht die Anforderungen für die Einreichung zur Veröffentlichung.
Der Endpunkt für den Produktivbetrieb muss:
- Den MCP-Transport Streamable HTTP unterstützen.
- Unter einer stabilen URL antworten, die üblicherweise auf
/mcpendet. - Die Anforderungen der Arbeitsabläufe des Plug-ins an Latenz und Verfügbarkeit erfüllen.
- Die benötigten Dienste und Datenspeicher erreichen.
- Die durch Authentifizierung und Autorisierung gesetzten Grenzen wahren.
- Protokolle und Metriken für fehlgeschlagene Initialisierungen und Werkzeugaufrufe erzeugen.
Wenn der MCP-Server privat bleiben muss, stelle einen öffentlichen HTTPS-Proxy bereit, der MCP-Anfragen an den privaten Server weiterleitet. Verwende von OpenAI verwaltetes mTLS, um ChatGPT als MCP-Client zu authentifizieren. Verwende OAuth 2.1, wenn dein Plug-in eine Authentifizierung der Nutzenden erfordert. Wenn dein Netzwerk eine IP-Zulassungsliste erfordert, verwende die veröffentlichten IP-Bereiche der ChatGPT-Konnektoren und aktualisiere die Zulassungsliste automatisch. Eine IP-Zulassungsliste ersetzt weder Authentifizierung noch Autorisierung.
Der öffentliche Endpunkt muss für die Überprüfung des Plug-ins und die Domainverifizierung erreichbar bleiben. Verwende für die Einreichung zur Veröffentlichung weder einen sicheren MCP-Tunnel allein noch einen temporären Tunnel oder einen lokalen Endpunkt.
Infrastruktur auswählen
Du kannst den MCP-Server auf einer Serverless-, Container- oder Edge-Infrastruktur oder auf herkömmlicher Anwendungsinfrastruktur bereitstellen. Wähle eine Plattform anhand folgender Kriterien:
- Unterstützung für Laufzeitumgebung und Abhängigkeiten.
- Verhalten beim Streaming von Antworten.
- Latenz bei Kaltstarts und Anfragen.
- Netzwerkzugriff auf benötigte Dienste.
- Anforderungen an Datenresidenz und Compliance.
- Verwaltung von Geheimnissen.
- Protokollierung, Tracing und Alarmierung.
- Unterstützung für Rollbacks und Versionierung.
Wenn der Server auch optionale UI-Ressourcen hostet, stelle diese unter stabilen Origins bereit, die durch die Content Security Policy der Komponente zugelassen sind.
Endpunkt für den Produktivbetrieb konfigurieren
Vor der Bereitstellung:
- Hinterlege die Zugangsdaten für den Produktivbetrieb im System des Hosts zur Verwaltung von Geheimnissen.
- Konfiguriere den Autorisierungsserver und das zulässige Weiterleitungsverhalten.
- Lege Zeitlimits und Ratenlimits für ressourcenintensive oder nach außen sichtbare Werkzeuge fest.
- Entferne Debug-Antworten und unnötige personenbezogene Daten.
- Vergewissere dich, dass die Protokolle keine Zugriffstoken oder sensiblen Werkzeugergebnisse enthalten.
Rufe nach der Bereitstellung den Endpunkt für den Produktivbetrieb mit MCP Inspector auf. Überprüfe Initialisierung, Serveranweisungen, Werkzeuge, Schemas, Annotationen, Authentifizierung, Ergebnisse und Fehler.
Aktualisierungen planen
Halte veröffentlichte Werkzeugnamen und Schemas abwärtskompatibel. Ergänze Felder oder Werkzeuge, ohne bestehende Schnittstellenverträge zu verletzen. Wenn sich Metadaten ändern, aktualisiere die Verbindung im Entwicklermodus und führe vor der Einreichung den Evaluierungssatz erneut aus.
Versioniere bei einer optionalen UI die Ressourcenkennungen, wenn Änderungen an HTML, JavaScript oder CSS die Funktion einer zwischengespeicherten Komponente beeinträchtigen könnten.
Optionale UI hinzufügen
Sobald die Werkzeuge durchgängig funktionieren, entscheide, ob ein Anwendungsfall visuelle Interaktion erfordert. Für Tabellen, Karten, bearbeitbare Zeitpläne oder Vergleichsansichten kann eine UI sinnvoll sein. Für Abfragen, Statusprüfungen oder Hintergrundaktionen ist sie oft nicht nötig.
Fahre mit Eine Benutzeroberfläche zu deinem MCP-Server hinzufügen fort, um eine MCP Apps-Ressource zu registrieren und mit ausgewählten Werkzeugen zu verknüpfen.
Sicherheitshinweise
- Behandle jede Werkzeugeingabe als nicht vertrauenswürdig.
- Validiere Parameter und erzwinge die Autorisierung auf dem Server.
- Verlange eine Bestätigung für Schreibaktionen mit weitreichenden Folgen.
- Halte Geheimnisse und sensible Daten aus den Metadaten und Ergebnissen der Werkzeuge heraus.
- Protokolliere genügend Kontext, um Fehler untersuchen zu können, ohne dabei Zugangsdaten oder unnötige personenbezogene Daten zu erfassen.
- Lege Ratenlimits für aufwendige oder nach außen sichtbare Aktionen fest.