Skip to content

MCP with ChatGPT and the OpenAI API: Remote Servers, Safely

By Shoaib HossainJuly 31, 202612 min readUpdated October 17, 2026

The Model Context Protocol (MCP) is an open protocol for exposing tools, resources, and prompts to AI applications over JSON-RPC 2.0. One server can serve many hosts: Claude Code, Gemini CLI, ChatGPT, and your own agents built on the OpenAI Responses API. This guide covers the OpenAI side of that picture: what your server must implement, how to connect it to ChatGPT as a custom server, how the Responses API's mcp tool works (including its approval flow), and the risks OpenAI itself warns about.

One caution up front. OpenAI has renamed the ChatGPT side of this several times (connectors, apps, and now plugins), so the exact UI path will change. The protocol and the API fields change much less, so this guide anchors on those and dates the UI steps. For the same server in Claude Code, see Claude Code MCP and Plugins.

Two ways to put an MCP server in front of OpenAI models: as a custom server in ChatGPT, or as an mcp tool in the Responses API
Two ways to put an MCP server in front of OpenAI models: as a custom server in ChatGPT, or as an mcp tool in the Responses API

What an MCP server has to implement

An MCP server answers JSON-RPC 2.0 requests. For tools, the two methods that matter are tools/list, which returns each tool's name, description, and JSON Schema for its input, and tools/call, which runs one. Servers can also expose resources (read with resources/read) and prompt templates.

The current specification defines two standard transports:

  • stdio: the client launches the server as a subprocess and exchanges newline-delimited JSON-RPC messages over stdin and stdout. This is how local tools run in Claude Code or Gemini CLI.
  • Streamable HTTP: the server is an independent process with one endpoint (for example https://example.com/mcp) that accepts POST and GET, optionally streaming with server-sent events. It replaced the older HTTP+SSE transport from the 2024-11-05 protocol version.

Hosted products such as ChatGPT and the Responses API connect to your server over the network, so the server must be reachable over HTTPS. A stdio server on your laptop is not reachable by them unless you put it behind a tunnel or redeploy it as a Streamable HTTP service. WebSockets are not one of the standard transports.

Quick reference

  • The spec requires Streamable HTTP servers to validate the Origin header to prevent DNS-rebinding attacks, and recommends binding local servers to 127.0.0.1 only.
  • Sessions are optional: a server may return an Mcp-Session-Id on initialisation, which the client then sends on every request.
  • Clients send an MCP-Protocol-Version header on HTTP requests, so servers can answer according to the negotiated version.

Remember this

Implement tools/list and tools/call behind a Streamable HTTP endpoint; hosted clients cannot reach a local stdio server directly.

Connecting a server to ChatGPT

In ChatGPT, a custom MCP server is added through its plugin interface. As of OpenAI's current quickstart (checked October 2026), the flow is:

  1. Open the plugins page in ChatGPT, select the plus button, and choose Add custom MCP server.
  2. Enter a name and the server URL (your HTTPS MCP endpoint), and choose the authentication the server uses.
  3. Read and confirm the risk warning, then create it as a plugin.
  4. Install it from your personal plugins, start a chat in the mode the quickstart names, type @, and select your plugin.

Test it the way the quickstart suggests: ask for something that should call exactly one tool with specific arguments, then try invalid inputs and requests that should not trigger the tool at all. The second half catches the more common failure, a tool called when it should not be.

Because this part of ChatGPT keeps changing (earlier versions called these connectors and apps, and access has varied by plan), check OpenAI's current plugin documentation before writing internal instructions for your team.

Quick reference

  • If the server needs a user's own data, use OAuth so each person authorises access with their own account instead of sharing one key.
  • Write tool descriptions for the model: what the tool does, when not to use it, and what its arguments mean. Vague descriptions cause wrong or missing calls.
  • Return errors as tool results with a clear message, so the model can explain or retry instead of failing silently.

Remember this

ChatGPT adds custom MCP servers by HTTPS URL through its plugin UI; the UI moves, so test calls, misuse, and non-calls.

The Responses API mcp tool

For your own applications, the OpenAI Responses API accepts an MCP server as a tool of type mcp:

1{2  "model": "<model>",3  "tools": [4    {5      "type": "mcp",6      "server_label": "docs",7      "server_url": "https://example.com/mcp",8      "allowed_tools": ["search_docs", "get_page"],9      "require_approval": "always"10    }11  ],12  "input": "Find the rate-limit section and summarise it."13}

What happens on a request, according to OpenAI's guide:

  • The API imports the server's tools and adds an mcp_list_tools item to the output. While that item stays in context, the tool list is not fetched again each turn. allowed_tools limits what is imported.
  • Before data is shared with the server, the API by default produces an mcp_approval_request item. Your application answers with an mcp_approval_response item in the next request. require_approval can be set to "never" or to an object that skips approval only for named tools.
  • Each tool invocation creates an mcp_call item recording the arguments and output.

For authenticated servers, pass an OAuth access token in the tool's authorization field. The API does not store it, so you send it on every request. The API supports servers using Streamable HTTP or the older HTTP+SSE transport, and a secure tunnel option for private servers.

Responses API MCP flow: list tools once, request approval before a call, then record the call and its output
Responses API MCP flow: list tools once, request approval before a call, then record the call and its output

Quick reference

  • Keep approvals on for any tool that sends data out or changes state; skip them only for read-only tools on servers you control.
  • allowed_tools also reduces the tokens spent on tool definitions when a server exposes many tools.
  • The older connector_id option is deprecated for newer models; use server_url.

Remember this

Declare the server as an mcp tool, allowlist its tools, and handle mcp_approval_request items in your app.

The risks OpenAI warns about

OpenAI's own guide is direct about remote MCP servers:

  • Exfiltration. A malicious server can exfiltrate sensitive data from anything that enters the model's context, not just what you send it explicitly.
  • Unverified servers. Remote servers have not been verified by OpenAI. Prefer official servers hosted by the service provider (OpenAI's example is Stripe's own server) over third-party aggregators.
  • Prompt injection. Malicious servers may include hidden instructions, in tool descriptions or in tool output, that try to redirect the model.

The controls follow: keep require_approval on for sensitive actions, use allowed_tools, and log the data sent to MCP servers. On your own server, apply least privilege: read-only database roles for query tools, OAuth scopes limited to what each tool needs, rate limits, and an audit log of every tools/call with the caller's identity.

A query tool that accepts raw SQL deserves special care. Even against a read replica, it can read any table the role can, and the model may construct queries you did not anticipate. Prefer narrow tools (get_order(order_id)) over general ones (query_database(sql)), and enforce limits in the server, not in the description.

MCP risks with hosted models: data exfiltration, hidden instructions, and over-broad tools, and the controls for each
MCP risks with hosted models: data exfiltration, hidden instructions, and over-broad tools, and the controls for each

Quick reference

  • Treat tool descriptions as part of your attack surface: review them when installing a third-party server, and pin its version.
  • Do not put secrets in tool output; anything a tool returns enters the model's context and may be repeated or forwarded.
  • A gateway in front of the server can add authentication, rate limits, and logging without changing the server code.

Remember this

Assume anything in context can leave through a tool; keep approvals on, allowlist tools, prefer official servers, and narrow every tool.

Hands-on: one server, two clients

  1. Build a minimal MCP server with one read-only tool (for example lookup_status(order_id)) using an official MCP SDK, served over Streamable HTTP at /mcp. Validate the Origin header and require a token.
  2. Expose it over HTTPS (a deployed service or a tunnel).
  3. Call it from the Responses API with type: "mcp", allowed_tools: ["lookup_status"], and require_approval: "always". Handle the mcp_approval_request in a small script and approve it.
  4. Add the same URL as a custom MCP server in ChatGPT and invoke it with @.
  5. Try a prompt that should not call the tool, and one with an invalid order ID.

Pass criterion: both clients called the same server, your script saw and answered an approval request, and the tool refused the invalid input with a clear error rather than guessing.

Quick reference

  • Log each tools/call on the server with timestamp and caller; compare with what the clients report.
  • If ChatGPT cannot reach the server, check that the URL is public HTTPS and that the endpoint answers POST and GET.
  • Add the same server to Claude Code with claude mcp add --transport http to see a third client against one server.

Remember this

One Streamable HTTP server can serve ChatGPT, the Responses API, and other MCP clients; approvals and narrow tools keep it safe.

Key takeaway

MCP lets one server provide tools to many AI hosts. For OpenAI's products, that server must be a network service: Streamable HTTP (or the older HTTP+SSE) at an HTTPS endpoint, implementing tools/list and tools/call. ChatGPT adds it as a custom MCP server through its plugin interface, which has been renamed often enough that you should check the current docs; the Responses API takes it as a type: "mcp" tool with server_url, allowed_tools, require_approval, and a per-request authorization token, and returns mcp_list_tools, mcp_approval_request, and mcp_call items.

The risks are the ones OpenAI names: exfiltration of anything in context, unverified servers, and hidden instructions. Keep approvals on for anything sensitive, allowlist tools, prefer official servers, and make your own tools narrow and audited. For the protocol compared with REST-style APIs, see MCP vs OpenAPI.

Practice (60 min): complete the five steps above with one read-only tool.

Share:

References

  1. MCP specification: Transports (2025-06-18) — checked Oct 17, 2026
  2. OpenAI docs: MCP and connectors in the Responses API — checked Oct 17, 2026
  3. OpenAI docs: Plugins quickstart (custom MCP servers in ChatGPT) — checked Oct 17, 2026

Shoaib Hossain

Author, Core Concept Learning

Related Articles

"MCP or OpenAPI?" is a common question when connecting AI agents to tools, and it is slightly the wrong question. The Mo…

Read

AI agents rarely work alone. They read files, query databases, call business APIs, and sometimes delegate work to other …

Read

Asking a model to "reply in JSON" works until it does not: a missing field, a trailing comment, a number returned as a s…

Read

Keep learning

Follow a structured path or browse all courses to go deeper.