您可以为 Realtime 会话添加工具,让模型在实时对话中查询数据、执行操作或调用服务。无论您的客户端使用 WebRTC 数据通道还是 WebSocket,工具配置都使用相同的事件接口。
如果应由您的应用执行工具并返回结果,请使用函数工具。如果应由 Realtime API 为您连接到远程工具服务器,请使用 MCP 工具。
选择工具类型
| 工具类型 | 适用场景 | 执行方 |
|---|---|---|
function | 您的应用负责业务逻辑、审批检查或私有系统访问。 | 您的客户端或服务器接收函数调用并返回 function_call_output。 |
搭配 server_url 使用的 mcp | 您希望模型调用远程 MCP 服务器提供的工具。 | Realtime API 调用远程 MCP 服务器。 |
搭配 connector_id 使用的 mcp | 您需要在现有模型中使用旧版内置连接器。 | Realtime API 使用您提供的授权调用连接器。 |
在 以下两个位置之一添加工具:
- 如果您希望工具在整个会话中可用,请通过
session.update中的session.tools在 会话级别 添加工具。 - 如果您只需要在一轮交互中使用工具,请通过
response.create中的response.tools在 响应级别 添加工具。
配置函数工具
如果工具需要在您的应用中运行,函数工具是合适的默认选择。模型输出函数调用参数,您的代码执行操作,然后通过 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));当模型调用函数时,监听函数调用项,运行您的应用逻辑,然后将输出返回:
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" }));如需按事件逐步了解函数调用的完整流程,请参阅管理对话。
配置 MCP 工具
如果工具已由远程 MCP 服务器提供,或现有模型使用旧版内置连接器,MCP 工具就很适用。与函数工具不同,MCP 工具由 Realtime API 本身执行。
在 Realtime 中,MCP 工具的结构如下:
type: "mcp"server_labelserver_url或connector_id,二选一- 可选的
authorization和headers - 可选的
allowed_tools - 可选的
require_approval - 可选的
server_description
此示例让提供文档的 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));旧版连接器
对于 2026 年 9 月 1 日之后发布的模型,connector_id 已弃用。
请使用 server_url 连接到远程 MCP 服务器,或使用
tunnel_id,通过
安全 MCP 隧道连接到本地 MCP 服务器。
现有模型仍支持连接器。以下示例使用
gpt-realtime-1.5,该模型在上述截止日期之前发布。
内置连接器使用相同的 MCP 工具结构,但传入的是 connector_id,
而不是 server_url。例如,Google Calendar 使用
connector_googlecalendar。在 Realtime 中,请使用这些内置连接器执行读取操作,
例如搜索或读取日历活动或电子邮件。通过 authorization 传入用户的 OAuth 访问 Token,
并尽可能使用
allowed_tools 限制可用工具的范围:
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 生命周期事件,以及在服务器要求审批时按需发送审批响应。
典型流程如下:
- 您发送
session.update或response.create,其中包含一个type为mcp的tools条目。 - 服务器开始导入工具,并发出
mcp_list_tools.in_progress。 - 在工具列表仍在加载时,模型无法调用尚未加载的工具。如果您希望等待工具加载后再开始依赖这些工具的一轮交互,请监听
mcp_list_tools.completed。item.type为mcp_list_tools的conversation.item.done事件会显示实际导入的工具名称。如果导入失败,您将收到mcp_list_tools.failed。 - 用户说话或发送文本后,由您的客户端创建响应,或根据会话配置自动创建响应。
- 如果模型选择了 MCP 工具,您将看到
response.mcp_call_arguments.delta和response.mcp_call_arguments.done。 - 如果需要审批,服务器会添加一个
item.type为mcp_approval_request的对话项。您的客户端必须使用mcp_approval_response项回应。 - 工具开始运行后,您将看到
response.mcp_call.in_progress。如果执行成功,您随后会收到一个item.type为mcp_call的response.output_item.done事件;如果执行失败,您将收到response.mcp_call.failed。 - 某个响应的
response.done可能会在其 MCP 调用完成之前到达。响应结束且其所有 MCP 调用均已完成后,请再发送一个response.create事件,让模型使用这些结果并继续对话。如果模型又发起了 MCP 调用,请重复此步骤。Realtime API 不会自动创建这些后续响应。
此事件处理程序会记录主要的 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,确认至少已导入一个工具,或者为不需要工具的对话轮次使用其他tool_choice设置。 - MCP 工具定义在开始导入前未通过验证:常见原因包括同一个
tools数组中存在重复的server_label、同时设置了server_url和connector_id、在初始会话创建请求中同时省略了这两项、使用了无效的connector_id,或同时发送了authorization和headers.Authorization。对于连接器,请勿发送headers.Authorization。
批准或拒绝 MCP 工具调用
如果工具需要审批,Realtime API 会在对话中插入一个 mcp_approval_request 项。 要继续,请发送一个新的 conversation.item.create 事件,并将其 item.type 设为 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));
}如果您拒绝该请求,请将 approve 设为 false,也可以附上 reason。
仅为单个响应使用 MCP
如果 MCP 应 仅在单轮对话中可用,请将同一个 MCP 工具对象添加到 response.tools,而不是 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));当只有一个响应需要外部上下文,或不同轮次的对话应使用不同的 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 定义,以便服务器导入其工具列表。