Repository Public
1# MCP servers23> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.45In addition to tools you make available to the model with [function calling](https://developers.openai.com/api/docs/guides/function-calling), you can give models new capabilities using **remote MCP servers** or **Secure MCP Tunnel**. These tools give the model the ability to connect to and control external services when needed to respond to a user's prompt. These tool calls can either be allowed automatically, or restricted with explicit approval required by you as the developer.67- **Remote MCP servers** can be any server on the public Internet that implements a remote [Model Context Protocol](https://modelcontextprotocol.io/introduction) (MCP) server.89- **Secure MCP Tunnel** connects a local or private MCP server without exposing it to the public internet.1011This guide shows how to use MCP tools with the Responses API. Built-in connectors remain supported for existing models; see [Legacy connectors](#connectors) for the deprecation policy and compatibility examples. For Agents API sessions, see [MCP connections](https://developers.openai.com/api/docs/guides/agents-api/tools/mcp), which covers connections from the managed service or from your sandbox.1213## Secure MCP Tunnel1415If your MCP server is private, on-premises, or behind a firewall, use [Secure MCP Tunnel](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels) to connect it to supported OpenAI products without exposing the server to the public internet. Download the latest public release from [openai/tunnel-client](https://github.com/openai/tunnel-client/releases/latest).1617## Quickstart1819Use the `mcp` tool type in the [Responses API](https://developers.openai.com/api/reference/resources/responses/methods/create). Set `server_url` for a remote MCP server, or use `tunnel_id` for a local MCP server through [Secure MCP Tunnel](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels). Depending on the server, you may also need an OAuth access token in the `authorization` parameter.2021Using a remote MCP server in the Responses API2223```bash24curl https://api.openai.com/v1/responses \ 25-H "Content-Type: application/json" \ 26-H "Authorization: Bearer $OPENAI_API_KEY" \ 27-d '{28 "model": "gpt-6-astra",29 "tools": [30 {31 "type": "mcp",32 "server_label": "dmcp",33 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",34 "server_url": "https://dmcp-server.deno.dev/mcp",35 "require_approval": "never"36 }37 ],38 "input": "Roll 2d4+1"39 }'40```4142```javascript43import OpenAI from "openai";44const client = new OpenAI();4546const resp = await client.responses.create({47 model: "gpt-6-astra",48 tools: [49 {50 type: "mcp",51 server_label: "dmcp",52 server_description:53 "A Dungeons and Dragons MCP server to assist with dice rolling.",54 server_url: "https://dmcp-server.deno.dev/mcp",55 require_approval: "never",56 },57 ],58 input: "Roll 2d4+1",59});6061console.log(resp.output_text);62```6364```python65from openai import OpenAI6667client = OpenAI()6869resp = client.responses.create(70 model="gpt-6-astra",71 tools=[72 {73 "type": "mcp",74 "server_label": "dmcp",75 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",76 "server_url": "https://dmcp-server.deno.dev/mcp",77 "require_approval": "never",78 },79 ],80 input="Roll 2d4+1",81)8283print(resp.output_text)84```8586```go87package main8889import (90 "context"91 "fmt"9293 "github.com/openai/openai-go/v3"94 "github.com/openai/openai-go/v3/responses"95)9697func main() {98 client := openai.NewClient()99 tool := responses.ToolParamOfMcp("dmcp")100 tool.OfMcp.ServerDescription = openai.String("A Dungeons and Dragons MCP server to assist with dice rolling.")101 tool.OfMcp.ServerURL = openai.String("https://dmcp-server.deno.dev/mcp")102 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}103104 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{105 Model: "gpt-6-astra",106 Tools: []responses.ToolUnionParam{tool},107 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Roll 2d4+1")},108 })109 if err != nil {110 panic(err)111 }112 fmt.Println(response.OutputText())113}114```115116```java117import com.openai.client.OpenAIClient;118import com.openai.client.okhttp.OpenAIOkHttpClient;119import com.openai.models.responses.ResponseCreateParams;120import com.openai.models.responses.Tool;121122ResponseCreateParams params =123 ResponseCreateParams.builder()124 .model("gpt-6-astra")125 .input("Roll 2d4+1")126 .addTool(127 Tool.Mcp.builder()128 .serverLabel("dmcp")129 .serverDescription(130 "A Dungeons and Dragons MCP server to assist with dice rolling.")131 .serverUrl("https://dmcp-server.deno.dev/mcp")132 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)133 .build())134 .build();135136client.responses().create(params).output().stream()137 .flatMap(item -> item.message().stream())138 .flatMap(message -> message.content().stream())139 .flatMap(content -> content.outputText().stream())140 .forEach(text -> System.out.println(text.text()));141```142143```csharp144using OpenAI.Responses;145#pragma warning disable OPENAI001146147string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;148ResponsesClient client = new(key);149150CreateResponseOptions options = new() { Model = "gpt-6-astra" };151options.Tools.Add(152 ResponseTool.CreateMcpTool(153 serverLabel: "dmcp",154 serverUri: new Uri("https://dmcp-server.deno.dev/mcp"),155 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval156 )157);158options.InputItems.Add(ResponseItem.CreateUserMessageItem("Roll 2d4+1"));159160ResponseResult response = await client.CreateResponseAsync(options);161162Console.WriteLine(response.GetOutputText());163```164165```ruby166require "openai"167168openai = OpenAI::Client.new169170response = openai.responses.create(171 model: "gpt-6-astra",172 tools: [173 {174 type: "mcp",175 server_label: "dmcp",176 server_description: "A Dungeons and Dragons MCP server to assist with dice rolling.",177 server_url: "https://dmcp-server.deno.dev/mcp",178 require_approval: "never"179 }180 ],181 input: "Roll 2d4+1"182)183184puts(response.output_text)185```186187188It is very important that developers trust any remote MCP server they use with189 the Responses API. A malicious server can exfiltrate sensitive data from190 anything that enters the model's context. Carefully review the 191 **Risks and Safety** section below before using this tool.192193The API will return new items in the `output` array of the model response. If the model decides to use an MCP server, it will first make a request to list available tools from the server, which will create a `mcp_list_tools` output item. From the remote MCP server example above, it contains only one tool definition:194195```json196{197 "id": "mcpl_68a6102a4968819c8177b05584dd627b0679e572a900e618",198 "type": "mcp_list_tools",199 "server_label": "dmcp",200 "tools": [201 {202 "annotations": null,203 "description": "Given a string of text describing a dice roll...",204 "input_schema": {205 "$schema": "https://json-schema.org/draft/2020-12/schema",206 "type": "object",207 "properties": {208 "diceRollExpression": {209 "type": "string"210 }211 },212 "required": ["diceRollExpression"],213 "additionalProperties": false214 },215 "name": "roll"216 }217 ]218}219```220221If the model decides to call one of the available tools from the MCP server, you will also find a `mcp_call` output which will show what the model sent to the MCP tool, and what the MCP tool sent back as output.222223```json224{225 "id": "mcp_68a6102d8948819c9b1490d36d5ffa4a0679e572a900e618",226 "type": "mcp_call",227 "approval_request_id": null,228 "arguments": "{\"diceRollExpression\":\"2d4 + 1\"}",229 "error": null,230 "name": "roll",231 "output": "4",232 "server_label": "dmcp"233}234```235236Read on in the guide below to learn more about how the MCP tool works, how to filter available tools, and how to handle tool call approval requests.237238## How it works239240The MCP tool is available in the [Responses API](https://developers.openai.com/api/reference/resources/responses/methods/create) in most recent models. Check MCP tool compatibility for your model [here](https://developers.openai.com/api/docs/models). When you're using the MCP tool, you only pay for [tokens](https://developers.openai.com/api/docs/pricing) used when importing tool definitions or making tool calls. No additional fees apply per tool call.241242Below, we'll step through the process the API takes when calling an MCP tool.243244### Step 1: Listing available tools245246When you specify a remote MCP server in the `tools` parameter, the API will attempt to get a list of tools from the server. The Responses API works with remote MCP servers that support either the Streamable HTTP or the HTTP/SSE transport protocols.247248If successful in retrieving the list of tools, a new `mcp_list_tools` output item will appear in the model response output. The `tools` property of this object will show the tools that were successfully imported.249250```json251{252 "id": "mcpl_68a6102a4968819c8177b05584dd627b0679e572a900e618",253 "type": "mcp_list_tools",254 "server_label": "dmcp",255 "tools": [256 {257 "annotations": null,258 "description": "Given a string of text describing a dice roll...",259 "input_schema": {260 "$schema": "https://json-schema.org/draft/2020-12/schema",261 "type": "object",262 "properties": {263 "diceRollExpression": {264 "type": "string"265 }266 },267 "required": ["diceRollExpression"],268 "additionalProperties": false269 },270 "name": "roll"271 }272 ]273}274```275276As long as the `mcp_list_tools` item is present in the context of an API277 request, the API will not fetch a list of tools from the MCP server again at278 each turn in a [conversation](https://developers.openai.com/api/docs/guides/conversation-state). We279 recommend you keep this item in the model's context as part of every280 conversation or workflow execution to optimize for latency.281282#### Filtering tools283284Some MCP servers can have dozens of tools, and exposing many tools to the model can result in high cost and latency. If you're only interested in a subset of tools an MCP server exposes, you can use the `allowed_tools` parameter to only import those tools.285286Constrain allowed tools287288```bash289curl https://api.openai.com/v1/responses \290-H "Content-Type: application/json" \291-H "Authorization: Bearer $OPENAI_API_KEY" \292-d '{293 "model": "gpt-6-astra",294 "tools": [295 {296 "type": "mcp",297 "server_label": "dmcp",298 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",299 "server_url": "https://dmcp-server.deno.dev/mcp",300 "require_approval": "never",301 "allowed_tools": ["roll"]302 }303 ],304 "input": "Roll 2d4+1"305 }'306```307308```javascript309import OpenAI from "openai";310const client = new OpenAI();311312const resp = await client.responses.create({313 model: "gpt-6-astra",314 tools: [315 {316 type: "mcp",317 server_label: "dmcp",318 server_description:319 "A Dungeons and Dragons MCP server to assist with dice rolling.",320 server_url: "https://dmcp-server.deno.dev/mcp",321 require_approval: "never",322 allowed_tools: ["roll"],323 },324 ],325 input: "Roll 2d4+1",326});327328console.log(resp.output_text);329```330331```python332from openai import OpenAI333334client = OpenAI()335336resp = client.responses.create(337 model="gpt-6-astra",338 tools=[339 {340 "type": "mcp",341 "server_label": "dmcp",342 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",343 "server_url": "https://dmcp-server.deno.dev/mcp",344 "require_approval": "never",345 "allowed_tools": ["roll"],346 }347 ],348 input="Roll 2d4+1",349)350351print(resp.output_text)352```353354```go355package main356357import (358 "context"359 "fmt"360361 "github.com/openai/openai-go/v3"362 "github.com/openai/openai-go/v3/responses"363)364365func main() {366 client := openai.NewClient()367 tool := responses.ToolParamOfMcp("dmcp")368 tool.OfMcp.ServerDescription = openai.String("A Dungeons and Dragons MCP server to assist with dice rolling.")369 tool.OfMcp.ServerURL = openai.String("https://dmcp-server.deno.dev/mcp")370 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}371 tool.OfMcp.AllowedTools = responses.ToolMcpAllowedToolsUnionParam{OfMcpAllowedTools: []string{"roll"}}372373 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{374 Model: "gpt-6-astra",375 Tools: []responses.ToolUnionParam{tool},376 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Roll 2d4+1")},377 })378 if err != nil {379 panic(err)380 }381 fmt.Println(response.OutputText())382}383```384385```java386import com.openai.client.OpenAIClient;387import com.openai.client.okhttp.OpenAIOkHttpClient;388import com.openai.models.responses.ResponseCreateParams;389import com.openai.models.responses.Tool;390import java.util.List;391392ResponseCreateParams params =393 ResponseCreateParams.builder()394 .model("gpt-6-astra")395 .input("Roll 2d4+1")396 .addTool(397 Tool.Mcp.builder()398 .serverLabel("dmcp")399 .serverDescription(400 "A Dungeons and Dragons MCP server to assist with dice rolling.")401 .serverUrl("https://dmcp-server.deno.dev/mcp")402 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)403 .allowedToolsOfMcp(List.of("roll"))404 .build())405 .build();406407client.responses().create(params).output().stream()408 .flatMap(item -> item.message().stream())409 .flatMap(message -> message.content().stream())410 .flatMap(content -> content.outputText().stream())411 .forEach(text -> System.out.println(text.text()));412```413414```csharp415using OpenAI.Responses;416#pragma warning disable OPENAI001417418string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;419ResponsesClient client = new(key);420421CreateResponseOptions options = new() { Model = "gpt-6-astra" };422options.Tools.Add(423 ResponseTool.CreateMcpTool(424 serverLabel: "dmcp",425 serverUri: new Uri("https://dmcp-server.deno.dev/mcp"),426 allowedTools: new McpToolFilter() { ToolNames = { "roll" } },427 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval428 )429);430options.InputItems.Add(ResponseItem.CreateUserMessageItem("Roll 2d4+1"));431432ResponseResult response = await client.CreateResponseAsync(options);433434Console.WriteLine(response.GetOutputText());435```436437```ruby438require "openai"439440client = OpenAI::Client.new441442response = client.responses.create(443 model: "gpt-6-astra",444 input: "Roll 2d4+1",445 tools: [446 {447 type: :mcp,448 server_label: "dmcp",449 server_description: "A Dungeons and Dragons MCP server to assist with dice rolling.",450 server_url: "https://dmcp-server.deno.dev/mcp",451 require_approval: :never,452 allowed_tools: ["roll"]453 }454 ]455)456457puts(response.output_text)458```459460461### Step 2: Calling tools462463Once the model has access to these tool definitions, it may choose to call them depending on what's in the model's context. When the model decides to call an MCP tool, the API will make an request to the remote MCP server to call the tool and put its output into the model's context. This creates an `mcp_call` item which looks like this:464465```json466{467 "id": "mcp_68a6102d8948819c9b1490d36d5ffa4a0679e572a900e618",468 "type": "mcp_call",469 "approval_request_id": null,470 "arguments": "{\"diceRollExpression\":\"2d4 + 1\"}",471 "error": null,472 "name": "roll",473 "output": "4",474 "server_label": "dmcp"475}476```477478This item includes both the arguments the model decided to use for this tool call, and the `output` that the remote MCP server returned. All models can choose to make multiple MCP tool calls, so you may see several of these items generated in a single API request.479480Failed tool calls will populate the error field of this item with MCP protocol errors, MCP tool execution errors, or general connectivity errors. The MCP errors are documented in the MCP spec [here](https://modelcontextprotocol.io/specification/2025-03-26/server/tools#error-handling).481482#### Approvals483484By default, OpenAI will request your approval before any data is shared with a connector or remote MCP server. Approvals help you maintain control and visibility over what data is being sent to an MCP server. We highly recommend that you carefully review (and optionally log) all data being shared with a remote MCP server. A request for an approval to make an MCP tool call creates a `mcp_approval_request` item in the Response's output that looks like this:485486```json487{488 "id": "mcpr_68a619e1d82c8190b50c1ccba7ad18ef0d2d23a86136d339",489 "type": "mcp_approval_request",490 "arguments": "{\"diceRollExpression\":\"2d4 + 1\"}",491 "name": "roll",492 "server_label": "dmcp"493}494```495496You can then respond to this by creating a new Response object and appending an `mcp_approval_response` item to it.497498Approving the use of tools in an API request499500```bash501curl https://api.openai.com/v1/responses \502-H "Content-Type: application/json" \503-H "Authorization: Bearer $OPENAI_API_KEY" \504-d '{505 "model": "gpt-6-astra",506 "tools": [507 {508 "type": "mcp",509 "server_label": "dmcp",510 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",511 "server_url": "https://dmcp-server.deno.dev/mcp",512 "require_approval": "always",513 }514 ],515 "previous_response_id": "resp_682d498bdefc81918b4a6aa477bfafd904ad1e533afccbfa",516 "input": [{517 "type": "mcp_approval_response",518 "approve": true,519 "approval_request_id": "mcpr_682d498e3bd4819196a0ce1664f8e77b04ad1e533afccbfa"520 }]521 }'522```523524```javascript525import OpenAI from "openai";526const client = new OpenAI();527528const resp = await client.responses.create({529 model: "gpt-6-astra",530 tools: [531 {532 type: "mcp",533 server_label: "dmcp",534 server_description:535 "A Dungeons and Dragons MCP server to assist with dice rolling.",536 server_url: "https://dmcp-server.deno.dev/mcp",537 require_approval: "always",538 },539 ],540 previous_response_id: "resp_682d498bdefc81918b4a6aa477bfafd904ad1e533afccbfa",541 input: [542 {543 type: "mcp_approval_response",544 approve: true,545 approval_request_id:546 "mcpr_682d498e3bd4819196a0ce1664f8e77b04ad1e533afccbfa",547 },548 ],549});550551console.log(resp.output_text);552```553554```python555from openai import OpenAI556557client = OpenAI()558559resp = client.responses.create(560 model="gpt-6-astra",561 tools=[562 {563 "type": "mcp",564 "server_label": "dmcp",565 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",566 "server_url": "https://dmcp-server.deno.dev/mcp",567 "require_approval": "always",568 }569 ],570 previous_response_id="resp_682d498bdefc81918b4a6aa477bfafd904ad1e533afccbfa",571 input=[572 {573 "type": "mcp_approval_response",574 "approve": True,575 "approval_request_id": "mcpr_682d498e3bd4819196a0ce1664f8e77b04ad1e533afccbfa",576 }577 ],578)579580print(resp.output_text)581```582583```go584package main585586import (587 "context"588 "fmt"589590 "github.com/openai/openai-go/v3"591 "github.com/openai/openai-go/v3/responses"592)593594func main() {595 client := openai.NewClient()596 tool := responses.ToolParamOfMcp("dmcp")597 tool.OfMcp.ServerDescription = openai.String("A Dungeons and Dragons MCP server to assist with dice rolling.")598 tool.OfMcp.ServerURL = openai.String("https://dmcp-server.deno.dev/mcp")599 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("always")}600601 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{602 Model: "gpt-6-astra",603 PreviousResponseID: openai.String("resp_682d498bdefc81918b4a6aa477bfafd904ad1e533afccbfa"),604 Tools: []responses.ToolUnionParam{tool},605 Input: responses.ResponseNewParamsInputUnion{OfInputItemList: responses.ResponseInputParam{606 responses.ResponseInputItemParamOfMcpApprovalResponse("mcpr_682d498e3bd4819196a0ce1664f8e77b04ad1e533afccbfa", true),607 }},608 })609 if err != nil {610 panic(err)611 }612 fmt.Println(response.OutputText())613}614```615616```java617import com.openai.client.OpenAIClient;618import com.openai.client.okhttp.OpenAIOkHttpClient;619import com.openai.models.responses.ResponseCreateParams;620import com.openai.models.responses.ResponseInputItem;621import com.openai.models.responses.Tool;622import java.util.List;623624String responseId = "resp_682d498bdefc81918b4a6aa477bfafd904ad1e533afccbfa";625626String approvalRequestId = "mcpr_682d498e3bd4819196a0ce1664f8e77b04ad1e533afccbfa";627628ResponseCreateParams params =629 ResponseCreateParams.builder()630 .model("gpt-6-astra")631 .input(632 ResponseCreateParams.Input.ofResponse(633 List.of(634 ResponseInputItem.ofMcpApprovalResponse(635 ResponseInputItem.McpApprovalResponse.builder()636 .approvalRequestId(approvalRequestId)637 .approve(true)638 .build()))))639 .previousResponseId(responseId)640 .addTool(641 Tool.Mcp.builder()642 .serverLabel("dmcp")643 .serverDescription("A Dungeons and Dragons MCP server.")644 .serverUrl("https://dmcp-server.deno.dev/mcp")645 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.ALWAYS)646 .build())647 .build();648649client.responses().create(params).output().stream()650 .flatMap(item -> item.message().stream())651 .flatMap(message -> message.content().stream())652 .flatMap(content -> content.outputText().stream())653 .forEach(text -> System.out.println(text.text()));654```655656```csharp657using OpenAI.Responses;658#pragma warning disable OPENAI001659660string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;661ResponsesClient client = new(key);662663CreateResponseOptions options = new() { Model = "gpt-6-astra" };664options.Tools.Add(665 ResponseTool.CreateMcpTool(666 serverLabel: "dmcp",667 serverUri: new Uri("https://dmcp-server.deno.dev/mcp"),668 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.AlwaysRequireApproval669 )670);671672// Step 1: Create a response that requests tool-call approval.673options.InputItems.Add(ResponseItem.CreateUserMessageItem("Roll 2d4+1"));674ResponseResult response1 = await client.CreateResponseAsync(options);675676McpToolCallApprovalRequestItem approvalRequest =677 response1.OutputItems.OfType<McpToolCallApprovalRequestItem>().Single();678679// Step 2: Approve the tool call and get the final response.680options.PreviousResponseId = response1.Id;681options.InputItems.Clear();682options.InputItems.Add(683 ResponseItem.CreateMcpApprovalResponseItem(approvalRequest.Id, approved: true)684);685ResponseResult response2 = await client.CreateResponseAsync(options);686687Console.WriteLine(response2.GetOutputText());688```689690```ruby691require "openai"692693client = OpenAI::Client.new694response = client.responses.create(695 model: "gpt-6-astra",696 previous_response_id: "resp_682d498bdefc81918b4a6aa477bfafd904ad1e533afccbfa",697 input: [698 {699 type: :mcp_approval_response,700 approval_request_id: "mcpr_682d498e3bd4819196a0ce1664f8e77b04ad1e533afccbfa",701 approve: true702 }703 ],704 tools: [705 {706 type: :mcp,707 server_label: "dmcp",708 server_url: "https://dmcp-server.deno.dev/mcp",709 server_description: "A Dungeons and Dragons MCP server.",710 require_approval: :always711 }712 ]713)714715puts(response.output_text)716```717718719Here we're using the `previous_response_id` parameter to chain this new Response, with the previous Response that generated the approval request. But you can also pass back the [outputs from one response, as inputs into another](https://developers.openai.com/api/docs/guides/conversation-state#manually-manage-conversation-state) for maximum control over what enters the model's context.720721If and when you feel comfortable trusting a remote MCP server, you can choose to skip the approvals for reduced latency. To do this, you can set the `require_approval` parameter of the MCP tool to an object listing just the tools you'd like to skip approvals for like shown below, or set it to the value `'never'` to skip approvals for all tools in that remote MCP server.722723Never require approval for some tools724725```bash726curl https://api.openai.com/v1/responses \727-H "Content-Type: application/json" \728-H "Authorization: Bearer $OPENAI_API_KEY" \729-d '{730 "model": "gpt-6-astra",731 "tools": [732 {733 "type": "mcp",734 "server_label": "deepwiki",735 "server_url": "https://mcp.deepwiki.com/mcp",736 "require_approval": {737 "never": {738 "tool_names": ["ask_question", "read_wiki_structure"]739 }740 }741 }742 ],743 "input": "What transport protocols does the 2025-03-26 version of the MCP spec (modelcontextprotocol/modelcontextprotocol) support?"744 }'745```746747```javascript748import OpenAI from "openai";749const client = new OpenAI();750751const resp = await client.responses.create({752 model: "gpt-6-astra",753 tools: [754 {755 type: "mcp",756 server_label: "deepwiki",757 server_url: "https://mcp.deepwiki.com/mcp",758 require_approval: {759 never: {760 tool_names: ["ask_question", "read_wiki_structure"],761 },762 },763 },764 ],765 input:766 "What transport protocols does the 2025-03-26 version of the MCP spec (modelcontextprotocol/modelcontextprotocol) support?",767});768769console.log(resp.output_text);770```771772```python773from openai import OpenAI774775client = OpenAI()776777resp = client.responses.create(778 model="gpt-6-astra",779 tools=[780 {781 "type": "mcp",782 "server_label": "deepwiki",783 "server_url": "https://mcp.deepwiki.com/mcp",784 "require_approval": {785 "never": {"tool_names": ["ask_question", "read_wiki_structure"]}786 },787 },788 ],789 input="What transport protocols does the 2025-03-26 version of the MCP spec (modelcontextprotocol/modelcontextprotocol) support?",790)791792print(resp.output_text)793```794795```go796package main797798import (799 "context"800 "fmt"801802 "github.com/openai/openai-go/v3"803 "github.com/openai/openai-go/v3/responses"804)805806func main() {807 client := openai.NewClient()808 tool := responses.ToolParamOfMcp("deepwiki")809 tool.OfMcp.ServerURL = openai.String("https://mcp.deepwiki.com/mcp")810 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{811 OfMcpToolApprovalFilter: &responses.ToolMcpRequireApprovalMcpToolApprovalFilterParam{812 Never: responses.ToolMcpRequireApprovalMcpToolApprovalFilterNeverParam{813 ToolNames: []string{"ask_question", "read_wiki_structure"},814 },815 },816 }817818 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{819 Model: "gpt-6-astra",820 Tools: []responses.ToolUnionParam{tool},821 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("What transport protocols does the 2025-03-26 version of the MCP spec (modelcontextprotocol/modelcontextprotocol) support?")},822 })823 if err != nil {824 panic(err)825 }826 fmt.Println(response.OutputText())827}828```829830```java831import com.openai.client.OpenAIClient;832import com.openai.client.okhttp.OpenAIOkHttpClient;833import com.openai.models.responses.ResponseCreateParams;834import com.openai.models.responses.Tool;835836ResponseCreateParams params =837 ResponseCreateParams.builder()838 .model("gpt-6-astra")839 .input("What transport protocols does the 2025-03-26 version of the MCP spec support?")840 .addTool(841 Tool.Mcp.builder()842 .serverLabel("deepwiki")843 .serverUrl("https://mcp.deepwiki.com/mcp")844 .requireApproval(845 Tool.Mcp.RequireApproval.McpToolApprovalFilter.builder()846 .never(847 Tool.Mcp.RequireApproval.McpToolApprovalFilter.Never.builder()848 .addToolName("ask_question")849 .addToolName("read_wiki_structure")850 .build())851 .build())852 .build())853 .build();854855client.responses().create(params).output().stream()856 .flatMap(item -> item.message().stream())857 .flatMap(message -> message.content().stream())858 .flatMap(content -> content.outputText().stream())859 .forEach(text -> System.out.println(text.text()));860```861862```csharp863using OpenAI.Responses;864#pragma warning disable OPENAI001865866string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;867ResponsesClient client = new(key);868869CreateResponseOptions options = new() { Model = "gpt-6-astra" };870options.Tools.Add(871 ResponseTool.CreateMcpTool(872 serverLabel: "deepwiki",873 serverUri: new Uri("https://mcp.deepwiki.com/mcp"),874 toolCallApprovalPolicy: new CustomMcpToolCallApprovalPolicy875 {876 ToolsNeverRequiringApproval = new McpToolFilter877 {878 ToolNames = { "ask_question", "read_wiki_structure" },879 },880 }881 )882);883options.InputItems.Add(884 ResponseItem.CreateUserMessageItem(885 "What transport protocols does the 2025-03-26 version of the MCP spec (modelcontextprotocol/modelcontextprotocol) support?"886 )887);888889ResponseResult response = await client.CreateResponseAsync(options);890891Console.WriteLine(response.GetOutputText());892```893894```ruby895require "openai"896897client = OpenAI::Client.new898899response = client.responses.create(900 model: "gpt-6-astra",901 input: "What transport protocols does the 2025-03-26 version of the MCP spec support?",902 tools: [903 {904 type: :mcp,905 server_label: "deepwiki",906 server_url: "https://mcp.deepwiki.com/mcp",907 require_approval: {908 never: { tool_names: ["ask_question", "read_wiki_structure"] }909 }910 }911 ]912)913914puts(response.output_text)915```916917918## Authentication919920Unlike the [example MCP server we used above](https://dash.deno.com/playground/dmcp-server), most other MCP servers require authentication. The most common scheme is an OAuth access token. Provide this token using the `authorization` field of the MCP tool:921922Use Stripe MCP tool923924```bash925curl https://api.openai.com/v1/responses \926-H "Content-Type: application/json" \927-H "Authorization: Bearer $OPENAI_API_KEY" \928-d '{929 "model": "gpt-6-astra",930 "input": "Create a payment link for $20",931 "tools": [932 {933 "type": "mcp",934 "server_label": "stripe",935 "server_url": "https://mcp.stripe.com",936 "authorization": "$STRIPE_OAUTH_ACCESS_TOKEN"937 }938 ]939 }'940```941942```javascript943import OpenAI from "openai";944const client = new OpenAI();945946const resp = await client.responses.create({947 model: "gpt-6-astra",948 input: "Create a payment link for $20",949 tools: [950 {951 type: "mcp",952 server_label: "stripe",953 server_url: "https://mcp.stripe.com",954 authorization: "$STRIPE_OAUTH_ACCESS_TOKEN",955 },956 ],957});958959console.log(resp.output_text);960```961962```python963import os964from openai import OpenAI965966client = OpenAI()967authorization = os.environ["STRIPE_OAUTH_ACCESS_TOKEN"]968969resp = client.responses.create(970 model="gpt-6-astra",971 input="Create a payment link for $20",972 tools=[973 {974 "type": "mcp",975 "server_label": "stripe",976 "server_url": "https://mcp.stripe.com",977 "authorization": authorization,978 }979 ],980)981982print(resp.output_text)983```984985```go986package main987988import (989 "context"990 "fmt"991 "os"992993 "github.com/openai/openai-go/v3"994 "github.com/openai/openai-go/v3/responses"995)996997func main() {998 authorization := os.Getenv("STRIPE_OAUTH_ACCESS_TOKEN")999 if authorization == "" {1000 panic("STRIPE_OAUTH_ACCESS_TOKEN is required")1001 }1002 client := openai.NewClient()1003 tool := responses.ToolParamOfMcp("stripe")1004 tool.OfMcp.ServerURL = openai.String("https://mcp.stripe.com")1005 tool.OfMcp.Authorization = openai.String(authorization)10061007 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{1008 Model: "gpt-6-astra",1009 Tools: []responses.ToolUnionParam{tool},1010 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Create a payment link for $20")},1011 })1012 if err != nil {1013 panic(err)1014 }1015 fmt.Println(response.OutputText())1016}1017```10181019```java1020import com.openai.client.OpenAIClient;1021import com.openai.client.okhttp.OpenAIOkHttpClient;1022import com.openai.models.responses.ResponseCreateParams;1023import com.openai.models.responses.Tool;10241025String stripeAccessToken = System.getenv("STRIPE_OAUTH_ACCESS_TOKEN");10261027ResponseCreateParams params =1028 ResponseCreateParams.builder()1029 .model("gpt-6-astra")1030 .input("Create a payment link for $20.")1031 .addTool(1032 Tool.Mcp.builder()1033 .serverLabel("stripe")1034 .serverUrl("https://mcp.stripe.com")1035 .authorization(stripeAccessToken)1036 .build())1037 .build();10381039client.responses().create(params).output().stream()1040 .flatMap(item -> item.message().stream())1041 .flatMap(message -> message.content().stream())1042 .flatMap(content -> content.outputText().stream())1043 .forEach(text -> System.out.println(text.text()));1044```10451046```csharp1047using OpenAI.Responses;1048#pragma warning disable OPENAI00110491050string authToken =1051 Environment.GetEnvironmentVariable("STRIPE_OAUTH_ACCESS_TOKEN")!;1052string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;1053ResponsesClient client = new(key);10541055CreateResponseOptions options = new() { Model = "gpt-6-astra" };1056options.Tools.Add(1057 ResponseTool.CreateMcpTool(1058 serverLabel: "stripe",1059 serverUri: new Uri("https://mcp.stripe.com"),1060 authorizationToken: authToken1061 )1062);1063options.InputItems.Add(1064 ResponseItem.CreateUserMessageItem("Create a payment link for $20")1065);10661067ResponseResult response = await client.CreateResponseAsync(options);10681069Console.WriteLine(response.GetOutputText());1070```10711072```ruby1073require "openai"10741075client = OpenAI::Client.new1076response = client.responses.create(1077 model: "gpt-6-astra",1078 input: "Create a payment link for $20.",1079 tools: [1080 {1081 type: :mcp,1082 server_label: "stripe",1083 server_url: "https://mcp.stripe.com",1084 authorization: ENV.fetch("STRIPE_OAUTH_ACCESS_TOKEN")1085 }1086 ]1087)10881089puts(response.output_text)1090```109110921093To prevent the leakage of sensitive tokens, the Responses API does not store the value you provide in the `authorization` field. This value will also not be visible in the Response object created. Because of this, you must send the `authorization` value in every Responses API creation request you make.10941095<a id="connectors"></a>10961097## Legacy connectors10981099`connector_id` is deprecated for models released after September 1,1100 2026. Use `server_url` to connect to a remote MCP server, or 1101 `tunnel_id` to connect to a local MCP server through 1102 [Secure MCP Tunnel](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels). Existing1103 models retain connector support. The examples in this section use1104 `gpt-5.2`, which predates the cutoff.11051106The Responses API has built-in support for a limited set of connectors to third-party services. These connectors let you pull in context from popular applications, like Dropbox and Gmail, to allow the model to interact with popular services.11071108Connectors can be used in the same way as remote MCP servers. Both let an OpenAI model access additional third-party tools in an API request. However, instead of passing a `server_url` as you would to call a remote MCP server, you pass a `connector_id` which uniquely identifies a connector available in the API.11091110Connectors require an OAuth access token provided by your application in the `authorization` parameter.11111112Use a legacy connector with GPT-5.211131114```bash1115curl https://api.openai.com/v1/responses \1116-H "Content-Type: application/json" \1117-H "Authorization: Bearer $OPENAI_API_KEY" \1118-d '{1119 "model": "gpt-5.2",1120 "tools": [1121 {1122 "type": "mcp",1123 "server_label": "Dropbox",1124 "connector_id": "connector_dropbox",1125 "authorization": "<oauth access token>",1126 "require_approval": "never"1127 }1128 ],1129 "input": "Summarize the Q2 earnings report."1130 }'1131```11321133```javascript1134import OpenAI from "openai";1135const client = new OpenAI();11361137const resp = await client.responses.create({1138 model: "gpt-5.2",1139 tools: [1140 {1141 type: "mcp",1142 server_label: "Dropbox",1143 connector_id: "connector_dropbox",1144 authorization: "<oauth access token>",1145 require_approval: "never",1146 },1147 ],1148 input: "Summarize the Q2 earnings report.",1149});11501151console.log(resp.output_text);1152```11531154```python1155import os11561157from openai import OpenAI11581159client = OpenAI()1160connector_authorization = os.environ["OPENAI_CONNECTOR_AUTHORIZATION"]11611162resp = client.responses.create(1163 model="gpt-5.2",1164 tools=[1165 {1166 "type": "mcp",1167 "server_label": "Dropbox",1168 "connector_id": "connector_dropbox",1169 "authorization": connector_authorization,1170 "require_approval": "never",1171 },1172 ],1173 input="Summarize the Q2 earnings report.",1174)11751176print(resp.output_text)1177```11781179```go1180package main11811182import (1183 "context"1184 "fmt"11851186 "github.com/openai/openai-go/v3"1187 "github.com/openai/openai-go/v3/responses"1188)11891190func main() {1191 client := openai.NewClient()1192 tool := responses.ToolParamOfMcp("Dropbox")1193 tool.OfMcp.ConnectorID = "connector_dropbox"1194 tool.OfMcp.Authorization = openai.String("<oauth access token>")1195 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}11961197 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{1198 Model: "gpt-5.2",1199 Tools: []responses.ToolUnionParam{tool},1200 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Summarize the Q2 earnings report.")},1201 })1202 if err != nil {1203 panic(err)1204 }1205 fmt.Println(response.OutputText())1206}1207```12081209```java1210import com.openai.client.OpenAIClient;1211import com.openai.client.okhttp.OpenAIOkHttpClient;1212import com.openai.models.responses.ResponseCreateParams;1213import com.openai.models.responses.Tool;12141215String oauthAccessToken = "<oauth access token>";12161217ResponseCreateParams params =1218 ResponseCreateParams.builder()1219 .model("gpt-5.2")1220 .input("Summarize the Q2 earnings report.")1221 .addTool(1222 Tool.Mcp.builder()1223 .serverLabel("Dropbox")1224 .connectorId(Tool.Mcp.ConnectorId.of("connector_dropbox"))1225 .authorization(oauthAccessToken)1226 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)1227 .build())1228 .build();12291230client.responses().create(params).output().stream()1231 .flatMap(item -> item.message().stream())1232 .flatMap(message -> message.content().stream())1233 .flatMap(content -> content.outputText().stream())1234 .forEach(text -> System.out.println(text.text()));1235```12361237```csharp1238using OpenAI.Responses;1239#pragma warning disable OPENAI00112401241string dropboxToken =1242 Environment.GetEnvironmentVariable("DROPBOX_OAUTH_ACCESS_TOKEN")!;1243string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;1244ResponsesClient client = new(key);12451246CreateResponseOptions options = new() { Model = "gpt-5.2" };1247options.Tools.Add(1248 ResponseTool.CreateMcpTool(1249 serverLabel: "Dropbox",1250 connectorId: McpToolConnectorId.Dropbox,1251 authorizationToken: dropboxToken,1252 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval1253 )1254);1255options.InputItems.Add(1256 ResponseItem.CreateUserMessageItem("Summarize the Q2 earnings report.")1257);12581259ResponseResult response = await client.CreateResponseAsync(options);12601261Console.WriteLine(response.GetOutputText());1262```12631264```ruby1265require "openai"12661267client = OpenAI::Client.new1268response = client.responses.create(1269 model: "gpt-5.2",1270 input: "Summarize the Q2 earnings report.",1271 tools: [1272 {1273 type: :mcp,1274 server_label: "Dropbox",1275 connector_id: "connector_dropbox",1276 authorization: "<oauth access token>",1277 require_approval: :never1278 }1279 ]1280)12811282puts(response.output_text)1283```128412851286### Available connectors12871288- Dropbox: `connector_dropbox`1289- Gmail: `connector_gmail`1290- Google Calendar: `connector_googlecalendar`1291- Google Drive: `connector_googledrive`1292- Microsoft Teams: `connector_microsoftteams`1293- Outlook Calendar: `connector_outlookcalendar`1294- Outlook Email: `connector_outlookemail`1295- SharePoint: `connector_sharepoint`12961297We prioritized services that don't have official remote MCP servers. GitHub, for instance, has an official MCP server you can connect to by passing `https://api.githubcopilot.com/mcp/` to the `server_url` field in the MCP tool.12981299### Authorizing a connector13001301In the `authorization` field, pass in an OAuth access token. OAuth client registration and authorization must be handled separately by your application.13021303For testing purposes, you can use Google's [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/) to generate temporary access tokens that you can use in an API request.13041305To use the playground to test the connectors API functionality, start by entering:13061307```1308https://www.googleapis.com/auth/calendar.events1309```13101311This authorization scope will enable the API to read Google Calendar events. In the UI under "Step 1: Select and authorize APIs".13121313After authorizing the application with your Google account, you will come to **Step 2: Exchange authorization code for tokens**. This will generate an access token you can use in an API request using the Google Calendar connector:13141315Use the Google Calendar connector13161317```bash1318curl https://api.openai.com/v1/responses \1319 -H "Content-Type: application/json" \1320 -H "Authorization: Bearer $OPENAI_API_KEY" \1321 -d '{1322 "model": "gpt-5.2",1323 "tools": [1324 {1325 "type": "mcp",1326 "server_label": "google_calendar",1327 "connector_id": "connector_googlecalendar",1328 "authorization": "ya29.A0AS3H6...",1329 "require_approval": "never"1330 }1331 ],1332 "input": "What is on my Google Calendar for today?"1333 }'1334```13351336```javascript1337import OpenAI from "openai";1338const client = new OpenAI();13391340const resp = await client.responses.create({1341 model: "gpt-5.2",1342 tools: [1343 {1344 type: "mcp",1345 server_label: "google_calendar",1346 connector_id: "connector_googlecalendar",1347 authorization: "ya29.A0AS3H6...",1348 require_approval: "never",1349 },1350 ],1351 input: "What's on my Google Calendar for today?",1352});13531354console.log(resp.output_text);1355```13561357```python1358import os1359from openai import OpenAI13601361client = OpenAI()1362authorization = os.environ["GOOGLE_CALENDAR_OAUTH_ACCESS_TOKEN"]13631364resp = client.responses.create(1365 model="gpt-5.2",1366 tools=[1367 {1368 "type": "mcp",1369 "server_label": "google_calendar",1370 "connector_id": "connector_googlecalendar",1371 "authorization": authorization,1372 "require_approval": "never",1373 },1374 ],1375 input="What's on my Google Calendar for today?",1376)13771378print(resp.output_text)1379```13801381```go1382package main13831384import (1385 "context"1386 "fmt"13871388 "github.com/openai/openai-go/v3"1389 "github.com/openai/openai-go/v3/responses"1390)13911392func main() {1393 client := openai.NewClient()1394 tool := responses.ToolParamOfMcp("google_calendar")1395 tool.OfMcp.ConnectorID = "connector_googlecalendar"1396 tool.OfMcp.Authorization = openai.String("<oauth access token>")1397 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}13981399 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{1400 Model: "gpt-5.2",1401 Tools: []responses.ToolUnionParam{tool},1402 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("What's on my Google Calendar for today?")},1403 })1404 if err != nil {1405 panic(err)1406 }1407 fmt.Println(response.OutputText())1408}1409```14101411```java1412import com.openai.client.OpenAIClient;1413import com.openai.client.okhttp.OpenAIOkHttpClient;1414import com.openai.models.responses.ResponseCreateParams;1415import com.openai.models.responses.Tool;14161417String oauthAccessToken = "<oauth access token>";14181419ResponseCreateParams params =1420 ResponseCreateParams.builder()1421 .model("gpt-5.2")1422 .input("What's on my Google Calendar for today?")1423 .addTool(1424 Tool.Mcp.builder()1425 .serverLabel("google_calendar")1426 .connectorId(Tool.Mcp.ConnectorId.of("connector_googlecalendar"))1427 .authorization(oauthAccessToken)1428 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)1429 .build())1430 .build();14311432client.responses().create(params).output().stream()1433 .flatMap(item -> item.message().stream())1434 .flatMap(message -> message.content().stream())1435 .flatMap(content -> content.outputText().stream())1436 .forEach(text -> System.out.println(text.text()));1437```14381439```csharp1440using OpenAI.Responses;1441#pragma warning disable OPENAI00114421443string authToken =1444 Environment.GetEnvironmentVariable("GOOGLE_CALENDAR_OAUTH_ACCESS_TOKEN")!;1445string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;1446ResponsesClient client = new(key);14471448CreateResponseOptions options = new() { Model = "gpt-5.2" };1449options.Tools.Add(1450 ResponseTool.CreateMcpTool(1451 serverLabel: "google_calendar",1452 connectorId: McpToolConnectorId.GoogleCalendar,1453 authorizationToken: authToken,1454 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval1455 )1456);1457options.InputItems.Add(1458 ResponseItem.CreateUserMessageItem("What's on my Google Calendar for today?")1459);14601461ResponseResult response = await client.CreateResponseAsync(options);14621463Console.WriteLine(response.GetOutputText());1464```14651466```ruby1467require "openai"14681469client = OpenAI::Client.new1470response = client.responses.create(1471 model: "gpt-5.2",1472 input: "What's on my Google Calendar for today?",1473 tools: [1474 {1475 type: :mcp,1476 server_label: "google_calendar",1477 connector_id: "connector_googlecalendar",1478 authorization: "<oauth access token>",1479 require_approval: :never1480 }1481 ]1482)14831484puts(response.output_text)1485```148614871488An MCP tool call from a Connector will look the same as an MCP tool call from a remote MCP server, using the `mcp_call` output item type. In this case, both the arguments to and the response from the Connector are JSON strings:14891490```json1491{1492 "id": "mcp_68a62ae1c93c81a2b98c29340aa3ed8800e9b63986850588",1493 "type": "mcp_call",1494 "approval_request_id": null,1495 "arguments": "{\"time_min\":\"2025-08-20T00:00:00\",\"time_max\":\"2025-08-21T00:00:00\",\"timezone_str\":null,\"max_results\":50,\"query\":null,\"calendar_id\":null,\"next_page_token\":null}",1496 "error": null,1497 "name": "search_events",1498 "output": "{\"events\": [{\"id\": \"2n8ni54ani58pc3ii6soelupcs_20250820\", \"summary\": \"Home\", \"location\": null, \"start\": \"2025-08-20T00:00:00\", \"end\": \"2025-08-21T00:00:00\", \"url\": \"https://www.google.com/calendar/event?eid=Mm44bmk1NGFuaTU4cGMzaWk2c29lbHVwY3NfMjAyNTA4MjAga3doaW5uZXJ5QG9wZW5haS5jb20&ctz=America/Los_Angeles\", \"description\": \"\\n\\n\", \"transparency\": \"transparent\", \"display_url\": \"https://www.google.com/calendar/event?eid=Mm44bmk1NGFuaTU4cGMzaWk2c29lbHVwY3NfMjAyNTA4MjAga3doaW5uZXJ5QG9wZW5haS5jb20&ctz=America/Los_Angeles\", \"display_title\": \"Home\"}], \"next_page_token\": null}",1499 "server_label": "Google_Calendar"1500}1501```15021503### Available tools in each connector15041505The available tools depend on which scopes your OAuth token has available to it. Expand the tables below to see what tools you can use when connecting to each application.1506150715081509#### Dropbox151015111512 <table>1513 <tr>1514 <th>Tool</th>1515 <th>Description</th>1516 <th>Scopes</th>1517 </tr>1518 <tr>1519 <td>`search`</td>1520 <td>Search Dropbox for files that match a query</td>1521 <td>files.metadata.read, account_info.read</td>1522 </tr>1523 <tr>1524 <td>`fetch`</td>1525 <td>Fetch a file by path with optional raw download</td>1526 <td>files.content.read</td>1527 </tr>1528 <tr>1529 <td>`search_files`</td>1530 <td>Search Dropbox files and return results</td>1531 <td>files.metadata.read, account_info.read</td>1532 </tr>1533 <tr>1534 <td>`fetch_file`</td>1535 <td>Retrieve a file's text or raw content</td>1536 <td>files.content.read, account_info.read</td>1537 </tr>1538 <tr>1539 <td>`list_recent_files`</td>1540 <td>Return the most recently modified files accessible to the user</td>1541 <td>files.metadata.read, account_info.read</td>1542 </tr>1543 <tr>1544 <td>`get_profile`</td>1545 <td>Retrieve the Dropbox profile of the current user</td>1546 <td>account_info.read</td>1547 </tr>1548 </table>1549155015511552155315541555#### Gmail155615571558 <table>1559 <tr>1560 <th>Tool</th>1561 <th>Description</th>1562 <th>Scopes</th>1563 </tr>1564 <tr>1565 <td>`get_profile`</td>1566 <td>Return the current Gmail user's profile</td>1567 <td>userinfo.email, userinfo.profile</td>1568 </tr>1569 <tr>1570 <td>`search_emails`</td>1571 <td>Search Gmail for emails matching a query or label</td>1572 <td>gmail.modify</td>1573 </tr>1574 <tr>1575 <td>`search_email_ids`</td>1576 <td>Retrieve Gmail message IDs matching a search</td>1577 <td>gmail.modify</td>1578 </tr>1579 <tr>1580 <td>`get_recent_emails`</td>1581 <td>Return the most recently received Gmail messages</td>1582 <td>gmail.modify</td>1583 </tr>1584 <tr>1585 <td>`read_email`</td>1586 <td>Fetch a single Gmail message including its body</td>1587 <td>gmail.modify</td>1588 </tr>1589 <tr>1590 <td>`batch_read_email`</td>1591 <td>Read multiple Gmail messages in one call</td>1592 <td>gmail.modify</td>1593 </tr>1594 </table>1595159615971598159916001601#### Google Calendar160216031604 <table>1605 <tr>1606 <th>Tool</th>1607 <th>Description</th>1608 <th>Scopes</th>1609 </tr>1610 <tr>1611 <td>`get_profile`</td>1612 <td>Return the current Calendar user's profile</td>1613 <td>userinfo.email, userinfo.profile</td>1614 </tr>1615 <tr>1616 <td>`search`</td>1617 <td>Search Calendar events within an optional time window</td>1618 <td>calendar.events</td>1619 </tr>1620 <tr>1621 <td>`fetch`</td>1622 <td>Get details for a single Calendar event</td>1623 <td>calendar.events</td>1624 </tr>1625 <tr>1626 <td>`search_events`</td>1627 <td>Look up Calendar events using filters</td>1628 <td>calendar.events</td>1629 </tr>1630 <tr>1631 <td>`read_event`</td>1632 <td>Read a Google Calendar event by ID</td>1633 <td>calendar.events</td>1634 </tr>1635 </table>1636163716381639164016411642#### Google Drive164316441645 <table>1646 <tr>1647 <th>Tool</th>1648 <th>Description</th>1649 <th>Scopes</th>1650 </tr>1651 <tr>1652 <td>`get_profile`</td>1653 <td>Return the current Drive user's profile</td>1654 <td>userinfo.email, userinfo.profile</td>1655 </tr>1656 <tr>1657 <td>`list_drives`</td>1658 <td>List shared drives accessible to the user</td>1659 <td>drive.readonly</td>1660 </tr>1661 <tr>1662 <td>`search`</td>1663 <td>Search Drive files using a query</td>1664 <td>drive.readonly</td>1665 </tr>1666 <tr>1667 <td>`recent_documents`</td>1668 <td>Return the most recently modified documents</td>1669 <td>drive.readonly</td>1670 </tr>1671 <tr>1672 <td>`fetch`</td>1673 <td>Download the content of a Drive file</td>1674 <td>drive.readonly</td>1675 </tr>1676 </table>1677167816791680168116821683#### Microsoft Teams168416851686 <table>1687 <tr>1688 <th>Tool</th>1689 <th>Description</th>1690 <th>Scopes</th>1691 </tr>1692 <tr>1693 <td>`search`</td>1694 <td>Search Microsoft Teams chats and channel messages</td>1695 <td>Chat.Read, ChannelMessage.Read.All</td>1696 </tr>1697 <tr>1698 <td>`fetch`</td>1699 <td>Fetch a Teams message by path</td>1700 <td>Chat.Read, ChannelMessage.Read.All</td>1701 </tr>1702 <tr>1703 <td>`get_chat_members`</td>1704 <td>List the members of a Teams chat</td>1705 <td>Chat.Read</td>1706 </tr>1707 <tr>1708 <td>`get_profile`</td>1709 <td>Return the authenticated Teams user's profile</td>1710 <td>User.Read</td>1711 </tr>1712 </table>1713171417151716171717181719#### Outlook Calendar172017211722 <table>1723 <tr>1724 <th>Tool</th>1725 <th>Description</th>1726 <th>Scopes</th>1727 </tr>1728 <tr>1729 <td>`search_events`</td>1730 <td>Search Outlook Calendar events with date filters</td>1731 <td>Calendars.Read</td>1732 </tr>1733 <tr>1734 <td>`fetch_event`</td>1735 <td>Retrieve details for a single event</td>1736 <td>Calendars.Read</td>1737 </tr>1738 <tr>1739 <td>`fetch_events_batch`</td>1740 <td>Retrieve multiple events in one call</td>1741 <td>Calendars.Read</td>1742 </tr>1743 <tr>1744 <td>`list_events`</td>1745 <td>List calendar events within a date range</td>1746 <td>Calendars.Read</td>1747 </tr>1748 <tr>1749 <td>`get_profile`</td>1750 <td>Retrieve the current user's profile</td>1751 <td>User.Read</td>1752 </tr>1753 </table>1754175517561757175817591760#### Outlook Email176117621763 <table>1764 <tr>1765 <th>Tool</th>1766 <th>Description</th>1767 <th>Scopes</th>1768 </tr>1769 <tr>1770 <td>`get_profile`</td>1771 <td>Return profile info for the Outlook account</td>1772 <td>User.Read</td>1773 </tr>1774 <tr>1775 <td>`list_messages`</td>1776 <td>Retrieve Outlook emails from a folder</td>1777 <td>Mail.Read</td>1778 </tr>1779 <tr>1780 <td>`search_messages`</td>1781 <td>Search Outlook emails with optional filters</td>1782 <td>Mail.Read</td>1783 </tr>1784 <tr>1785 <td>`get_recent_emails`</td>1786 <td>Return the most recently received emails</td>1787 <td>Mail.Read</td>1788 </tr>1789 <tr>1790 <td>`fetch_message`</td>1791 <td>Fetch a single email by ID</td>1792 <td>Mail.Read</td>1793 </tr>1794 <tr>1795 <td>`fetch_messages_batch`</td>1796 <td>Retrieve multiple emails in one request</td>1797 <td>Mail.Read</td>1798 </tr>1799 </table>1800180118021803180418051806#### Sharepoint180718081809 <table>1810 <tr>1811 <th>Tool</th>1812 <th>Description</th>1813 <th>Scopes</th>1814 </tr>1815 <tr>1816 <td>`get_site`</td>1817 <td>Resolve a SharePoint site by hostname and path</td>1818 <td>Sites.Read.All</td>1819 </tr>1820 <tr>1821 <td>`search`</td>1822 <td>Search SharePoint/OneDrive documents by keyword</td>1823 <td>Sites.Read.All, Files.Read.All</td>1824 </tr>1825 <tr>1826 <td>`list_recent_documents`</td>1827 <td>Return recently accessed documents</td>1828 <td>Files.Read.All</td>1829 </tr>1830 <tr>1831 <td>`fetch`</td>1832 <td>Fetch content from a Graph file download URL</td>1833 <td>Files.Read.All</td>1834 </tr>1835 <tr>1836 <td>`get_profile`</td>1837 <td>Retrieve the current user's profile</td>1838 <td>User.Read</td>1839 </tr>1840 </table>18411842184318441845## Defer loading tools in an MCP server18461847If you are using [tool search](https://developers.openai.com/api/docs/guides/tools-tool-search), you can defer loading the functions exposed by an MCP server until the model decides it needs them. To do this, set `defer_loading: true` on the MCP server tool definition.18481849When you defer loading an MCP server, the model can still use the MCP server's label and description to decide when to search it, but the individual function definitions are loaded only when needed. This can help reduce overall token usage, and it is most useful for MCP servers that expose large numbers of functions.18501851```json1852{1853 "type": "mcp",1854 "server_label": "dmcp",1855 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",1856 "server_url": "https://dmcp-server.deno.dev/mcp",1857// highlight-start:subtle1858 "defer_loading": true,1859// highlight-end1860 "require_approval": "never"1861}1862```186318641865## Risks and safety18661867The MCP tool permits you to connect OpenAI models to external services. This is a powerful feature that comes with some risks.18681869For connectors, there is a risk of potentially sending sensitive data to OpenAI, or allowing models read access to potentially sensitive data in those services.18701871Remote MCP servers carry those same risks, but also have not been verified by OpenAI. These servers can allow models to access, send, and receive data, and take action in these services. All MCP servers are third-party services that are subject to their own terms and conditions.18721873If you come across a malicious MCP server, please report it to `security@openai.com`.18741875Below are some best practices to consider when integrating connectors and remote MCP servers.18761877#### Prompt injection18781879[Prompt injection](https://chatgpt.com/?prompt=what%20is%20prompt%20injection?) is an important security consideration in any LLM application, and is especially true when you give the model access to MCP servers and connectors which can access sensitive data or take action. Use these tools with appropriate caution and protective measures if the prompt for the model contains user-provided content.18801881#### Always require approval for sensitive actions18821883Use the available configurations of the `require_approval` and `allowed_tools` parameters to ensure that any sensitive actions require an approval flow.18841885#### URLs within MCP tool calls and outputs18861887It can be dangerous to request URLs or embed image URLs provided by tool call outputs either from connectors or remote MCP servers. Ensure that you trust the domains and services providing those URLs before embedding or otherwise using them in your application code.18881889#### Connecting to trusted servers18901891Pick official servers hosted by the service providers themselves (for example, we recommend connecting to the Stripe server hosted by Stripe at `mcp.stripe.com`, instead of a Stripe MCP server hosted by a third party). Because there aren't too many official remote MCP servers today, you may be tempted to use an MCP server hosted by an organization that doesn't operate that server and proxies requests to that service via your API. If you must do this, be extra careful in doing your due diligence on these "aggregators," and carefully review how they use your data.18921893#### Log and review data being shared with third party MCP servers.18941895Because MCP servers define their own tool definitions, they may request for data that you may not always be comfortable sharing with the host of that MCP server. Because of this, the MCP tool in the Responses API defaults to requiring approvals of each MCP tool call being made. When developing your application, review the type of data being shared with these MCP servers carefully and robustly. Once you gain confidence in your trust of this MCP server, you can skip these approvals to reduce execution latency.18961897We also recommend logging any data sent to MCP servers. If you're using the Responses API with `store=true`, these data are already logged via the API for 30 days unless Zero Data Retention is enabled for your organization. You may also want to log these data in your own systems and perform periodic reviews on this to ensure data is being shared per your expectations.18981899Malicious MCP servers may include hidden instructions (prompt injections) designed to make OpenAI models behave unexpectedly. While OpenAI has implemented built-in safeguards to help detect and block these threats, it's essential to carefully review inputs and outputs, and ensure connections are established only with trusted servers.19001901MCP servers may update tool behavior unexpectedly, potentially leading to unintended or malicious behavior.19021903#### Implications on Zero Data Retention and Data Residency19041905The MCP tool is compatible with Zero Data Retention and Data Residency, but it's important to note that MCP servers are third-party services, and data sent to an MCP server is subject to their data retention and data residency policies.19061907In other words, if you're an organization with Data Residency in Europe, OpenAI will limit inference and storage of Customer Content to take place in Europe up until the point communication or data is sent to the MCP server. It is your responsibility to ensure that the MCP server also adheres to any Zero Data Retention or Data Residency requirements you may have. Learn more about Zero Data Retention and Data Residency [here](https://developers.openai.com/api/docs/guides/your-data).19081909## Usage notes19101911<table>1912 <tbody>19131914 19151916<tr>1917 <th>API Availability</th>1918 <th>Rate limits</th>1919 <th>Notes</th>1920</tr>19211922<tr>1923<td>192419251926 [Responses](https://developers.openai.com/api/reference/resources/responses)19271928192919301931 [Chat Completions](https://developers.openai.com/api/reference/resources/chat)19321933193419351936 [Assistants](https://developers.openai.com/api/reference/resources/beta/subresources/assistants)193719381939</td>1940<td style={{"maxWidth": "150px"}}>1941**Tier 1**19421943200 RPM19441945**Tier 2 and 3**194619471000 RPM19481949**Tier 4 and 5**195019512000 RPM19521953</td>1954<td style={{"maxWidth": "150px"}}>1955[Pricing](https://developers.openai.com/api/docs/pricing#built-in-tools) 19561957[ZDR and data residency](https://developers.openai.com/api/docs/guides/your-data)1958</td>1959</tr>19601961</tbody>1962</table>