For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
メインナビゲーション

リアルタイムでのツールの使用

リアルタイム音声エージェントから関数ツールやリモート MCP サーバーを呼び出せるようにします。

Realtime セッションにツールを追加すると、モデルがリアルタイムの会話中にデータを検索したり、アクションを実行したり、サービスを呼び出したりできるようになります。クライアントが WebRTC データチャネルWebSocket のどちらを使用する場合も、ツールの構成には同じイベントインターフェースを使用します。

アプリケーション側でツールを実行して結果を返す場合は、関数ツールを使用します。Realtime API にリモートのツールサーバーへの接続を任せる場合は、MCP ツールを使用します。

ツールの種類の選択

ツールの種類使用する場面実行主体
functionアプリケーションがビジネスロジック、承認チェック、または非公開システムへのアクセスを担う場合。クライアントまたはサーバーが関数呼び出しを受け取り、function_call_output を返します。
server_url を指定した mcpリモート MCP サーバーが公開するツールをモデルに呼び出させたい場合。Realtime API がリモート MCP サーバーを呼び出します。
connector_id を指定した mcp既存のモデルでレガシーの組み込みコネクタを使用する場合。Realtime API が、指定された認可情報を使ってコネクタを呼び出します。

ツールは 次の 2 か所のいずれかに追加します。

  • セッション全体でツールを利用できるようにする場合は、session.updatesession.tools を使い、 セッションレベル で追加します。
  • 1 ターンだけツールが必要な場合は、response.createresponse.tools を使い、 レスポンスレベル で追加します。

関数ツールの設定

アプリケーション内でツールを実行する場合は、関数ツールが基本的な選択肢です。モデルが関数呼び出しの引数を出力し、アプリケーションのコードがアクションを実行して、function_call_output アイテムで結果を返します。

session.update による関数ツールの設定
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));

モデルが関数を呼び出したら、関数呼び出しアイテムを受け取り、アプリケーションのロジックを実行してから、出力を返します。

関数呼び出しの出力の送信
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" }));

Function Calling の流れをイベントごとに詳しく説明した手順については、会話の管理を参照してください。

MCP ツールの設定

MCP ツールは、リモート MCP サーバー経由で利用できるツールがすでにある場合や、既存のモデルでレガシーの組み込みコネクタを使用する場合に役立ちます。関数ツールとは異なり、MCP ツールは Realtime API 自体が実行します。

Realtime の MCP ツールは、次の構造で定義します。

  • type: "mcp"
  • server_label
  • server_url または connector_id のいずれか
  • 任意の authorizationheaders
  • 任意の allowed_tools
  • 任意の require_approval
  • 任意の server_description

次の例では、ドキュメント用の MCP サーバーをセッション全体で利用できるようにします。

session.update による MCP ツールの設定
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));

レガシーコネクタ

connector_id は、2026 年 9 月 1 日より後にリリースされたモデルでは非推奨です。 リモート MCP サーバーに接続するには server_url を使用します。 また、 tunnel_id を使用すると、セキュア MCP トンネルを介してローカル MCP サーバーに接続できます。 既存のモデルでは、引き続きコネクタがサポートされます。 以下の例では、この日付より前にリリースされた gpt-realtime-1.5 を使用します。

組み込みコネクタも同じ MCP ツールの構造を使用しますが、server_url の代わりに connector_id を渡します。 たとえば、Google Calendar では connector_googlecalendar を使用します。 Realtime では、これらの組み込みコネクタを、予定やメールの検索・読み取りなどの 読み取りアクションに使用します。ユーザーの OAuth アクセストークンを authorization に渡し、 可能であれば allowed_tools を使って 利用できるツールを絞り込みます。

Google Calendar コネクタの設定
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));

リモート MCP サーバーは 会話のコンテキスト全体を自動的に受け取るわけではありませんが、 モデルがツール呼び出しで送信するデータはすべて参照できますallowed_tools利用できるツールを絞り込み、 自動実行を許可しないアクションには必ず承認を求めてください。

Realtime の MCP 処理フロー

Realtime の function ツールとは異なり、リモート MCP ツールは Realtime API 自体が実行しますクライアントがリモートツールを実行することはなくfunction_call_output を返すこともありません。代わりに、クライアントはアクセスを設定し、MCP のライフサイクルイベントを受信します。また、サーバーから承認を求められた場合は、必要に応じて承認応答を送信します。

一般的な処理の流れは次のとおりです。

  1. typemcptools エントリを含めて、session.update または response.create を送信します。
  2. サーバーがツールのインポートを開始し、mcp_list_tools.in_progress を送出します。
  3. ツール一覧の取得中は、モデルはまだ読み込まれていないツールを呼び出せません。それらのツールに依存するターンを開始する前に待機する場合は、mcp_list_tools.completed を待ちます。item.typemcp_list_toolsconversation.item.done イベントで、実際にインポートされたツールの名前を確認できます。インポートに失敗すると、mcp_list_tools.failed を受信します。
  4. ユーザーが発話するかテキストを送信すると、クライアントによって、またはセッション設定に従って自動的に、レスポンスが作成されます。
  5. モデルが MCP ツールを選択すると、response.mcp_call_arguments.deltaresponse.mcp_call_arguments.done を受信します。
  6. 承認が必要な場合、サーバーは item.typemcp_approval_request の会話アイテムを追加します。クライアントは、mcp_approval_response アイテムで応答する必要があります。
  7. ツールの実行が始まると、response.mcp_call.in_progress を受信します。成功した場合は、その後 item.typemcp_callresponse.output_item.done イベントを受信します。失敗した場合は、response.mcp_call.failed を受信します。
  8. レスポンスの response.done は、そのレスポンスに含まれる MCP 呼び出しが完了する前に届くことがあります。レスポンスと、それに含まれるすべての MCP 呼び出しが完了したら、response.create イベントを再度送信し、モデルが結果を使って会話を続けられるようにします。モデルが追加の MCP 呼び出しを行った場合は、この手順を繰り返します。Realtime API は、これらの後続レスポンスを自動的には作成しません。

次のイベントハンドラーは、MCP の主なライフサイクルイベントをログに記録します。後続レスポンスの管理は行いません。

Realtime セッションでの MCP イベントの受信
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;
  }
});

よくあるエラー

  • mcp_list_tools.failed:Realtime API がリモートサーバーまたはコネクタからツールをインポートできませんでした。server_url または connector_id、認証、サーバーへの接続状況、および allowed_tools に指定したツール名を確認してください。
  • response.mcp_call.failed:モデルがツールを選択しましたが、ツール呼び出しが完了しませんでした。イベントのペイロードと、その後の mcp_call 項目を調べ、MCP プロトコル、実行、通信のエラーがないか確認してください。
  • mcp_approval_request に対応する mcp_approval_response がありません:クライアントが明示的に承認または拒否するまで、ツール呼び出しは続行できません。
  • mcp_list_tools.in_progress がまだ進行中の状態でターンが開始されます:そのターンで使用できるのは、すでに読み込みが完了したツールだけです。
  • レスポンスで tool_choice: "required" を使用していますが、現在利用可能なツールがありません:モデルが呼び出せるツールがない状態です。mcp_list_tools.completed を待ち、少なくとも 1 つのツールがインポートされたことを確認するか、ツールを必要としないターンでは tool_choice に別の値を使用してください。
  • インポートの開始前に MCP ツール定義の検証が失敗します:よくある原因は、同じ tools 配列内での server_label の重複、server_urlconnector_id の両方の設定、最初のセッション作成リクエストでの両方の省略、無効な connector_id の使用、または authorizationheaders.Authorization の両方の送信です。コネクタの場合、headers.Authorization は一切送信しないでください。

MCP ツール呼び出しの承認または拒否

ツールに承認が必要な場合、Realtime API は会話に mcp_approval_request 項目を挿入します。 続行するにはitem.typemcp_approval_response の新しい conversation.item.create イベントを送信してください。

MCP リクエストの承認
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));
}

リクエストを拒否する場合は、approvefalse に設定し、必要に応じて reason を含めてください。

単一のレスポンスでのみ MCP を使用

MCP を 単一のターンでのみ利用可能にする場合は、同じ MCP ツールオブジェクトを session.tools ではなく response.tools に追加します。

単一のレスポンスへの MCP ツールの追加
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));

これは、単一のレスポンスだけが外部コンテキストを必要とする場合や、ターンごとに異なる MCP サーバーを使用する場合に便利です。

定義済みのサーバーラベルの再利用

server_label は、現在の Realtime セッション内でツール定義を識別する固定のハンドルです。 サーバーまたはコネクタを一度定義する際に、 server_label と、server_url または connector_id を指定しておけば、その後の session.update または response.create イベントでは、同じ server_label だけを参照できます。 Realtime API は以前の定義を再利用するため、 ツールオブジェクト全体を再送信する必要はありません。

定義済みのコネクタの再利用
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));

この再利用は同じセッション内に限られます。新しい Realtime セッションを開始する場合は、サーバーがツール一覧をインポートできるよう、MCP 定義全体を再送信してください。