Codex plugins: what the 180 in the marketplace actually contain
We opened every plugin in Codex's curated marketplace. Most are thin wrappers around an app connector, a minority bundle skills or MCP servers, and two ship hooks that run scripts after your edits and commands. How codex plugin works, what to check before installing, and how to override a plugin's MCP servers in config.toml.
A Codex plugin sounds like a new kind of capability. It isn't. A plugin is packaging: a manifest that points at skills, app connectors, MCP servers, and occasionally hooks, which are all things Codex supports on their own. The useful question about any plugin is what is inside it, and the marketplace listing does not show you that.
So we looked. Codex CLI 0.147.0 keeps a local snapshot of the curated marketplace on disk, and we read every manifest in it. This post covers the commands, then what the 180 curated plugins turned out to contain, and what that means for which ones you install.
The commands
codex plugin list # plugins in configured marketplaces
codex plugin list --available --json # include uninstalled ones, machine-readable
codex plugin add github@openai-curated # install
codex plugin remove github@openai-curated # uninstall from config and cache
Plugins are named PLUGIN@MARKETPLACE. You can also pass the plugin name alone and add --marketplace <name>.
Marketplaces have their own subcommand:
codex plugin marketplace list
codex plugin marketplace add owner/repo@v1.2.0
codex plugin marketplace upgrade
codex plugin marketplace remove my-team
marketplace add accepts a local path, owner/repo with an optional @ref, an HTTPS Git URL, or an SSH Git URL. marketplace upgrade refreshes Git marketplace snapshots. Give it a name to refresh one, or leave the name off to refresh all of them.
On our machine the default marketplace is named openai-curated, with its root at ~/.codex/.tmp/plugins. That directory holds a readable copy of every plugin, and it is where the numbers below come from.
What a plugin is on disk
Each plugin is a directory with one required file, .codex-plugin/plugin.json, plus optional components next to it:
skills/, the sameSKILL.mdformat as standalone skills.app.json, a reference to an app connector.mcp.json, one or more MCP server definitionsagents/andcommands/hooks.json, for lifecycle hooksassets/, icons and images for the listing
The manifest names what the plugin bundles. A trimmed version of the GitHub plugin's manifest:
{
"name": "github",
"version": "0.1.6",
"skills": "./skills/",
"apps": "./.app.json",
"mcpServers": "./.mcp.json",
"interface": {
"displayName": "GitHub",
"category": "Developer Tools",
"capabilities": ["Interactive", "Write"]
}
}
The skills, apps, and mcpServers lines are the ones to check. Everything under interface is listing copy.
What the 180 curated plugins contain
The curated marketplace on our machine lists 180 plugins. Counting components across all of them:
| Component | Plugins that include it |
|---|---|
App connector (.app.json) |
154 |
| Skills | 72 |
| Agents | 14 |
MCP servers (.mcp.json) |
8 |
| Commands | 6 |
Hooks (hooks.json) |
2 |
Four things follow from that table.
Most plugins are a connector with a listing page. A .app.json holds little more than an app ID. For 154 of 180 plugins, the main thing you get is authentication to a hosted service. That is a convenient way to connect Slack or Linear, but it adds no local capability.
Skills are where most of the value is. 72 plugins bundle skills, which are written procedures for a kind of task. The GitHub plugin, for example, includes skills for fixing failing CI and addressing review comments. If you want to know whether a plugin will change how Codex works rather than just what it can reach, look at its skills/ directory. The format is the same one we covered in the Claude Code skills post.
Only 8 plugins bring MCP servers. Those are build-ios-apps, cloudflare, codex-security, figma, github, linear, notion, and openai-developers. Installing one of these puts a server process or remote endpoint into your setup, with the same startup, timeout, and approval settings covered in the Codex MCP post.
Two plugins ship hooks. They deserve a closer look.
The two plugins that run code
Hooks are the component that executes on your machine without you asking each time, so these are worth reading in full.
figma runs a script after every file write or edit:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "./scripts/post_write_figma_parity_check.sh" }
]
}
]
}
}
replayio runs a script after Bash commands, and another one when the turn stops:
{
"hooks": {
"PostToolUse": [
{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "./scripts/post_bash_upload.sh" }] }
],
"Stop": [
{ "hooks": [{ "type": "command", "command": "./scripts/stop_close_and_upload.sh" }] }
]
}
}
Both scripts have upload in their names. Neither of these is necessarily a problem. A recording tool that uploads recordings is doing what it says. But it is exactly the kind of behavior you should decide to accept on purpose, not discover afterward.
Codex's own hook rules help here. Per the hooks documentation, installing or enabling a plugin does not automatically trust its hooks, and each hook definition has to be reviewed and trusted before it runs. When Codex asks you to trust a plugin's hook, open the script it points to first.
Authentication and the API key catalog
Each marketplace entry has a policy. In the curated list, all 180 have "installation": "AVAILABLE". Authentication differs: 177 authenticate ON_INSTALL, and three authenticate ON_USE (build-web-apps, build-web-data-visualization, and codex-security). An ON_INSTALL plugin asks you to sign in when you add it, even if you never end up using it that week.
The snapshot also contains a second file, api_marketplace.json, with 29 entries. According to the openai/plugins repository, that is the marketplace for people signed in with an API key rather than a ChatGPT account. If a colleague mentions a plugin you cannot find, check how each of you is logged in before assuming it was removed.
Controlling a plugin in config.toml
Installed plugins are recorded in config.toml. Plugin names contain @, so the TOML key has to be quoted:
[plugins."github@openai-curated"]
enabled = false
The more useful part is that you can adjust a plugin's bundled MCP servers without editing the plugin:
[plugins."github@openai-curated".mcp_servers.github]
default_tools_approval_mode = "prompt"
disabled_tools = ["merge_pull_request"]
[plugins."github@openai-curated".mcp_servers.github.tools.search_code]
approval_mode = "auto"
enabled, enabled_tools, disabled_tools, default_tools_approval_mode, and per-tool approval_mode work the same way here as they do for MCP servers you configure yourself. Settings you put in your own config.toml stay put when the plugin's manifest changes, which makes this the right place for your own policy.
The server name github is the real one: the plugin's .mcp.json defines a single HTTP server by that name, pointing at https://api.githubcopilot.com/mcp/ and reading its token from the GITHUB_PAT_TOKEN environment variable, which is the right pattern for secrets. The tool names above are illustrative. Run codex mcp list --json after installing a plugin to see the names it actually registers before you write overrides for them.
Your own marketplace
A team marketplace is a Git repository or a local directory that uses the same layout as the curated one: .agents/plugins/marketplace.json at the root, listing plugins by path. In config.toml:
[marketplaces.my-team]
source = "https://github.com/acme/codex-plugins.git"
source_type = "git"
ref = "v1.4.0"
sparse_paths = ["plugins/deploy", ".agents"]
Pin ref to a tag. A marketplace that tracks a branch can change which scripts your team's Codex installs run the next time someone upgrades. sparse_paths limits the checkout to the plugins you actually use.
Check pinning inside individual plugins too. build-ios-apps, for example, starts its MCP server with npx -y xcodebuildmcp@latest mcp, which means whatever version was published most recently. That is convenient, but it is not reproducible. If you need a fixed version, override the server in your own config or use a plugin that pins one.
What to install, and what to check first
- Want a connector? Install the plugin. There is little to review beyond the sign-in it requests.
- Want to change how Codex works? Read the
skills/directory before installing. The skills are the substance of the plugin. - Plugin includes
.mcp.json? Look at the server command, check whether versions are pinned, and set approval modes in your own config afterward. - Plugin includes
hooks.json? Read every script it points to before you trust it. Currently that applies to two curated plugins, and it will apply to more over time.
If you also use Claude Code, the model is very similar, and the Claude Code plugins post covers that side. The practical rule is the same in both tools: a plugin is a bundle of things you could have configured yourself, so decide based on its contents, not its listing.