For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Hauptnavigation

Einen MCP-Server entwickeln

Ergänze dein Plug-in um Live-Daten und kontrollierte Werkzeuge.

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:

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.

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 die SKILL.md des Skills verweist.
  • frontmatter mit sämtlichen Einträgen aus dem geparsten Frontmatter von SKILL.md. Nimm auch die Einträge name und description auf.
  • Eine vollständige Liste resources, die SKILL.md und 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/list ein leeres Objekt ({}).
  • Akzeptiere bei jeder weiteren Anfrage an skills/list den zurückgegebenen Cursor, beispielsweise { "cursor": "next-page-cursor" }.
  • Akzeptiere bei skills/get die 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.md stimmt 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:

InhaltLimit
SKILL.md256 KiB
Jede ergänzende Datei1 MiB
Alle Ressourcen eines Skills5 MiB
Generierte Skill-Archive pro Scan8 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: true nur 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 auf false gesetzt 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:

  1. Vergewissere dich, dass die Initialisierung erfolgreich ist.
  2. Überprüfe die Serveranweisungen und die Liste der angebotenen Werkzeuge.
  3. Rufe jedes Werkzeug mit repräsentativen und ungültigen Eingaben auf.
  4. Überprüfe Schemas, Ergebnisse, Fehler und Annotationen.
  5. 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 /mcp endet.
  • 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:

  1. Hinterlege die Zugangsdaten für den Produktivbetrieb im System des Hosts zur Verwaltung von Geheimnissen.
  2. Konfiguriere den Autorisierungsserver und das zulässige Weiterleitungsverhalten.
  3. Lege Zeitlimits und Ratenlimits für ressourcenintensive oder nach außen sichtbare Werkzeuge fest.
  4. Entferne Debug-Antworten und unnötige personenbezogene Daten.
  5. 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.