ChatGPT Plugins: The New Plugin System vs. the 2023 Program
Kashish Hora
Co-founder of AgentCat
Two unrelated things have gone by the name ChatGPT plugins, and they share the word and nothing else.
The one that exists now is a packaging and distribution format. A plugin bundles capabilities into a reusable workflow for ChatGPT and Codex, it can carry skills, connectors backed by MCP servers, or both, and both products browse one shared directory (Plugins).
The one from 2023 was a way to hand ChatGPT a REST API: you hosted a manifest at /.well-known/ai-plugin.json that pointed at an OpenAPI spec, and users installed it from a Plugin store inside ChatGPT. That program was retired in 2024, superseded by GPTs, and OpenAI's own quickstart repo for it has been archived and read-only since May 2026 (openai/plugins-quickstart).
What a plugin is now
A plugin is a container with a stable identity, a manifest, and pointers to whatever it bundles. Six kinds of thing can go inside (Plugins).
- Skills: folders of instructions with a
SKILL.mdat the root, teaching the model when and how to run a repeatable workflow. - Connectors: connections to services like GitHub, Slack, or Google Drive. They expose tools and can optionally include custom UI.
- MCP servers: the services behind connectors. They define tools, enforce auth, return structured data, and act on external systems.
- Browser extensions: browser capabilities a workflow needs.
- Hooks: commands that run at configured lifecycle points, which users have to review and trust before they run.
- Scheduled task templates: reusable starting points for recurring tasks, where scheduled tasks are available.
On disk, one file is mandatory. Every plugin has a .codex-plugin/plugin.json manifest, and that manifest identifies the package, points at bundled components, and supplies the metadata that install surfaces render (Package your plugin).
{
"name": "acme-support",
"version": "1.0.0",
"description": "Triage and answer support tickets.",
"skills": "./skills/",
"apps": "./.app.json",
"mcpServers": "./.mcp.json"
}Only plugin.json belongs in .codex-plugin/. Everything else (skills/, hooks/, assets/, .mcp.json, .app.json) sits at the plugin root, and every manifest path starts with ./ and resolves relative to that root. The two server-shaped fields do different jobs: mcpServers points at an .mcp.json describing a server you distribute inside the plugin, while apps points at an .app.json that references an MCP server connection already registered with ChatGPT. The apps name looks like a separate primitive and isn't one, which OpenAI says outright: "the filename is a compatibility identifier; the underlying primitive is the MCP server."
Published plugins use a much richer manifest than that skeleton. The one OpenAI ships for Figma carries fourteen fields in its interface object alone: display name, category (Creativity), capability labels, a brand color, two icon fields, and three starter prompts, with license, homepage, and repository sitting at the top level (plugins/figma/.codex-plugin/plugin.json). Figma, Notion, and build-web-apps are all readable in full in that repository.
Where plugins actually work
Availability is narrower than the name suggests. Plugins run in:
- ChatGPT Work on the web
- ChatGPT Work or Codex in the ChatGPT desktop app
- Codex CLI, via the
/pluginsbrowser and configured marketplaces
They aren't available in regular Chat, in the IDE extension, or on mobile (Plugins). If you're in a normal ChatGPT conversation on your phone looking for a plugin menu, there isn't one to find.
Being able to see the directory is a weaker condition than being able to use it. OpenAI migrated the app directory into the plugin directory on July 9, 2026, and the plugin directory is visible across ChatGPT plans, while installing or invoking any given plugin depends on plan, workspace settings, role, surface, region, and whatever apps that plugin requires (Plugins in ChatGPT and Codex).
Workspace admins control both halves: plugin availability under Workspace settings → Plugins, and the underlying app permissions under Workspace settings → Apps.
Two behaviors matter once something is installed:
- Bundled skills become available only in a chat or CLI session started after the install.
- A plugin's connectors may ask for sign-in either during setup or the first time they're used.
Plugins, apps, skills, connectors, and GPTs
Five nouns circle the same territory, and the relationships are mostly containment rather than competition.
| Thing | What it is | Where you get it | Relationship to a plugin |
|---|---|---|---|
| Plugin | A package of skills and/or server-backed capabilities for a workflow | The plugin directory, or a repo or personal marketplace | The container |
| App | An MCP server plus optional UI, connecting ChatGPT or Codex to external data and actions | Packaged inside a plugin listing | A component it carries; existing apps were repackaged into plugins |
| Skill | A SKILL.md folder of workflow instructions, references, and scripts | Bundled in a plugin | A component; a plugin can ship skills and no server at all |
| Connector (ChatGPT) | A connection to a service like GitHub or Slack, backed by an MCP server | Connected during plugin install or on first use | How a plugin reaches an outside system |
| Connector (API) | "OpenAI-maintained MCP wrappers for popular services like Google Workspace or Dropbox" | The API's mcp tool, addressed by connector_id | Unrelated to plugin packaging |
| GPT | A configured ChatGPT: instructions, conversation starters, knowledge, capabilities, plus apps or actions | Explore GPTs, or the GPT Store | Not a plugin and not packaged as one |
GPTs draw the most confusion here, partly because GPTs are what replaced the 2023 plugins. They're still around and still a separate product: a GPT is a version of ChatGPT you open and talk to, while a plugin is a capability you install into work you're already doing. GPTs also carry a constraint with no equivalent on the plugin side, since a plugin can bundle whatever it likes: "A GPT can use either apps or actions, but not both at the same time" (GPTs in ChatGPT).
The API-side "connector" is a third use of the word, and it's genuinely a different thing from the connector inside a plugin. Anthropic has the same collision on its side of the fence, which Claude Connectors vs. MCP servers vs. the MCP connector API untangles.
If you're carrying the 2023 model
The old program's parts do have successors, and the mapping is clean enough to translate an old mental model in one pass.
| The 2023 program | Its counterpart now |
|---|---|
/.well-known/ai-plugin.json, hosted on your domain | .codex-plugin/plugin.json, inside the plugin folder |
| An OpenAPI spec describing REST endpoints | An MCP server declaring tools, schemas, and auth |
description_for_model steering tool choice | Skills, as SKILL.md folders with their own descriptions |
| A Plugin store inside ChatGPT | One universal plugin directory shared by ChatGPT and Codex |
| "Develop your own plugin" against a localhost manifest URL | Developer-mode server registration plus a local or repo marketplace |
| Text responses only | Optional inline UI on the MCP server, via the MCP Apps standard |
Every one of those left-hand pieces is visible in OpenAI's archived quickstart, where the manifest declares "api": {"type": "openapi"} alongside description_for_model, and the install flow is a Plugin store entry called "Develop your own plugin" pointed at localhost:5003. The right-hand column is a different protocol with a different distribution story, so nothing about an old plugin ports over mechanically. The API behind it is still perfectly good raw material for an MCP server.
The part you build
If you write MCP servers, the practical news is that the plugin is packaging and the server is the artifact. A plugin can be submitted as skills only, as an MCP server with optional custom UI, or as both together (Submit plugins). Which means the work splits cleanly:
- Build the server and its UI. That's the app half, and it's the same MCP server that renders in other hosts. The OpenAI Apps SDK TypeScript quickstart and Python quickstart each take it end to end.
- Make the UI portable while you're there. The
ui://resource is standard, and one MCP app in Claude and ChatGPT covers what's shared versus what's ChatGPT dialect. - Wrap it in a plugin and ship it. Manifest, marketplace, review, listing. Publishing an MCP server as a ChatGPT and Codex plugin is that path.
Our take on sequencing: build the server first and treat skills as a second pass. A skills-only plugin is a legitimate shipping target, but skills describe how to combine tools, so writing them before the tools exist tends to produce workflow prose you rewrite anyway.
What's doing the work underneath
That's the useful question whenever you hit the word "plugin". In the current system the answer is an MCP server, a folder of skills, or both, wrapped in a manifest and listed in a directory. In the 2023 system it was an OpenAPI spec behind a manifest on your own domain, and that mechanism is gone.
It's also the question that matters after shipping. A plugin can install cleanly and still disappoint: the skills load, the connector authenticates, and then the bundled server's tools get called with arguments nobody expected, or never get called at all. Every layer of the packaging is OpenAI's; the server underneath is yours, and it's where that evidence accrues. Debugging a plugin in practice means reading your MCP server's traffic, which is what AgentCat instruments.
Related Guides
Publish Your MCP Server as a ChatGPT and Codex Plugin
The manifest, the .app.json vs .mcp.json decision, and what the submission portal checks before your server reaches the shared plugin directory.
OpenAI Apps SDK TypeScript Quickstart
Build a working ChatGPT app in TypeScript: an MCP server whose tool is bound to a ui:// resource so the widget actually renders inline. Uses McpServer, the MCP Apps extension helpers, and Streamable HTTP, verified against current docs.
One MCP App, Two Hosts: UI That Renders in Claude and ChatGPT
An app's UI is just an MCP resource. What's standard, what's ChatGPT-specific, and the diff that makes one server render in both hosts.