Key takeaways
- Custom GPTs retire on 11 December 2026, or 11 February 2027 for Enterprise workspaces with an approved deferral.
- The migration button moves instructions, knowledge files and connected apps. Custom Actions have to be rebuilt.
- ChatGPT can’t send a custom API key to an MCP server, so API-key Actions need OAuth or no auth.
- Design MCP tools around user intents and set read and destructive annotations from what each tool really does.
- Test the plugin against saved prompts from the old GPT before you move anyone over.
OpenAI is retiring custom GPTs on 11 December 2026. Enterprise workspaces with an approved deferral have until 11 February 2027.1 A built-in migration turns each GPT into a ChatGPT plugin. Its instructions become a skill, its knowledge files become reference files and its connected apps come along. Custom Actions don’t. Any GPT that calls your API through an Action stops calling it on the retirement date unless someone rebuilds that integration, usually as an MCP server.
The rebuild is mostly mechanical. An OpenAPI operation maps fairly directly onto an MCP tool. The part that needs real work is authentication. An Action could hold an API key that the GPT’s builder typed into the editor, and ChatGPT’s MCP client can’t present one. Every API-key Action has to move to OAuth or to no authentication.
This post covers the dates, what the migration moves, how each part of an Action maps to MCP, what to do about API keys and OAuth clients, and how to test the result before switching people over.
The dates that apply to you
OpenAI’s FAQ says the change affects all ChatGPT plans. The dates follow the workspace where the GPT was created, even when people use it from another account.1
| Date | What happens | Who it applies to |
|---|---|---|
| 22 September 2026 | Target for the migration option and user banner | Affected Enterprise workspaces |
| 1 October 2026 | Banner target for workspaces that opted into delayed banners | Those Enterprise workspaces |
| 26 October 2026 (planned) | No new custom GPTs can be created; existing ones can still be edited until migrated | Affected Enterprise workspaces |
| 11 December 2026 | Custom GPTs and their GPT pages become inaccessible | All plans, standard date |
| 11 February 2027 | Retirement for workspaces with a qualified, approved deferral | Those workspaces only |
OpenAI marks the Enterprise milestones as subject to change, and says a target migration date doesn’t guarantee every account can migrate that day. Existing conversations with custom GPTs stay accessible after retirement. The GPTs themselves don’t.
Migration uses the GPT’s latest published version. Drafts and unpublished edits are dropped, so publish anything you want to keep first. Publishing doesn’t mean sharing publicly. After migration the original GPT becomes read-only and its creator can’t delete it, so finish any edits before pressing the button.
What the migration moves and what it leaves
| Part of the GPT | After migration |
|---|---|
| Instructions | Become a skill in the plugin |
| Knowledge files | Copied into the plugin’s reference files |
| Connected apps | Added to the plugin as apps |
| Custom Actions | Not transferred; rebuild with an existing app or a custom MCP server |
| Selected model | Not carried over; Enterprise defaults apply in Enterprise workspaces |
| Conversation starters | Not carried over one-to-one; save the useful ones |
| Capability settings (web search, image generation, data analysis) | Not guaranteed to match; test them |
| Sharing settings | Not carried over; the plugin starts private |
The FAQ and OpenAI’s migration guide are the sources for this table.12 Two details catch people out. Permission to use a GPT gives no right to migrate it, so only the creator or, in Enterprise, a workspace admin can. And an installed plugin doesn’t run on every request. ChatGPT picks a skill when its description matches the request, or when the user calls it with an @ mention.
How an Action maps onto an MCP tool
An Action is an OpenAPI schema plus an authentication setting. An MCP server exposes tools, each with a name, a description, an input schema and annotations, over streamable HTTP. Most of the schema carries across.
| Action (OpenAPI) | MCP tool | Notes |
|---|---|---|
servers URL |
The MCP server URL, usually ending in /mcp |
Must be public HTTPS, or reached through OpenAI’s Secure MCP Tunnel3 |
operationId |
Tool name |
OpenAI suggests stable verb_noun names such as create_project4 |
summary and description |
Tool description |
Describe the user’s intent and when to use the tool |
| Parameters and request body | inputSchema (JSON Schema) |
Give types, allowed values and limits; don’t make the model guess IDs |
| Response body | Structured tool output | Return stable IDs for follow-up calls; leave out tokens and internal detail |
x-openai-isConsequential |
readOnlyHint, destructiveHint, openWorldHint |
Hints for ChatGPT’s confirmation behaviour; enforce on the server too |
| Auth: None | securitySchemes: noauth |
Still validate every call |
| Auth: OAuth | OAuth 2.1, authorisation code with PKCE (S256) | New discovery metadata and client registration |
| Auth: API key | No equivalent | See the next section |
The confirmation flag deserves a closer look. On an Action, x-openai-isConsequential: true made ChatGPT ask the user every time with no “always allow” button. If the flag was omitted, GET operations counted as non-consequential and everything else as consequential.5 MCP has no such default. OpenAI’s tool guidance says to set readOnlyHint to true only when a tool cannot change state, and destructiveHint to true when an outcome may be irreversible or hard to reverse. It also says annotations “do not replace server-side authorization, input validation, or confirmation.”4 A rebuilt booking or payment tool should still check on the server that the user approved it.
Some Action limits go away. Actions had a 45-second timeout and a 100,000-character cap on each request and response, didn’t support custom headers, and sent text only.5 An MCP tool can return structured content, and the 2026-07-28 MCP revision moved tasks for long-running work into an official extension.6 Our stateless MCP migration guide covers that revision if you are starting fresh.
API-key Actions need the most work
A GPT Action could use an API key entered in the GPT editor and stored encrypted by OpenAI. OpenAI recommended it for actions that needed more protection than no auth but didn’t need each user to sign in.7 Many internal GPTs worked this way. One key, held by the GPT, was shared by everyone who used it.
ChatGPT’s MCP client has no place for that key. The Apps SDK docs say ChatGPT “does not support machine-to-machine OAuth grants” and cannot present “custom API keys or customer-provided mTLS certificates”.8 Tools are either noauth or oauth2. That leaves three options.
- Make the tool unauthenticated. This only fits data that is already public, such as a product catalogue or published documentation. The server should still rate-limit and validate inputs, and the docs say to enforce auth on every call even for tools declared
noauth. - Put OAuth in front of the API. Each user signs in once, and the MCP server calls your API on their behalf. This is more work, but every call now carries a real user identity, which the shared key never did.
- Keep the shared key on the server. The MCP server holds the API key in its own secret store and requires an OAuth sign-in from users before it will use it. The key never reaches ChatGPT. This is the quickest route for an internal tool, as long as the OAuth step checks that the user belongs to your organisation.
For a ChatGPT Enterprise or Business workspace, the docs also describe restricting sign-in by workspace domain. The server advertises the openid and email scopes and returns a verified email from its UserInfo endpoint.8 If your servers sit on a private network, OpenAI’s Secure MCP Tunnel lets ChatGPT reach them without a public endpoint.3 The tunnel only handles reachability, so you still need one of the three options above.
OAuth Actions: what changes
An OAuth Action was configured with a static client ID and secret, an authorisation URL, a token URL and a scope, and used a callback URL containing the GPT’s ID, such as https://chatgpt.com/aip/g-.../oauth/callback.7 That registration won’t carry over.
The MCP version follows the MCP authorisation spec. According to OpenAI’s Apps SDK docs, ChatGPT expects:8
- Protected resource metadata at
/.well-known/oauth-protected-resource, naming your authorisation server. - Authorisation server metadata that lists
S256incode_challenge_methods_supported. Servers without S256 aren’t supported. - Client registration through a Client ID Metadata Document, which OpenAI prefers, or Dynamic Client Registration.
- The
resourceparameter copied into the token’s audience, and tokens checked for signature, issuer, expiry, audience and scopes on every call.
We wrote up the OAuth failures we hit making one MCP server work in Claude, ChatGPT, Cursor and VS Code in a separate post. The same server can serve the plugin, which is a good reason to build it to the spec rather than to ChatGPT alone.
Design tools around what users ask for
The quickest rebuild generates one tool per OpenAPI operation. OpenAI’s guidance warns against “mirroring an internal API”. It suggests mapping each use case to its reads and writes, grouping operations that form one action, and splitting tools that differ in permissions, risk or confirmation needs.4 An Action with 20 operations often becomes six or eight tools, with reads and writes kept apart.
Here is one rebuilt tool as it appears in the server’s tools/list response, whatever SDK produced it:
{
"name": "get_order_status",
"description": "Look up the delivery status of one of the signed-in user's orders. Use when the user asks where an order is. Needs the order ID from the confirmation email.",
"inputSchema": {
"type": "object",
"properties": {"order_id": {"type": "string", "pattern": "^[A-Z0-9-]{6,20}$"}},
"required": ["order_id"]
},
"annotations": {"readOnlyHint": true, "destructiveHint": false, "openWorldHint": false},
"securitySchemes": [{"type": "oauth2", "scopes": ["orders.read"]}]
}
The description says when to use the tool and what it needs, which is what ChatGPT reads when it picks a tool. The securitySchemes field is ChatGPT’s per-tool way of saying which tools need a signed-in user.8 OpenAI’s plugin guidelines require explicit true or false values for all three hints on every tool. If automated review flags one, you can appeal with an explanation.9
Testing the plugin against the old GPT
OpenAI’s FAQ suggests comparing familiar prompts and at least one harder case.1 It lists four checks: the plugin picks the right skill, uses the expected reference material, produces complete answers in the right format and has the tools it needs. We’d make that concrete before the old GPT goes read-only.
- Export 10 to 20 real prompts the GPT handles, with the answers it gave, while it still runs.
- Run each one in the plugin twice, once by @-mentioning the plugin and once without. The second run tells you whether the skill description is good enough for ChatGPT to pick it unprompted.
- For every rebuilt tool, test one call that should need confirmation and one that shouldn’t.
- Sign in as a second user and confirm they see only their own data.
The FAQ is clear that a rebuilt integration “should not be assumed to provide every capability of the original action”, so treat any difference as a bug until you’ve decided it isn’t.
Sharing the replacement
Migration doesn’t carry over sharing settings or give the GPT’s users access to the plugin. In Enterprise, sharing with people or groups needs the Share plugins permission and publishing to the workspace directory needs Publish plugins to workspace. Using the plugin needs Use plugins and a policy that lets people install it or installs it for them. A public plugin goes through a separate submission process.1 Users of any included app still sign in to it themselves, and installing a plugin grants no extra access to data in the connected service.
Migration checklist
- List every GPT your team relies on, who created it and which workspace it lives in.
- Publish any drafts you need, and finish edits before migrating.
- Save real prompts and answers from each GPT as a test set.
- Run the migration and check the generated skill and reference files.
- For each Action, decide between an existing app and a custom MCP server.
- Replace API-key auth with OAuth, a server-held key behind OAuth, or no auth for public data.
- Design tools around intents, and set all three annotations from real behaviour.
- Enforce authorisation and confirmation on the server, whatever the annotations say.
- Run the test set with and without @-mentions, as two different users.
- Share the plugin, have one user install and test it, then move the team before 11 December.
-
OpenAI Help Center, “Custom GPT retirement and migration FAQ”, read 13 October 2026, https://help.openai.com/en/articles/20001519-custom-gpt-retirement-and-migration-faq ↩↩↩↩↩
-
OpenAI, “Moving your custom GPT workflows to plugins”, ChatGPT Learn, read 13 October 2026, https://learn.chatgpt.com/docs/migrate-custom-gpts ↩
-
OpenAI, “Connect and test your plugin”, https://developers.openai.com/plugins/deploy/connect-chatgpt ↩↩
-
OpenAI, “Define tools”, https://developers.openai.com/plugins/plan/tools ↩↩↩
-
OpenAI, “Production notes on GPT Actions”, https://developers.openai.com/api/docs/actions/production ↩↩
-
Model Context Protocol specification 2026-07-28, “Key Changes”, https://modelcontextprotocol.io/specification/2026-07-28/changelog ↩
-
OpenAI, “GPT Action authentication”, https://developers.openai.com/api/docs/actions/authentication ↩↩
-
OpenAI, “Authentication”, Apps SDK documentation, https://developers.openai.com/apps-sdk/build/auth ↩↩↩↩
-
OpenAI, “Plugin guidelines”, https://developers.openai.com/plugins/plugin-guidelines ↩
Frequently asked questions
When are Custom GPTs being retired?
OpenAI’s FAQ schedules the retirement for 11 December 2026. Enterprise workspaces with a qualified, approved deferral get until 11 February 2027. After that, custom GPTs and their GPT pages become inaccessible.
Do GPT Actions transfer to ChatGPT plugins?
No. OpenAI says custom actions don’t transfer through the migration workflow. You either use an existing app that covers the same tasks or rebuild the integration as a custom MCP server.
Can a ChatGPT MCP server use an API key?
Not the way an Action could. OpenAI’s Apps SDK docs say ChatGPT cannot present custom API keys or customer-provided mTLS certificates. Tools are either unauthenticated or use OAuth 2.1 with PKCE.
Will my old Custom GPT conversations be deleted?
No. OpenAI’s FAQ says existing conversations with custom GPTs stay accessible after retirement, with no action needed. The GPT itself stops working at the retirement date.
What replaces x-openai-isConsequential in MCP?
MCP tool annotations. Set readOnlyHint and destructiveHint from what the tool does, and ChatGPT uses them when deciding whether to ask the user. OpenAI says annotations don’t replace server-side authorisation or confirmation.
Building something like this?
9io is a small team of senior engineers with a fractional CTO, and we work by the hour. Send us a note about your product. The reply comes from the person who'd do the work.