Puedes agregar herramientas a una sesión de Realtime para que el modelo consulte datos, realice acciones o llame a servicios durante una conversación en vivo. La configuración de herramientas usa la misma interfaz de eventos, tanto si tu cliente usa un canal de datos WebRTC como si usa un WebSocket.
Usa herramientas de función cuando tu aplicación deba ejecutar la herramienta y devolver el resultado. Usa herramientas MCP cuando la Realtime API deba conectarse a un servidor de herramientas remoto por ti.
Elige un tipo de herramienta
| Tipo de herramienta | Cuándo usarlo | Quién lo ejecuta |
|---|---|---|
function | Tu aplicación se encarga de la lógica de negocio, las verificaciones de aprobación o el acceso a sistemas privados. | Tu cliente o servidor recibe una llamada a función y devuelve function_call_output. |
mcp con server_url | Quieres que el modelo llame a herramientas expuestas por un servidor MCP remoto. | La Realtime API llama al servidor MCP remoto. |
mcp con connector_id | Usas un conector integrado heredado con un modelo existente. | La Realtime API llama al conector con la autorización que proporcionas. |
Agrega herramientas en uno de estos dos lugares:
- A nivel de sesión , con
session.toolsensession.update, si quieres que la herramienta esté disponible durante toda la sesión. - A nivel de respuesta , con
response.toolsenresponse.create, si solo necesitas la herramienta para un turno.
Configura una herramienta de función
Las herramientas de función son la opción predeterminada adecuada cuando la herramienta debe ejecutarse en tu aplicación. El modelo emite los argumentos de la llamada a función, tu código ejecuta la acción y envía el resultado mediante un elemento function_call_output.
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));Cuando el modelo llame a la función, espera a recibir el elemento de llamada a función, ejecuta la lógica de tu aplicación y luego envía el resultado:
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" }));Para ver una explicación completa de las llamadas a funciones, evento por evento, consulta Gestión de conversaciones.
Configura una herramienta MCP
Las herramientas MCP son útiles cuando la herramienta ya está disponible a través de un servidor MCP remoto o cuando un modelo existente usa un conector integrado heredado. A diferencia de las herramientas de función, las herramientas MCP las ejecuta la propia Realtime API.
En Realtime, la estructura de una herramienta MCP es la siguiente:
type: "mcp"server_label- Uno de estos dos campos:
server_urloconnector_id authorizationyheaders, opcionalesallowed_tools, opcionalrequire_approval, opcionalserver_description, opcional
Este ejemplo hace que un servidor MCP de documentación esté disponible durante toda la sesión:
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 heredados
connector_id está en desuso para los modelos lanzados después del 1 de septiembre de
2026. Usa server_url para conectarte a un servidor MCP remoto, o
tunnel_id para conectarte a un servidor MCP local a través de
Túnel MCP seguro. Los modelos
existentes mantienen la compatibilidad con los conectores. El siguiente ejemplo usa
gpt-realtime-1.5, que se lanzó antes de esa fecha límite.
Los conectores integrados usan la misma estructura de herramienta MCP, pero se les pasa connector_id
en lugar de server_url. Por ejemplo, Google Calendar usa
connector_googlecalendar. En Realtime, usa estos conectores integrados para acciones de
lectura, como buscar o leer eventos o correos electrónicos. Pasa el token de acceso OAuth
del usuario en authorization y limita las herramientas disponibles con
allowed_tools cuando sea posible:
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));Los servidores MCP remotos
no reciben automáticamente el contexto completo de la conversación,
pero pueden ver cualquier dato que el modelo envíe en una llamada a herramienta.
Mantén limitado el conjunto de herramientas disponibles con allowed_tools,
y exige aprobación para cualquier acción que no ejecutarías automáticamente.
Flujo de MCP en Realtime
A diferencia de las herramientas function de Realtime, las herramientas MCP remotas las ejecuta la propia Realtime API. Tu cliente no ejecuta la herramienta remota ni devuelve un function_call_output. En cambio, tu cliente configura el acceso, escucha los eventos del ciclo de vida de MCP y, de manera opcional, envía una respuesta de aprobación si el servidor la solicita.
Un flujo típico es el siguiente:
- Envías
session.updateoresponse.createcon una entrada entoolscuyotypeesmcp. - El servidor comienza a importar herramientas y emite
mcp_list_tools.in_progress. - Mientras se sigue obteniendo la lista de herramientas, el modelo no puede llamar a una herramienta que aún no se haya cargado. Si quieres esperar antes de iniciar un turno que dependa de esas herramientas, espera a recibir
mcp_list_tools.completed. El eventoconversation.item.donecuyoitem.typeesmcp_list_toolsmuestra los nombres de las herramientas que se importaron realmente. Si la importación falla, recibirásmcp_list_tools.failed. - El usuario habla o envía texto y se crea una respuesta, ya sea desde tu cliente o automáticamente según la configuración de la sesión.
- Si el modelo elige una herramienta MCP, verás
response.mcp_call_arguments.deltayresponse.mcp_call_arguments.done. - Si se requiere aprobación, el servidor agrega un elemento a la conversación cuyo
item.typeesmcp_approval_request. Tu cliente debe responder con un elementomcp_approval_response. - Cuando la herramienta se ejecute, verás
response.mcp_call.in_progress. Si se ejecuta correctamente, más adelante recibirás un eventoresponse.output_item.donecuyoitem.typeesmcp_call; si falla, recibirásresponse.mcp_call.failed. - El evento
response.donede una respuesta puede llegar antes de que finalicen sus llamadas MCP. Una vez que hayan finalizado la respuesta y todas sus llamadas MCP, envía otro eventoresponse.createpara que el modelo use los resultados y continúe la conversación. Repite este paso si el modelo realiza más llamadas MCP. La Realtime API no crea estas respuestas de seguimiento automáticamente.
Este manejador de eventos registra los principales eventos del ciclo de vida de MCP; no gestiona las respuestas de seguimiento:
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;
}
});Fallas comunes
mcp_list_tools.failed: la Realtime API no pudo importar herramientas del servidor remoto o del conector. Revisaserver_urloconnector_id, la autenticación, la conectividad del servidor y los nombres que hayas especificado enallowed_tools.response.mcp_call.failed: el modelo seleccionó una herramienta, pero la llamada a la herramienta no se completó. Inspecciona el contenido del evento y el elementomcp_callposterior para detectar errores del protocolo MCP, de ejecución o de transporte.mcp_approval_requestsin unmcp_approval_responsecorrespondiente: la llamada a la herramienta no puede continuar hasta que tu cliente la apruebe o rechace explícitamente.- Un turno comienza mientras
mcp_list_tools.in_progresssigue activo: solo las herramientas que ya terminaron de cargarse pueden usarse en ese turno. - Una respuesta usa
tool_choice: "required", pero no hay herramientas disponibles en ese momento: el modelo no tiene ninguna herramienta que pueda llamar. Espera a que se emitamcp_list_tools.completed, confirma que se haya importado al menos una herramienta o usa un valor diferente detool_choicepara los turnos que no requieran una herramienta. - La validación de la definición de la herramienta MCP falla antes de que comience la importación: las causas comunes son un
server_labelduplicado en el mismo arreglotools, configurar tantoserver_urlcomoconnector_id, omitir ambos en la solicitud inicial de creación de la sesión, usar unconnector_idno válido o enviar tantoauthorizationcomoheaders.Authorization. Para los conectores, no envíesheaders.Authorizationen ningún caso.
Aprobar o rechazar llamadas a herramientas MCP
Si una herramienta requiere aprobación, la Realtime API inserta un elemento mcp_approval_request en la conversación. Para continuar, envía un nuevo evento conversation.item.create cuyo item.type sea mcp_approval_response.
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));
}Si rechazas la solicitud, establece approve en false y, de forma opcional, incluye reason.
Usar MCP para una sola respuesta
Si MCP debe estar disponible solo durante un turno, agrega el mismo objeto de herramienta MCP a response.tools en lugar de session.tools:
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));Esto es útil cuando solo una respuesta necesita contexto externo o cuando distintos turnos deben usar distintos servidores MCP.
Reutilizar una etiqueta de servidor definida previamente
server_label es el identificador estable de una definición de herramienta en la sesión
Realtime actual. Después de definir un servidor o conector una vez con
server_label junto con server_url o connector_id, los eventos session.update o
response.create posteriores pueden hacer referencia únicamente a ese mismo server_label, y la
Realtime API reutilizará la definición anterior sin que tengas que volver a enviar
el objeto completo de la herramienta.
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));Esta reutilización se limita a la sesión actual. Si inicias una nueva sesión Realtime, vuelve a enviar la definición completa de MCP para que el servidor pueda importar su lista de herramientas.