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

Echtzeitnutzung mit Tools

Lass Echtzeit-Sprachagenten Funktionswerkzeuge und Remote-MCP-Server aufrufen.

Du kannst einer Realtime-Sitzung Werkzeuge hinzufügen, damit das Modell während eines laufenden Gesprächs Daten abfragen, Aktionen ausführen oder Dienste aufrufen kann. Die Konfiguration der Werkzeuge erfolgt über dieselbe Ereignisschnittstelle, unabhängig davon, ob dein Client einen WebRTC-Datenkanal oder einen WebSocket verwendet.

Verwende Funktionswerkzeuge, wenn deine Anwendung das Werkzeug ausführen und das Ergebnis zurückgeben soll. Verwende MCP-Werkzeuge, wenn die Realtime API für dich eine Verbindung zu einem Remote-Werkzeugserver herstellen soll.

Tool-Typ auswählen

Tool-TypEinsatzbereichAusführung durch
functionDeine Anwendung übernimmt die Geschäftslogik, Genehmigungsprüfungen oder den Zugriff auf private Systeme.Dein Client oder Server empfängt einen Funktionsaufruf und gibt function_call_output zurück.
mcp mit server_urlDu möchtest, dass das Modell Tools aufruft, die ein entfernter MCP-Server bereitstellt.Die Realtime API ruft den entfernten MCP-Server auf.
mcp mit connector_idDu verwendest einen älteren integrierten Konnektor mit einem bestehenden Modell.Die Realtime API ruft den Konnektor mit der von dir bereitgestellten Autorisierung auf.

Füge Tools an einer von zwei Stellen hinzu:

  • Auf Sitzungsebene mit session.tools in session.update, wenn das Tool während der gesamten Sitzung verfügbar sein soll.
  • Auf Antwortebene mit response.tools in response.create, wenn du das Tool nur für einen Gesprächsschritt benötigst.

Ein Funktions-Tool konfigurieren

Funktions-Tools sind die passende Standardwahl, wenn das Tool in deiner Anwendung ausgeführt werden soll. Das Modell gibt die Argumente für den Funktionsaufruf aus. Dein Code führt die Aktion aus und sendet das Ergebnis mit einem function_call_output-Element zurück.

Ein Funktions-Tool mit session.update konfigurieren
const event = {
  type: "session.update",
  session: {
    type: "realtime",
    model: "gpt-realtime-2.1",
    tools: [
      {
        type: "function",
        name: "lookup_order",
        description: "Look up an order by its order number.",
        parameters: {
          type: "object",
          properties: {
            order_number: {
              type: "string",
              description: "The customer-facing order number.",
            },
          },
          required: ["order_number"],
        },
      },
    ],
    tool_choice: "auto",
  },
};

ws.send(JSON.stringify(event));

Wenn das Modell die Funktion aufruft, warte auf das Element mit dem Funktionsaufruf, führe deine Anwendungslogik aus und sende dann die Ausgabe zurück:

Ausgabe des Funktionsaufrufs senden
const event = {
  type: "conversation.item.create",
  item: {
    type: "function_call_output",
    call_id: functionCall.call_id,
    output: JSON.stringify({
      status: "shipped",
      delivery_date: "2026-05-09",
    }),
  },
};

ws.send(JSON.stringify(event));
ws.send(JSON.stringify({ type: "response.create" }));

Eine vollständige Anleitung zum Funktionsaufruf, die jedes einzelne Ereignis erläutert, findest du unter Unterhaltungen verwalten.

Ein MCP-Tool konfigurieren

MCP-Werkzeuge eignen sich, wenn das Werkzeug bereits über einen Remote-MCP-Server verfügbar ist oder ein bestehendes Modell einen älteren integrierten Konnektor verwendet. Anders als Funktionswerkzeuge werden MCP-Werkzeuge von der Realtime API selbst ausgeführt.

In Realtime hat ein MCP-Tool folgende Struktur:

  • type: "mcp"
  • server_label
  • Entweder server_url oder connector_id
  • Optional: authorization und headers
  • Optional: allowed_tools
  • Optional: require_approval
  • Optional: server_description

Dieses Beispiel stellt einen MCP-Server für Dokumentation während der gesamten Sitzung bereit:

Ein MCP-Tool mit session.update konfigurieren
const event = {
  type: "session.update",
  session: {
    type: "realtime",
    model: "gpt-realtime-2.1",
    output_modalities: ["text"],
    tools: [
      {
        type: "mcp",
        server_label: "openai_docs",
        server_url: "https://developers.openai.com/mcp",
        allowed_tools: ["search_openai_docs", "fetch_openai_doc"],
        require_approval: "never",
      },
    ],
  },
};

ws.send(JSON.stringify(event));

Ältere Konnektoren

connector_id gilt für Modelle, die nach dem 1. September 2026 veröffentlicht wurden, als veraltet. Verwende server_url, um eine Verbindung zu einem Remote-MCP-Server herzustellen, oder tunnel_id für eine Verbindung zu einem lokalen MCP-Server über den Sicheren MCP-Tunnel. Bestehende Modelle unterstützen weiterhin Konnektoren. Das folgende Beispiel verwendet gpt-realtime-1.5, das vor diesem Stichtag veröffentlicht wurde.

Integrierte Konnektoren verwenden dieselbe Struktur wie MCP-Tools, übergeben aber connector_id anstelle von server_url. Google Calendar verwendet beispielsweise connector_googlecalendar. Verwende diese integrierten Konnektoren in Realtime für Lesezugriffe, etwa zum Suchen oder Lesen von Terminen oder E-Mails. Übergib das OAuth-Zugriffstoken der nutzenden Person in authorization und schränke die verfügbaren Tools nach Möglichkeit mit allowed_tools ein:

Einen Konnektor für Google Calendar konfigurieren
const event = {
  type: "session.update",
  session: {
    type: "realtime",
    model: "gpt-realtime-1.5",
    output_modalities: ["text"],
    tools: [
      {
        type: "mcp",
        server_label: "google_calendar",
        connector_id: "connector_googlecalendar",
        authorization: "<google-oauth-access-token>",
        allowed_tools: ["search_events", "read_event"],
        require_approval: "never",
      },
    ],
  },
};

ws.send(JSON.stringify(event));

Entfernte MCP-Server erhalten nicht automatisch den vollständigen Unterhaltungskontext, aber sie können alle Daten sehen, die das Modell in einem Tool-Aufruf sendet. Beschränke die verfügbaren Tools mit allowed_tools und verlange eine Genehmigung für jede Aktion, die du nicht automatisch ausführen würdest.

MCP-Ablauf in Realtime

Anders als Realtime-Tools vom Typ function werden entfernte MCP-Tools von der Realtime API selbst ausgeführt. Dein Client führt das entfernte Tool nicht aus und gibt auch kein function_call_output zurück. Stattdessen konfiguriert dein Client den Zugriff, wartet auf Ereignisse im MCP-Lebenszyklus und sendet gegebenenfalls eine Antwort auf eine Genehmigungsanfrage, wenn der Server sie anfordert.

Ein typischer Ablauf sieht so aus:

  1. Du sendest session.update oder response.create mit einem Eintrag in tools, dessen type den Wert mcp hat.
  2. Der Server beginnt mit dem Import der Tools und sendet mcp_list_tools.in_progress.
  3. Solange die Tool-Liste noch geladen wird, kann das Modell kein Tool aufrufen, das noch nicht geladen wurde. Wenn du mit einem Gesprächsschritt warten möchtest, der diese Tools benötigt, warte auf mcp_list_tools.completed. Das Ereignis conversation.item.done, dessen item.type den Wert mcp_list_tools hat, zeigt, welche Tool-Namen tatsächlich importiert wurden. Wenn der Import fehlschlägt, erhältst du mcp_list_tools.failed.
  4. Die nutzende Person spricht oder sendet Text. Daraufhin wird eine Antwort erstellt, entweder durch deinen Client oder automatisch gemäß der Sitzungskonfiguration.
  5. Wenn das Modell ein MCP-Tool auswählt, erhältst du response.mcp_call_arguments.delta und response.mcp_call_arguments.done.
  6. Wenn eine Genehmigung erforderlich ist, fügt der Server der Unterhaltung ein Element hinzu, dessen item.type den Wert mcp_approval_request hat. Dein Client muss darauf mit einem mcp_approval_response-Element antworten.
  7. Sobald das Tool ausgeführt wird, erhältst du response.mcp_call.in_progress. Bei Erfolg erhältst du später ein Ereignis response.output_item.done, dessen item.type den Wert mcp_call hat. Bei einem Fehler erhältst du response.mcp_call.failed.
  8. response.done für eine Antwort kann eintreffen, bevor ihre MCP-Aufrufe abgeschlossen sind. Sobald die Antwort und alle zugehörigen MCP-Aufrufe abgeschlossen sind, sende ein weiteres Ereignis response.create, damit das Modell die Ergebnisse verwenden und die Unterhaltung fortsetzen kann. Wiederhole diesen Schritt, wenn das Modell weitere MCP-Aufrufe ausführt. Die Realtime API erstellt diese Folgeantworten nicht automatisch.

Dieser Ereignishandler protokolliert die wichtigsten Ereignisse im MCP-Lebenszyklus. Er verwaltet keine Folgeantworten:

Während einer Realtime-Sitzung auf MCP-Ereignisse warten
function parseRealtimeEvent(rawMessage) {
  if (typeof rawMessage === "string") {
    return JSON.parse(rawMessage);
  }

  if (typeof rawMessage?.data === "string") {
    return JSON.parse(rawMessage.data);
  }

  return JSON.parse(rawMessage.toString());
}

function getOutputText(item) {
  if (item.type !== "message") return "";

  return (item.content ?? [])
    .filter((part) => part.type === "output_text")
    .map((part) => part.text)
    .join("");
}

ws.on("message", (rawMessage) => {
  const event = parseRealtimeEvent(rawMessage);

  switch (event.type) {
    case "mcp_list_tools.in_progress":
      console.log("Listing MCP tools for item:", event.item_id);
      break;

    case "mcp_list_tools.completed":
      console.log("MCP tool listing complete for item:", event.item_id);
      break;

    case "mcp_list_tools.failed":
      console.error("MCP tool listing failed for item:", event.item_id);
      break;

    case "conversation.item.done":
      if (event.item.type === "mcp_list_tools") {
        const names = event.item.tools.map((tool) => tool.name).join(", ");
        console.log(`MCP tools ready on ${event.item.server_label}: ${names}`);
      }

      if (event.item.type === "mcp_approval_request") {
        console.log(
          "Approval required for:",
          event.item.name,
          event.item.arguments
        );
      }
      break;

    case "response.mcp_call_arguments.done":
      console.log("Final MCP call arguments:", event.arguments);
      break;

    case "response.mcp_call.in_progress":
      console.log("Running MCP tool for item:", event.item_id);
      break;

    case "response.mcp_call.failed":
      console.error("MCP tool call failed for item:", event.item_id);
      break;

    case "response.output_item.done":
      if (event.item.type === "mcp_call") {
        console.log(
          `MCP output from ${event.item.server_label}.${event.item.name}:`,
          event.item.output
        );
      }

      if (event.item.type === "message") {
        console.log("Assistant:", getOutputText(event.item));
      }
      break;

    case "response.done":
      console.log("Realtime turn complete.");
      break;
  }
});

Häufige Fehler

  • mcp_list_tools.failed: Die Realtime API konnte keine Tools vom entfernten Server oder Konnektor importieren. Prüfe server_url oder connector_id, die Authentifizierung, die Verbindung zum Server und alle Tool-Namen, die du in allowed_tools angegeben hast.
  • response.mcp_call.failed: Das Modell hat ein Tool ausgewählt, aber der Tool-Aufruf wurde nicht abgeschlossen. Prüfe die Ereignisdaten und das spätere mcp_call-Element auf MCP-Protokoll-, Ausführungs- oder Übertragungsfehler.
  • mcp_approval_request ohne passende mcp_approval_response: Der Tool-Aufruf kann erst fortgesetzt werden, wenn dein Client ihn ausdrücklich genehmigt oder ablehnt.
  • Ein Gesprächsschritt beginnt, während mcp_list_tools.in_progress noch aktiv ist: Für diesen Gesprächsschritt stehen nur Tools zur Verfügung, die bereits vollständig geladen wurden.
  • Eine Antwort verwendet tool_choice: "required", aber derzeit sind keine Tools verfügbar: Das Modell kann kein geeignetes Tool aufrufen. Warte auf mcp_list_tools.completed, stelle sicher, dass mindestens ein Tool importiert wurde, oder verwende für Gesprächsschritte, die kein Tool benötigen, einen anderen Wert für tool_choice.
  • Die Validierung der MCP-Tool-Definition schlägt fehl, bevor der Import beginnt. Häufige Ursachen sind ein doppelter server_label-Wert im selben tools-Array, das gleichzeitige Setzen von server_url und connector_id, das Weglassen beider Angaben bei der ursprünglichen Anfrage zur Sitzungserstellung, ein ungültiger connector_id-Wert oder das gleichzeitige Senden von authorization und headers.Authorization. Sende bei Konnektoren grundsätzlich kein headers.Authorization.

MCP-Tool-Aufrufe genehmigen oder ablehnen

Wenn ein Tool eine Genehmigung erfordert, fügt die Realtime API ein mcp_approval_request-Element in die Unterhaltung ein. Um fortzufahren, sende ein neues conversation.item.create-Ereignis, bei dem item.type den Wert mcp_approval_response hat.

Eine MCP-Anfrage genehmigen
function approveMcpRequest(approvalRequestId) {
  const event = {
    type: "conversation.item.create",
    item: {
      id: `mcp_approval_${approvalRequestId}`,
      type: "mcp_approval_response",
      approval_request_id: approvalRequestId,
      approve: true,
    },
  };

  ws.send(JSON.stringify(event));
}

Wenn du die Anfrage ablehnst, setze approve auf false und gib optional eine Begründung in reason an.

MCP nur für eine Antwort verwenden

Wenn MCP nur für einen einzelnen Gesprächsschritt verfügbar sein soll, füge dasselbe MCP-Tool-Objekt zu response.tools statt zu session.tools hinzu:

MCP-Tools für eine einzelne Antwort hinzufügen
const event = {
  type: "response.create",
  response: {
    output_modalities: ["text"],
    input: [
      {
        type: "message",
        role: "user",
        content: [
          {
            type: "input_text",
            text: "Which transport should I use for browser clients in the Realtime API?",
          },
        ],
      },
    ],
    tools: [
      {
        type: "mcp",
        server_label: "openai_docs",
        server_url: "https://developers.openai.com/mcp",
        allowed_tools: ["search_openai_docs", "fetch_openai_doc"],
        require_approval: "never",
      },
    ],
  },
};

ws.send(JSON.stringify(event));

Das ist nützlich, wenn nur eine Antwort externen Kontext benötigt oder wenn verschiedene Gesprächsschritte unterschiedliche MCP-Server verwenden sollen.

Eine zuvor definierte Serverkennung wiederverwenden

server_label ist die feste Kennung für eine Tool-Definition in der aktuellen Realtime-Sitzung. Nachdem du einen Server oder Konnektor einmal mit server_label sowie server_url oder connector_id definiert hast, genügt es, in späteren Ereignissen vom Typ session.update oder response.create nur auf denselben server_label-Wert zu verweisen. Die Realtime API verwendet dann die frühere Definition, ohne dass du das vollständige Tool-Objekt erneut senden musst.

Einen zuvor definierten Konnektor wiederverwenden
const event = {
  type: "response.create",
  response: {
    output_modalities: ["text"],
    input: [
      {
        type: "message",
        role: "user",
        content: [
          {
            type: "input_text",
            text: "Check my schedule for this afternoon.",
          },
        ],
      },
    ],
    // Reuses the google_calendar connector defined earlier in this session.
    tools: [
      {
        type: "mcp",
        server_label: "google_calendar",
      },
    ],
  },
};

ws.send(JSON.stringify(event));

Diese Wiederverwendung ist auf die jeweilige Sitzung beschränkt. Wenn du eine neue Realtime-Sitzung startest, sende die vollständige MCP-Definition erneut, damit der Server seine Tool-Liste importieren kann.