Build1 publisher3 min readPublished
The portable Agent Plugins manifest puts OpenAI's extras under extensions.com.openai
OpenAI's plugin docs define one root manifest and a single directory shared by ChatGPT and Codex, while the built-in scaffold still writes the older .codex-plugin layout and an MCP file that needs converting.
The Engineer · Build desk

What happened
- OpenAI's own documentation states that the current @plugin-creator scaffold uses the Codex compatibility layout.
- The docs warn against renaming .mcp.json into the portable format, because the portable MCP format also declares a transport type for each server.
- Testing a plugin with an MCP server requires registering the server in ChatGPT developer mode and copying the connection's technical ID, which starts with plugin_asdk_app, out of the browser URL.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- decision A team that wants the portable root manifest has to write it by hand, because the documented fast path emits the compatibility layout; fast setup and portable packaging are two different jobs.
- constraint Anything else that reads the Agent Plugins schema inherits a vendor namespace it must decide how to treat, so portability here means the package moves.
- cost The MCP test loop begins with a click-through in ChatGPT settings, and the ID it yields is tied to that account, so a fresh clone of the repo cannot reproduce the wiring without repeating the registration.
- capability Shipping an MCP server no longer means choosing a surface first, since one publish reaches installers in both ChatGPT and Codex.
A `plugin.json` at the plugin root declares the Agent Plugins schema, and the folder can also carry a `skills/` directory, an `mcp.json` for MCP servers distributed with the plugin, plus optional assets and lifecycle hooks [2]. The documentation describes packaging as giving the plugin a stable identity and telling ChatGPT and Codex which skills, MCP server connections and other resources belong together [1].
One file holds the vendor-specific fields too. OpenAI-specific presentation, registered MCP server mappings and hook settings go under `extensions.com.openai` in the root `plugin.json` [3]. Authentication and UI remain part of the MCP server integration; the manifest connects that integration to the rest of the package [5].
The quick path writes a different file. `@plugin-creator` scaffolds a supported `.codex-plugin/plugin.json` compatibility manifest and can generate a local marketplace entry for testing [8], and the docs state that the current scaffold uses the Codex compatibility layout [9]. Ask for every optional component and you get seven paths under the plugin root [10]. Only `.codex-plugin/plugin.json` is always created, so six of the seven are optional [11][12]. Two of them arrive empty: `.mcp.json` with an empty `mcpServers` object and `.app.json` with an empty `apps` object [13]. Requesting hooks creates an empty `hooks/` directory, with no hook configuration and no executable script in it [14]. The manifest declares `skills: "./skills/"`, and skill folders go there before you test a skills-based plugin [15].
Converting the scaffold output takes more than a rename. The documentation warns against simply renaming `.mcp.json`, because the portable MCP format also declares a transport type for each server [16].
To test an MCP plugin, you start outside the repo. You still need a local folder and manifest, and you register the MCP server connection in ChatGPT developer mode first [17], which is enabled under Settings, then Security and login [18]. Registration happens in ChatGPT Plugins: the plus button, a modal for the server URL and connection details, then you copy the connection's technical ID out of the browser URL, where it starts with `plugin_asdk_app` [19]. Copying an identifier from the address bar is the documented step. That ID goes to `@plugin-creator` in Work mode in ChatGPT or `$plugin-creator` in Codex [20]. Afterwards the docs tell you to check that `.app.json` points at the right `plugin_asdk_app` ID and that the `apps` field in `.codex-plugin/plugin.json` points to `./.app.json` [21].
Distribution is the part that genuinely collapses to one target. Public plugins are published once to the universal plugin directory shared by ChatGPT and Codex [6]. Local and repo marketplaces are separate authoring, testing and team-distribution sources, and the docs warn that their availability can vary by surface [7].
For a plugin I expect to maintain, I would hand-write the root `plugin.json` and `mcp.json` against the Agent Plugins schemas and keep the scaffold for local testing. The compatibility manifest is documented as a fallback [4], and the scaffold itself remains supported [23]. The docs name Figma, Notion and Build web apps as complete public examples to inspect [22].
What to watch
- Whether @plugin-creator starts scaffolding the portable root plugin.json instead of the .codex-plugin compatibility manifest.
- Whether OpenAI publishes an end date for .codex-plugin/plugin.json support as a compatibility fallback.
- Whether the docs specify which local and repo marketplace sources work on which surface, instead of saying availability can vary.