For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navegação principal
Theme

Ferramentas no Realtime

Permita que agentes de voz em tempo real chamem ferramentas de função e servidores MCP remotos.

Você pode adicionar ferramentas a uma sessão Realtime para que o modelo consulte dados, execute ações ou chame serviços durante uma conversa ao vivo. O cliente usa os mesmos eventos para configurar as ferramentas, tanto com um canal de dados WebRTC quanto com uma conexão WebSocket.

Use ferramentas de função quando o aplicativo precisar executar a ferramenta e retornar o resultado. Use ferramentas MCP quando quiser que a Realtime API se conecte a um servidor remoto de ferramentas.

Escolha o tipo de ferramenta

Tipo de ferramenta Quando usar Quem executa
function Seu aplicativo controla a lógica de negócio, as verificações de aprovação ou o acesso a sistemas privados. Seu cliente ou servidor recebe uma chamada de função e retorna function_call_output.
mcp com server_url Você quer que o modelo chame ferramentas disponibilizadas por um servidor MCP remoto. A Realtime API chama o servidor MCP remoto.
mcp com connector_id Você usa um conector integrado legado com um modelo existente. A Realtime API chama o conector com a autorização que você fornece.

Adicione as ferramentas em um dos dois níveis:

  • No nível da sessão, use session.tools em session.update se quiser disponibilizar a ferramenta durante toda a sessão.
  • No nível da resposta, use response.tools em response.create se precisar da ferramenta por apenas um turno.

Configure uma ferramenta de função

Prefira ferramentas de função quando a execução couber ao aplicativo. O modelo fornece os argumentos da chamada de função, e seu código executa a ação e envia o resultado de volta em um item function_call_output.

Configure uma ferramenta de função com 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));

Quando o modelo chamar a função, aguarde o item de chamada de função, execute a lógica do aplicativo e envie o resultado de volta:

Envie o resultado da chamada de função
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",
    response: { output_modalities: ["text"], tool_choice: "none" },
  })
);

Para acompanhar uma chamada de função evento por evento, consulte Gerenciamento de conversas.

Configure uma ferramenta MCP

As ferramentas MCP são úteis quando um servidor MCP remoto já disponibiliza a ferramenta ou quando um modelo existente usa um conector integrado legado. Ao contrário das ferramentas de função, as ferramentas MCP são executadas pela própria Realtime API.

No Realtime, a definição de uma ferramenta MCP tem os seguintes campos:

  • type: "mcp"
  • server_label
  • Um dos campos server_url ou connector_id
  • Os campos opcionais authorization e headers
  • O campo opcional allowed_tools
  • O campo opcional require_approval
  • O campo opcional server_description

Este exemplo disponibiliza um servidor MCP de documentação durante toda a sessão:

Configure uma ferramenta MCP com session.update
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));

Conectores legados

O uso de connector_id está obsoleto nos modelos lançados após 1º de setembro de 2026. Use server_url para se conectar a um servidor MCP remoto ou tunnel_id para se conectar a um servidor MCP local por meio de um túnel MCP seguro. Os modelos existentes continuam oferecendo suporte a conectores. O exemplo abaixo usa o modelo gpt-realtime-1.5, lançado antes dessa data.

Os conectores integrados usam a mesma estrutura das ferramentas MCP, mas recebem connector_id em vez de server_url. Por exemplo, o Google Agenda usa connector_googlecalendar. No Realtime, use esses conectores integrados para operações de leitura, como pesquisar ou ler eventos ou e-mails. Informe o token de acesso OAuth do usuário em authorization e, sempre que possível, restrinja as ferramentas disponíveis com allowed_tools:

Configure um conector do Google Agenda
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));

Os servidores MCP remotos não recebem automaticamente todo o contexto da conversa, mas podem ver qualquer dado que o modelo envie em uma chamada de ferramenta. Limite as ferramentas disponíveis com allowed_tools e exija aprovação para qualquer ação que você não executaria automaticamente.

Fluxo de execução das ferramentas MCP no Realtime

Ao contrário das ferramentas do tipo function no Realtime, as ferramentas MCP remotas são executadas pela própria Realtime API. Seu cliente não executa a ferramenta remota nem retorna um item function_call_output. O cliente configura o acesso, monitora os eventos do ciclo de vida do MCP e pode enviar uma resposta de aprovação se o servidor a solicitar.

O fluxo típico segue estas etapas:

  1. Você envia session.update ou response.create com uma entrada em tools cujo type é mcp.
  2. O servidor começa a importar as ferramentas e emite mcp_list_tools.in_progress.
  3. Enquanto a listagem estiver em andamento, o modelo só poderá chamar ferramentas já carregadas. Se quiser aguardar antes de iniciar um turno que dependa dessas ferramentas, monitore o evento mcp_list_tools.completed. O evento conversation.item.done cujo item.type é mcp_list_tools mostra os nomes das ferramentas que o servidor de fato importou. Se a importação falhar, você receberá mcp_list_tools.failed.
  4. O usuário fala ou envia texto. O cliente cria uma resposta, ou a sessão a cria automaticamente, conforme a configuração.
  5. Se o modelo escolher uma ferramenta MCP, você verá response.mcp_call_arguments.delta e response.mcp_call_arguments.done.
  6. Se a ferramenta exigir aprovação, o servidor adicionará à conversa um item cujo item.type é mcp_approval_request. Seu cliente deve responder com um item mcp_approval_response.
  7. Quando a ferramenta começar a ser executada, você verá response.mcp_call.in_progress. Se a execução for bem-sucedida, você receberá em seguida um evento response.output_item.done cujo item.type é mcp_call. Se houver falha, você receberá response.mcp_call.failed.
  8. O evento response.done de uma resposta pode chegar antes que as chamadas MCP dessa resposta terminem. Quando a resposta e todas as suas chamadas MCP tiverem terminado, envie outro evento response.create para que o modelo use os resultados e continue a conversa. Repita essa etapa se o modelo fizer outras chamadas MCP. A Realtime API não cria essas respostas subsequentes automaticamente.

Este manipulador de eventos registra os principais eventos do ciclo de vida do MCP, mas não gerencia as respostas subsequentes:

Monitore eventos MCP durante uma sessão Realtime
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;
  }
});

Falhas comuns

  • mcp_list_tools.failed: a Realtime API não conseguiu importar ferramentas do servidor remoto ou do conector. Verifique o valor de server_url ou connector_id, a autenticação, a conexão com o servidor e os nomes das ferramentas que você especificou em allowed_tools.
  • response.mcp_call.failed: o modelo selecionou uma ferramenta, mas a chamada não foi concluída. Examine o conteúdo do evento e o item mcp_call recebido em seguida para identificar erros de protocolo MCP, de execução ou de transporte.
  • mcp_approval_request sem um mcp_approval_response correspondente: a chamada da ferramenta fica pendente até que o cliente a aprove ou rejeite explicitamente.
  • Um turno começa enquanto mcp_list_tools.in_progress ainda está ativo: nesse turno, o modelo só pode usar ferramentas que já terminaram de carregar.
  • Uma resposta usa tool_choice: "required", mas nenhuma ferramenta está disponível no momento: o modelo não tem nenhuma ferramenta que possa chamar. Aguarde mcp_list_tools.completed, confirme que pelo menos uma ferramenta foi importada ou use outro valor de tool_choice nos turnos que não exigem uma ferramenta.
  • A validação da definição da ferramenta MCP falha antes do início da importação: as causas comuns incluem repetir um server_label no mesmo array tools, definir tanto server_url quanto connector_id, omitir ambos na solicitação inicial de criação da sessão, usar um connector_id inválido ou enviar authorization e headers.Authorization juntos. Para conectores, nunca envie headers.Authorization.

Aprove ou rejeite chamadas de ferramentas MCP

Se uma ferramenta exigir aprovação, a Realtime API inserirá um item mcp_approval_request na conversa. Para prosseguir, envie um novo evento conversation.item.create cujo item.type seja mcp_approval_response.

Aprove uma solicitação MCP
function approveMcpRequest(approvalRequestId) {
  const event = {
    type: "conversation.item.create",
    item: {
      type: "mcp_approval_response",
      approval_request_id: approvalRequestId,
      approve: true,
    },
  };

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

Se você rejeitar a solicitação, defina approve como false e, se quiser, inclua uma justificativa em reason.

Use o MCP em uma única resposta

Se o MCP só precisar ficar disponível por um turno, adicione o mesmo objeto de ferramenta MCP a response.tools em vez de session.tools:

Adicione ferramentas MCP a uma única resposta
const event = {
  type: "response.create",
  response: {
    output_modalities: ["text"],
    tool_choice: "required",
    parallel_tool_calls: false,
    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));

Isso é útil quando apenas uma resposta precisa de contexto externo ou quando turnos diferentes devem usar servidores MCP diferentes.

Reutilize um rótulo de servidor já definido

server_label identifica de forma estável a definição de uma ferramenta na sessão Realtime atual. Depois de definir um servidor ou conector com server_label e um dos campos server_url ou connector_id, basta informar o mesmo rótulo nos eventos session.update ou response.create subsequentes. Com esse server_label, a Realtime API reutiliza a definição anterior sem exigir que você envie novamente o objeto completo da ferramenta.

Reutilize um conector já definido
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));

A definição só pode ser reutilizada na mesma sessão. Se você iniciar uma nova sessão Realtime, envie novamente a definição MCP completa para que o servidor possa importar a lista de ferramentas.