GPTAction Rescue

Free guide · December 11, 2026

Migrate custom GPT actions to MCP.

When you migrate a custom GPT to a ChatGPT plugin, instructions and files come along. Custom actions don't. This guide shows how to rebuild an action from its OpenAPI schema as a remote MCP server, host it, and connect it in ChatGPT. Every claim about ChatGPT links to OpenAI's own pages, all accessed November 13, 2026.

OpenAI's retirement and migration FAQ: "GPT custom actions do not transfer through the migration workflow. Features that depend on them will not work in the plugin until you set up a replacement. [...] Rebuilding the connection may require a custom MCP server and technical setup." The scheduled retirement is December 11, 2026 (February 11, 2027 for FedRAMP workspaces and Enterprise workspaces with an approved deferral). Check the notice in your own account.


01 / What moves

What carries over, and what doesn't.

From OpenAI's FAQ:

Part of your GPTAfter migration
InstructionsCarries over, as a skill within the new plugin
Knowledge filesCarries over, copied into the plugin's reference files
Connected appsCarries over, added to the plugin as apps
Custom actionsDon't transfer. You need a replacement, which may be a custom MCP server
Selected modelDoesn't carry over
Sharing / audienceNot automatic. The plugin starts private, and existing GPT users don't get access automatically
Drafts and unpublished editsDon't transfer. Migration uses the latest published version
Existing conversationsStay accessible after retirement

The FAQ also says the original GPT becomes read-only after migration, so finish edits and copy your action schema first.


02 / The steps

Seven steps from schema to a working plugin tool.

  1. Check that your plan can use a custom MCP server
  2. Export the action's OpenAPI schema
  3. Convert the schema into an MCP server
  4. Put secrets in environment variables
  5. Host it on a public HTTPS endpoint
  6. Connect it in ChatGPT
  7. Test it against your old prompts

Step 1. Check that your plan can use a custom MCP server

OpenAI's help article says custom MCP server connections and full MCP support are available for ChatGPT Business and Enterprise/Edu on ChatGPT web, and that Pro users can connect custom MCP servers with read/fetch permissions.

Plan details from OpenAI's Connecting custom MCP servers in ChatGPT:

  • Business. Full MCP, including write and modify actions. Only admins and owners can create and publish plugins for custom MCP servers.
  • Enterprise/Edu. Full MCP. Admins and owners create and test connections and can grant members permission with role-based access control. Only admins and owners publish for the workspace.
  • Pro. "Pro users can connect custom MCP servers with read/fetch permissions." Full MCP is "only available to Business and Enterprise/Edu users, currently."
  • Plus and other plans. The article doesn't mention them. If you don't see Add custom MCP server under Plugins, your account can't do this step in ChatGPT.
  • It's web only. The article's answer for mobile is "No - web only."
  • Deep research can use custom apps for read/fetch actions only, not write actions.

The same MCP server also works in other MCP clients, so a rebuilt action isn't wasted if your ChatGPT plan can't use it yet.

Step 2. Export the action's OpenAPI schema

Before you migrate, open your GPT in the editor, open the action, and copy everything in its Schema box into a file. Note which authentication it uses: None, API Key, or OAuth.

In the GPT editor, copy the full OpenAPI schema from the Schema box into a file, for example action.json or action.yaml. OpenAI's GPT Actions guide describes this as the box where you "paste in your Open API schema". Repeat for each action. Write down:

  • The authentication type. OpenAI's action authentication docs list three options: None, API Key or OAuth. The key or client secret itself isn't shown in the schema. You'll need it from the API provider.
  • The servers URL at the top of the schema. If it's relative (for example /api/v3), you'll need the full base URL.
  • Your GPT's instructions that mention the action by its operation name. Tool names in the rebuilt server come from the schema's operationIds when present, so those references still make sense.

Do this before you migrate. After migration, the original GPT becomes read-only.

Step 3. Convert the schema into an MCP server

Run the converter on the schema file. It writes a self-contained server.mjs, a tools.json manifest, a .env.example and a README with tools, auth variables and warnings.

Our converter is free to use. It's two files, with no npm install needed. It needs Node.js 20.6 or newer. Keep both files in the same folder.

node convert.mjs action.yaml -o my-action
# relative server URL in the schema? pass the real base:
node convert.mjs action.yaml -o my-action --base-url https://api.example.com/v1
# only some operations, and a display name:
node convert.mjs action.yaml -o my-action --ops getThing,createThing --name "My API"

The input can be a JSON or YAML file, or an https URL to the schema. Tool names come from this function in the converter. If the operation has no operationId, a path like GET /v1/forecast becomes the tool get_v1_forecast:

function toolName(op, method, p, used) {
  let base = op.operationId || `${method}_${p.replace(/\{([^}]+)\}/g, "by_$1")}`;
  base = base
    .replace(/[^A-Za-z0-9_-]+/g, "_")
    .replace(/^_+|_+$/g, "")
    .replace(/_+/g, "_")
    .slice(0, 60) || `${method}_root`;
  let n = base, i = 2;
  while (used.has(n)) n = `${base}_${i++}`;
  used.add(n);
  return n;
}

The output folder contains:

  • server.mjs: the MCP server runtime (streamable HTTP, stateless, at /mcp by default, with health at /healthz).
  • tools.json: one MCP tool per API operation. Each tool's input schema is the operation's parameters plus a body argument when there is one. GET, HEAD and OPTIONS tools are marked read-only. DELETE tools are marked destructive.
  • .env.example: the settings and one GAR_AUTH_<SCHEME> line per auth scheme in the schema.
  • README.md: the tool list, auth variables and any conversion warnings. Read these first. They tell you what didn't convert.

It accepts OpenAPI 3.0 and 3.1 with local $refs, and path, query, header and cookie parameters with JSON or form bodies. Swagger 2.0 is rejected with a message, so convert it to OpenAPI 3 first.

Step 4. Put secrets in environment variables

Copy .env.example to .env and fill in the GAR_AUTH_ variables. The server adds the key or token to upstream requests and never sends it to the MCP client.

cd my-action
cp .env.example .env
# edit .env: fill in e.g. GAR_AUTH_APIKEYAUTH=... (never commit this file)
node --env-file=.env server.mjs
  • API key (header, query or cookie), bearer and basic schemes are added server-side from GAR_AUTH_<SCHEME>. For basic auth, the value is user:password.
  • Other settings: PORT, HOST, MCP_PATH, RATE_LIMIT_PER_MIN (per IP, 0 = off), UPSTREAM_TIMEOUT_MS (default 30000), MAX_RESPONSE_BYTES (default 100000), TRUST_PROXY=1 behind a reverse proxy, and an optional MCP_BEARER_TOKEN.
  • If a secret is missing, the tool returns a clear error instead of calling your API without it. Logs record only the tool name, upstream status and timing, not arguments or IPs.

Check it locally before hosting it. OpenAI's Connect and test your plugin page suggests MCP Inspector:

npx @modelcontextprotocol/inspector --cli http://127.0.0.1:8080/mcp --transport http --method tools/list

Step 5. Host it on a public HTTPS endpoint

Run server.mjs on a machine with Node 20.6 or newer behind a reverse proxy that serves HTTPS, so ChatGPT can reach the /mcp path. Or use Secure MCP Tunnel for a private server.

OpenAI's Connect and test your plugin page says the server must be reachable "through a public HTTPS endpoint or Secure MCP Tunnel", and that a public endpoint "supports streamable HTTP, typically at /mcp". Options:

  • A small VPS or any always-on machine with Node 20.6+, running server.mjs under a process manager (for example systemd), behind a reverse proxy that serves HTTPS. Set HOST=127.0.0.1 and TRUST_PROXY=1.
  • Any host that runs a long-lived Node process and gives it an HTTPS URL. The server keeps no state between requests and needs no database.
  • Secure MCP Tunnel, if the server must stay on a private network. Its tunnel-client makes outbound connections only. It needs OpenAI Platform tunnel permissions, which are separate from ChatGPT workspace permissions. OpenAI notes it doesn't support public plugin submission.

Without OAuth, the URL is the only protection. Set MCP_PATH to a long random path (for example /mcp/ plus 32 random hex characters), because anyone who has the URL can call the tools with your stored key. That's only acceptable for read-only or low-risk actions. MCP_BEARER_TOKEN works for other MCP clients, not ChatGPT (see Step 6).

Step 6. Connect it in ChatGPT

In ChatGPT on the web, go to Plugins, select the plus button, then Add custom MCP server. Enter the URL including the /mcp path, configure authentication, accept the risk warning, and select Create as a plugin.

From OpenAI's help article and Connect and test your plugin:

  1. On ChatGPT web, go to Plugins.
  2. Select the plus button, then Add custom MCP server.
  3. Enter a name and, optionally, a description.
  4. Under Connection, enter your public HTTPS MCP URL, including the /mcp path (or your random MCP_PATH). Or select Tunnel.
  5. Configure authentication for your server.
  6. Review the risk warning and select "I understand and want to continue".
  7. Select Create as a plugin, then review the tools ChatGPT discovered.

No Developer Mode step is needed. The help article says: "In the current Plugins experience, add a custom MCP server directly from Plugins. You don't need to turn on Developer Mode first." Account and workspace policies still apply.

OpenAI's authentication guide says many MCP servers "can operate in a read-only, anonymous mode", and that anything exposing customer-specific data or write actions should authenticate users with OAuth 2.1. It also says ChatGPT "does not support machine-to-machine OAuth grants such as client credentials, service accounts, or JWT bearer assertions, nor can it present custom API keys". If you use OAuth, the help article warns that ChatGPT may lose access when the original authorization expires unless your provider issues refresh tokens (for OpenID Connect, the offline_access scope).

After you change the server (tool names, descriptions, schemas), open the connection in Plugins and select Refresh, per the connect guide. In Business and Enterprise/Edu workspaces, ChatGPT uses a frozen snapshot of the tools approved by an admin, and calls can error if the live server no longer matches until an admin refreshes it.

OpenAI's pages describe packaging a plugin "with its skills, manifest, and MCP server connection". We haven't found a step-by-step for adding a server to an already-migrated plugin, so follow the in-product options you see.

Step 7. Test it against your old prompts

Install the resulting plugin, start a new conversation, type @ to select it, and rerun the prompts you used with the GPT, including at least one harder case.

OpenAI's FAQ says a migrated plugin may respond differently and that a rebuilt integration "should not be assumed to provide every capability of the original action". Keep a few familiar prompts and one harder case, and check that the right tool is called with the right arguments. Per OpenAI's help article, ChatGPT may ask you to confirm write actions, so a pending confirmation can look like a call that silently failed.

Want to try it without your own API first? Our live demo server, a public weather API rebuilt with this converter, no auth, rate-limited, is at https://gptrescue.pages.dev/mcp. See the demo section.


03 / Failures

Common failures, and what to do.

SymptomCause and fix
OAuth-only operations (the action used "Sign in with ...")The converter warns: per-user OAuth is not proxied. It can only send one static token from GAR_AUTH_<SCHEME> as a bearer, like a service account or long-lived token. A real per-user sign-in needs an OAuth 2.1 authorization server that meets the MCP authorization spec. OpenAI's auth guide lists PKCE with S256, protected resource metadata, and client registration via CIMD, DCR or a predefined client. MCP connections use different redirect URIs from the old action callback. Copy the exact one shown on the MCP server's management page.
File uploads missingOperations with multipart/*, application/octet-stream or image/* request bodies are skipped and listed in the warnings. Keep those as a separate flow, or change the API to accept a URL or base64 JSON field.
Relative server URL (servers: - url: /api/v3)The converter warns that the server URL is relative and to pass --base-url. Rerun with --base-url https://your-api.example.com. If you pass the schema as an https URL, relative servers resolve against it.
ChatGPT can't connectCheck the URL includes /mcp and is HTTPS, then run MCP Inspector against the public URL. The server answers POST only, so a browser GET on /mcp returns 405, which is expected.
You want ChatGPT to send an API key or bearer tokenIt can't. Keep the upstream key in .env and use no auth on a random path for low-risk tools, or OAuth.
Read tools work but write tools don'tOn Pro, custom MCP servers are read/fetch only, and deep research is read/fetch only. Also check for a pending confirmation prompt.
Tools stopped working after you edited the serverRefresh the connection in Plugins. In workspaces, an admin must refresh the approved snapshot.
Swagger 2.0 is not supportedConvert the schema to OpenAPI 3 first.
Upstream returns an errorThe tool returns the HTTP status and body as an error result, so you can see it in ChatGPT or Inspector. Test the same call with curl to rule out the API itself.

Also not supported by the converter: external $ref files, streaming responses, and per-user state.


04 / FAQ

Straight answers.

Do custom GPT actions transfer when I migrate my GPT to a plugin?

No. OpenAI's FAQ says GPT custom actions do not transfer through the migration workflow, and that rebuilding the connection may require a custom MCP server and technical setup.

When do custom GPTs retire?

OpenAI's FAQ gives December 11, 2026 as the scheduled retirement date. FedRAMP workspaces and affected Enterprise workspaces with a qualifying, approved deferral have February 11, 2027. Follow the notice in your own account.

Do I need Developer Mode to add a custom MCP server?

No. OpenAI's help article says that in the current Plugins experience you add a custom MCP server directly from Plugins and don't need to turn on Developer Mode first. You acknowledge a risk warning for each server instead.

Can ChatGPT send my API key to the MCP server?

No. OpenAI's authentication guide says ChatGPT cannot present custom API keys. Keep the API key on the MCP server as an environment variable, and use OAuth or no authentication between ChatGPT and the server.

Can I connect a custom MCP server on ChatGPT mobile?

No. OpenAI's help article answers that connecting custom MCP servers is web only.


05 / Sources

What we checked, and when.

All accessed November 13, 2026. We only state what these pages said on that date. ChatGPT changes often, so check them again.

Want it done for you?

We rebuild and host the action from your schema, test it against your real API, and help you connect it. We'll tell you whether it fits before you pay anything. Scope and price · northlab.research@outlook.com