SpyBara
Go Premium

Documentation 2026-07-23 21:57 UTC to 2026-07-24 15:00 UTC

30 files changed +491 −2,474. View all changes and history on the product overview
2026
Fri 24 15:00 Thu 23 21:57 Wed 22 20:02 Tue 21 22:02 Mon 20 23:01 Fri 17 22:57 Thu 16 20:57 Wed 15 19:58 Tue 14 17:03 Wed 8 02:01 Mon 6 22:58
Details

388 },388 },

389 {389 {

390 name: "Plugin sharing",390 name: "Plugin sharing",

391 href: "/codex/build-plugins#share-a-local-plugin-with-your-workspace",391 href: "https://developers.openai.com/plugins/build/plugins#share-a-local-plugin-with-your-workspace",

392 availability: {392 availability: {

393 bedrock: "unavailable",393 bedrock: "unavailable",

394 },394 },

app/commands.md +2 −2

Details

160 160 

161### Plugins161### Plugins

162 162 

163Plugin links use different forms depending on whether you are installing from a marketplace, opening a plugin, or working from a local `marketplace.json`. For plugin basics, see [Plugins](https://learn.chatgpt.com/docs/plugins). For local or repo marketplace setup, see [Build plugins](https://learn.chatgpt.com/docs/build-plugins#build-your-own-curated-plugin-list).163Plugin links use different forms depending on whether you are installing from a marketplace, opening a plugin, or working from a local `marketplace.json`. For plugin basics, see [Plugins](https://learn.chatgpt.com/docs/plugins). For local or repo marketplace setup, see [Build plugins](https://developers.openai.com/plugins/build/plugins#build-your-own-curated-plugin-list).

164 164 

165#### Plugin install165#### Plugin install

166 166 


195 195 

196#### Local plugin196#### Local plugin

197 197 

198For local or repo marketplace setup, see [Build plugins](https://learn.chatgpt.com/docs/build-plugins#build-your-own-curated-plugin-list).198For local or repo marketplace setup, see [Build plugins](https://developers.openai.com/plugins/build/plugins#build-your-own-curated-plugin-list).

199 199 

200| Deep link | Opens |200| Deep link | Opens |

201| --------------------------------------------------------------------------- | ---------------------------------------------------- |201| --------------------------------------------------------------------------- | ---------------------------------------------------- |

auth.md +5 −0

Details

84Compare support by plan in84Compare support by plan in

85[Feature availability](https://learn.chatgpt.com/docs/pricing#feature-availability).85[Feature availability](https://learn.chatgpt.com/docs/pricing#feature-availability).

86 86 

87In Codex CLI and Codex in the ChatGPT desktop app, API key authentication

88includes access to supported OpenAI-curated plugins. Some plugins aren't

89available because their connection flows require unsupported OAuth

90capabilities. See [Use plugins](https://learn.chatgpt.com/docs/plugins#api-key-availability).

91 

87When you sign in with an API key, Codex uses standard API pricing instead of92When you sign in with an API key, Codex uses standard API pricing instead of

88included ChatGPT plan credits.93included ChatGPT plan credits.

89 94 

build-app.md +0 −81 deleted

File Deleted View Diff

1# Build an app

2 

3Apps are one part of the plugin model. A plugin is the package users discover,

4install, submit, and publish. An app is the MCP-backed capability inside that

5package.

6 

7The [Apps SDK](https://developers.openai.com/apps-sdk) is the ChatGPT app development framework for

8MCP-backed apps. It builds on MCP: your server exposes tools and returns

9structured data, and, when you need UI, Apps SDK conventions let you register

10MCP UI resources and connect them to those tools inside ChatGPT.

11 

12Build an app when your plugin needs to connect to a service, expose tools,

13authenticate users, or take action through an MCP server.

14 

15## App building model

16 

17An app can include:

18 

19- **An MCP server:** the server defines tools, handles authentication, returns

20 structured data, and enforces the integration's real behavior. See

21 [Build your MCP server](https://developers.openai.com/apps-sdk/build/mcp-server).

22- **Tool metadata and annotations:** required for reliable model behavior,

23 discovery, and review. Tool names, descriptions, schemas, `readOnlyHint`,

24 `openWorldHint`, and `destructiveHint` should match what the tool actually

25 does. See the [Apps SDK reference](https://developers.openai.com/apps-sdk/reference#tool-descriptor-parameters)

26 for the descriptor fields and annotation details.

27- **Optional MCP UI:** useful when users need to inspect, compare, edit,

28 confirm, or navigate structured information inside ChatGPT. If your app can

29 complete its job through tool calls and model responses, you do not need

30 custom UI. Build this with [Apps SDK](https://developers.openai.com/apps-sdk) UI resources when tool calls

31 and model responses are not enough.

32 

33## Build MCP-first

34 

35Define the app's capabilities before designing UI:

36 

371. Identify the user workflows the app should support.

382. [Define the MCP tools](https://developers.openai.com/apps-sdk/plan/tools) needed for those workflows.

393. Write clear tool names, descriptions, input schemas, and output schemas.

40 Use the [metadata optimization guide](https://developers.openai.com/apps-sdk/guides/optimize-metadata)

41 to improve discovery and model selection.

424. Mark every tool with accurate safety annotations, then review the

43 [security and privacy guidance](https://developers.openai.com/apps-sdk/guides/security-privacy) for write

44 actions, data handling, and network access.

455. Add [authentication](https://developers.openai.com/apps-sdk/build/auth) only for data or actions that

46 require it.

476. Test the app from ChatGPT developer mode before packaging it into a plugin.

48 

49## Add UI if it materially improves the app experience

50 

51The [Apps SDK quickstart](https://developers.openai.com/apps-sdk/quickstart) shows how to build a simple

52MCP-backed app with an optional UI component. The [Apps SDK](https://developers.openai.com/apps-sdk) helps

53you build [MCP UI](https://developers.openai.com/apps-sdk/mcp-apps-in-chatgpt) for an MCP-backed app. It is

54optional: use it when the app needs an embedded component, modal, fullscreen

55view, or other custom interaction in ChatGPT. See

56[Build your MCP UI](https://developers.openai.com/apps-sdk/build/chatgpt-ui) for UI-specific patterns.

57 

58Do not add UI just to show a banner ad or brand placement. The UI should

59materially improve the user's workflow by making the app easier to inspect,

60edit, compare, confirm, or navigate.

61 

62Even when you add UI, keep the tools decoupled from the rendering layer. Tools

63should still return useful structured data and model-readable results, while UI

64components focus on presentation and interaction. See

65[Separate data processing from UI rendering](https://developers.openai.com/apps-sdk/build/chatgpt-ui#separate-data-processing-from-ui-rendering).

66 

67## Package the app as a plugin

68 

69After the app works in developer mode, package it into a plugin so users can

70install it.

71 

721. Create or scaffold the plugin folder. See

73 [Build plugins](https://learn.chatgpt.com/docs/build-plugins#create-and-test-a-plugin-locally-that-points-to-an-mcp-server-backed-dev-mode-app).

742. Add the app reference to the plugin manifest.

753. Add bundled skills if ChatGPT should follow repeatable workflows alongside

76 the app.

774. Test the plugin locally.

785. Review the Apps SDK

79 [app guidelines](https://developers.openai.com/apps-sdk/app-guidelines), then

80 submit it for review as part of a plugin when it is ready for public

81 distribution. See [Submit plugins](https://learn.chatgpt.com/docs/submit-plugins).

build-plugins.md +78 −681

Details

1# Build plugins1# Build plugins

2 2 

3This page is for plugin authors. If you want to browse, install, and use3To build or submit a plugin, use the complete

4plugins with ChatGPT Work on the web or with ChatGPT Work or Codex in the4[builder documentation on developers.openai.com](https://developers.openai.com/plugins).

5ChatGPT desktop app, see [Plugins](https://learn.chatgpt.com/docs/plugins). If you are still iterating on

6one repo or one personal workflow, start with a local skill. Build a plugin when

7you want to share that workflow across teams, bundle connectors or MCP config,

8package lifecycle hooks, or publish a stable package.

9 5 

10A plugin can include skills, an MCP-backed app, or both. If your plugin needs6<div className="not-prose my-6">

11to connect to a service or expose tools through an MCP server, see7 <ButtonLink href="/plugins" color="primary" variant="solid" size="lg">

12[Build an app](https://learn.chatgpt.com/docs/build-app).8 Build and submit a plugin

9 </ButtonLink>

10</div>

11 

12This page provides a brief introduction. A plugin is an installable package

13that can include skills, an MCP server, or both. An MCP server can also return

14optional UI.

15 

16ChatGPT and Codex share one universal plugin directory. Publish a public plugin

17once to make the same listing discoverable from supported surfaces in both

18products. During development, use a local marketplace to test the package

19before submitting it to the universal directory.

13 20 

14For complete public examples, inspect21Start with a skill when you are still iterating on one personal workflow.

15[Figma](https://github.com/openai/plugins/tree/main/plugins/figma),22Build a plugin when you want to share that workflow, package related skills,

16[Notion](https://github.com/openai/plugins/tree/main/plugins/notion), and23connect to an external service, or distribute a stable capability to a team.

17[Build web apps](https://github.com/openai/plugins/tree/main/plugins/build-web-apps).

18 24 

19## Create a plugin with `@plugin-creator`25## Create a plugin with `@plugin-creator`

20 26 

21For the fastest setup, use the built-in `@plugin-creator` skill.27For the fastest setup, use the built-in `@plugin-creator` skill in ChatGPT Work

28mode or `$plugin-creator` in Codex.

22 29 

23<CodexScreenshot30<CodexScreenshot

24 alt="Plugin creator skill in ChatGPT"31 alt="Plugin creator skill in ChatGPT"


26 darkSrc="/images/codex/plugins/plugin-creator-dark.png"33 darkSrc="/images/codex/plugins/plugin-creator-dark.png"

27/>34/>

28 35 

29It scaffolds the required `.codex-plugin/plugin.json` manifest and can also36Describe the outcome, the skills or MCP server to include, and whether you want

30generate a local marketplace entry for testing. If you already have a plugin37a local marketplace entry for testing. For example:

31folder, you can still use `@plugin-creator` to wire it into a local

32marketplace.

33 

34<CodexScreenshot

35 alt="how to invoke the plugin-creator skill"

36 lightSrc="/images/codex/plugins/plugin-creator-invoke.png"

37 darkSrc="/images/codex/plugins/plugin-creator-invoke-dark.png"

38/>

39 

40### Create and test a plugin locally that points to an MCP-server-backed dev-mode app

41 

42You can also use the plugin-creator skill if you want to test a plugin locally

43that includes an MCP-server backed app. The plugin still needs a local plugin

44folder and manifest, but the app itself starts in ChatGPT developer mode.

45 

46First, enable developer mode in ChatGPT:

47 

481. Open [ChatGPT](https://chatgpt.com).

492. Open **Settings**.

503. Select **Security and login**.

514. Turn on **Developer mode**.

52 

53Then create the app in developer mode:

54 

551. Open **Settings → Plugins** or [the Plugins page](https://chatgpt.com/plugins).

562. Select the plus button.

573. Complete the modal to create a developer-mode app for your MCP server.

584. After ChatGPT creates it, copy the app ID from the browser URL. It starts

59 with `plugin_asdk_app`.

60 

61Give that `plugin_asdk_app...` ID to `@plugin-creator` in a ChatGPT Work chat

62or `$plugin-creator` in Codex. For example, with ChatGPT Work:

63 

64<div class="not-prose my-6 overflow-hidden rounded-xl border border-subtle bg-surface shadow-sm">

65 <div class="border-b border-subtle bg-surface-secondary px-4 py-3">

66 <span class="inline-flex rounded-md bg-purple-100 px-2.5 py-1 text-sm font-medium text-purple-700 dark:bg-purple-950/60 dark:text-purple-200">

67 Plugin Creator prompt

68 </span>

69 </div>

70 <div class="overflow-x-auto p-4 font-mono text-sm leading-6 text-primary">

71 <code class="whitespace-pre-wrap break-words">{`@plugin-creator create a Codex plugin for my ChatGPT app.

72Use plugin_asdk_app_6a4c0062f3b88191855c0a80eac5d53d and name it Acme Support.

73Include a personal marketplace entry so I can test it locally.`}</code>

74 </div>

75</div>

76 

77The plugin-creator skill will create the plugin folder, create the required

78`.codex-plugin/plugin.json`, and add app wiring for the ChatGPT app. If you ask

79it to create a personal marketplace entry, the plugin appears under your local

80source in the Plugins Directory for testing.

81 

82After the plugin-creator skill creates the plugin:

83 38 

841. Review `.app.json` and confirm it points at the correct39```text

85 `plugin_asdk_app...` ID.40@plugin-creator Create a plugin named meeting-follow-up.

862. Review `.codex-plugin/plugin.json` and make sure its `apps` field points to41Include a skill that turns meeting notes into decisions, owners, and next steps.

87 `./.app.json`.42Add it to a personal marketplace so I can test it locally.

883. Add any bundled skills under `skills/` if the plugin should include43```

89 repeatable workflows alongside the app.

904. If the skill created a personal marketplace entry, refresh ChatGPT

91 and install the plugin from your local source in the Plugins Directory. Then

92 test it in a new chat.

93 

94For the manifest shape and file layout, see [Plugin structure](#plugin-structure)

95and [Path rules](#path-rules).

96 

97### Build your own curated plugin list

98 

99A marketplace is a JSON catalog of plugins. `@plugin-creator` can generate one

100for a single plugin, and you can keep adding entries to that same marketplace

101to build your own curated list for a repo, team, or personal workflow.

102 

103In ChatGPT Work or Codex in the ChatGPT desktop app, each marketplace appears as a

104selectable source in the Plugins Directory. Use

105`$REPO_ROOT/.agents/plugins/marketplace.json` for a repo-scoped list or

106`~/.agents/plugins/marketplace.json` for a personal list. Add one entry per

107plugin under `plugins[]`, point each `source.path` at the plugin folder with a

108`./`-prefixed path relative to the marketplace root, and set

109`interface.displayName` to the label you want the app to show in the marketplace

110picker. Then restart the ChatGPT desktop app. After that, open the Plugins

111Directory, choose your marketplace, and browse or install the plugins in that

112curated list.

113 44 

114You don't need a separate marketplace per plugin. One marketplace can expose a45The skill creates the required `.codex-plugin/plugin.json` manifest, organizes

115single plugin while you are testing, then grow into a larger curated catalog as46the plugin folder, and can add the plugin to a local marketplace.

116you add more plugins.

117 47 

118<CodexScreenshot48<CodexScreenshot

119 alt="custom local marketplace in the Plugins Directory"49 alt="Invoking the plugin creator skill"

120 lightSrc="/images/codex/plugins/codex-local-plugin-light.png"50 lightSrc="/images/codex/plugins/plugin-creator-invoke.png"

121 darkSrc="/images/codex/plugins/codex-local-plugin.png"51 darkSrc="/images/codex/plugins/plugin-creator-invoke-dark.png"

122/>52/>

123 53 

124### Add a marketplace from the CLI54After it finishes:

125 55 

126Use `codex plugin marketplace add` to add and track a marketplace source instead561. Review `.codex-plugin/plugin.json`.

127of editing `config.toml` by hand. These commands support plugin authoring and572. Check each bundled skill under `skills/`.

128catalog setup. Use the ChatGPT desktop app to install and test a local plugin.583. Refresh ChatGPT or Codex and install the plugin from its local marketplace

59 source.

604. Test the plugin in a new conversation with representative requests.

129 61 

130```bash62If the plugin includes an MCP server, first build and test that server, then

131codex plugin marketplace add owner/repo63give `@plugin-creator` the registered connection details. Follow the complete

132codex plugin marketplace add owner/repo --ref main64[MCP server workflow](https://developers.openai.com/plugins/build/mcp-server)

133codex plugin marketplace add https://github.com/example/plugins.git --sparse .agents/plugins65for tools, authentication, deployment, and testing.

134codex plugin marketplace add ./local-marketplace-root

135```

136 66 

137Marketplace sources can be GitHub shorthand (`owner/repo` or67## Create a skills-only plugin manually

138`owner/repo@ref`), HTTP or HTTPS Git URLs, SSH Git URLs, or local marketplace root

139directories. Use `--ref` to pin a Git ref, and repeat `--sparse PATH` to use a

140sparse checkout for Git-backed marketplace repos. `--sparse` is valid only for

141Git marketplace sources.

142 68 

143To inspect, refresh, or remove configured marketplaces:69A minimal plugin contains a manifest and at least one skill:

144 70 

145```bash71```text

146codex plugin marketplace list72meeting-follow-up/

147codex plugin marketplace upgrade73├── .codex-plugin/

148codex plugin marketplace upgrade marketplace-name74│ └── plugin.json

149codex plugin marketplace remove marketplace-name75└── skills/

76 └── meeting-follow-up/

77 └── SKILL.md

150```78```

151 79 

152`codex plugin marketplace list` prints each marketplace Codex is considering80Create `.codex-plugin/plugin.json`:

153and the root path it resolves from, including local default marketplaces and

154configured marketplace snapshots.

155 

156### Create a plugin manually

157 

158Start with a minimal plugin that packages one skill.

159 

1601. Create a plugin folder with a manifest at `.codex-plugin/plugin.json`.

161 

162```bash

163mkdir -p my-first-plugin/.codex-plugin

164```

165 

166`my-first-plugin/.codex-plugin/plugin.json`

167 81 

168```json82```json

169{83{

170 "name": "my-first-plugin",84 "name": "meeting-follow-up",

171 "version": "1.0.0",85 "version": "1.0.0",

172 "description": "Reusable greeting workflow",86 "description": "Turn meeting notes into decisions and next steps",

173 "skills": "./skills/"87 "skills": "./skills/"

174}88}

175```89```

176 90 

177Use a stable plugin `name` in kebab-case. Codex uses it as the plugin91Then add `skills/meeting-follow-up/SKILL.md`:

178identifier and component namespace.

179 

1802. Add a skill under `skills/<skill-name>/SKILL.md`.

181 

182```bash

183mkdir -p my-first-plugin/skills/hello

184```

185 

186`my-first-plugin/skills/hello/SKILL.md`

187 92 

188```md93```md

189---94---

190name: hello95name: meeting-follow-up

191description: Greet the user with a friendly message.96description: Extract decisions, owners, and next steps from meeting notes.

192---97---

193 98 

194Greet the user warmly and ask how you can help.99Review the meeting notes. Return:

195```

196 

1973. Add the plugin to a marketplace. Use `@plugin-creator` to generate one, or

198 follow [Build your own curated plugin list](#build-your-own-curated-plugin-list)

199 to wire the plugin into Codex manually.

200 

201From there, you can add MCP config, connectors, or marketplace metadata

202as needed.

203 

204### Install a local plugin manually

205 

206Use a repo marketplace or a personal marketplace, depending on who should be

207able to access the plugin or curated list.

208 

209<Tabs

210 id="codex-plugins-local-install"

211 param="install-scope"

212 defaultTab="workspace"

213 tabs={[

214 {

215 id: "workspace",

216 label: "Repo",

217 },

218 {

219 id: "global",

220 label: "Personal",

221 },

222 ]}

223>

224 <div slot="workspace">

225 Add a marketplace file at `$REPO_ROOT/.agents/plugins/marketplace.json`

226 and store your plugins under `$REPO_ROOT/plugins/`.

227 

228 **Repo marketplace example**

229 

230 Step 1: Copy the plugin folder into `$REPO_ROOT/plugins/my-plugin`.

231 

232```bash

233mkdir -p ./plugins

234cp -R /absolute/path/to/my-plugin ./plugins/my-plugin

235```

236 

237 Step 2: Add or update `$REPO_ROOT/.agents/plugins/marketplace.json` so

238 that `source.path` points to that plugin directory with a `./`-prefixed

239 relative path:

240 

241```json

242{

243 "name": "local-repo",

244 "plugins": [

245 {

246 "name": "my-plugin",

247 "source": {

248 "source": "local",

249 "path": "./plugins/my-plugin"

250 },

251 "policy": {

252 "installation": "AVAILABLE",

253 "authentication": "ON_INSTALL"

254 },

255 "category": "Productivity"

256 }

257 ]

258}

259```

260 

261 Step 3: Restart the ChatGPT desktop app and verify that the plugin appears.

262 

263 </div>

264 

265 <div slot="global">

266 Add a marketplace file at `~/.agents/plugins/marketplace.json` and store

267 your plugins under `~/.codex/plugins/`.

268 

269 **Personal marketplace example**

270 

271 Step 1: Copy the plugin folder into `~/.codex/plugins/my-plugin`.

272 

273```bash

274mkdir -p ~/.codex/plugins

275cp -R /absolute/path/to/my-plugin ~/.codex/plugins/my-plugin

276```

277 

278 Step 2: Add or update `~/.agents/plugins/marketplace.json` so that the

279 plugin entry's `source.path` points to that directory.

280 

281 Step 3: Restart the ChatGPT desktop app and verify that the plugin appears.

282 

283 </div>

284</Tabs>

285 

286The marketplace file points to the plugin location, so those directories are

287examples rather than fixed requirements. Codex resolves `source.path` relative

288to the marketplace root, not relative to the `.agents/plugins/` folder. See

289[Marketplace metadata](#marketplace-metadata) for the file format.

290 

291After you change the plugin, update the plugin directory that your marketplace

292entry points to and restart the ChatGPT desktop app so the local install picks

293up the new files.

294 

295### Share a local plugin with your workspace

296 

297After you create a plugin, add it from the ChatGPT desktop app. Select ChatGPT

298and switch to Work in the switcher, or select Codex, then open **Plugins**. You can then

299share it with other members of your ChatGPT workspace.

300 

3011. Open **Plugins** in the ChatGPT desktop app.

3022. Go to **Created by you** and open the plugin details page.

3033. Select **Share**.

3044. Add workspace members or workspace groups, or copy a share link.

3055. Choose who has access, then send the invitation or link.

306 

307People you share with can find the plugin under **Shared with you** in the

308Plugins Directory. Sharing a local plugin with your workspace doesn't publish

309it to the public Plugins Directory. Shared plugins stay within your workspace

310and organization boundary; accounts that aren't signed in to that workspace

311can't access them. Use groups when a team or role should share the same plugin

312access. Use a marketplace when you want repo or CLI distribution, and use

313workspace sharing when you want selected teammates to install a plugin from the

314ChatGPT desktop app.

315 

316Workspace admins can disable plugin sharing from cloud-managed requirements by

317adding `features.plugin_sharing = false` to `requirements.toml`:

318 

319```toml

320features.plugin_sharing = false

321```

322 

323### Marketplace metadata

324 

325If you maintain a repo marketplace, define it in

326`$REPO_ROOT/.agents/plugins/marketplace.json`. For a personal marketplace, use

327`~/.agents/plugins/marketplace.json`. A marketplace file controls plugin

328ordering and install policies in the ChatGPT desktop app. It can represent one

329plugin while you are testing or a curated list of plugins that you want the app

330to show together under one marketplace name. Before you add a plugin to a

331marketplace, make sure its `version`, publisher metadata, and install-surface

332copy are ready for other developers to see.

333 

334```json

335{

336 "name": "local-example-plugins",

337 "interface": {

338 "displayName": "Local Example Plugins"

339 },

340 "plugins": [

341 {

342 "name": "my-plugin",

343 "source": {

344 "source": "local",

345 "path": "./plugins/my-plugin"

346 },

347 "policy": {

348 "installation": "AVAILABLE",

349 "authentication": "ON_INSTALL"

350 },

351 "category": "Productivity"

352 },

353 {

354 "name": "research-helper",

355 "source": {

356 "source": "local",

357 "path": "./plugins/research-helper"

358 },

359 "policy": {

360 "installation": "AVAILABLE",

361 "authentication": "ON_INSTALL"

362 },

363 "category": "Productivity"

364 }

365 ]

366}

367```

368 

369- Use top-level `name` to identify the marketplace.

370- Use `interface.displayName` for the marketplace title shown in the ChatGPT

371 desktop app.

372- Add one object per plugin under `plugins` to build a curated list that the app

373 shows under that marketplace title.

374- Point each plugin entry's `source.path` at the plugin directory you want

375 Codex to load. For repo installs, that often lives under `./plugins/`. For

376 personal installs, a common pattern is `./.codex/plugins/<plugin-name>`.

377- Keep `source.path` relative to the marketplace root, start it with `./`, and

378 keep it inside that root.

379- For local entries, `source` can also be a plain string path such as

380 `"./plugins/my-plugin"`.

381- Always include `policy.installation`, `policy.authentication`, and

382 `category` on each plugin entry.

383- Use `policy.installation` values such as `AVAILABLE`,

384 `INSTALLED_BY_DEFAULT`, or `NOT_AVAILABLE`.

385- Use `policy.authentication` to decide whether auth happens on install or

386 first use.

387 

388The marketplace controls where Codex loads the plugin from. A local

389`source.path` can point somewhere else if your plugin lives outside those

390example directories. A marketplace file can live in the repo where you are

391developing the plugin or in a separate marketplace repo, and one marketplace

392file can point to one plugin or many.

393 

394Marketplace entries can also point at Git-backed plugin sources. Use

395`"source": "url"` when the plugin lives at the repository root, or

396`"source": "git-subdir"` when the plugin lives in a subdirectory:

397 

398```json

399{

400 "name": "remote-helper",

401 "source": {

402 "source": "git-subdir",

403 "url": "https://github.com/example/codex-plugins.git",

404 "path": "./plugins/remote-helper",

405 "ref": "main"

406 },

407 "policy": {

408 "installation": "AVAILABLE",

409 "authentication": "ON_INSTALL"

410 },

411 "category": "Productivity"

412}

413```

414 

415Git-backed entries may use `ref` or `sha` selectors. If Codex can't resolve a

416marketplace entry's source, it skips that plugin entry instead of failing the

417whole marketplace.

418 

419Marketplace entries can also install a plugin from a JavaScript package registry:

420 

421```json

422{

423 "name": "npm-helper",

424 "source": {

425 "source": "npm",

426 "package": "@example/codex-plugin",

427 "version": "^1.2.0",

428 "registry": "https://registry.npmjs.org"

429 },

430 "policy": {

431 "installation": "AVAILABLE",

432 "authentication": "ON_INSTALL"

433 },

434 "category": "Productivity"

435}

436```

437 

438`package` is required and can include a registry scope. `version` is optional

439and accepts package versions, distribution tags, and version ranges, but not

440path or URL selectors.

441`registry` is optional and must be an HTTPS URL without embedded credentials,

442a query, or a fragment. Codex downloads the package without running lifecycle

443scripts. The `npm` CLI must be installed, and registry authentication comes

444from its configuration.

445 

446### How the ChatGPT desktop app uses marketplaces

447 

448A plugin marketplace is a JSON catalog of plugins that the ChatGPT desktop app

449can read and install.

450 

451The app can read marketplace files from:

452 

453- the curated marketplace that powers the official Plugins Directory

454- a repo marketplace at `$REPO_ROOT/.agents/plugins/marketplace.json`

455- a legacy-compatible marketplace at `$REPO_ROOT/.claude-plugin/marketplace.json`

456- a personal marketplace at `~/.agents/plugins/marketplace.json`

457 

458You can install any plugin exposed through a marketplace. The app installs

459plugins into

460`~/.codex/plugins/cache/$MARKETPLACE_NAME/$PLUGIN_NAME/$VERSION/`. For local

461plugins, `$VERSION` is `local`, and the app loads the installed copy from that

462cache path rather than directly from the marketplace entry.

463 

464You can enable or disable each plugin individually. The app stores each plugin's

465on or off state in `~/.codex/config.toml`.

466 

467## Package and distribute plugins

468 

469### Plugin structure

470 

471Every plugin has a manifest at `.codex-plugin/plugin.json`. It can also include

472a `skills/` directory, a `hooks/` directory for lifecycle hooks, an `.app.json`

473file that points at one or more connectors, an `.mcp.json` file that

474configures MCP servers, and assets used to present the plugin across supported

475surfaces.

476 

477<FileTree

478 class="mt-4"

479 tree={[

480 {

481 name: "my-plugin/",

482 open: true,

483 children: [

484 {

485 name: ".codex-plugin/",

486 open: true,

487 children: [

488 {

489 name: "plugin.json",

490 comment: "Required: plugin manifest",

491 },

492 ],

493 },

494 {

495 name: "skills/",

496 open: true,

497 children: [

498 {

499 name: "my-skill/",

500 open: true,

501 children: [

502 {

503 name: "SKILL.md",

504 comment: "Optional: skill instructions",

505 },

506 ],

507 },

508 ],

509 },

510 {

511 name: "hooks/",

512 open: true,

513 children: [

514 {

515 name: "hooks.json",

516 comment: "Optional: lifecycle hooks",

517 },

518 ],

519 },

520 {

521 name: ".app.json",

522 comment: "Optional: app or connector mappings",

523 },

524 {

525 name: ".mcp.json",

526 comment: "Optional: MCP server configuration",

527 },

528 {

529 name: "assets/",

530 comment: "Optional: icons, logos, screenshots",

531 },

532 ],

533 },

534 ]}

535/>

536 

537Only `plugin.json` belongs in `.codex-plugin/`. Keep `skills/`, `hooks/`,

538`assets/`, `.mcp.json`, and `.app.json` at the plugin root.

539 

540Published plugins typically use a richer manifest than the minimal example that

541appears in quick-start scaffolds. The manifest has three jobs:

542 

543- Identify the plugin.

544- Point to bundled components such as skills, connectors, MCP servers, or hooks.

545- Provide install-surface metadata such as descriptions, icons, and legal

546 links.

547 

548Here's a complete manifest example:

549 

550```json

551{

552 "name": "my-plugin",

553 "version": "0.1.0",

554 "description": "Bundle reusable skills and connectors.",

555 "author": {

556 "name": "Your team",

557 "email": "team@example.com",

558 "url": "https://example.com"

559 },

560 "homepage": "https://example.com/plugins/my-plugin",

561 "repository": "https://github.com/example/my-plugin",

562 "license": "MIT",

563 "keywords": ["research", "crm"],

564 "skills": "./skills/",

565 "mcpServers": "./.mcp.json",

566 "apps": "./.app.json",

567 "hooks": "./hooks/hooks.json",

568 "interface": {

569 "displayName": "My Plugin",

570 "shortDescription": "Reusable skills and connectors",

571 "longDescription": "Distribute skills and connectors together.",

572 "developerName": "Your team",

573 "category": "Productivity",

574 "capabilities": ["Read", "Write"],

575 "websiteURL": "https://example.com",

576 "privacyPolicyURL": "https://example.com/privacy",

577 "termsOfServiceURL": "https://example.com/terms",

578 "defaultPrompt": [

579 "Use My Plugin to summarize new CRM notes.",

580 "Use My Plugin to triage new customer follow-ups."

581 ],

582 "brandColor": "#10A37F",

583 "composerIcon": "./assets/icon.png",

584 "logo": "./assets/logo.png",

585 "screenshots": ["./assets/screenshot-1.png"]

586 }

587}

588```

589 

590`.codex-plugin/plugin.json` is the required entry point. The other manifest

591fields are optional, but published plugins commonly use them.

592 

593### Manifest fields

594 

595Use the top-level fields to define package metadata and point to bundled

596components:

597 

598- `name`, `version`, and `description` identify the plugin.

599- `author`, `homepage`, `repository`, `license`, and `keywords` provide

600 publisher and discovery metadata.

601- `skills`, `mcpServers`, `apps`, and `hooks` point to bundled components

602 relative to the plugin root.

603- `interface` controls how install surfaces present the plugin.

604 

605Use the `interface` object for install-surface metadata:

606 

607- `displayName`, `shortDescription`, and `longDescription` control the title

608 and descriptive copy.

609- `developerName`, `category`, and `capabilities` add publisher and capability

610 metadata.

611- `websiteURL`, `privacyPolicyURL`, and `termsOfServiceURL` provide external

612 links.

613- `defaultPrompt`, `brandColor`, `composerIcon`, `logo`, and `screenshots`

614 control starter prompts and visual presentation.

615 

616### Path rules

617 

618- Keep manifest paths relative to the plugin root and start them with `./`.

619- Store visual assets such as `composerIcon`, `logo`, and `screenshots` under

620 `./assets/` when possible.

621- Use `skills` for bundled skill folders, `apps` for `.app.json`,

622 `mcpServers` for `.mcp.json`, and `hooks` for lifecycle hooks.

623- Enabled plugins can include lifecycle hooks alongside skills, MCP servers, and

624 connectors.

625- If your plugin stores hooks at `./hooks/hooks.json`, you don't need a

626 `hooks` entry in `.codex-plugin/plugin.json`; Codex checks that default file

627 automatically.

628 

629### Bundled MCP servers and lifecycle hooks

630 

631`mcpServers` can point to an `.mcp.json` file that contains either a direct

632server map or a wrapped `mcp_servers` object.

633 

634Direct server map:

635 

636```json

637{

638 "docs": {

639 "command": "docs-mcp",

640 "args": ["--stdio"]

641 }

642}

643```

644 

645Wrapped server map:

646 

647```json

648{

649 "mcp_servers": {

650 "docs": {

651 "command": "docs-mcp",

652 "args": ["--stdio"]

653 }

654 }

655}

656```

657 

658After installation, users can enable or disable a bundled MCP server and tune

659tool approval policy from their Codex config without editing the plugin. Use

660`plugins.<plugin>.mcp_servers.<server>` for plugin-scoped MCP server policy:

661 100 

662```toml1011. Decisions

663[plugins."my-plugin".mcp_servers.docs]1022. Action items with owners

664enabled = true1033. Open questions

665default_tools_approval_mode = "prompt"

666enabled_tools = ["search"]

667 

668[plugins."my-plugin".mcp_servers.docs.tools.search]

669approval_mode = "approve"

670```104```

671 105 

672When your plugin is enabled, Codex can load lifecycle hooks from your plugin106Use a stable plugin name in kebab case. Keep the skill description specific

673alongside user, project, and managed hooks.107enough for ChatGPT and Codex to recognize when the workflow applies.

674 

675Installing or enabling a plugin doesn't automatically trust its hooks.

676Plugin-bundled hooks are non-managed hooks, so Codex skips them until the user

677reviews and trusts the current hook definition.

678 

679The default plugin hook file is `hooks/hooks.json`:

680 

681```json

682{

683 "hooks": {

684 "SessionStart": [

685 {

686 "hooks": [

687 {

688 "type": "command",

689 "command": "python3 ${PLUGIN_ROOT}/hooks/session_start.py",

690 "statusMessage": "Loading plugin context"

691 }

692 ]

693 }

694 ]

695 }

696}

697```

698 

699If you define `hooks` in `.codex-plugin/plugin.json`, Codex uses that manifest

700entry instead of the default `hooks/hooks.json`. The manifest field can be a

701single path, an array of paths, an inline hooks object, or an array of inline

702hooks objects.

703 

704```json

705{

706 "name": "repo-policy",

707 "hooks": ["./hooks/session.json", "./hooks/tools.json"]

708}

709```

710 108 

711Hook paths follow the same manifest path rules as `skills`, `apps`, and109Use `@plugin-creator` to add the folder to a local marketplace, then install and

712`mcpServers`: start with `./`, resolve relative to the plugin root, and stay110test it before sharing it.

713inside the plugin root.

714 111 

715Plugin hook commands receive the Codex-specific environment variables112## Continue with the builder documentation

716`PLUGIN_ROOT` and `PLUGIN_DATA`. `PLUGIN_ROOT` points to the installed plugin

717root, and `PLUGIN_DATA` points to the plugin's writable data directory. Codex

718also sets `CLAUDE_PLUGIN_ROOT` and `CLAUDE_PLUGIN_DATA` for compatibility with

719existing plugin hooks.

720 113 

721Plugin hooks use the same event schema as regular hooks. See114For complete builder documentation, use the

722[Hooks](https://learn.chatgpt.com/docs/hooks) for supported events, inputs, outputs, trust review, and115[Plugins documentation](https://developers.openai.com/plugins/). It covers:

723current limitations.

724 116 

725### Publish official public plugins117- [Plugin architecture](https://developers.openai.com/plugins/concepts/plugins)

118- [Building skills](https://developers.openai.com/plugins/build/skills)

119- [Building an MCP server](https://developers.openai.com/plugins/build/mcp-server)

120- [Adding optional UI](https://developers.openai.com/plugins/build/chatgpt-ui)

121- [Packaging a plugin](https://developers.openai.com/plugins/build/plugins)

122- [Testing a plugin](https://developers.openai.com/plugins/deploy/connect-chatgpt)

123- [Submitting and publishing](https://developers.openai.com/plugins/deploy/submission)

726 124 

727To publish a plugin for public use, submit it through the plugin submission125To browse, install, enable, or remove plugins, see [Use

728portal. See [Submit plugins](https://learn.chatgpt.com/docs/submit-plugins) for the full review and126plugins](https://learn.chatgpt.com/docs/plugins).

729publishing process.

build-skills.md +52 −24

Details

1# Build skills1# Build skills

2 2 

3Use agent skills to extend Codex with task-specific capabilities. A skill packages instructions, resources, and optional scripts so Codex can follow a workflow reliably. Skills build on the [open agent skills standard](https://agentskills.io).3Use agent skills to extend ChatGPT and Codex with task-specific capabilities. A

4 4skill packages instructions, resources, and optional scripts so either product

5Skills are the authoring format for reusable workflows. Plugins distribute reusable skills and connectors to ChatGPT Work on the web and to ChatGPT Work and Codex in the desktop app. Codex CLI can also install plugins. Use skills to design the workflow itself, then package it as a [plugin](https://learn.chatgpt.com/docs/build-plugins) when you want other people in your workspace to install it.5can follow a workflow reliably. Skills build on the

6 6[open agent skills standard](https://agentskills.io).

7Skills are available in the ChatGPT desktop app, Codex CLI, and IDE extension.7 

8Skills are the authoring format for reusable workflows. Plugins distribute

9reusable skills and connectors through the universal plugin directory shared

10by ChatGPT and Codex. Plugins are available with ChatGPT Work on the web, with

11ChatGPT Work and Codex in the ChatGPT desktop app, and through Codex CLI. Use

12skills to design the workflow itself, then package it as a

13[plugin](https://developers.openai.com/plugins/build/plugins) when you want

14other people to install it.

15 

16Standalone skills are available in the ChatGPT desktop app, Codex CLI, and IDE

17extension. Skills bundled in plugins are also available through supported

18plugin surfaces, including ChatGPT Work on the web.

8 19 

9In the ChatGPT desktop app, open **Skills** in the sidebar to view and explore skills20In the ChatGPT desktop app, open **Skills** in the sidebar to view and explore skills

10created across your projects.21created across your projects.


17 class="my-8"28 class="my-8"

18/>29/>

19 30 

20Skills use **progressive disclosure** to manage context efficiently: Codex starts with each skill's name, description, and file path. Codex loads the full `SKILL.md` instructions only when it decides to use a skill.31Skills use **progressive disclosure** to manage context efficiently. ChatGPT and

32Codex start with each skill's name and description, then load the full

33`SKILL.md` instructions when they decide to use that skill.

21 34 

22Codex includes an initial list of available skills in context so it can choose the right skill for a task. To avoid crowding out the rest of the prompt, this list uses at most 2% of the model’s context window, or 8,000 characters when the context window is unknown. If many skills are installed, Codex shortens skill descriptions first. For large skill sets, Codex may omit some skills from the initial list and show a warning.35In Codex, the initial list also includes each skill's file path. To avoid

36crowding out the rest of the prompt, this list uses at most 2% of the model's

37context window, or 8,000 characters when the context window is unknown. If many

38skills are installed, Codex shortens skill descriptions first. For large skill

39sets, Codex may omit some skills from the initial list and show a warning.

23 40 

24This budget applies only to the initial skills list. When Codex selects a skill, it still reads the full SKILL.md instructions for that skill.41This budget applies only to the initial skills list. When Codex selects a skill, it still reads the full SKILL.md instructions for that skill.

25 42 


64]}81]}

65/>82/>

66 83 

67## How Codex uses skills84<a id="how-codex-uses-skills"></a>

68 85 

69Codex can activate skills in two ways:86## How ChatGPT and Codex use skills

70 87 

711. **Explicit invocation:** Include the skill directly in your prompt. In CLI/IDE, run `/skills` or type `$` to mention a skill.88ChatGPT and Codex can activate skills in two ways:

722. **Implicit invocation:** Codex can choose a skill when your task matches the skill `description`.

73 89 

74Because implicit matching depends on `description`, write concise descriptions with clear scope and boundaries. Front-load the key use case and trigger words so Codex can still match the skill if descriptions are shortened.901. **Explicit invocation:** Include the skill directly in your prompt. In

91 ChatGPT, type `@` to select a skill. In Codex CLI or the IDE extension, run

92 `/skills` or type `$` to mention a skill.

932. **Implicit invocation:** ChatGPT or Codex can choose a skill when your task

94 matches the skill `description`.

95 

96Because implicit matching depends on `description`, write concise descriptions

97with clear scope and boundaries. Front-load the key use case and trigger words

98so a host can still match the skill if descriptions are shortened.

75 99 

76## Create a skill100## Create a skill

77 101 

78If you already know the workflow and it's easier to show than describe, use102If you already know the workflow and it's easier to show than describe, use

79[Record & Replay](https://learn.chatgpt.com/docs/extend/record-and-replay). Codex records the workflow,103[Record & Replay](https://learn.chatgpt.com/docs/extend/record-and-replay). The recorder captures the

80inspects the steps, and drafts a reusable skill from the demonstration.104workflow, inspects the steps, and drafts a reusable skill from the

105demonstration.

81 106 

82If you want to describe the skill instead, use the built-in creator:107If you want to describe the skill instead, use the built-in creator. In ChatGPT

108Work, invoke it as `@skill-creator`. In Codex, invoke it as:

83 109 

84```text110```text

85$skill-creator111$skill-creator


95description: Explain exactly when this skill should and should not trigger.121description: Explain exactly when this skill should and should not trigger.

96---122---

97 123 

98Skill instructions for Codex to follow.124Skill instructions for ChatGPT or Codex to follow.

99```125```

100 126 

101Codex detects skill changes automatically. If an update doesn't appear, restart Codex.127Codex detects skill changes automatically. If an update doesn't appear, restart Codex.

102 128 

103## Where to save skills129<a id="where-to-save-skills"></a>

130 

131## Where Codex loads local skills

104 132 

105Codex reads skills from repository, user, admin, and system locations. For repositories, Codex scans `.agents/skills` in every directory from your current working directory up to the repository root. If two skills share the same `name`, Codex doesn't merge them; both can appear in skill selectors.133Codex reads skills from repository, user, admin, and system locations. For repositories, Codex scans `.agents/skills` in every directory from your current working directory up to the repository root. If two skills share the same `name`, Codex doesn't merge them; both can appear in skill selectors.

106 134 


117 145 

118These locations are for authoring and local discovery. When you want to146These locations are for authoring and local discovery. When you want to

119distribute reusable skills beyond a single repo, or optionally bundle them with147distribute reusable skills beyond a single repo, or optionally bundle them with

120connectors, use [plugins](https://learn.chatgpt.com/docs/build-plugins).148connectors, use [plugins](https://developers.openai.com/plugins/build/plugins).

121 149 

122## Distribute skills with plugins150## Distribute skills with plugins

123 151 

124Direct skill folders are best for local authoring and repo-scoped workflows. If152Direct skill folders are best for local authoring and repo-scoped workflows. If

125you want to distribute a reusable skill, bundle two or more skills together, or153you want to distribute a reusable skill, bundle two or more skills together, or

126ship a skill alongside a connector, package them as a154ship a skill alongside a connector, package them as a

127[plugin](https://learn.chatgpt.com/docs/build-plugins).155[plugin](https://developers.openai.com/plugins/build/plugins).

128 156 

129Plugins can include one or more skills. They can also optionally bundle app157Plugins can include one or more skills. They can also optionally bundle

130mappings, MCP server configuration, and presentation assets in a single158registered MCP server connections, bundled MCP server configuration, and

131package.159presentation assets in a single package.

132 160 

133## Install curated skills for local use161## Install curated skills for local use

134 162 


145Use this for local setup and experimentation. For reusable distribution of your173Use this for local setup and experimentation. For reusable distribution of your

146own skills, prefer plugins.174own skills, prefer plugins.

147 175 

148## Enable or disable skills176## Enable or disable local Codex skills

149 177 

150Use `[[skills.config]]` entries in `~/.codex/config.toml` to disable a skill without deleting it:178Use `[[skills.config]]` entries in `~/.codex/config.toml` to disable a skill without deleting it:

151 179 


197[Linear](https://github.com/openai/skills/tree/main/skills/.curated/linear),225[Linear](https://github.com/openai/skills/tree/main/skills/.curated/linear),

198[openai/skills](https://github.com/openai/skills), and the226[openai/skills](https://github.com/openai/skills), and the

199[agent skills specification](https://agentskills.io/specification). For227[agent skills specification](https://agentskills.io/specification). For

200installable distribution, prefer [plugins](https://learn.chatgpt.com/docs/build-plugins).228installable distribution, prefer [plugins](https://developers.openai.com/plugins/build/plugins).

Details

118 118 

119Skills can be global (in your user directory, for you as a developer) or repo-specific (checked into `.agents/skills`, for your team). Put repo skills in `.agents/skills` when the workflow applies to that project; use your user directory for skills you want across all repos.119Skills can be global (in your user directory, for you as a developer) or repo-specific (checked into `.agents/skills`, for your team). Put repo skills in `.agents/skills` when the workflow applies to that project; use your user directory for skills you want across all repos.

120 120 

121| Layer | Global | Repo |121| Layer | Global | repo |

122| :----- | :------------------- | :--------------------------------------------- |122| :----- | :------------------- | :--------------------------------------------- |

123| AGENTS | `~/.codex/AGENTS.md` | `AGENTS.md` in repo root or nested directories |123| AGENTS | `~/.codex/AGENTS.md` | `AGENTS.md` in repo root or nested directories |

124| Skills | `~/.agents/skills` | `.agents/skills` in repo |124| Skills | `~/.agents/skills` | `.agents/skills` in repo |

Details

118 {118 {

119 title: "Record & Replay",119 title: "Record & Replay",

120 description:120 description:

121 "Show ChatGPT a workflow and turn it into a reusable skill.",121 "Show ChatGPT or Codex a workflow and turn it into a reusable skill.",

122 href: "/codex/extend/record-and-replay",122 href: "/codex/extend/record-and-replay",

123 icon: "tools",123 icon: "tools",

124 },124 },

Details

118 118 

119Skills can be global (in your user directory, for you as a developer) or repo-specific (checked into `.agents/skills`, for your team). Put repo skills in `.agents/skills` when the workflow applies to that project; use your user directory for skills you want across all repos.119Skills can be global (in your user directory, for you as a developer) or repo-specific (checked into `.agents/skills`, for your team). Put repo skills in `.agents/skills` when the workflow applies to that project; use your user directory for skills you want across all repos.

120 120 

121| Layer | Global | Repo |121| Layer | Global | repo |

122| :----- | :------------------- | :--------------------------------------------- |122| :----- | :------------------- | :--------------------------------------------- |

123| AGENTS | `~/.codex/AGENTS.md` | `AGENTS.md` in repo root or nested directories |123| AGENTS | `~/.codex/AGENTS.md` | `AGENTS.md` in repo root or nested directories |

124| Skills | `~/.agents/skills` | `.agents/skills` in repo |124| Skills | `~/.agents/skills` | `.agents/skills` in repo |

developers.md +2 −20

Details

41 {41 {

42 title: "Build skills",42 title: "Build skills",

43 description:43 description:

44 "Package instructions and resources for repeatable tasks.",44 "Package instructions and resources for repeatable tasks in ChatGPT and Codex.",

45 href: "/codex/build-skills",45 href: "/codex/build-skills",

46 icon: "tools",46 icon: "tools",

47 },47 },

48 {48 {

49 title: "Build plugins",49 title: "Build plugins",

50 description: "Create and distribute plugins for ChatGPT and Codex.",50 description: "Package skills and MCP servers for ChatGPT and Codex.",

51 href: "/codex/build-plugins",51 href: "/codex/build-plugins",

52 icon: "plugin",

53 },

54 {

55 title: "Build an app",

56 description: "Build the MCP-backed app portion of a plugin.",

57 href: "/codex/build-app",

58 icon: "connect",52 icon: "connect",

59 },53 },

60 {

61 title: "Submit plugins",

62 description: "Submit plugins for review and public publishing.",

63 href: "/codex/submit-plugins",

64 icon: "plugin",

65 },

66 {54 {

67 title: "Hooks",55 title: "Hooks",

68 description: "Run custom commands when Codex emits lifecycle events.",56 description: "Run custom commands when Codex emits lifecycle events.",


192 href: "/codex/developer-settings?surface=app",180 href: "/codex/developer-settings?surface=app",

193 icon: "settings",181 icon: "settings",

194 },182 },

195 {

196 title: "Plugin submission errors",

197 description: "Find and fix plugin package and submission errors.",

198 href: "/codex/plugin-submission-errors",

199 icon: "plugin",

200 },

201 ],183 ],

202 },184 },

203 ]}185 ]}

Details

1673. Test it with non-sensitive data and the least access it needs.1673. Test it with non-sensitive data and the least access it needs.

1684. Record who owns re-review and retirement.1684. Record who owns re-review and retirement.

169 169 

170Plugins are available with ChatGPT Work on the web, and with ChatGPT Work and Codex170Plugins are available with ChatGPT Work on the web, with ChatGPT Work and Codex

171in the ChatGPT desktop app, and through the Codex CLI plugin browser. They aren't171in the ChatGPT desktop app, and through the Codex CLI plugin browser. They

172available in Chat, the IDE extension, or mobile.172aren't available in Chat, the IDE extension, or mobile.

173ChatGPT and Codex share one universal public plugin directory; workspace

174controls determine which of those plugins members can access.

173 175 

174See [Plugin controls](https://learn.chatgpt.com/docs/enterprise/apps-and-connectors) and176See [Plugin controls](https://learn.chatgpt.com/docs/enterprise/apps-and-connectors) and

175[Skill controls](https://learn.chatgpt.com/docs/enterprise/skills) for the complete model.177[Skill controls](https://learn.chatgpt.com/docs/enterprise/skills) for the complete model.

Details

1# Plugin controls1# Plugin controls

2 2 

3A plugin extends Codex by packaging skills and optional connectors so teams can3A plugin extends ChatGPT and Codex by packaging skills and optional connectors

4distribute workflows and knowledge. Learn more about [plugins](https://learn.chatgpt.com/docs/plugins),4so teams can distribute workflows and knowledge. The products share one

5universal plugin directory, while admins control availability and installation

6for their workspace. Learn more about [plugins](https://learn.chatgpt.com/docs/plugins),

5[skills](https://learn.chatgpt.com/docs/skills-and-plugins), and7[skills](https://learn.chatgpt.com/docs/skills-and-plugins), and

6[apps and connectors](https://help.openai.com/en/articles/11487775).8[apps and connectors](https://help.openai.com/en/articles/11487775).

7 9 


38 40 

39Workspace plugin controls determine whether a plugin is available or installed41Workspace plugin controls determine whether a plugin is available or installed

40for supported workspace roles. The Codex CLI plugin browser controls CLI42for supported workspace roles. The Codex CLI plugin browser controls CLI

41installation through its own path. See [Build plugins](https://learn.chatgpt.com/docs/build-plugins) for43installation through its own path. See [Build plugins](https://developers.openai.com/plugins/build/plugins) for

42packaging and distribution.44packaging and distribution.

43 45 

44## Connector-backed capability controls46## Connector-backed capability controls

45 47 

46In ChatGPT, plugins can include connectors that search, retrieve, sync, or act48Plugins in ChatGPT and Codex can include connectors that search, retrieve, sync,

47on external systems. Workspace admins configure plugin availability separately49or act on external systems. Workspace admins configure plugin availability

48from the access and actions granted to each connector.50separately from the access and actions granted to each connector.

49 51 

50Manage connector-backed capabilities from52Manage connector-backed capabilities from

51[Workspace apps](https://chatgpt.com/admin/ca) and53[Workspace apps](https://chatgpt.com/admin/ca) and


69For a broad initial rollout, consider plugin categories teams use every day:71For a broad initial rollout, consider plugin categories teams use every day:

70email, calendar, and file or document systems such as Google Drive or Notion.72email, calendar, and file or document systems such as Google Drive or Notion.

71Use the [Plugins Directory](https://chatgpt.com/apps) to confirm current73Use the [Plugins Directory](https://chatgpt.com/apps) to confirm current

72availability and capabilities.74availability and capabilities across supported ChatGPT and Codex surfaces.

73 75 

74Start with read actions. Enable write actions only after reviewing the plugin's76Start with read actions. Enable write actions only after reviewing the plugin's

75owner, each connector's requested scopes, data access, external effects, and77owner, each connector's requested scopes, data access, external effects, and


79 81 

80When ChatGPT uses a connector-backed plugin, the connector sends a request to82When ChatGPT uses a connector-backed plugin, the connector sends a request to

81the connected service and returns data or action results allowed by the83the connected service and returns data or action results allowed by the

82authenticated user's provider permissions. Custom Apps SDK apps expose these84authenticated user's provider permissions. Custom MCP servers expose these

83operations as tools through Model Context Protocol (MCP).85operations as tools through Model Context Protocol (MCP).

84 86 

85For non-synced connector use, ChatGPT processes data from Chat and deep87For non-synced connector use, ChatGPT processes data from Chat and deep


109- [Manage workspace settings](https://help.openai.com/en/articles/8411955)111- [Manage workspace settings](https://help.openai.com/en/articles/8411955)

110- [Plugins](https://learn.chatgpt.com/docs/plugins)112- [Plugins](https://learn.chatgpt.com/docs/plugins)

111- [Skills and plugins](https://learn.chatgpt.com/docs/skills-and-plugins)113- [Skills and plugins](https://learn.chatgpt.com/docs/skills-and-plugins)

112- [Build plugins](https://learn.chatgpt.com/docs/build-plugins)114- [Build plugins](https://developers.openai.com/plugins/build/plugins)

113- [Admin rollout guide](https://learn.chatgpt.com/docs/enterprise/admin-setup)115- [Admin rollout guide](https://learn.chatgpt.com/docs/enterprise/admin-setup)

Details

518 518 

519If `mcp_servers` is present but empty, the local client disables all MCP servers.519If `mcp_servers` is present but empty, the local client disables all MCP servers.

520 520 

521### Control plugin availability

522 

523To turn off plugins in supported local clients, set `features.plugins` to

524`false` in `requirements.toml`:

525 

526```toml

527features.plugins = false

528```

529 

530This setting also applies when users sign in to Codex with an API key. See the

531[`features.plugins`

532reference](https://learn.chatgpt.com/docs/config-file/config-reference#requirementstoml) for the

533supported configuration.

534 

521### Restrict plugin marketplace sources535### Restrict plugin marketplace sources

522 536 

523To restrict operations on user-configured marketplace sources, set537To restrict operations on user-configured marketplace sources, set

Details

23transfer ChatGPT workspace ownership, sharing, role assignments, plugin23transfer ChatGPT workspace ownership, sharing, role assignments, plugin

24installation state, or connector authorization.24installation state, or connector authorization.

25 25 

26Plugins are available with ChatGPT Work on the web, and with ChatGPT Work and Codex26Plugins are available with ChatGPT Work on the web, with ChatGPT Work and Codex

27in the ChatGPT desktop app, and through the Codex CLI plugin browser. They aren't27in the ChatGPT desktop app, and through the Codex CLI plugin browser. They

28available in Chat, the IDE extension, or mobile.28aren't available in Chat, the IDE extension, or mobile.

29Those supported surfaces draw public plugins from one universal directory

30shared by ChatGPT and Codex.

29 31 

30## Owning controls32## Owning controls

31 33 

32See [Build skills](https://learn.chatgpt.com/docs/build-skills) for filesystem locations and authoring,34See [Build skills](https://learn.chatgpt.com/docs/build-skills) for filesystem locations and authoring,

33[Skills in ChatGPT](https://help.openai.com/en/articles/20001066-skills-in-chatgpt)35[Skills in ChatGPT](https://help.openai.com/en/articles/20001066-skills-in-chatgpt)

34for current workspace procedures, and [Build plugins](https://learn.chatgpt.com/docs/build-plugins) for36for current workspace procedures, and [Build plugins](https://developers.openai.com/plugins/build/plugins) for

35plugin packaging.37plugin packaging.

36 38 

37ChatGPT workspace controls don't install local filesystem skills or plugins.39ChatGPT workspace controls don't install local filesystem skills or plugins.


45- [Skills and plugins](https://learn.chatgpt.com/docs/skills-and-plugins)47- [Skills and plugins](https://learn.chatgpt.com/docs/skills-and-plugins)

46- [Plugins](https://learn.chatgpt.com/docs/plugins)48- [Plugins](https://learn.chatgpt.com/docs/plugins)

47- [Build skills](https://learn.chatgpt.com/docs/build-skills)49- [Build skills](https://learn.chatgpt.com/docs/build-skills)

48- [Build plugins](https://learn.chatgpt.com/docs/build-plugins)50- [Build plugins](https://developers.openai.com/plugins/build/plugins)

49- [Admin rollout guide](https://learn.chatgpt.com/docs/enterprise/admin-setup)51- [Admin rollout guide](https://learn.chatgpt.com/docs/enterprise/admin-setup)

50- [Plugin controls](https://learn.chatgpt.com/docs/enterprise/apps-and-connectors)52- [Plugin controls](https://learn.chatgpt.com/docs/enterprise/apps-and-connectors)

Details

10 10 

11For example, you might record how you file an expense, book a parking space,11For example, you might record how you file an expense, book a parking space,

12create a correctly configured issue, publish a video, or download a recurring12create a correctly configured issue, publish a video, or download a recurring

13report. Codex can package the pattern into a skill that you can use again with13report. ChatGPT or Codex can package the pattern into a skill that you can use

14Computer Use, browser actions, connected plugins, or a combination of them.14again with Computer Use, browser actions, connected plugins, or a combination

15of them.

15 16 

16## Before you start17## Before you start

17 18 


251. In the ChatGPT desktop app, select ChatGPT and turn on Work in the switcher, or select Codex. Then open **Plugins**.261. In the ChatGPT desktop app, select ChatGPT and turn on Work in the switcher, or select Codex. Then open **Plugins**.

262. Open the **+** menu.272. Open the **+** menu.

273. Select **Record a skill**.283. Select **Record a skill**.

284. Review the suggested prompt, give Codex any helpful context, and submit it.294. Review the suggested prompt, add any helpful context, and submit it.

295. When Codex asks for permission to record your actions, approve the request305. When the chat asks for permission to record your actions, approve the

30 once you are ready to demonstrate the workflow.31 request once you are ready to demonstrate the workflow.

316. Perform the workflow on your Mac.326. Perform the workflow on your Mac.

327. When you are done, stop recording from the menu bar, overlay, or tell Codex337. When you are done, stop recording from the menu bar or overlay, or tell the

33 that you are done.34 chat that you are done.

34 35 

35</WorkflowSteps>36</WorkflowSteps>

36 37 

37During recording, Codex observes the actions and window content needed to learn38During recording, ChatGPT or Codex observes the actions and window content

38the workflow. Recording continues until you stop it. Keep the recording focused39needed to learn the workflow. Recording continues until you stop it. Keep the

39on the task you want Codex to learn.40recording focused on the task you want the skill to teach.

40 41 

41After you stop recording, Codex inspects the captured workflow and drafts a42After you stop recording, ChatGPT or Codex inspects the captured workflow and

42skill. The skill explains when to use the workflow, what inputs it needs, what43drafts a skill. The skill explains when to use the workflow, what inputs it

43steps to follow, and how to verify the result. You can also ask Codex to44needs, what steps to follow, and how to verify the result. You can also ask for

44refine the skill further.45further refinements.

45 46 

46## Replay the workflow47## Replay the workflow

47 48 

48Start a new chat and ask Codex to use the generated skill. Give it the49Start a new ChatGPT or Codex chat and ask it to use the generated skill. Give

49values that are different this time, such as the file to upload, the issue to50it the values that are different this time, such as the file to upload, the

50create, or the date range for the report.51issue to create, or the date range for the report.

51 52 

52Codex uses the skill as reusable context for the task. It can then complete the53The product uses the skill as reusable context for the task. It can then

53workflow with the tools available in the current environment, including54complete the workflow with the tools available in the current environment,

54Computer Use, browser actions, and installed plugins.55including Computer Use, browser actions, and installed plugins.

55 56 

56## Tips for better recordings57## Tips for better recordings

57 58 

58- Keep the demonstration short and complete.59- Keep the demonstration short and complete.

59- Let Codex know your goal and any specific inputs that might vary between60- State your goal and any specific inputs that might vary between

60 skill uses before you start recording.61 skill uses before you start recording.

61- Use realistic inputs, but avoid secrets and sensitive data.62- Use realistic inputs, but avoid secrets and sensitive data.

62- Refine the skill after recording to call out hidden preferences that matter,63- Refine the skill after recording to call out hidden preferences that matter,


70If you want to distribute a separate stable package across a team, bundle71If you want to distribute a separate stable package across a team, bundle

71multiple skills, include connectors, add MCP servers, or manage install72multiple skills, include connectors, add MCP servers, or manage install

72metadata, package that workflow as its own plugin. See73metadata, package that workflow as its own plugin. See

73[Build plugins](https://learn.chatgpt.com/docs/build-plugins).74[Build plugins](https://developers.openai.com/plugins/build/plugins).

74 75 

75## Troubleshooting76## Troubleshooting

76 77 

glossary.md +5 −5

Details

521 href: "/codex/plugins",521 href: "/codex/plugins",

522 appliesTo: "Desktop app (ChatGPT Work, Codex), Web (ChatGPT Work), CLI",522 appliesTo: "Desktop app (ChatGPT Work, Codex), Web (ChatGPT Work), CLI",

523 description:523 description:

524 "An installable bundle of capabilities such as skills, connectors, and tools.",524 "An installable bundle of capabilities, such as skills, connectors, and tools, distributed through the universal directory shared by ChatGPT and Codex.",

525 },525 },

526 {526 {

527 key: "Plugin manifest",527 key: "Plugin manifest",

528 href: "/codex/build-plugins#plugin-structure",528 href: "https://developers.openai.com/plugins/build/plugins#plugin-structure",

529 appliesTo: "Plugin authoring",529 appliesTo: "Plugin authoring",

530 description:530 description:

531 "Plugin metadata file that identifies a plugin and points to bundled skills, connector mappings, MCP servers, hooks, and metadata.",531 "Plugin metadata file that identifies a plugin and points to bundled skills, connector mappings, MCP servers, hooks, and metadata.",


546 {546 {

547 key: "Progressive disclosure",547 key: "Progressive disclosure",

548 href: "/codex/build-skills",548 href: "/codex/build-skills",

549 appliesTo: "Desktop app, CLI, IDE extension",549 appliesTo: "Desktop app, Web (ChatGPT Work), CLI, IDE extension",

550 description:550 description:

551 "Loading skill details only when needed to preserve context.",551 "Loading skill details only when needed to preserve context.",

552 },552 },


660 {660 {

661 key: "Skill",661 key: "Skill",

662 href: "/codex/build-skills",662 href: "/codex/build-skills",

663 appliesTo: "Desktop app, CLI, IDE extension",663 appliesTo: "Desktop app, Web (ChatGPT Work), CLI, IDE extension",

664 description:664 description:

665 "Reusable workflow package with instructions and optional scripts or references.",665 "Reusable workflow package with instructions and optional scripts or references.",

666 },666 },

667 {667 {

668 key: "Skill invocation",668 key: "Skill invocation",

669 href: "/codex/build-skills#how-codex-uses-skills",669 href: "/codex/build-skills#how-codex-uses-skills",

670 appliesTo: "Desktop app, CLI, IDE extension",670 appliesTo: "Desktop app, Web (ChatGPT Work), CLI, IDE extension",

671 description: "Explicit or implicit activation of a skill.",671 description: "Explicit or implicit activation of a skill.",

672 },672 },

673 {673 {

hooks.md +1 −1

Details

33 33 

34Installed plugins can also bundle lifecycle config through their plugin34Installed plugins can also bundle lifecycle config through their plugin

35manifest or a default `hooks/hooks.json` file. See [Build35manifest or a default `hooks/hooks.json` file. See [Build

36plugins](https://learn.chatgpt.com/docs/build-plugins#bundled-mcp-servers-and-lifecycle-hooks) for the36plugins](https://developers.openai.com/plugins/build/plugins#bundled-mcp-servers-and-lifecycle-hooks) for the

37plugin packaging rules.37plugin packaging rules.

38 38 

39In practice, the four most useful locations are:39In practice, the four most useful locations are:

open-source.md +1 −1

Details

11| Codex CLI | [openai/codex](https://github.com/openai/codex) | The primary home for Codex open-source development |11| Codex CLI | [openai/codex](https://github.com/openai/codex) | The primary home for Codex open-source development |

12| Codex SDK | [openai/codex/codex-sdk](https://github.com/openai/codex/tree/main/sdk) | SDK sources live in the Codex repo |12| Codex SDK | [openai/codex/codex-sdk](https://github.com/openai/codex/tree/main/sdk) | SDK sources live in the Codex repo |

13| Codex App Server | [openai/codex/codex-rs/app-server](https://github.com/openai/codex/tree/main/codex-rs/app-server) | App-server sources live in the Codex repo |13| Codex App Server | [openai/codex/codex-rs/app-server](https://github.com/openai/codex/tree/main/codex-rs/app-server) | App-server sources live in the Codex repo |

14| Skills | [openai/skills](https://github.com/openai/skills) | Reusable skills that extend Codex |14| Skills | [openai/skills](https://github.com/openai/skills) | Reusable skills that extend ChatGPT and Codex |

15| IDE extension | - | Not open source |15| IDE extension | - | Not open source |

16| Codex cloud | - | Not open source |16| Codex cloud | - | Not open source |

17| Universal cloud environment | [openai/codex-universal](https://github.com/openai/codex-universal) | Base environment used by Codex cloud |17| Universal cloud environment | [openai/codex-universal](https://github.com/openai/codex-universal) | Base environment used by Codex cloud |

plugin-submission-errors.md +0 −455 deleted

File Deleted View Diff

1# Plugin submission errors

2 

3Plugins submitted to the public directory are held to a higher standard than

4plugins installed in a workspace. Directory submissions must pass the shared

5package checks and the additional checks for listing fields, review materials,

6MCP tools, skills, assets, and images. This reference also covers shared

7package checks, such as app references, that can appear outside the submission

8portal.

9 

10Use the error code returned during submission to find the matching requirement.

11Errors block submission. Warnings don't block submission, but you should review

12them before continuing.

13 

14Non-empty values can't contain only whitespace. Supported text excludes control

15characters, Unicode line or paragraph separators, and unsupported invisible

16formatting characters. HTTPS URLs must include a host and contain no embedded

17credentials or unsupported characters.

18 

19## Final directory submission

20 

21A package can pass upload validation and still fail final directory submission.

22Final submission uses stricter listing limits and checks MCP configuration,

23skill scans, test cases, and policy attestations.

24 

25| Field | Final submission rule |

26| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

27| Package name | Required; at most 64 characters. Start with an ASCII letter or digit and use only ASCII letters, digits, `_`, and `-`. |

28| Version | Required; use a semantic version of at most 64 characters. |

29| Display name | Required; one line; at most 30 characters. |

30| Short description | Required; one line; at most 30 characters. |

31| Long description | Required; at most 4,000 characters. Line breaks are allowed. |

32| Developer name | Required; one line; at most 80 characters. |

33| Category | Required; choose a supported category listed in the [Listing and interface errors](#listing-and-interface-errors) section. |

34| Capabilities | At most 20. Each capability must be non-empty, one line, and at most 120 characters. |

35| Starter prompts | At most 3. Each prompt must be non-empty, unique after Unicode and whitespace normalization, one line, at most 128 characters, and contain no app `@mention`. |

36| URLs | Required for MCP-backed submissions; optional for skills-only submissions. Website, support, privacy policy, and terms URLs must use HTTPS and be at most 1,024 characters. |

37| Brand colors | Optional six-digit hex colors. The light color must have at least 2:1 contrast against white, and the dark color must have at least 2:1 contrast against `#212121`. |

38 

39Every plugin submission also requires:

40 

41- Passing safety and security scans for every bundled skill. Scans can take up

42 to 2 hours.

43- A verified developer or business identity and all required policy

44 attestations.

45 

46For an MCP-backed plugin, final submission also requires:

47 

48- Website, support, privacy policy, and terms URLs that meet the rules above.

49- A demo-recording URL that shows the main use cases and tools across supported

50 platforms.

51- Exactly five positive test cases, three negative test cases, and release

52 notes.

53- A production HTTPS MCP server URL, a completed domain-verification challenge,

54 and a successful, current tool scan.

55- Explicit `readOnlyHint`, `openWorldHint`, and `destructiveHint` values and a

56 justification for each value on every MCP tool.

57- Reviewer-ready demo credentials when the server uses OAuth.

58- Screenshots only when the MCP server provides custom UI. If you add

59 screenshots, provide one PNG or JPEG image for every starter prompt. Each

60 screenshot must be exactly 706 pixels wide and 400–860 pixels tall.

61 

62### Final metadata errors

63 

64In these error names, `subtitle` means short description and `description`

65means long description.

66 

67| Name | Requirement |

68| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |

69| `submission_display_name_required` | Display name is required, non-empty, and single-line. |

70| `submission_display_name_too_long` | Display name must be 30 characters or fewer. |

71| `submission_display_name_character_unsupported` | Display name must use supported text and fit on one line. |

72| `submission_subtitle_required` | Short description is required, non-empty, and single-line. |

73| `submission_subtitle_too_long` | Short description must be 30 characters or fewer. |

74| `submission_subtitle_character_unsupported` | Short description must use supported text and fit on one line. |

75| `submission_description_required` | Long description is required and must be non-empty. Line breaks are allowed. |

76| `submission_description_too_long` | Long description must be 4,000 characters or fewer. |

77| `submission_description_character_unsupported` | Long description must use supported text. Line breaks are allowed. |

78| `submission_developer_name_required` | Developer name is required, non-empty, and single-line. |

79| `submission_developer_name_too_long` | Developer name must be 80 characters or fewer. |

80| `submission_developer_name_character_unsupported` | Developer name must use supported text and fit on one line. |

81| `plugin_capability_invalid` | Each capability must be non-empty, use supported text, fit on one line, and be 120 characters or fewer. |

82| `plugin_default_prompt_mention` | Starter prompts must not contain app `@mentions`. |

83| `plugin_default_prompt_duplicate` | Starter prompts must be unique after Unicode and whitespace normalization. |

84 

85### MCP and review errors

86 

87These errors apply to MCP-backed submissions.

88 

89| Name | Requirement |

90| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

91| `annotations_required` | Every MCP tool must set `readOnlyHint`, `openWorldHint`, and `destructiveHint` accurately. |

92| `justification_required` | Every MCP tool annotation must include a justification for its read-only, open-world, or destructive behavior. |

93| `scan_required` | MCP tools must have a successful, current scan of the production MCP server. |

94| `domain_verification_required` | The exact verification token must be hosted at the generated `/.well-known/openai-apps-challenge` URL on the MCP host or an allowed parent host, and **Verify Domain** must pass. |

95| `frame_domain_explanation_required` | Every external frame domain reported by the MCP tool scan must have an explanation of why the UI needs it and what content it provides. |

96| `screenshots_not_allowed` | Screenshots are allowed only when the current MCP tool scan reports a UI output template. |

97 

98## Archive errors

99 

100### Skills-only ZIP upload errors and warnings

101 

102**Skills only** uploads accept a plugin manifest and bundled skills. A changed

103package name blocks an update; the other findings require confirmation.

104 

105| Name | Requirement |

106| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |

107| `plugin_name_mismatch` | The package name in an update must match the existing plugin name. |

108| `plugin_version_unchanged` | A new release must use a different manifest `version`; reusing the published version requires confirmation. |

109| `mcp_configuration_excluded` | Skills-only ZIP uploads must not include `mcpServers` or `.mcp.json`; MCP-backed plugins must use **With MCP**. |

110| `app_configuration_excluded` | Skills-only ZIP uploads must not include `apps` or `.app.json`; plugins with app content must use **With MCP**. |

111| `screenshot_configuration_excluded` | Skills-only ZIP uploads must not include `interface.screenshots`; screenshots require **With MCP** and custom UI. |

112| `claude_format_normalized` | `.claude-plugin/plugin.json` is converted to `.codex-plugin/plugin.json`, with missing interface defaults and normalized text fields added by the portal. |

113| `manifest_normalized` | The portal saves the normalized manifest as `.codex-plugin/plugin.json`; changed fields require confirmation. |

114| `developer_name_defaulted` | `author.name` and `interface.developerName` must match, or the selected verified identity is used for both after confirmation. |

115 

116### ZIP structure and limit errors

117 

118| Name | Requirement |

119| --------------------------------------------- | ------------------------------------------------------------------------------------------------ |

120| `archive_empty` | Archive must not be empty. |

121| `archive_too_large` | Compressed ZIP must be 100 MB or less. |

122| `archive_format_not_zip` | Archive must be a valid, uncorrupted ZIP file. |

123| `archive_member_path_empty` | Archive entry path must not be empty. |

124| `archive_member_path_has_outer_whitespace` | Archive entry path must not begin or end with whitespace. |

125| `archive_member_path_has_backslash` | Archive entry path must use `/`, not backslashes. |

126| `archive_member_path_absolute` | Archive entry path must be relative to the archive root. |

127| `archive_member_path_has_empty_segment` | Archive entry path must not contain empty segments. |

128| `archive_member_path_has_parent_segment` | Archive entry path must not contain `..` segments. |

129| `archive_member_path_too_deep` | Archive entry path must contain at most 20 segments, including the filename. |

130| `archive_member_path_too_long` | Archive entry path must be within the supported path-length limit. |

131| `archive_member_path_normalization_collision` | Archive entry paths must remain unique after case and Unicode normalization. |

132| `archive_member_type_unsupported` | Archive entries must be regular files or directories. |

133| `archive_member_too_large` | Archive entry must not exceed 100 MiB. |

134| `archive_member_path_duplicate` | Archive entry path must be unique. |

135| `archive_member_path_type_conflict` | A file path cannot also be a directory or contain another archive entry. |

136| `archive_too_many_entries` | Archive must not contain more than 5,000 entries. |

137| `archive_uncompressed_too_large` | Extracted archive must not exceed 512 MiB. |

138| `archive_member_unreadable` | Every archive entry must be readable, must not be encrypted, and must use supported compression. |

139 

140## Plugin root errors

141 

142| Name | Requirement |

143| ------------------------------ | --------------------------------------------------------------------------------------------------------------------- |

144| `plugin_root_missing` | The selected path must exist and be a directory containing a plugin. |

145| `archive_plugin_files_missing` | A skills-only ZIP must contain a supported plugin manifest and at least one valid skill at `skills/<skill>/SKILL.md`. |

146| `plugin_root_ambiguous` | ZIP must contain exactly one plugin root, either at the archive root or in one top-level directory. |

147| `plugin_root_has_siblings` | A ZIP with a top-level plugin directory must not contain sibling files. |

148 

149## Plugin manifest errors

150 

151| Name | Requirement |

152| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |

153| `plugin_manifest_missing` | ZIP must contain `.codex-plugin/plugin.json`, `.agent-plugin/plugin.json`, or `.claude-plugin/plugin.json` at the root or in its single top-level directory. |

154| `plugin_manifest_not_file` | Plugin manifest must be a regular JSON file. |

155| `plugin_manifest_unreadable` | Plugin manifest must be readable UTF-8 text. |

156| `plugin_manifest_json_malformed` | Plugin manifest must contain valid JSON; malformed syntax is reported with a line number. |

157| `plugin_manifest_root_not_object` | Plugin manifest must contain a JSON object at the top level. |

158| `codex_manifest_parent_not_directory` | `.codex-plugin` must be a directory. |

159| `codex_manifest_path_not_file` | `.codex-plugin/plugin.json` must be a regular JSON file. |

160| `plugin_id_wrong_type` | `id` must be a string when provided. |

161| `plugin_id_empty` | `id` must be non-empty when provided. |

162| `plugin_name_missing` | `name` is required. |

163| `plugin_name_wrong_type` | `name` must be a string. |

164| `plugin_name_empty` | `name` must be non-empty. |

165| `plugin_name_too_long` | `name` must be 64 characters or fewer. |

166| `plugin_name_format` | `name` must start with an ASCII letter or digit and contain only ASCII letters, digits, `_`, or `-`. |

167| `plugin_version_missing` | `version` is required. |

168| `plugin_version_wrong_type` | `version` must be a string. |

169| `plugin_version_empty` | `version` must be a non-empty semantic-version string, such as `1.0.0`. |

170| `plugin_version_not_semver` | `version` must use semantic versioning, such as `1.0.0`. |

171| `plugin_version_too_long` | `version` must be 64 characters or fewer. |

172| `plugin_description_missing` | `description` is required. |

173| `plugin_description_wrong_type` | `description` must be a string. |

174| `plugin_description_empty` | `description` must be non-empty. |

175| `plugin_description_too_long` | `description` must be 1,024 characters or fewer. |

176| `plugin_description_character_unsupported` | `description` must use supported text. Line breaks are allowed. |

177| `plugin_developer_missing` | `author.name` is required. `interface.developerName` is also required and is reported separately. |

178| `plugin_author_wrong_type` | `author` must be an object. |

179| `plugin_author_name_wrong_type` | `author.name` must be a string. |

180| `plugin_author_name_empty` | `author.name` must be non-empty. |

181| `plugin_author_name_too_long` | `author.name` must be 120 characters or fewer. |

182| `plugin_author_name_character_unsupported` | `author.name` must use supported text. |

183| `plugin_author_email_wrong_type` | `author.email` must be a string when provided. |

184| `plugin_author_email_empty` | `author.email` must be non-empty when provided. |

185| `plugin_author_email_too_long` | `author.email` must be 320 characters or fewer. |

186| `plugin_author_email_character_unsupported` | `author.email` must use supported text. |

187| `plugin_author_url_wrong_type` | `author.url` must be a string when provided. |

188| `plugin_author_url_empty` | `author.url` must be non-empty when provided. |

189| `plugin_author_url_not_https` | `author.url` must be an HTTPS URL. |

190| `plugin_author_url_has_credentials` | `author.url` must not contain credentials. |

191| `plugin_author_url_too_long` | `author.url` must be 2,048 characters or fewer. |

192| `plugin_author_url_character_unsupported` | `author.url` must use supported text. |

193 

194## Listing and interface errors

195 

196The plugin manifest's `interface` object defines the public listing shown to

197users. It lives in `.codex-plugin/plugin.json` and uses fields such as

198`displayName` and `shortDescription`:

199 

200```json

201{

202 "interface": {

203 "displayName": "Example Plugin",

204 "shortDescription": "Summarize documents",

205 "longDescription": "Summarize and organize documents.",

206 "developerName": "Example",

207 "category": "Productivity",

208 "capabilities": ["Summarize documents"]

209 }

210}

211```

212 

213The four listing URLs (website, privacy policy, terms, and support) are

214optional for skills-only plugins and required for MCP-backed plugins. Their

215length limit is 2,048 characters for package validation and 1,024 characters

216for final directory submission.

217 

218| Name | Requirement |

219| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

220| `plugin_interface_wrong_type` | The plugin manifest's `interface` field must be a JSON object. |

221| `plugin_display_name_wrong_type` | `interface.displayName` must be a string. |

222| `plugin_display_name_empty` | `interface.displayName` is required and must be non-empty. |

223| `plugin_display_name_too_long` | `interface.displayName` must be 80 characters or fewer for package validation and 30 characters or fewer for final directory submission. |

224| `plugin_display_name_character_unsupported` | `interface.displayName` must use supported text. |

225| `plugin_short_description_missing` | `interface.shortDescription` is required, must fit on one line, and must be 240 characters or fewer for package validation and 30 characters or fewer for final directory submission. |

226| `plugin_short_description_wrong_type` | `interface.shortDescription` must be a string. |

227| `plugin_short_description_empty` | `interface.shortDescription` must be non-empty. |

228| `plugin_short_description_too_long` | `interface.shortDescription` must be 240 characters or fewer for package validation and 30 characters or fewer for final directory submission. |

229| `plugin_short_description_character_unsupported` | `interface.shortDescription` must use supported text. |

230| `plugin_long_description_wrong_type` | `interface.longDescription` must be a string. |

231| `plugin_long_description_empty` | `interface.longDescription` is required and must be non-empty. |

232| `plugin_long_description_too_long` | `interface.longDescription` must be 4,000 characters or fewer. |

233| `plugin_long_description_character_unsupported` | `interface.longDescription` must use supported text. Line breaks are allowed. |

234| `plugin_developer_name_wrong_type` | `interface.developerName` must be a string. |

235| `plugin_developer_name_empty` | `interface.developerName` is required and must be non-empty. |

236| `plugin_developer_name_too_long` | `interface.developerName` must be 120 characters or fewer for package validation and 80 characters or fewer for final directory submission. |

237| `plugin_developer_name_character_unsupported` | `interface.developerName` must use supported text. |

238| `plugin_category_wrong_type` | `interface.category` must be a string. |

239| `plugin_category_empty` | `interface.category` must be non-empty when provided; omit it to use `Other`. |

240| `plugin_category_unknown` | `interface.category` must be `Productivity`, `Creativity`, `Developer Tools`, `Business & Operations`, `Data & Analytics`, `Communication`, `Education & Research`, `Security`, `Finance`, `Healthcare`, `Travel`, `Entertainment`, or `Other`. |

241| `plugin_category_character_unsupported` | `interface.category` must use supported text. |

242| `plugin_capabilities_wrong_type` | `interface.capabilities` must be a list of strings. |

243| `plugin_capabilities_too_many` | `interface.capabilities` must contain 20 entries or fewer. |

244| `plugin_capability_wrong_type` | Each `interface.capabilities` entry must be a string. |

245| `plugin_capability_empty` | Each `interface.capabilities` entry must be non-empty when provided. |

246| `plugin_capability_too_long` | Each `interface.capabilities` entry must be 120 characters or fewer. |

247| `plugin_capability_character_unsupported` | Each `interface.capabilities` entry must use supported text. |

248| `plugin_website_url_wrong_type` | `interface.websiteURL` must be a string when provided. |

249| `plugin_website_url_empty` | `interface.websiteURL` must be non-empty when provided. |

250| `plugin_website_url_format` | `interface.websiteURL` must be an HTTPS URL. |

251| `plugin_website_url_too_long` | `interface.websiteURL` must meet the listing URL length limits. |

252| `plugin_privacy_policy_url_wrong_type` | `interface.privacyPolicyURL` must be a string when provided. |

253| `plugin_privacy_policy_url_empty` | `interface.privacyPolicyURL` must be non-empty when provided. |

254| `plugin_privacy_policy_url_format` | `interface.privacyPolicyURL` must be an HTTPS URL. |

255| `plugin_privacy_policy_url_too_long` | `interface.privacyPolicyURL` must meet the listing URL length limits. |

256| `plugin_terms_of_service_url_wrong_type` | `interface.termsOfServiceURL` must be a string when provided. |

257| `plugin_terms_of_service_url_empty` | `interface.termsOfServiceURL` must be non-empty when provided. |

258| `plugin_terms_of_service_url_format` | `interface.termsOfServiceURL` must be an HTTPS URL. |

259| `plugin_terms_of_service_url_too_long` | `interface.termsOfServiceURL` must meet the listing URL length limits. |

260| `plugin_support_url_wrong_type` | `interface.supportURL` must be a string when provided. |

261| `plugin_support_url_empty` | `interface.supportURL` must be non-empty when provided. |

262| `plugin_support_url_format` | `interface.supportURL` must be an HTTPS URL. |

263| `plugin_support_url_too_long` | `interface.supportURL` must meet the listing URL length limits. |

264| `plugin_homepage_wrong_type` | `homepage` must be a string when provided. |

265| `plugin_homepage_empty` | `homepage` must be non-empty when provided. |

266| `plugin_homepage_format` | `homepage` must be an HTTPS URL. |

267| `plugin_homepage_too_long` | `homepage` must be 2,048 characters or fewer. |

268| `plugin_brand_color_wrong_type` | `interface.brandColor` must be a string when provided. |

269| `plugin_brand_color_empty` | `interface.brandColor` must be non-empty when provided. |

270| `plugin_brand_color_format` | `interface.brandColor` must be a six-digit hex color, such as `#1ABCFE`. |

271| `plugin_brand_color_dark_wrong_type` | `interface.brandColorDark` must be a string when provided. |

272| `plugin_brand_color_dark_empty` | `interface.brandColorDark` must be non-empty when provided. |

273| `plugin_brand_color_dark_format` | `interface.brandColorDark` must be a six-digit hex color, such as `#1ABCFE`. |

274| `plugin_brand_color_contrast` | `interface.brandColor` must have at least 2:1 contrast against white. |

275| `plugin_brand_color_dark_contrast` | `interface.brandColorDark` must have at least 2:1 contrast against `#212121`. |

276| `plugin_default_prompt_wrong_type` | `interface.defaultPrompt` must be a string or list of strings. |

277| `plugin_default_prompt_too_many` | `interface.defaultPrompt` must contain at most three prompts. |

278| `plugin_default_prompt_entry_wrong_type` | Each `interface.defaultPrompt` entry must be a string. |

279| `plugin_default_prompt_empty` | Each `interface.defaultPrompt` entry must be non-empty when provided. |

280| `plugin_default_prompt_too_long` | Each `interface.defaultPrompt` entry must be 512 characters or fewer for package validation and 128 characters or fewer for final directory submission. |

281| `plugin_default_prompt_character_unsupported` | Each `interface.defaultPrompt` entry must use supported text and fit on one line. |

282 

283## Plugin content errors

284 

285| Name | Requirement |

286| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |

287| `plugin_skills_path_wrong_type` | `skills` must be a string path for the root `skills/` directory. |

288| `plugin_skills_path_empty` | `skills` must be a non-empty path to the root `skills/` directory when provided. |

289| `plugin_skills_path_unsupported` | `skills` must resolve to the root `skills/` directory. |

290| `plugin_skills_directory_missing` | A declared root `skills/` directory must exist. |

291| `plugin_skills_path_not_directory` | Root `skills/` must be a directory when declared. |

292| `plugin_apps_path_wrong_type` | `apps` must be a string path for the root `.app.json`. |

293| `plugin_apps_path_empty` | `apps` must be a non-empty path to the root `.app.json` when provided. |

294| `plugin_apps_path_unsupported` | `apps` must resolve to the root `.app.json`. |

295| `plugin_apps_file_missing` | A declared root `.app.json` file must exist. |

296| `plugin_apps_path_not_file` | Root `.app.json` must be a regular file when declared. |

297| `plugin_runtime_surface_missing` | A skills-only ZIP must contain at least one valid skill at `skills/<skill>/SKILL.md`; app and MCP references don't satisfy this requirement. |

298 

299## Skill errors

300 

301| Name | Requirement |

302| ----------------------------------------- | --------------------------------------------------------------------------------------------- |

303| `skill_manifest_missing` | Skill must contain a `SKILL.md` file. |

304| `skill_bundle_too_large` | Each compressed skill bundle must be within the MiB limit reported in the error. |

305| `skill_directory_hidden` | Skill directory names must not begin with `.`. |

306| `skill_manifest_nested` | Each skill directory must be an immediate child of `skills/`. |

307| `skill_manifest_not_regular_file` | `SKILL.md` must be a regular file. |

308| `skill_manifest_unreadable` | `SKILL.md` must be readable. |

309| `skill_manifest_invalid_utf8` | `SKILL.md` must contain valid UTF-8. |

310| `skill_frontmatter_missing` | `SKILL.md` must start with YAML front matter between `---` lines. |

311| `skill_frontmatter_unclosed` | `SKILL.md` YAML front matter must end with `---`. |

312| `skill_frontmatter_yaml_malformed` | `SKILL.md` front matter must contain valid YAML. |

313| `skill_frontmatter_wrong_type` | `SKILL.md` front matter must contain a YAML mapping. |

314| `skill_name_missing` | `name` is required and must not be empty. |

315| `skill_name_wrong_type` | `name` must be a string. |

316| `skill_name_empty` | `name` must be non-empty. |

317| `skill_name_character_unsupported` | Skill front matter `name` must use supported text. |

318| `skill_description_missing` | `description` is required and must not be empty. |

319| `skill_description_wrong_type` | `description` must be a string. |

320| `skill_description_empty` | `description` must be non-empty. |

321| `skill_description_too_long` | `description` must be 1,024 characters or fewer. |

322| `skill_description_character_unsupported` | Skill front matter `description` must use supported text. |

323| `skill_body_empty` | Skill instructions must not be empty. |

324| `skill_identity_too_long` | The combined plugin and skill name (`plugin-name:skill-name`) must be 64 characters or fewer. |

325| `skill_identity_duplicate` | Each skill `name` must be unique within the plugin. |

326 

327## Skill agent metadata errors

328 

329A bundled skill can define its own `interface` in

330`skills/<skill>/agents/openai.yaml`. This controls how the skill appears to

331users and is separate from the plugin manifest's `interface`. Skill interface

332fields use snake_case:

333 

334```yaml

335interface:

336 display_name: "Summarize documents"

337 short_description: "Summarize a document"

338 icon_small: "./assets/icon.png"

339 default_prompt: "Summarize the selected document."

340```

341 

342| Name | Requirement |

343| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

344| `skill_agent_not_regular_file` | `agents/openai.yaml` must be a regular file. |

345| `skill_agent_unreadable` | `agents/openai.yaml` must be readable. |

346| `skill_agent_invalid_utf8` | `agents/openai.yaml` must contain valid UTF-8. |

347| `skill_agent_yaml_malformed` | `agents/openai.yaml` must contain valid YAML. |

348| `skill_agent_top_level_wrong_type` | `agents/openai.yaml` must contain a YAML mapping at the top level. |

349| `skill_agent_interface_missing` | `interface` is required in `agents/openai.yaml` when that file is included. |

350| `skill_agent_interface_wrong_type` | `interface` in `agents/openai.yaml` must be a YAML mapping. |

351| `skill_agent_display_name_missing` | `interface.display_name` is required and must not be empty. |

352| `skill_agent_display_name_wrong_type` | `interface.display_name` must be a string. |

353| `skill_agent_display_name_empty` | `interface.display_name` must not be empty. |

354| `skill_agent_short_description_missing` | `interface.short_description` is required and must not be empty. |

355| `skill_agent_short_description_wrong_type` | `interface.short_description` must be a string. |

356| `skill_agent_short_description_empty` | `interface.short_description` must not be empty. |

357| `skill_agent_icon_small_wrong_type` | `interface.icon_small` must be a non-empty relative file path when provided. |

358| `skill_agent_icon_small_empty` | `interface.icon_small` must be a non-empty relative file path when provided, such as `assets/icon.png`. |

359| `skill_agent_icon_large_wrong_type` | `interface.icon_large` must be a non-empty relative file path when provided. |

360| `skill_agent_icon_large_empty` | `interface.icon_large` must be a non-empty relative file path when provided, such as `assets/icon.png`. |

361| `skill_agent_brand_color_wrong_type` | `interface.brand_color` must be a string when provided. |

362| `skill_agent_brand_color_empty` | `interface.brand_color` must be a non-empty six-digit hex color when provided, such as `#1ABCFE`. |

363| `skill_agent_brand_color_format` | `interface.brand_color` must be a six-digit hex color, such as `#1ABCFE`. |

364| `skill_agent_default_prompt_wrong_type` | `interface.default_prompt` must be a string when provided. |

365| `skill_agent_default_prompt_empty` | `interface.default_prompt` must be non-empty when provided. |

366| `skill_agent_policy_wrong_type` | `policy` must be a YAML mapping when provided. |

367| `skill_agent_allow_implicit_invocation_wrong_type` | `policy` may contain only `products` and `allow_implicit_invocation`. `products` must contain `CHAT`, `CODEX`, or both, and `allow_implicit_invocation` must be `true` or `false`. |

368| `skill_agent_dependencies_wrong_type` | `dependencies` must be a YAML mapping; only `tools` is supported. |

369| `skill_agent_dependency_unsupported` | Only `dependencies.tools` is supported in `agents/openai.yaml`. |

370 

371## Asset path errors

372 

373| Name | Requirement |

374| ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |

375| `declared_asset_path_wrong_type` | The named asset field must be a file path string. |

376| `declared_asset_path_empty` | The named asset field must not be empty. |

377| `declared_asset_path_has_outer_whitespace` | The named asset field must not begin or end with whitespace. |

378| `declared_asset_path_has_control_character` | The named asset field must not contain characters U+0000–U+001F or U+007F. |

379| `branding_asset_path_missing_root_prefix` | The named asset field must start with `./`. |

380| `declared_asset_path_unsafe` | The named asset field must be a relative path inside the plugin and must not contain an absolute path, drive prefix, or `..` traversal segment. |

381| `declared_asset_path_outside_package` | The named asset field must reference a file inside the plugin. |

382| `declared_asset_file_missing` | The named asset field references a file that does not exist. |

383| `declared_asset_not_regular_file` | The named asset field must reference a file, not a directory or special file. |

384 

385## Image errors

386 

387Directory branding images must use a supported file type and meet the size and

388dimension limits below. These rules apply to packaged branding assets;

389starter-prompt screenshots use the separate portal limits listed above.

390 

391| Name | Requirement |

392| ----------------------------------------- | -------------------------------------------------------------------------- |

393| `plugin_logo_path_missing` | `interface.logo` is required and must reference a square image. |

394| `plugin_composer_icon_path_missing` | `interface.composerIcon` is required and must reference a square image. |

395| `image_file_unreadable` | Image file must be readable. |

396| `image_file_too_large` | Image must not exceed 5 MiB. |

397| `image_file_format_unsupported` | Image filename must end in `.png`, `.jpg`, `.jpeg`, `.webp`, or `.svg`. |

398| `raster_image_decode_failed` | Raster image must be a PNG, JPEG, or WebP file that can be decoded safely. |

399| `raster_image_extension_content_mismatch` | Image filename extension must match the detected image format. |

400| `raster_image_not_square` | Image must be square. |

401| `raster_image_dimensions_too_small` | Image dimensions must be at least 48×48 pixels. |

402| `raster_image_dimensions_too_large` | Image dimensions must not exceed 4,096×4,096 pixels. |

403| `svg_xml_malformed` | SVG must contain valid UTF-8 XML. |

404| `svg_root_element_invalid` | SVG root element must be `<svg>`. |

405| `svg_dimensions_missing` | SVG must define a numeric `viewBox` or numeric `width` and `height`. |

406| `svg_dimensions_not_numeric` | SVG dimensions must be numeric and omit units and percentages. |

407| `svg_dimensions_not_positive` | SVG width and height must be positive finite numbers. |

408| `svg_dimensions_not_square` | SVG dimensions must be square. |

409| `svg_dimensions_too_small` | SVG dimensions must be at least 48×48 pixels. |

410 

411## App reference errors

412 

413The shared package checks validate `.app.json` when a plugin references apps.

414The submission portal doesn't publish references to existing ChatGPT apps: a

415**Skills only** upload removes `.app.json`, and an MCP-backed submission must

416use **With MCP** and submit the MCP server directly.

417 

418For local or workspace packages, the top-level `apps` object maps each app

419alias to an app entry.

420 

421| Name | Requirement |

422| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

423| `app_manifest_unreadable` | `.app.json` must be readable UTF-8 text. |

424| `app_manifest_json_malformed` | `.app.json` contains malformed JSON near the reported line. |

425| `app_manifest_wrong_type` | `.app.json` must contain a JSON object at the top level. |

426| `app_entries_missing` | `apps` is required. |

427| `app_entries_wrong_type` | `apps` must be an object. |

428| `app_entry_wrong_type` | Each app entry must be an object. |

429| `app_id_missing` | Each app entry's `id` is required. |

430| `app_id_wrong_type` | Each app entry's `id` must be a string. |

431| `app_id_format` | Each app entry's `id` must begin with `asdk_app_`, `connector_`, or `templated_apps_`, followed by a letter or digit and then only letters, digits, `_`, or `-`. |

432| `app_entry_optional_wrong_type` | Each app entry's `optional` value must be `true` or `false` when provided. |

433| `app_entry_required_wrong_type` | Each app entry's `required` value must be `true` or `false` when provided. |

434| `app_not_eligible` | For a local or workspace package, each referenced app must be a released public Codex app, available connector, or released app template. Directory submissions must use **With MCP** and submit the MCP server directly. |

435 

436## Package warnings

437 

438These warnings identify package content that validation ignores or normalizes.

439They don't block submission. Review them to confirm the submitted plugin

440contains the expected files and settings.

441 

442| Name | Requirement |

443| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |

444| `duplicate_app_reference` | Each app ID in `.app.json` must be referenced once; duplicate references are treated as one app. |

445| `undeclared_app_manifest_ignored` | A root `.app.json` is imported only when the plugin-manifest `apps` field is set to `./.app.json`. |

446| `undeclared_mcp_manifest_ignored` | A root `.mcp.json` is imported only when the plugin-manifest `mcpServers` field is set to `./.mcp.json`. |

447| `skill_file_ignored` | Files directly under `skills/` aren't imported as skills; each skill must be in a directory containing `SKILL.md`. |

448| `skill_symlink_ignored` | Symbolic links directly under `skills/` aren't imported as skills; each skill must be a real directory containing `SKILL.md`. |

449| `skill_frontmatter_adjusted` | Skill `name` and `description` are normalized during import by trimming outer whitespace and collapsing internal whitespace. |

450| `skill_metadata_ignored` | Skill interface settings must use the `interface` mapping in `agents/openai.yaml`; `metadata` in `SKILL.md` doesn't configure the interface. |

451 

452## Next steps

453 

454After resolving all validation errors, return to

455[Submit plugins](https://learn.chatgpt.com/docs/submit-plugins) to complete the submission.

plugins.md +52 −29

Details

2 2 

3## Overview3## Overview

4 4 

5Plugins bundle capabilities into reusable workflows in ChatGPT. They can5Plugins bundle capabilities into reusable workflows in ChatGPT and Codex. They

6include skills, connectors, or both. Plugins are available with ChatGPT Work on6can include skills, connectors, or both. Both products use one universal plugin

7the web and with ChatGPT Work or Codex in the ChatGPT desktop app. Codex7directory, so the same public plugins are discoverable from their supported

8surfaces.

9 

10Plugins are available with ChatGPT Work on the web and with ChatGPT Work or

11Codex in the ChatGPT desktop app. Codex

8CLI also has a plugin browser for Codex environments. Plugins aren't available12CLI also has a plugin browser for Codex environments. Plugins aren't available

9in Chat, the IDE extension, or mobile.13in Chat, the IDE extension, or mobile.

10 14 


22 26 

23 27 

24 28 

25Extend what ChatGPT can do, for example:29Extend what ChatGPT and Codex can do, for example:

26 30 

27- Install the Codex Security plugin to scan authorized code and confirm31- Install the Codex Security plugin to scan authorized code and confirm

28 plausible vulnerability findings.32 plausible vulnerability findings.

29- Install the Gmail plugin to let ChatGPT read and manage Gmail.33- Install the Gmail plugin to work with Gmail.

30- Install the Google Drive plugin to work across Drive, Docs, Sheets, and34- Install the Google Drive plugin to work across Drive, Docs, Sheets, and

31 Slides.35 Slides.

32- Install the Slack plugin to summarize channels or draft replies.36- Install the Slack plugin to summarize channels or draft replies.

33 37 

34A plugin can contain one or more of these parts:38A plugin can contain one or more of these parts:

35 39 

36- **Skills:** reusable instructions for specific kinds of work. ChatGPT can load40- **Skills:** reusable instructions for specific kinds of work. ChatGPT and

37 them when needed so it follows the right steps and uses the right references41 Codex can load them when needed so they follow the right steps and use the

38 or helper scripts for a task.42 right references or helper scripts for a task.

39- **Connectors:** connections to tools like GitHub, Slack, or Google Drive, so43- **Connectors:** connections to tools like GitHub, Slack, or Google Drive, so

40 ChatGPT can read information from those tools and take actions in them.44 ChatGPT and Codex can read information from those tools and take actions in

41 Connectors expose tools and can optionally include custom ChatGPT UI.45 them. Connectors expose tools and can optionally include custom UI.

42- **MCP servers:** services that give ChatGPT access to more tools or shared46- **MCP servers:** services that give ChatGPT and Codex access to more tools or

43 information, often from systems outside your local project. They're also the47 shared information, often from systems outside your local project. They're

44 services behind connectors. They define tools, enforce auth, return structured48 also the services behind connectors. They define tools, enforce auth, return

45 data, and perform actions against external systems.49 structured data, and perform actions against external systems.

46- **Browser extensions:** browser capabilities that a plugin needs for its50- **Browser extensions:** browser capabilities that a plugin needs for its

47 workflow.51 workflow.

48- **Hooks:** commands that run at configured lifecycle points. Review and trust52- **Hooks:** commands that run at configured lifecycle points. Review and trust


51 where scheduled tasks are available.55 where scheduled tasks are available.

52 56 

53You can share plugins by publishing them through a marketplace source, such as a57You can share plugins by publishing them through a marketplace source, such as a

54repo marketplace for a project or team. See [Build plugins](https://learn.chatgpt.com/docs/build-plugins)58repo marketplace for a project or team. See [Build plugins](https://developers.openai.com/plugins/build/plugins)

55for marketplace setup, packaging, and distribution guidance.59for marketplace setup, packaging, and distribution guidance.

56 60 

57If you are building an integration, start with [Build an app](https://learn.chatgpt.com/docs/build-app).61If you are building an integration, start with

58If the app needs custom ChatGPT UI, use the62[Build an MCP server](https://developers.openai.com/plugins/build/mcp-server).

59[Apps SDK](https://developers.openai.com/apps-sdk) for that optional UI layer.63If the plugin needs custom UI, use the

64[optional UI guide](https://developers.openai.com/plugins/build/chatgpt-ui).

60 65 

61## Use and install plugins66## Use and install plugins

62 67 


64 69 

65 70 

66 71 

67### Plugins in ChatGPT72### Universal plugin directory

68 73 

69To browse and install curated plugins:74ChatGPT and Codex use the same public plugin catalog. To browse and install

75plugins from a supported graphical surface:

70 76 

71- On the web, turn on Work in the switcher and open **Plugins**.77- On the web, turn on Work in the switcher and open **Plugins**.

72- In the ChatGPT desktop app, select ChatGPT and turn on Work in the switcher, or select78- In the ChatGPT desktop app, select ChatGPT and turn on Work in the switcher, or select


95 101 

96Use the separate **Installed** row to review plugins you already installed.102Use the separate **Installed** row to review plugins you already installed.

97 103 

98### Install and use a plugin in ChatGPT104### Install and use a plugin

99 105 

100Once you open the Plugins Directory:106Once you open the Plugins Directory:

101 107 


1063. If the plugin needs a connector, connect it when prompted. Some plugins1123. If the plugin needs a connector, connect it when prompted. Some plugins

107 ask you to authenticate during install. Others wait until the first time you113 ask you to authenticate during install. Others wait until the first time you

108 use them.114 use them.

1094. After installation, start a new chat and ask ChatGPT to use the plugin.1154. After installation, start a new chat and ask ChatGPT or Codex to use the

116 plugin.

110 117 

111</WorkflowSteps>118</WorkflowSteps>

112 119 


156 163 

157 164 

158 165 

166<a id="api-key-availability"></a>

167 

168 

169 

170### API key availability

171 

172If you [sign in to Codex with an OpenAI API

173key](https://learn.chatgpt.com/docs/auth#sign-in-with-an-api-key), you can browse, install, and manage

174supported OpenAI-curated plugins in Codex CLI and Codex in the ChatGPT desktop

175app. Some plugins aren't available with API key authentication because their

176connection flows require unsupported OAuth capabilities. Review plugin usage

177on the [Platform Usage page](https://platform.openai.com/usage).

178 

179 

180 

159### How permissions and data sharing work181### How permissions and data sharing work

160 182 

161 183 


171 193 

172- Bundled skills become available when you start a new chat or CLI session194- Bundled skills become available when you start a new chat or CLI session

173 after installation.195 after installation.

174- If a plugin includes connectors, ChatGPT may prompt you to install or sign in to196- If a plugin includes connectors, the active product may prompt you to install

175 those connectors in ChatGPT during setup or the first time you use them.197 or sign in to those connectors during setup or the first time you use them.

176- If a plugin includes MCP servers, they may require extra setup or198- If a plugin includes MCP servers, they may require extra setup or

177 authentication before you can use them.199 authentication before you can use them.

178- When ChatGPT sends data through a bundled connector, that service's terms and privacy200- When ChatGPT sends data through a bundled connector, that service's terms and privacy


192## Build your own plugin214## Build your own plugin

193 215 

194If you want to create, test, or distribute your own plugin, see216If you want to create, test, or distribute your own plugin, see

195[Build plugins](https://learn.chatgpt.com/docs/build-plugins). That page covers local scaffolding,217[Build plugins](https://developers.openai.com/plugins/build/plugins). That page covers local scaffolding,

196manual marketplace setup, workspace sharing, plugin manifests, and packaging218manual marketplace setup, workspace sharing, plugin manifests, and packaging

197guidance.219guidance.

198 220 

199If your plugin includes an app, see [Build an app](https://learn.chatgpt.com/docs/build-app). Apps are221If your plugin includes server-backed capabilities, see

200MCP-backed integrations. They can work with tools alone, or add custom ChatGPT UI222[Build an MCP server](https://developers.openai.com/plugins/build/mcp-server).

201through the [Apps SDK](https://developers.openai.com/apps-sdk) when a visual surface helps the workflow.223MCP tools can work without custom UI or return UI when a visual surface helps

224the workflow.

202 225 

203When your plugin is ready for review, see226When your plugin is ready for review, see

204[Submit plugins](https://learn.chatgpt.com/docs/submit-plugins) for the OpenAI Platform submission227[Submit plugins](https://developers.openai.com/plugins/deploy/submission) for the OpenAI Platform submission

205flow, required permissions, review materials, MCP checks, and test case228flow, required permissions, review materials, MCP checks, and test case

206requirements.229requirements.

207 230 

plugins/build.md +78 −681

Details

1# Build plugins1# Build plugins

2 2 

3This page is for plugin authors. If you want to browse, install, and use3To build or submit a plugin, use the complete

4plugins with ChatGPT Work on the web or with ChatGPT Work or Codex in the4[builder documentation on developers.openai.com](https://developers.openai.com/plugins).

5ChatGPT desktop app, see [Plugins](https://learn.chatgpt.com/docs/plugins). If you are still iterating on

6one repo or one personal workflow, start with a local skill. Build a plugin when

7you want to share that workflow across teams, bundle connectors or MCP config,

8package lifecycle hooks, or publish a stable package.

9 5 

10A plugin can include skills, an MCP-backed app, or both. If your plugin needs6<div className="not-prose my-6">

11to connect to a service or expose tools through an MCP server, see7 <ButtonLink href="/plugins" color="primary" variant="solid" size="lg">

12[Build an app](https://learn.chatgpt.com/docs/build-app).8 Build and submit a plugin

9 </ButtonLink>

10</div>

11 

12This page provides a brief introduction. A plugin is an installable package

13that can include skills, an MCP server, or both. An MCP server can also return

14optional UI.

15 

16ChatGPT and Codex share one universal plugin directory. Publish a public plugin

17once to make the same listing discoverable from supported surfaces in both

18products. During development, use a local marketplace to test the package

19before submitting it to the universal directory.

13 20 

14For complete public examples, inspect21Start with a skill when you are still iterating on one personal workflow.

15[Figma](https://github.com/openai/plugins/tree/main/plugins/figma),22Build a plugin when you want to share that workflow, package related skills,

16[Notion](https://github.com/openai/plugins/tree/main/plugins/notion), and23connect to an external service, or distribute a stable capability to a team.

17[Build web apps](https://github.com/openai/plugins/tree/main/plugins/build-web-apps).

18 24 

19## Create a plugin with `@plugin-creator`25## Create a plugin with `@plugin-creator`

20 26 

21For the fastest setup, use the built-in `@plugin-creator` skill.27For the fastest setup, use the built-in `@plugin-creator` skill in ChatGPT Work

28mode or `$plugin-creator` in Codex.

22 29 

23<CodexScreenshot30<CodexScreenshot

24 alt="Plugin creator skill in ChatGPT"31 alt="Plugin creator skill in ChatGPT"


26 darkSrc="/images/codex/plugins/plugin-creator-dark.png"33 darkSrc="/images/codex/plugins/plugin-creator-dark.png"

27/>34/>

28 35 

29It scaffolds the required `.codex-plugin/plugin.json` manifest and can also36Describe the outcome, the skills or MCP server to include, and whether you want

30generate a local marketplace entry for testing. If you already have a plugin37a local marketplace entry for testing. For example:

31folder, you can still use `@plugin-creator` to wire it into a local

32marketplace.

33 

34<CodexScreenshot

35 alt="how to invoke the plugin-creator skill"

36 lightSrc="/images/codex/plugins/plugin-creator-invoke.png"

37 darkSrc="/images/codex/plugins/plugin-creator-invoke-dark.png"

38/>

39 

40### Create and test a plugin locally that points to an MCP-server-backed dev-mode app

41 

42You can also use the plugin-creator skill if you want to test a plugin locally

43that includes an MCP-server backed app. The plugin still needs a local plugin

44folder and manifest, but the app itself starts in ChatGPT developer mode.

45 

46First, enable developer mode in ChatGPT:

47 

481. Open [ChatGPT](https://chatgpt.com).

492. Open **Settings**.

503. Select **Security and login**.

514. Turn on **Developer mode**.

52 

53Then create the app in developer mode:

54 

551. Open **Settings → Plugins** or [the Plugins page](https://chatgpt.com/plugins).

562. Select the plus button.

573. Complete the modal to create a developer-mode app for your MCP server.

584. After ChatGPT creates it, copy the app ID from the browser URL. It starts

59 with `plugin_asdk_app`.

60 

61Give that `plugin_asdk_app...` ID to `@plugin-creator` in a ChatGPT Work chat

62or `$plugin-creator` in Codex. For example, with ChatGPT Work:

63 

64<div class="not-prose my-6 overflow-hidden rounded-xl border border-subtle bg-surface shadow-sm">

65 <div class="border-b border-subtle bg-surface-secondary px-4 py-3">

66 <span class="inline-flex rounded-md bg-purple-100 px-2.5 py-1 text-sm font-medium text-purple-700 dark:bg-purple-950/60 dark:text-purple-200">

67 Plugin Creator prompt

68 </span>

69 </div>

70 <div class="overflow-x-auto p-4 font-mono text-sm leading-6 text-primary">

71 <code class="whitespace-pre-wrap break-words">{`@plugin-creator create a Codex plugin for my ChatGPT app.

72Use plugin_asdk_app_6a4c0062f3b88191855c0a80eac5d53d and name it Acme Support.

73Include a personal marketplace entry so I can test it locally.`}</code>

74 </div>

75</div>

76 

77The plugin-creator skill will create the plugin folder, create the required

78`.codex-plugin/plugin.json`, and add app wiring for the ChatGPT app. If you ask

79it to create a personal marketplace entry, the plugin appears under your local

80source in the Plugins Directory for testing.

81 

82After the plugin-creator skill creates the plugin:

83 38 

841. Review `.app.json` and confirm it points at the correct39```text

85 `plugin_asdk_app...` ID.40@plugin-creator Create a plugin named meeting-follow-up.

862. Review `.codex-plugin/plugin.json` and make sure its `apps` field points to41Include a skill that turns meeting notes into decisions, owners, and next steps.

87 `./.app.json`.42Add it to a personal marketplace so I can test it locally.

883. Add any bundled skills under `skills/` if the plugin should include43```

89 repeatable workflows alongside the app.

904. If the skill created a personal marketplace entry, refresh ChatGPT

91 and install the plugin from your local source in the Plugins Directory. Then

92 test it in a new chat.

93 

94For the manifest shape and file layout, see [Plugin structure](#plugin-structure)

95and [Path rules](#path-rules).

96 

97### Build your own curated plugin list

98 

99A marketplace is a JSON catalog of plugins. `@plugin-creator` can generate one

100for a single plugin, and you can keep adding entries to that same marketplace

101to build your own curated list for a repo, team, or personal workflow.

102 

103In ChatGPT Work or Codex in the ChatGPT desktop app, each marketplace appears as a

104selectable source in the Plugins Directory. Use

105`$REPO_ROOT/.agents/plugins/marketplace.json` for a repo-scoped list or

106`~/.agents/plugins/marketplace.json` for a personal list. Add one entry per

107plugin under `plugins[]`, point each `source.path` at the plugin folder with a

108`./`-prefixed path relative to the marketplace root, and set

109`interface.displayName` to the label you want the app to show in the marketplace

110picker. Then restart the ChatGPT desktop app. After that, open the Plugins

111Directory, choose your marketplace, and browse or install the plugins in that

112curated list.

113 44 

114You don't need a separate marketplace per plugin. One marketplace can expose a45The skill creates the required `.codex-plugin/plugin.json` manifest, organizes

115single plugin while you are testing, then grow into a larger curated catalog as46the plugin folder, and can add the plugin to a local marketplace.

116you add more plugins.

117 47 

118<CodexScreenshot48<CodexScreenshot

119 alt="custom local marketplace in the Plugins Directory"49 alt="Invoking the plugin creator skill"

120 lightSrc="/images/codex/plugins/codex-local-plugin-light.png"50 lightSrc="/images/codex/plugins/plugin-creator-invoke.png"

121 darkSrc="/images/codex/plugins/codex-local-plugin.png"51 darkSrc="/images/codex/plugins/plugin-creator-invoke-dark.png"

122/>52/>

123 53 

124### Add a marketplace from the CLI54After it finishes:

125 55 

126Use `codex plugin marketplace add` to add and track a marketplace source instead561. Review `.codex-plugin/plugin.json`.

127of editing `config.toml` by hand. These commands support plugin authoring and572. Check each bundled skill under `skills/`.

128catalog setup. Use the ChatGPT desktop app to install and test a local plugin.583. Refresh ChatGPT or Codex and install the plugin from its local marketplace

59 source.

604. Test the plugin in a new conversation with representative requests.

129 61 

130```bash62If the plugin includes an MCP server, first build and test that server, then

131codex plugin marketplace add owner/repo63give `@plugin-creator` the registered connection details. Follow the complete

132codex plugin marketplace add owner/repo --ref main64[MCP server workflow](https://developers.openai.com/plugins/build/mcp-server)

133codex plugin marketplace add https://github.com/example/plugins.git --sparse .agents/plugins65for tools, authentication, deployment, and testing.

134codex plugin marketplace add ./local-marketplace-root

135```

136 66 

137Marketplace sources can be GitHub shorthand (`owner/repo` or67## Create a skills-only plugin manually

138`owner/repo@ref`), HTTP or HTTPS Git URLs, SSH Git URLs, or local marketplace root

139directories. Use `--ref` to pin a Git ref, and repeat `--sparse PATH` to use a

140sparse checkout for Git-backed marketplace repos. `--sparse` is valid only for

141Git marketplace sources.

142 68 

143To inspect, refresh, or remove configured marketplaces:69A minimal plugin contains a manifest and at least one skill:

144 70 

145```bash71```text

146codex plugin marketplace list72meeting-follow-up/

147codex plugin marketplace upgrade73├── .codex-plugin/

148codex plugin marketplace upgrade marketplace-name74│ └── plugin.json

149codex plugin marketplace remove marketplace-name75└── skills/

76 └── meeting-follow-up/

77 └── SKILL.md

150```78```

151 79 

152`codex plugin marketplace list` prints each marketplace Codex is considering80Create `.codex-plugin/plugin.json`:

153and the root path it resolves from, including local default marketplaces and

154configured marketplace snapshots.

155 

156### Create a plugin manually

157 

158Start with a minimal plugin that packages one skill.

159 

1601. Create a plugin folder with a manifest at `.codex-plugin/plugin.json`.

161 

162```bash

163mkdir -p my-first-plugin/.codex-plugin

164```

165 

166`my-first-plugin/.codex-plugin/plugin.json`

167 81 

168```json82```json

169{83{

170 "name": "my-first-plugin",84 "name": "meeting-follow-up",

171 "version": "1.0.0",85 "version": "1.0.0",

172 "description": "Reusable greeting workflow",86 "description": "Turn meeting notes into decisions and next steps",

173 "skills": "./skills/"87 "skills": "./skills/"

174}88}

175```89```

176 90 

177Use a stable plugin `name` in kebab-case. Codex uses it as the plugin91Then add `skills/meeting-follow-up/SKILL.md`:

178identifier and component namespace.

179 

1802. Add a skill under `skills/<skill-name>/SKILL.md`.

181 

182```bash

183mkdir -p my-first-plugin/skills/hello

184```

185 

186`my-first-plugin/skills/hello/SKILL.md`

187 92 

188```md93```md

189---94---

190name: hello95name: meeting-follow-up

191description: Greet the user with a friendly message.96description: Extract decisions, owners, and next steps from meeting notes.

192---97---

193 98 

194Greet the user warmly and ask how you can help.99Review the meeting notes. Return:

195```

196 

1973. Add the plugin to a marketplace. Use `@plugin-creator` to generate one, or

198 follow [Build your own curated plugin list](#build-your-own-curated-plugin-list)

199 to wire the plugin into Codex manually.

200 

201From there, you can add MCP config, connectors, or marketplace metadata

202as needed.

203 

204### Install a local plugin manually

205 

206Use a repo marketplace or a personal marketplace, depending on who should be

207able to access the plugin or curated list.

208 

209<Tabs

210 id="codex-plugins-local-install"

211 param="install-scope"

212 defaultTab="workspace"

213 tabs={[

214 {

215 id: "workspace",

216 label: "Repo",

217 },

218 {

219 id: "global",

220 label: "Personal",

221 },

222 ]}

223>

224 <div slot="workspace">

225 Add a marketplace file at `$REPO_ROOT/.agents/plugins/marketplace.json`

226 and store your plugins under `$REPO_ROOT/plugins/`.

227 

228 **Repo marketplace example**

229 

230 Step 1: Copy the plugin folder into `$REPO_ROOT/plugins/my-plugin`.

231 

232```bash

233mkdir -p ./plugins

234cp -R /absolute/path/to/my-plugin ./plugins/my-plugin

235```

236 

237 Step 2: Add or update `$REPO_ROOT/.agents/plugins/marketplace.json` so

238 that `source.path` points to that plugin directory with a `./`-prefixed

239 relative path:

240 

241```json

242{

243 "name": "local-repo",

244 "plugins": [

245 {

246 "name": "my-plugin",

247 "source": {

248 "source": "local",

249 "path": "./plugins/my-plugin"

250 },

251 "policy": {

252 "installation": "AVAILABLE",

253 "authentication": "ON_INSTALL"

254 },

255 "category": "Productivity"

256 }

257 ]

258}

259```

260 

261 Step 3: Restart the ChatGPT desktop app and verify that the plugin appears.

262 

263 </div>

264 

265 <div slot="global">

266 Add a marketplace file at `~/.agents/plugins/marketplace.json` and store

267 your plugins under `~/.codex/plugins/`.

268 

269 **Personal marketplace example**

270 

271 Step 1: Copy the plugin folder into `~/.codex/plugins/my-plugin`.

272 

273```bash

274mkdir -p ~/.codex/plugins

275cp -R /absolute/path/to/my-plugin ~/.codex/plugins/my-plugin

276```

277 

278 Step 2: Add or update `~/.agents/plugins/marketplace.json` so that the

279 plugin entry's `source.path` points to that directory.

280 

281 Step 3: Restart the ChatGPT desktop app and verify that the plugin appears.

282 

283 </div>

284</Tabs>

285 

286The marketplace file points to the plugin location, so those directories are

287examples rather than fixed requirements. Codex resolves `source.path` relative

288to the marketplace root, not relative to the `.agents/plugins/` folder. See

289[Marketplace metadata](#marketplace-metadata) for the file format.

290 

291After you change the plugin, update the plugin directory that your marketplace

292entry points to and restart the ChatGPT desktop app so the local install picks

293up the new files.

294 

295### Share a local plugin with your workspace

296 

297After you create a plugin, add it from the ChatGPT desktop app. Select ChatGPT

298and switch to Work in the switcher, or select Codex, then open **Plugins**. You can then

299share it with other members of your ChatGPT workspace.

300 

3011. Open **Plugins** in the ChatGPT desktop app.

3022. Go to **Created by you** and open the plugin details page.

3033. Select **Share**.

3044. Add workspace members or workspace groups, or copy a share link.

3055. Choose who has access, then send the invitation or link.

306 

307People you share with can find the plugin under **Shared with you** in the

308Plugins Directory. Sharing a local plugin with your workspace doesn't publish

309it to the public Plugins Directory. Shared plugins stay within your workspace

310and organization boundary; accounts that aren't signed in to that workspace

311can't access them. Use groups when a team or role should share the same plugin

312access. Use a marketplace when you want repo or CLI distribution, and use

313workspace sharing when you want selected teammates to install a plugin from the

314ChatGPT desktop app.

315 

316Workspace admins can disable plugin sharing from cloud-managed requirements by

317adding `features.plugin_sharing = false` to `requirements.toml`:

318 

319```toml

320features.plugin_sharing = false

321```

322 

323### Marketplace metadata

324 

325If you maintain a repo marketplace, define it in

326`$REPO_ROOT/.agents/plugins/marketplace.json`. For a personal marketplace, use

327`~/.agents/plugins/marketplace.json`. A marketplace file controls plugin

328ordering and install policies in the ChatGPT desktop app. It can represent one

329plugin while you are testing or a curated list of plugins that you want the app

330to show together under one marketplace name. Before you add a plugin to a

331marketplace, make sure its `version`, publisher metadata, and install-surface

332copy are ready for other developers to see.

333 

334```json

335{

336 "name": "local-example-plugins",

337 "interface": {

338 "displayName": "Local Example Plugins"

339 },

340 "plugins": [

341 {

342 "name": "my-plugin",

343 "source": {

344 "source": "local",

345 "path": "./plugins/my-plugin"

346 },

347 "policy": {

348 "installation": "AVAILABLE",

349 "authentication": "ON_INSTALL"

350 },

351 "category": "Productivity"

352 },

353 {

354 "name": "research-helper",

355 "source": {

356 "source": "local",

357 "path": "./plugins/research-helper"

358 },

359 "policy": {

360 "installation": "AVAILABLE",

361 "authentication": "ON_INSTALL"

362 },

363 "category": "Productivity"

364 }

365 ]

366}

367```

368 

369- Use top-level `name` to identify the marketplace.

370- Use `interface.displayName` for the marketplace title shown in the ChatGPT

371 desktop app.

372- Add one object per plugin under `plugins` to build a curated list that the app

373 shows under that marketplace title.

374- Point each plugin entry's `source.path` at the plugin directory you want

375 Codex to load. For repo installs, that often lives under `./plugins/`. For

376 personal installs, a common pattern is `./.codex/plugins/<plugin-name>`.

377- Keep `source.path` relative to the marketplace root, start it with `./`, and

378 keep it inside that root.

379- For local entries, `source` can also be a plain string path such as

380 `"./plugins/my-plugin"`.

381- Always include `policy.installation`, `policy.authentication`, and

382 `category` on each plugin entry.

383- Use `policy.installation` values such as `AVAILABLE`,

384 `INSTALLED_BY_DEFAULT`, or `NOT_AVAILABLE`.

385- Use `policy.authentication` to decide whether auth happens on install or

386 first use.

387 

388The marketplace controls where Codex loads the plugin from. A local

389`source.path` can point somewhere else if your plugin lives outside those

390example directories. A marketplace file can live in the repo where you are

391developing the plugin or in a separate marketplace repo, and one marketplace

392file can point to one plugin or many.

393 

394Marketplace entries can also point at Git-backed plugin sources. Use

395`"source": "url"` when the plugin lives at the repository root, or

396`"source": "git-subdir"` when the plugin lives in a subdirectory:

397 

398```json

399{

400 "name": "remote-helper",

401 "source": {

402 "source": "git-subdir",

403 "url": "https://github.com/example/codex-plugins.git",

404 "path": "./plugins/remote-helper",

405 "ref": "main"

406 },

407 "policy": {

408 "installation": "AVAILABLE",

409 "authentication": "ON_INSTALL"

410 },

411 "category": "Productivity"

412}

413```

414 

415Git-backed entries may use `ref` or `sha` selectors. If Codex can't resolve a

416marketplace entry's source, it skips that plugin entry instead of failing the

417whole marketplace.

418 

419Marketplace entries can also install a plugin from a JavaScript package registry:

420 

421```json

422{

423 "name": "npm-helper",

424 "source": {

425 "source": "npm",

426 "package": "@example/codex-plugin",

427 "version": "^1.2.0",

428 "registry": "https://registry.npmjs.org"

429 },

430 "policy": {

431 "installation": "AVAILABLE",

432 "authentication": "ON_INSTALL"

433 },

434 "category": "Productivity"

435}

436```

437 

438`package` is required and can include a registry scope. `version` is optional

439and accepts package versions, distribution tags, and version ranges, but not

440path or URL selectors.

441`registry` is optional and must be an HTTPS URL without embedded credentials,

442a query, or a fragment. Codex downloads the package without running lifecycle

443scripts. The `npm` CLI must be installed, and registry authentication comes

444from its configuration.

445 

446### How the ChatGPT desktop app uses marketplaces

447 

448A plugin marketplace is a JSON catalog of plugins that the ChatGPT desktop app

449can read and install.

450 

451The app can read marketplace files from:

452 

453- the curated marketplace that powers the official Plugins Directory

454- a repo marketplace at `$REPO_ROOT/.agents/plugins/marketplace.json`

455- a legacy-compatible marketplace at `$REPO_ROOT/.claude-plugin/marketplace.json`

456- a personal marketplace at `~/.agents/plugins/marketplace.json`

457 

458You can install any plugin exposed through a marketplace. The app installs

459plugins into

460`~/.codex/plugins/cache/$MARKETPLACE_NAME/$PLUGIN_NAME/$VERSION/`. For local

461plugins, `$VERSION` is `local`, and the app loads the installed copy from that

462cache path rather than directly from the marketplace entry.

463 

464You can enable or disable each plugin individually. The app stores each plugin's

465on or off state in `~/.codex/config.toml`.

466 

467## Package and distribute plugins

468 

469### Plugin structure

470 

471Every plugin has a manifest at `.codex-plugin/plugin.json`. It can also include

472a `skills/` directory, a `hooks/` directory for lifecycle hooks, an `.app.json`

473file that points at one or more connectors, an `.mcp.json` file that

474configures MCP servers, and assets used to present the plugin across supported

475surfaces.

476 

477<FileTree

478 class="mt-4"

479 tree={[

480 {

481 name: "my-plugin/",

482 open: true,

483 children: [

484 {

485 name: ".codex-plugin/",

486 open: true,

487 children: [

488 {

489 name: "plugin.json",

490 comment: "Required: plugin manifest",

491 },

492 ],

493 },

494 {

495 name: "skills/",

496 open: true,

497 children: [

498 {

499 name: "my-skill/",

500 open: true,

501 children: [

502 {

503 name: "SKILL.md",

504 comment: "Optional: skill instructions",

505 },

506 ],

507 },

508 ],

509 },

510 {

511 name: "hooks/",

512 open: true,

513 children: [

514 {

515 name: "hooks.json",

516 comment: "Optional: lifecycle hooks",

517 },

518 ],

519 },

520 {

521 name: ".app.json",

522 comment: "Optional: app or connector mappings",

523 },

524 {

525 name: ".mcp.json",

526 comment: "Optional: MCP server configuration",

527 },

528 {

529 name: "assets/",

530 comment: "Optional: icons, logos, screenshots",

531 },

532 ],

533 },

534 ]}

535/>

536 

537Only `plugin.json` belongs in `.codex-plugin/`. Keep `skills/`, `hooks/`,

538`assets/`, `.mcp.json`, and `.app.json` at the plugin root.

539 

540Published plugins typically use a richer manifest than the minimal example that

541appears in quick-start scaffolds. The manifest has three jobs:

542 

543- Identify the plugin.

544- Point to bundled components such as skills, connectors, MCP servers, or hooks.

545- Provide install-surface metadata such as descriptions, icons, and legal

546 links.

547 

548Here's a complete manifest example:

549 

550```json

551{

552 "name": "my-plugin",

553 "version": "0.1.0",

554 "description": "Bundle reusable skills and connectors.",

555 "author": {

556 "name": "Your team",

557 "email": "team@example.com",

558 "url": "https://example.com"

559 },

560 "homepage": "https://example.com/plugins/my-plugin",

561 "repository": "https://github.com/example/my-plugin",

562 "license": "MIT",

563 "keywords": ["research", "crm"],

564 "skills": "./skills/",

565 "mcpServers": "./.mcp.json",

566 "apps": "./.app.json",

567 "hooks": "./hooks/hooks.json",

568 "interface": {

569 "displayName": "My Plugin",

570 "shortDescription": "Reusable skills and connectors",

571 "longDescription": "Distribute skills and connectors together.",

572 "developerName": "Your team",

573 "category": "Productivity",

574 "capabilities": ["Read", "Write"],

575 "websiteURL": "https://example.com",

576 "privacyPolicyURL": "https://example.com/privacy",

577 "termsOfServiceURL": "https://example.com/terms",

578 "defaultPrompt": [

579 "Use My Plugin to summarize new CRM notes.",

580 "Use My Plugin to triage new customer follow-ups."

581 ],

582 "brandColor": "#10A37F",

583 "composerIcon": "./assets/icon.png",

584 "logo": "./assets/logo.png",

585 "screenshots": ["./assets/screenshot-1.png"]

586 }

587}

588```

589 

590`.codex-plugin/plugin.json` is the required entry point. The other manifest

591fields are optional, but published plugins commonly use them.

592 

593### Manifest fields

594 

595Use the top-level fields to define package metadata and point to bundled

596components:

597 

598- `name`, `version`, and `description` identify the plugin.

599- `author`, `homepage`, `repository`, `license`, and `keywords` provide

600 publisher and discovery metadata.

601- `skills`, `mcpServers`, `apps`, and `hooks` point to bundled components

602 relative to the plugin root.

603- `interface` controls how install surfaces present the plugin.

604 

605Use the `interface` object for install-surface metadata:

606 

607- `displayName`, `shortDescription`, and `longDescription` control the title

608 and descriptive copy.

609- `developerName`, `category`, and `capabilities` add publisher and capability

610 metadata.

611- `websiteURL`, `privacyPolicyURL`, and `termsOfServiceURL` provide external

612 links.

613- `defaultPrompt`, `brandColor`, `composerIcon`, `logo`, and `screenshots`

614 control starter prompts and visual presentation.

615 

616### Path rules

617 

618- Keep manifest paths relative to the plugin root and start them with `./`.

619- Store visual assets such as `composerIcon`, `logo`, and `screenshots` under

620 `./assets/` when possible.

621- Use `skills` for bundled skill folders, `apps` for `.app.json`,

622 `mcpServers` for `.mcp.json`, and `hooks` for lifecycle hooks.

623- Enabled plugins can include lifecycle hooks alongside skills, MCP servers, and

624 connectors.

625- If your plugin stores hooks at `./hooks/hooks.json`, you don't need a

626 `hooks` entry in `.codex-plugin/plugin.json`; Codex checks that default file

627 automatically.

628 

629### Bundled MCP servers and lifecycle hooks

630 

631`mcpServers` can point to an `.mcp.json` file that contains either a direct

632server map or a wrapped `mcp_servers` object.

633 

634Direct server map:

635 

636```json

637{

638 "docs": {

639 "command": "docs-mcp",

640 "args": ["--stdio"]

641 }

642}

643```

644 

645Wrapped server map:

646 

647```json

648{

649 "mcp_servers": {

650 "docs": {

651 "command": "docs-mcp",

652 "args": ["--stdio"]

653 }

654 }

655}

656```

657 

658After installation, users can enable or disable a bundled MCP server and tune

659tool approval policy from their Codex config without editing the plugin. Use

660`plugins.<plugin>.mcp_servers.<server>` for plugin-scoped MCP server policy:

661 100 

662```toml1011. Decisions

663[plugins."my-plugin".mcp_servers.docs]1022. Action items with owners

664enabled = true1033. Open questions

665default_tools_approval_mode = "prompt"

666enabled_tools = ["search"]

667 

668[plugins."my-plugin".mcp_servers.docs.tools.search]

669approval_mode = "approve"

670```104```

671 105 

672When your plugin is enabled, Codex can load lifecycle hooks from your plugin106Use a stable plugin name in kebab case. Keep the skill description specific

673alongside user, project, and managed hooks.107enough for ChatGPT and Codex to recognize when the workflow applies.

674 

675Installing or enabling a plugin doesn't automatically trust its hooks.

676Plugin-bundled hooks are non-managed hooks, so Codex skips them until the user

677reviews and trusts the current hook definition.

678 

679The default plugin hook file is `hooks/hooks.json`:

680 

681```json

682{

683 "hooks": {

684 "SessionStart": [

685 {

686 "hooks": [

687 {

688 "type": "command",

689 "command": "python3 ${PLUGIN_ROOT}/hooks/session_start.py",

690 "statusMessage": "Loading plugin context"

691 }

692 ]

693 }

694 ]

695 }

696}

697```

698 

699If you define `hooks` in `.codex-plugin/plugin.json`, Codex uses that manifest

700entry instead of the default `hooks/hooks.json`. The manifest field can be a

701single path, an array of paths, an inline hooks object, or an array of inline

702hooks objects.

703 

704```json

705{

706 "name": "repo-policy",

707 "hooks": ["./hooks/session.json", "./hooks/tools.json"]

708}

709```

710 108 

711Hook paths follow the same manifest path rules as `skills`, `apps`, and109Use `@plugin-creator` to add the folder to a local marketplace, then install and

712`mcpServers`: start with `./`, resolve relative to the plugin root, and stay110test it before sharing it.

713inside the plugin root.

714 111 

715Plugin hook commands receive the Codex-specific environment variables112## Continue with the builder documentation

716`PLUGIN_ROOT` and `PLUGIN_DATA`. `PLUGIN_ROOT` points to the installed plugin

717root, and `PLUGIN_DATA` points to the plugin's writable data directory. Codex

718also sets `CLAUDE_PLUGIN_ROOT` and `CLAUDE_PLUGIN_DATA` for compatibility with

719existing plugin hooks.

720 113 

721Plugin hooks use the same event schema as regular hooks. See114For complete builder documentation, use the

722[Hooks](https://learn.chatgpt.com/docs/hooks) for supported events, inputs, outputs, trust review, and115[Plugins documentation](https://developers.openai.com/plugins/). It covers:

723current limitations.

724 116 

725### Publish official public plugins117- [Plugin architecture](https://developers.openai.com/plugins/concepts/plugins)

118- [Building skills](https://developers.openai.com/plugins/build/skills)

119- [Building an MCP server](https://developers.openai.com/plugins/build/mcp-server)

120- [Adding optional UI](https://developers.openai.com/plugins/build/chatgpt-ui)

121- [Packaging a plugin](https://developers.openai.com/plugins/build/plugins)

122- [Testing a plugin](https://developers.openai.com/plugins/deploy/connect-chatgpt)

123- [Submitting and publishing](https://developers.openai.com/plugins/deploy/submission)

726 124 

727To publish a plugin for public use, submit it through the plugin submission125To browse, install, enable, or remove plugins, see [Use

728portal. See [Submit plugins](https://learn.chatgpt.com/docs/submit-plugins) for the full review and126plugins](https://learn.chatgpt.com/docs/plugins).

729publishing process.

prompting.md +6 −5

Details

67 67 

68### Use plugins68### Use plugins

69 69 

70Plugins give ChatGPT reusable instructions and connections to tools such as70Plugins give ChatGPT and Codex reusable instructions and connections to tools

71Google Drive, Gmail, Slack, and GitHub. Ask for the result you need and let71such as Google Drive, Gmail, Slack, and GitHub. Both products draw public

72ChatGPT choose from the tools available to it. To choose a specific plugin, type72plugins from the same universal directory. Ask for the result you need and let

73`@` in the composer.73the active surface choose from the tools available to it. In ChatGPT, type `@`

74in the composer to choose a specific plugin.

74 75 

75[<IconItem title="Learn about plugins" className="mt-4">76[<IconItem title="Learn about plugins" className="mt-4">

76 <span slot="icon">77 <span slot="icon">

77 <Plugin />78 <Plugin />

78 </span>79 </span>

79 Find, install, and use plugins in ChatGPT.80 Find, install, and use plugins in ChatGPT and Codex.

80 </IconItem>](https://learn.chatgpt.com/docs/plugins)81 </IconItem>](https://learn.chatgpt.com/docs/plugins)

81 82 

82### Personalize ChatGPT83### Personalize ChatGPT

Details

10 10 

11For example, you might record how you file an expense, book a parking space,11For example, you might record how you file an expense, book a parking space,

12create a correctly configured issue, publish a video, or download a recurring12create a correctly configured issue, publish a video, or download a recurring

13report. Codex can package the pattern into a skill that you can use again with13report. ChatGPT or Codex can package the pattern into a skill that you can use

14Computer Use, browser actions, connected plugins, or a combination of them.14again with Computer Use, browser actions, connected plugins, or a combination

15of them.

15 16 

16## Before you start17## Before you start

17 18 


251. In the ChatGPT desktop app, select ChatGPT and turn on Work in the switcher, or select Codex. Then open **Plugins**.261. In the ChatGPT desktop app, select ChatGPT and turn on Work in the switcher, or select Codex. Then open **Plugins**.

262. Open the **+** menu.272. Open the **+** menu.

273. Select **Record a skill**.283. Select **Record a skill**.

284. Review the suggested prompt, give Codex any helpful context, and submit it.294. Review the suggested prompt, add any helpful context, and submit it.

295. When Codex asks for permission to record your actions, approve the request305. When the chat asks for permission to record your actions, approve the

30 once you are ready to demonstrate the workflow.31 request once you are ready to demonstrate the workflow.

316. Perform the workflow on your Mac.326. Perform the workflow on your Mac.

327. When you are done, stop recording from the menu bar, overlay, or tell Codex337. When you are done, stop recording from the menu bar or overlay, or tell the

33 that you are done.34 chat that you are done.

34 35 

35</WorkflowSteps>36</WorkflowSteps>

36 37 

37During recording, Codex observes the actions and window content needed to learn38During recording, ChatGPT or Codex observes the actions and window content

38the workflow. Recording continues until you stop it. Keep the recording focused39needed to learn the workflow. Recording continues until you stop it. Keep the

39on the task you want Codex to learn.40recording focused on the task you want the skill to teach.

40 41 

41After you stop recording, Codex inspects the captured workflow and drafts a42After you stop recording, ChatGPT or Codex inspects the captured workflow and

42skill. The skill explains when to use the workflow, what inputs it needs, what43drafts a skill. The skill explains when to use the workflow, what inputs it

43steps to follow, and how to verify the result. You can also ask Codex to44needs, what steps to follow, and how to verify the result. You can also ask for

44refine the skill further.45further refinements.

45 46 

46## Replay the workflow47## Replay the workflow

47 48 

48Start a new chat and ask Codex to use the generated skill. Give it the49Start a new ChatGPT or Codex chat and ask it to use the generated skill. Give

49values that are different this time, such as the file to upload, the issue to50it the values that are different this time, such as the file to upload, the

50create, or the date range for the report.51issue to create, or the date range for the report.

51 52 

52Codex uses the skill as reusable context for the task. It can then complete the53The product uses the skill as reusable context for the task. It can then

53workflow with the tools available in the current environment, including54complete the workflow with the tools available in the current environment,

54Computer Use, browser actions, and installed plugins.55including Computer Use, browser actions, and installed plugins.

55 56 

56## Tips for better recordings57## Tips for better recordings

57 58 

58- Keep the demonstration short and complete.59- Keep the demonstration short and complete.

59- Let Codex know your goal and any specific inputs that might vary between60- State your goal and any specific inputs that might vary between

60 skill uses before you start recording.61 skill uses before you start recording.

61- Use realistic inputs, but avoid secrets and sensitive data.62- Use realistic inputs, but avoid secrets and sensitive data.

62- Refine the skill after recording to call out hidden preferences that matter,63- Refine the skill after recording to call out hidden preferences that matter,


70If you want to distribute a separate stable package across a team, bundle71If you want to distribute a separate stable package across a team, bundle

71multiple skills, include connectors, add MCP servers, or manage install72multiple skills, include connectors, add MCP servers, or manage install

72metadata, package that workflow as its own plugin. See73metadata, package that workflow as its own plugin. See

73[Build plugins](https://learn.chatgpt.com/docs/build-plugins).74[Build plugins](https://developers.openai.com/plugins/build/plugins).

74 75 

75## Troubleshooting76## Troubleshooting

76 77 

Details

133Use a dedicated always-on Mac or Windows PC when you want ChatGPT to stay133Use a dedicated always-on Mac or Windows PC when you want ChatGPT to stay

134reachable for longer-running work.134reachable for longer-running work.

135 135 

136Install the projects, credentials, MCP servers, skills, and tools ChatGPT should136Install the projects, credentials, MCP servers, skills, and tools ChatGPT or

137use on that machine.137Codex should use on that machine.

138 138 

139### <span class="not-prose inline-flex items-center gap-3 align-middle"><span class="inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-surface-secondary text-secondary"><Terminal width={17} height={17} /></span><span>A remote development environment</span></span>139### <span class="not-prose inline-flex items-center gap-3 align-middle"><span class="inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-surface-secondary text-secondary"><Terminal width={17} height={17} /></span><span>A remote development environment</span></span>

140 140 

skills.md +52 −24

Details

1# Build skills1# Build skills

2 2 

3Use agent skills to extend Codex with task-specific capabilities. A skill packages instructions, resources, and optional scripts so Codex can follow a workflow reliably. Skills build on the [open agent skills standard](https://agentskills.io).3Use agent skills to extend ChatGPT and Codex with task-specific capabilities. A

4 4skill packages instructions, resources, and optional scripts so either product

5Skills are the authoring format for reusable workflows. Plugins distribute reusable skills and connectors to ChatGPT Work on the web and to ChatGPT Work and Codex in the desktop app. Codex CLI can also install plugins. Use skills to design the workflow itself, then package it as a [plugin](https://learn.chatgpt.com/docs/build-plugins) when you want other people in your workspace to install it.5can follow a workflow reliably. Skills build on the

6 6[open agent skills standard](https://agentskills.io).

7Skills are available in the ChatGPT desktop app, Codex CLI, and IDE extension.7 

8Skills are the authoring format for reusable workflows. Plugins distribute

9reusable skills and connectors through the universal plugin directory shared

10by ChatGPT and Codex. Plugins are available with ChatGPT Work on the web, with

11ChatGPT Work and Codex in the ChatGPT desktop app, and through Codex CLI. Use

12skills to design the workflow itself, then package it as a

13[plugin](https://developers.openai.com/plugins/build/plugins) when you want

14other people to install it.

15 

16Standalone skills are available in the ChatGPT desktop app, Codex CLI, and IDE

17extension. Skills bundled in plugins are also available through supported

18plugin surfaces, including ChatGPT Work on the web.

8 19 

9In the ChatGPT desktop app, open **Skills** in the sidebar to view and explore skills20In the ChatGPT desktop app, open **Skills** in the sidebar to view and explore skills

10created across your projects.21created across your projects.


17 class="my-8"28 class="my-8"

18/>29/>

19 30 

20Skills use **progressive disclosure** to manage context efficiently: Codex starts with each skill's name, description, and file path. Codex loads the full `SKILL.md` instructions only when it decides to use a skill.31Skills use **progressive disclosure** to manage context efficiently. ChatGPT and

32Codex start with each skill's name and description, then load the full

33`SKILL.md` instructions when they decide to use that skill.

21 34 

22Codex includes an initial list of available skills in context so it can choose the right skill for a task. To avoid crowding out the rest of the prompt, this list uses at most 2% of the model’s context window, or 8,000 characters when the context window is unknown. If many skills are installed, Codex shortens skill descriptions first. For large skill sets, Codex may omit some skills from the initial list and show a warning.35In Codex, the initial list also includes each skill's file path. To avoid

36crowding out the rest of the prompt, this list uses at most 2% of the model's

37context window, or 8,000 characters when the context window is unknown. If many

38skills are installed, Codex shortens skill descriptions first. For large skill

39sets, Codex may omit some skills from the initial list and show a warning.

23 40 

24This budget applies only to the initial skills list. When Codex selects a skill, it still reads the full SKILL.md instructions for that skill.41This budget applies only to the initial skills list. When Codex selects a skill, it still reads the full SKILL.md instructions for that skill.

25 42 


64]}81]}

65/>82/>

66 83 

67## How Codex uses skills84<a id="how-codex-uses-skills"></a>

68 85 

69Codex can activate skills in two ways:86## How ChatGPT and Codex use skills

70 87 

711. **Explicit invocation:** Include the skill directly in your prompt. In CLI/IDE, run `/skills` or type `$` to mention a skill.88ChatGPT and Codex can activate skills in two ways:

722. **Implicit invocation:** Codex can choose a skill when your task matches the skill `description`.

73 89 

74Because implicit matching depends on `description`, write concise descriptions with clear scope and boundaries. Front-load the key use case and trigger words so Codex can still match the skill if descriptions are shortened.901. **Explicit invocation:** Include the skill directly in your prompt. In

91 ChatGPT, type `@` to select a skill. In Codex CLI or the IDE extension, run

92 `/skills` or type `$` to mention a skill.

932. **Implicit invocation:** ChatGPT or Codex can choose a skill when your task

94 matches the skill `description`.

95 

96Because implicit matching depends on `description`, write concise descriptions

97with clear scope and boundaries. Front-load the key use case and trigger words

98so a host can still match the skill if descriptions are shortened.

75 99 

76## Create a skill100## Create a skill

77 101 

78If you already know the workflow and it's easier to show than describe, use102If you already know the workflow and it's easier to show than describe, use

79[Record & Replay](https://learn.chatgpt.com/docs/extend/record-and-replay). Codex records the workflow,103[Record & Replay](https://learn.chatgpt.com/docs/extend/record-and-replay). The recorder captures the

80inspects the steps, and drafts a reusable skill from the demonstration.104workflow, inspects the steps, and drafts a reusable skill from the

105demonstration.

81 106 

82If you want to describe the skill instead, use the built-in creator:107If you want to describe the skill instead, use the built-in creator. In ChatGPT

108Work, invoke it as `@skill-creator`. In Codex, invoke it as:

83 109 

84```text110```text

85$skill-creator111$skill-creator


95description: Explain exactly when this skill should and should not trigger.121description: Explain exactly when this skill should and should not trigger.

96---122---

97 123 

98Skill instructions for Codex to follow.124Skill instructions for ChatGPT or Codex to follow.

99```125```

100 126 

101Codex detects skill changes automatically. If an update doesn't appear, restart Codex.127Codex detects skill changes automatically. If an update doesn't appear, restart Codex.

102 128 

103## Where to save skills129<a id="where-to-save-skills"></a>

130 

131## Where Codex loads local skills

104 132 

105Codex reads skills from repository, user, admin, and system locations. For repositories, Codex scans `.agents/skills` in every directory from your current working directory up to the repository root. If two skills share the same `name`, Codex doesn't merge them; both can appear in skill selectors.133Codex reads skills from repository, user, admin, and system locations. For repositories, Codex scans `.agents/skills` in every directory from your current working directory up to the repository root. If two skills share the same `name`, Codex doesn't merge them; both can appear in skill selectors.

106 134 


117 145 

118These locations are for authoring and local discovery. When you want to146These locations are for authoring and local discovery. When you want to

119distribute reusable skills beyond a single repo, or optionally bundle them with147distribute reusable skills beyond a single repo, or optionally bundle them with

120connectors, use [plugins](https://learn.chatgpt.com/docs/build-plugins).148connectors, use [plugins](https://developers.openai.com/plugins/build/plugins).

121 149 

122## Distribute skills with plugins150## Distribute skills with plugins

123 151 

124Direct skill folders are best for local authoring and repo-scoped workflows. If152Direct skill folders are best for local authoring and repo-scoped workflows. If

125you want to distribute a reusable skill, bundle two or more skills together, or153you want to distribute a reusable skill, bundle two or more skills together, or

126ship a skill alongside a connector, package them as a154ship a skill alongside a connector, package them as a

127[plugin](https://learn.chatgpt.com/docs/build-plugins).155[plugin](https://developers.openai.com/plugins/build/plugins).

128 156 

129Plugins can include one or more skills. They can also optionally bundle app157Plugins can include one or more skills. They can also optionally bundle

130mappings, MCP server configuration, and presentation assets in a single158registered MCP server connections, bundled MCP server configuration, and

131package.159presentation assets in a single package.

132 160 

133## Install curated skills for local use161## Install curated skills for local use

134 162 


145Use this for local setup and experimentation. For reusable distribution of your173Use this for local setup and experimentation. For reusable distribution of your

146own skills, prefer plugins.174own skills, prefer plugins.

147 175 

148## Enable or disable skills176## Enable or disable local Codex skills

149 177 

150Use `[[skills.config]]` entries in `~/.codex/config.toml` to disable a skill without deleting it:178Use `[[skills.config]]` entries in `~/.codex/config.toml` to disable a skill without deleting it:

151 179 


197[Linear](https://github.com/openai/skills/tree/main/skills/.curated/linear),225[Linear](https://github.com/openai/skills/tree/main/skills/.curated/linear),

198[openai/skills](https://github.com/openai/skills), and the226[openai/skills](https://github.com/openai/skills), and the

199[agent skills specification](https://agentskills.io/specification). For227[agent skills specification](https://agentskills.io/specification). For

200installable distribution, prefer [plugins](https://learn.chatgpt.com/docs/build-plugins).228installable distribution, prefer [plugins](https://developers.openai.com/plugins/build/plugins).

Details

1# Skills & Plugins1# Skills & Plugins

2 2 

3Skills and plugins help ChatGPT complete repeatable work with the right3Skills and plugins help ChatGPT and Codex complete repeatable work with the

4instructions, resources, and tools. They reduce the need to paste the same4right instructions, resources, and tools. They reduce the need to paste the

5prompt, template, requirements, or process into every chat.5same prompt, template, requirements, or process into every chat.

6 6 

7- A **skill** packages instructions and supporting resources for a specific7- A **skill** packages instructions and supporting resources for a specific

8 task or workflow.8 task or workflow.


12 12 

13## Use skills for repeatable work13## Use skills for repeatable work

14 14 

15A skill is a reusable workflow that gives ChatGPT task-specific guidance. It15A skill is a reusable workflow that gives ChatGPT or Codex task-specific

16can capture the way you already perform recurring work so ChatGPT follows the16guidance. It can capture the way you already perform recurring work so either

17same process whenever that task comes up.17product follows the same process whenever that task comes up.

18 18 

19A skill can combine:19A skill can combine:

20 20 

21- A name and description that help ChatGPT recognize when the skill applies.21- A name and description that help ChatGPT and Codex recognize when the skill

22 applies.

22- Workflow instructions that define the process and expected result.23- Workflow instructions that define the process and expected result.

23- Supporting resources such as templates, examples, brand guidance, schemas,24- Supporting resources such as templates, examples, brand guidance, schemas,

24 or connected tools.25 or connected tools.


32workflow, and share a standard process instead of relying on undocumented33workflow, and share a standard process instead of relying on undocumented

33knowledge.34knowledge.

34 35 

35ChatGPT can choose a skill when your request matches its purpose. You can also36ChatGPT and Codex can choose a skill when your request matches its purpose. You

36select one explicitly from the composer. ChatGPT supports `@` mentions, while37can also select one explicitly. ChatGPT supports `@` mentions, while Codex

37Codex supports `$` mentions for skills.38supports `$` mentions for skills.

38 39 

39## Build skills40## Build skills

40 41 

41You can start by turning a task you already repeat into a simple playbook for42You can start by turning a task you already repeat into a focused playbook for

42ChatGPT. Good first skills include a weekly update, a campaign brief, a meeting43ChatGPT and Codex. Good first skills include a weekly update, a campaign brief,

43follow-up, or any task where the steps and format should stay consistent.44a meeting follow-up, or any task where the steps and format should stay

45consistent.

44 46 

45To build a useful skill:47To build a useful skill:

46 48 

471. **Choose one focused task.** Note what you normally start with, such as491. **Choose one focused task.** Note what you normally start with, such as

48 files, links, or notes, and what a finished result should look like.50 files, links, or notes, and what a finished result should look like.

492. **Describe the workflow to ChatGPT.** Start a new chat with “Build me a512. **Describe the workflow.** In ChatGPT, start with `@skill-creator`; in Codex,

50 skill…” and explain the goal, the steps to follow, the expected format, and52 use `$skill-creator`. Explain the goal, the steps to follow, the expected

51 anything it should always include or avoid. Add a template or a good example53 format, and anything the skill should always include or avoid. Add a template

52 when you have one.54 or a good example when you have one.

533. **Review and try the draft.** Check the instructions, test the skill with a553. **Review and try the draft.** Check the instructions, test the skill with a

54 realistic request, and refine it if the result misses a step or drifts from56 realistic request, and refine it if the result misses a step or drifts from

55 the format you want.57 the format you want.

564. **Install and reuse it.** Once the skill is enabled, ChatGPT can use it for584. **Install and reuse it.** Once the skill is enabled, ChatGPT or Codex can use

57 relevant requests, or you can select it explicitly. You can also share it59 it for relevant requests, or you can select it explicitly. You can also

58 with teammates when your workspace settings allow it.60 share it with teammates when your workspace settings allow it.

59 61 

60For more details on building skills, see our dedicated guide below.62For more details on building skills, see our dedicated guide below.

61 63 


63 <span slot="icon">65 <span slot="icon">

64 <Tools />66 <Tools />

65 </span>67 </span>

66 Create, test, and share reusable skills with Codex.68 Create, test, and share reusable skills with ChatGPT and Codex.

67 </IconItem>](https://learn.chatgpt.com/docs/build-skills)69 </IconItem>](https://learn.chatgpt.com/docs/build-skills)

68 70 

69## Use plugins for tools and shared workflows71## Use plugins for tools and shared workflows


72combine skills with connectors for services such as GitHub, Google Drive, or74combine skills with connectors for services such as GitHub, Google Drive, or

73Slack, and can include MCP servers for additional tools and context.75Slack, and can include MCP servers for additional tools and context.

74 76 

75Browse the Plugins Directory when you want to add an existing workflow instead77ChatGPT and Codex share one universal plugin directory. Browse it when you want

76of building one yourself. After installing a plugin, describe the task directly78to add an existing workflow instead of building one yourself. After installing

77or type `@` to choose a specific plugin or bundled skill.79a plugin, describe the task directly or explicitly choose a plugin or bundled

80skill using the invocation syntax for your surface.

78 81 

79[Learn how to install and use plugins](https://learn.chatgpt.com/docs/plugins).82[Learn how to install and use plugins](https://learn.chatgpt.com/docs/plugins).

80 83 


87You can also demonstrate a workflow with90You can also demonstrate a workflow with

88[Record & Replay](https://learn.chatgpt.com/docs/extend/record-and-replay), which turns the recording into a91[Record & Replay](https://learn.chatgpt.com/docs/extend/record-and-replay), which turns the recording into a

89reusable skill. To package and distribute your own bundle, see92reusable skill. To package and distribute your own bundle, see

90[Build plugins](https://learn.chatgpt.com/docs/build-plugins).93[Build plugins](https://developers.openai.com/plugins/build/plugins).

91 94 

92If your plugin needs to connect to a service or expose MCP tools, see95If your plugin needs to connect to a service or expose MCP tools, see

93[Build an app](https://learn.chatgpt.com/docs/build-app). When your plugin is ready for public review,96[Build an MCP server](https://developers.openai.com/plugins/build/mcp-server). When your plugin is ready for public review,

94see [Submit plugins](https://learn.chatgpt.com/docs/submit-plugins).97see [Submit plugins](https://developers.openai.com/plugins/deploy/submission).

95 98 

96For more examples of reusable workflows, see [Using skills in OpenAI99For more examples of reusable workflows, see [Using skills in OpenAI

97Academy](https://openai.com/academy/skills/).100Academy](https://openai.com/academy/skills/).

submit-plugins.md +0 −339 deleted

File Deleted View Diff

1# Submit plugins

2 

3Use the plugin submission portal to submit a plugin for review when you're

4ready to publish it for public use.

5 

6A plugin is an app, skills, or both. You can submit:

7 

8- A skills-only plugin that packages reusable workflows.

9- An app-only plugin backed by an MCP server. Custom UI is optional.

10- An app-plus-skills plugin that combines an MCP-backed app with bundled skills.

11 

12The submission form collects listing information, MCP server details, bundled

13skills, starter prompts, test cases, country availability, and policy

14attestations. Which fields you complete depends on whether the plugin includes

15skills, an app, or both.

16 

17For local development, packaging, and marketplace setup, see

18[Build plugins](https://learn.chatgpt.com/docs/build-plugins).

19 

20For the app portion of the plugin, see [Build an app](https://learn.chatgpt.com/docs/build-app).

21 

22## Before you submit

23 

24### Submit the MCP server, not an existing app reference

25 

26You will not be able to submit a plugin that references an existing,

27already-published ChatGPT app. If your plugin includes an app that already

28exists in ChatGPT, submit that app's MCP server from scratch through the portal

29as a new MCP-backed plugin submission. The portal scans that MCP server,

30validates the tool metadata, and uses the submitted server details during

31review.

32 

33### Get plugin submission access

34 

35You need an organization role with app management write access before you can

36create or submit plugin drafts.

37 

381. Open [OpenAI Platform roles settings](https://platform.openai.com/settings/organization/people/roles).

392. Select the organization that owns the plugin.

403. Open the role assigned to the submitter, or create a new role.

414. In the role permissions, set **Apps Management** to **Write**.

425. Save the role and assign it to each person who needs to create, edit, or

43 submit plugin drafts.

446. Reload the [plugin submission portal](https://platform.openai.com/plugins).

45 

46![Apps Management write permission in Platform role settings](https://developers.openai.com/images/codex/plugins/submit/apps-management-permissions.webp)

47 

48Organization owners already have app management permissions. Non-owner

49submitters need write access to create or submit drafts, and read access to view

50drafts and review status.

51 

52### Verify your developer or business identity

53 

54Every public submission must use a verified developer or business identity in

55the OpenAI Platform. Reviewers use this identity to confirm the submission

56matches the name, website, support contact, privacy policy, and terms in your

57public listing.

58 

59To verify an identity:

60 

611. Sign in to the [OpenAI Platform](https://platform.openai.com).

622. Select the organization that will publish the plugin.

633. Open [organization settings](https://platform.openai.com/settings/organization/general).

644. Complete **individual verification** if you will publish under your own

65 name, or **business verification** if you will publish under a company name.

665. Return to the plugin submission form and select the verified identity in the

67 **Developer Identity** field.

68 

69Reviewers may reject submissions that use an unverified or mismatched publisher

70identity. See the Apps SDK

71[organization verification requirements](https://developers.openai.com/apps-sdk/deploy/submission#organization-verification)

72for the underlying review rule.

73 

74If the Platform shows that the developer or business identity is verified but

75the plugin submission form does not recognize it, check that you are submitting

76from the same organization and project where the identity was verified. The

77submitter also needs **Apps Management** write access for that organization.

78Ask an organization owner or admin to update the role assigned to the

79submitter, then reload the plugin submission portal.

80 

81### Prepare required materials

82 

83Before opening the form, collect:

84 

85| Material | What to prepare |

86| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

87| Listing details | Plugin name, short description, long description, logo, category, website, support URL, privacy policy URL, and terms URL. |

88| Developer identity | Verified individual or business identity in the OpenAI Platform. |

89| MCP server | For plugins that contain apps: public MCP server URL, domain verification access, authentication details, demo credentials if needed, content security policy, and accurate tool metadata. |

90| Tool annotations | For plugins that contain apps: `readOnlyHint`, `openWorldHint`, and `destructiveHint` values for every MCP tool. |

91| Skills | For skills plugins: skill bundle or ZIP with the final skill file tree. |

92| Prompts | Starter prompts that show useful, realistic workflows. |

93| Test cases | Five positive test cases and three negative test cases with clear expected behavior. |

94| Availability | Countries or regions where the plugin should be available. |

95| Release notes | A short summary of what you are submitting and what changed since any prior version. |

96 

97## Create a plugin submission

98 

991. Open the [plugin submission portal](https://platform.openai.com/plugins).

1002. Select **Create plugin**.

1013. Choose the submission type:

102 - **Skills only** for a plugin that only packages skills.

103 - **With MCP** for an app-only plugin backed by an MCP server.

104 - **With MCP** for an app-plus-skills plugin that combines an MCP-backed app

105 with bundled skills.

106 

107![Create plugin menu showing MCP and skills-only options](https://developers.openai.com/images/codex/plugins/submit/create-plugin-menu.webp)

108 

109The portal saves the submission as a draft while you complete the form.

110 

111## Complete the form

112 

113### Info

114 

115Complete the public listing and publisher fields:

116 

117- **Plugin name:** Use the customer-facing product or workflow name.

118- **Descriptions:** Explain what the plugin helps users do. Keep the short

119 description concise and use the long description for workflow details.

120- **Developer Identity:** Select the verified individual or business identity

121 for the publisher.

122- **Logo and category:** Use production-ready brand assets.

123- **Website, support, privacy, and terms URLs:** Use public URLs that match the

124 publisher and disclose relevant data handling.

125 

126![Info tab with plugin listing and developer identity fields filled out](https://developers.openai.com/images/codex/plugins/submit/info-fields.webp)

127 

128![Info tab with publisher and policy URLs filled out](https://developers.openai.com/images/codex/plugins/submit/developer-identity.webp)

129 

130Review your MCP responses against your privacy policy before you submit. Remove

131unnecessary personal data, auth secrets, debug payloads, internal identifiers,

132and undisclosed user-related fields from tool responses.

133 

134### MCP

135 

136For app or MCP submissions:

137 

1381. Enter the production MCP server URL.

1392. Configure authentication and provide reviewer-ready demo credentials if the

140 server requires sign-in.

1413. Define a content security policy that allows the exact domains your app

142 fetches from.

1434. Complete domain verification if the portal shows a **Domain not verified**

144 challenge. Use an HTTPS origin on the MCP host or a parent host, and

145 host the exact token at `/.well-known/openai-apps-challenge`.

1465. Select **Scan Tools**.

1476. Review the discovered tools, domains, validation output, and tool metadata.

1487. Fix server or metadata issues, deploy the fix, then scan again.

149 

150![MCP tab after scanning a demo MCP server with metadata recommendations](https://developers.openai.com/images/codex/plugins/submit/mcp-scan.webp)

151 

152Do not enter a ChatGPT app ID or try to point the portal at an existing,

153published ChatGPT app. The submission must provide the MCP server URL and review

154materials directly, even when that server backs an app that is already published

155in ChatGPT.

156 

157#### Domain verification

158 

159Plugins that contain apps must verify control of the domain that hosts the

160app's MCP server. When the portal shows a domain verification challenge, place

161the exact verification token at the generated well-known URL:

162 

163```text

164https://<challenge-base-host>/.well-known/openai-apps-challenge

165```

166 

167The challenge endpoint must return only that plugin's verification token. Do not

168return JSON, a list of tokens, or multiple tokens from the same URL.

169 

170The **Challenge Base URL** is an optional HTTPS origin that tells the portal

171where to check the token. It must be the MCP host or a parent host.

172Paths are ignored. For example, if the MCP server URL is

173`https://api.example.com/mcp`, the default challenge URL is

174`https://api.example.com/.well-known/openai-apps-challenge`, and

175`https://example.com` can be used as a parent-origin challenge base if you can

176host the token there.

177 

178If two plugins that contain apps share the same MCP host but differ only by

179path, they also share the same default challenge URL. You cannot verify them

180separately by putting different tenant paths in the Challenge Base URL, because

181the path is ignored. Use a parent origin that can host the new token, give the

182app's MCP server a distinct host, or work with OpenAI support if neither

183hosting option is possible.

184 

185If another plugin that contains an app already uses the same MCP host, do

186not replace its existing challenge token unless that plugin no longer needs it.

187Use an allowed parent-origin Challenge Base URL or a distinct MCP host for

188the new submission.

189 

190Every tool should have clear names, descriptions, schemas, and output

191structure. Add output schemas when they help reviewers and models understand

192what the tool returns.

193 

194Set tool annotations to match each tool's real behavior:

195 

196| Annotation | Use it when |

197| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

198| `readOnlyHint` | Set to `true` only when the tool fetches, looks up, lists, retrieves, previews, or computes information and doesn't change anything. Set to `false` if the tool can create, update, delete, send, enqueue, run jobs, start workflows, write logs, or otherwise change state. |

199| `openWorldHint` | For write tools, set to `true` if the tool can change publicly visible internet state, such as posting online, sending external messages, publishing content, pushing code, or submitting forms to third parties. Set to `false` only if the tool operates entirely within closed or private systems and can't change publicly visible internet state. |

200| `destructiveHint` | For write tools, set to `true` if the tool can delete, overwrite, revoke access, send messages or transactions that can't be undone, or cause another irreversible side effect. Otherwise, set it to `false`. |

201 

202![MCP tool metadata with explicit annotations and justifications](https://developers.openai.com/images/codex/plugins/submit/mcp-tool-metadata.webp)

203 

204For implementation details, see

205[tool annotations and elicitation](https://developers.openai.com/apps-sdk/build/mcp-server#tool-annotations-and-elicitation).

206For review expectations, see the Apps SDK

207[tool hint rejection guidance](https://developers.openai.com/apps-sdk/deploy/submission#review-and-approval-faqs).

208 

209### Skills

210 

211Upload the final skill bundle for skills-only or app-plus-skills submissions.

212Use the same file tree and instructions you tested locally.

213 

214For a **Skills only** submission, upload a ZIP no larger than 100 MB with one

215plugin root. Put the plugin manifest, such as `.codex-plugin/plugin.json`, and

216`skills/<skill>/SKILL.md` in that root. ZIP uploads only support skills. The

217portal excludes `.mcp.json`, `mcpServers`, `.app.json`, `apps`, and

218`interface.screenshots` and reports a warning when they are present.

219 

220![Skills tab with a skill bundle ready to upload](https://developers.openai.com/images/codex/plugins/submit/skills-upload.webp)

221 

222Each skill should include:

223 

224- A clear `SKILL.md` with trigger conditions and task instructions.

225- Any referenced scripts, templates, or assets.

226- Minimal, scoped instructions that fit the plugin's purpose.

227 

228Uploaded skills are scanned for policy compliance and security risks, including

229sensitive information, unnecessary access requests, and instructions that may

230conflict with safe or expected plugin behavior. Skills must follow the same

231standards as the rest of the plugin and may block submission or require

232remediation if they fail automated scanning.

233 

234### Prompts

235 

236Add starter prompts that show the plugin's highest-value workflows. Good

237prompts are specific enough to show when to use the plugin, but general enough

238that users can adapt them.

239 

240Examples:

241 

242- "Investigate checkout errors from the last release and summarize likely root

243 causes."

244- "Create a P1 incident brief from the latest support tickets and related

245 deploys."

246- "Review unsuccessful deployment logs and recommend the next debugging step."

247 

248![Prompts tab with example starter prompts](https://developers.openai.com/images/codex/plugins/submit/prompts.webp)

249 

250### Testing

251 

252Submit exactly five positive test cases and three negative test cases.

253 

254For each positive test case, include:

255 

256- User prompt.

257- Expected tool, skill, or workflow behavior.

258- Expected result shape.

259- Test account or fixture data required to reproduce it.

260 

261For each negative test case, include:

262 

263- User prompt or scenario.

264- Expected refusal, clarification, or safe fallback behavior.

265- Why the plugin shouldn't complete the requested action.

266 

267Use test cases that reviewers can run without internal context. If your plugin

268requires authentication, make sure the provided demo credentials can complete

269each test without MFA, SMS, email confirmation, or private-network access.

270 

271![Testing tab with positive and negative test cases](https://developers.openai.com/images/codex/plugins/submit/testing.webp)

272 

273### Global

274 

275Choose the countries or regions where the plugin should be available. Only

276select locations where the publisher, product, support process, and legal terms

277are ready for users.

278 

279![Global tab for country and region availability](https://developers.openai.com/images/codex/plugins/submit/global.webp)

280 

281### Submit

282 

283Review the full draft before submitting.

284 

285Directory plugins are held to a higher standard and require additional

286validation. See [Plugin submission errors](https://learn.chatgpt.com/docs/plugin-submission-errors) for

287the full list of checks and how to fix each error.

288 

289In the release notes, summarize:

290 

291- What the plugin does.

292- Whether this is an initial submission or an update.

293- What changed since the prior submitted version, if any.

294- Anything reviewers should know about test credentials, expected data, or

295 setup.

296 

297Complete the policy attestations only after confirming the listing, server,

298skills, prompts, tests, and availability are accurate. Then select

299**Submit for Review**.

300 

301![Submit tab with release notes and final attestations](https://developers.openai.com/images/codex/plugins/submit/submit.webp)

302 

303## Public publishing flow

304 

305Submitting a plugin starts review; it doesn't publish the plugin immediately.

306For public availability, the flow is:

307 

3081. Submit the plugin through the plugin submission portal.

3092. OpenAI reviews the submission. Review timelines may vary as OpenAI builds

310 and scales the review process.

3113. After OpenAI approves the plugin, the developer chooses when to publish it

312 and publishes it from the portal.

3134. After publication, the plugin appears in the Plugins Directory

314 available in both ChatGPT and Codex.

315 

316Plugins that contain apps, skills-only plugins, and app-plus-skills plugins all

317appear in the Plugins Directory.

318 

319## Final checklist

320 

321Before submitting, confirm:

322 

323- The submitter has **Apps Management** write access.

324- The publisher has a verified developer or business identity.

325- The MCP server uses a public, production URL.

326- Plugins that contain apps define a content security policy for the exact

327 domains the app fetches from.

328- Reviewer credentials work without MFA, email confirmation, SMS confirmation,

329 or private-network access.

330- Tool names, descriptions, schemas, and annotations match actual behavior.

331- Every tool has accurate `readOnlyHint`, `openWorldHint`, and

332 `destructiveHint` values.

333- Tool responses don't include unnecessary personal data, auth secrets, debug

334 payloads, internal identifiers, or undisclosed user-related fields.

335- You tested the skills locally with the final file tree.

336- Starter prompts show realistic user workflows.

337- The submission includes five positive and three negative test cases.

338- Privacy policy, terms, support, and website URLs are public and match the

339 publisher identity.

Details

55 suggestedEffort: medium55 suggestedEffort: medium

56relatedLinks:56relatedLinks:

57 - label: Apps SDK quickstart57 - label: Apps SDK quickstart

58 url: /apps-sdk/quickstart58 url: /plugins/quickstart

59 - label: Build an MCP server59 - label: Build an MCP server

60 url: /apps-sdk/build/mcp-server60 url: /plugins/build/mcp-server

61 - label: Testing61 - label: Testing

62 url: /apps-sdk/deploy/testing62 url: /plugins/deploy/connect-chatgpt

63techStack:63techStack:

64 - need: Widget framework64 - need: Widget framework

65 goodDefault: "[React](https://react.dev/)"65 goodDefault: "[React](https://react.dev/)"


73 73 

74## What you build74## What you build

75 75 

76Every ChatGPT app has three parts:76Every MCP-backed plugin has three parts:

77 77 

78- An MCP server that defines tools, returns data, enforces auth, and points ChatGPT at any UI resources.78- An MCP server that defines tools, returns data, enforces auth, and points ChatGPT at any UI resources.

79- An optional web component that renders inside a ChatGPT iframe. You can build it with React or with plain HTML, CSS, and JavaScript.79- An optional web component that renders inside a ChatGPT iframe. You can build it with React or with plain HTML, CSS, and JavaScript.

80- A model that decides when to call the app's tools based on the metadata you provide.80- A model that decides when to call the plugin's tools based on the metadata you provide.

81 81 

82Codex is most useful when it owns the repetitive engineering work around those parts:82Codex is most useful when it owns the repetitive engineering work around those parts:

83 83 


85- Scaffolding the server and widget.85- Scaffolding the server and widget.

86- Wiring local run scripts.86- Wiring local run scripts.

87- Adding auth and deployment changes in focused passes.87- Adding auth and deployment changes in focused passes.

88- Writing the verification loop that proves the app works in ChatGPT.88- Writing the verification loop that proves the plugin works in ChatGPT.

89 89 

90## Why Codex is a strong fit90## Why Codex is a strong fit

91 91 

92- ChatGPT apps already split cleanly into a server, an optional widget, and model-driven tool calls.92- MCP-backed plugins split cleanly into a server, optional UI, and model-driven

93- Codex prompting works best when the task is explicit, scoped, and straightforward to verify, which matches app-building work well.93 tool calls.

94- Codex prompting works best when the task is explicit, scoped, and

95 straightforward to verify, which matches plugin-building work well.

94- Skills and `AGENTS.md` give Codex the reusable instructions and project rules it needs to stay grounded.96- Skills and `AGENTS.md` give Codex the reusable instructions and project rules it needs to stay grounded.

95 97 

96To learn more about how to install and use skills, see our [skills documentation](https://developers.openai.com/codex/build-skills).98To learn more about how to install and use skills, see our [skills documentation](https://developers.openai.com/codex/build-skills).


102- Start with one core user outcome instead of trying to port an entire product into chat.104- Start with one core user outcome instead of trying to port an entire product into chat.

103- Choose the stack up front: TypeScript or Python for the server, and React or plain HTML, CSS, and JavaScript for the widget.105- Choose the stack up front: TypeScript or Python for the server, and React or plain HTML, CSS, and JavaScript for the widget.

104- Decide what HTTPS path you will use during development, such as `ngrok` or Cloudflare Tunnel.106- Decide what HTTPS path you will use during development, such as `ngrok` or Cloudflare Tunnel.

105- Current docs usually say app, but some older pages and settings still say connector. During local testing, treat them as the same setup object.107- Some settings still use older terms for an MCP server connection. During

108 local testing, treat those labels as referring to the registered server.

106 109 

1071. Start with one narrow app outcome and ask Codex to propose three to five tools with clear names, descriptions, inputs, and outputs.1101. Start with one narrow plugin outcome and ask Codex to propose three to five tools with clear names, descriptions, inputs, and outputs.

1082. Decide whether v1 can stay data-only or needs a widget, then scaffold the MCP server and optional widget using existing repo patterns before adding dependencies.1112. Decide whether v1 can stay data-only or needs a widget, then scaffold the MCP server and optional widget using existing repository patterns before adding dependencies.

1093. Run the app locally behind HTTPS, connect it in ChatGPT developer mode, and test it with a small direct, indirect, and negative prompt set.1123. Run the MCP server locally behind HTTPS, connect it in ChatGPT developer mode, and test it with a small direct, indirect, and negative prompt set.

1104. Iterate on metadata, state handling, `structuredContent`, and `_meta` payloads until the core read flow behaves reliably inside ChatGPT.1134. Iterate on metadata, state handling, `structuredContent`, and `_meta` payloads until the core read flow behaves reliably inside ChatGPT.

1115. Add OAuth 2.1 only when user-specific data or write actions require it, while keeping anonymous or read-only flows simple where possible.1145. Add OAuth 2.1 only when user-specific data or write actions require it, without complicating anonymous or read-only flows.

1126. Prepare a hosted preview with a stable `/mcp` endpoint, verify streaming and widget asset hosting, and review the launch checklist before sharing or submitting the app.1156. Prepare a hosted preview with a stable `/mcp` endpoint, verify streaming and UI asset hosting, and review the launch checklist before sharing or submitting the plugin.

113 116 

114## Suggested prompts117## Suggested prompts

115 118 

116Strong prompts for this workflow share the same ingredients:119Strong prompts for this workflow share the same ingredients:

117 120 

118- One clear outcome: say what the app should help the user do inside ChatGPT.121- One clear outcome: say what the plugin should help the user do inside ChatGPT.

119- A concrete stack: say whether you want TypeScript or Python on the server, and whether the widget should use React or stay lightweight.122- A concrete stack: say whether you want TypeScript or Python on the server, and whether the widget should use React or stay lightweight.

120- Explicit tool boundaries: ask Codex to propose or build a small set of tools with one job per tool.123- Explicit tool boundaries: ask Codex to propose or build a small set of tools with one job per tool.

121- Auth expectations: state whether the first version can be anonymous or whether it needs linked accounts and write actions.124- Auth expectations: state whether the first version can be anonymous or whether it needs linked accounts and write actions.


124 127 

125Avoid one giant prompt that asks for planning, implementation, auth, deployment, submission, and polish in one pass. Split the work into smaller milestones instead.128Avoid one giant prompt that asks for planning, implementation, auth, deployment, submission, and polish in one pass. Split the work into smaller milestones instead.

126 129 

127**Plan the App Before You Scaffold It**130**Plan the Plugin Before You Scaffold It**

128 131 

129**Scaffold the First Working Version**132**Scaffold the First Working Version**

130 133 

131**Add Auth Only After the Core Flow Works**134**Add Auth Only After the Core Flow Works**

132 135 

133**Prepare the App for Deployment and Review**136**Prepare the Plugin for Deployment and Review**

134 137 

135## Launch readiness138## Launch readiness

136 139 

137- The app has one narrow outcome that is obvious to a user.140- The plugin has one narrow outcome that users can understand.

138- The tool set stays small and has explicit metadata, inputs, and outputs.141- The tool set stays small and has explicit metadata, inputs, and outputs.

139- The MCP server works end to end and returns concise `structuredContent`, reserving widget-only data for `_meta`.142- The MCP server works end to end and returns concise `structuredContent`, reserving widget-only data for `_meta`.

140- The widget, if needed, renders correctly inside ChatGPT.143- The widget, if needed, renders correctly inside ChatGPT.

141- A local HTTPS testing loop works through ChatGPT developer mode.144- A local HTTPS testing loop works through ChatGPT developer mode.

142- A small direct, indirect, and negative prompt set passes with the expected conversation flow and tool payloads.145- A small direct, indirect, and negative prompt set passes with the expected conversation flow and tool payloads.

143- Auth is added only where user-specific data or write actions require it.146- Auth is added only where user-specific data or write actions require it.

144- A deployment plan and launch-readiness review cover metadata, tool hints, privacy, and test prompts before the app is shared or submitted.147- A deployment plan and launch-readiness review cover metadata, tool hints, privacy, and test prompts before the plugin is shared or submitted.

145 148 

146## Common pitfalls149## Common pitfalls

147 150 

148- Asking Codex to port the whole product into ChatGPT. Better move: ask for one core user outcome, three to five tools, and one narrow widget.151- Asking Codex to port the whole product into ChatGPT. Better move: ask for one core user outcome, three to five tools, and one narrow widget.

149- Starting with a giant implementation prompt. Better move: split the work into planning, scaffold, auth, deployment, and review passes.152- Starting with a giant implementation prompt. Better move: split the work into planning, scaffold, auth, deployment, and review passes.

150- Writing UI before the tool contract is clear. Better move: plan the tool surface and response schema first, then build the widget.153- Writing UI before the tool contract is clear. Better move: plan the tool surface and response schema first, then build the widget.

151- Skipping official docs grounding. Better move: pair `$chatgpt-apps` with `$openai-docs` so the scaffold follows current Apps SDK guidance.154- Skipping official docs grounding. Better move: pair `$chatgpt-apps` with `$openai-docs` so the scaffold follows current plugin guidance.

152- Treating metadata as an afterthought. Better move: write tool descriptions and parameter docs early, then replay a prompt set against them.155- Treating metadata as an afterthought. Better move: write tool descriptions and parameter docs early, then replay a prompt set against them.

153- Adding auth before proving the anonymous or read-only path. Better move: get the core tool flow working first, then add OAuth for the tools that actually need it.156- Adding auth before proving the anonymous or read-only path. Better move: get the core tool flow working first, then add OAuth for the tools that actually need it.

154- Declaring the app done before testing inside ChatGPT. Better move: connect the app in developer mode, inspect tool payloads, and verify the real conversation flow.157- Declaring the plugin done before testing inside ChatGPT. Better move: connect

158 the MCP server in developer mode, inspect tool payloads, and verify the real

159 conversation flow.

whats-new.md +6 −6

Details

122 122 

123### Turn demonstrated workflows into reusable skills123### Turn demonstrated workflows into reusable skills

124 124 

125[Record & Replay](https://learn.chatgpt.com/docs/extend/record-and-replay) lets you show Codex a workflow on125[Record & Replay](https://learn.chatgpt.com/docs/extend/record-and-replay) lets you show ChatGPT or

126macOS and turn the demonstration into a reusable skill. Use it for repetitive126Codex a workflow on macOS and turn the demonstration into a reusable skill. Use

127tasks that are easier to show than describe, then refine the generated skill127it for repetitive tasks that are easier to show than describe, then refine the

128and replay it with new inputs. Initial availability excludes the EEA, the128generated skill and replay it with new inputs. Initial availability excludes

129United Kingdom, and Switzerland, and requires Computer Use.129the EEA, the United Kingdom, and Switzerland, and requires Computer Use.

130 130 

131<a id="continue-a-task-on-another-host"></a>131<a id="continue-a-task-on-another-host"></a>

132 132 


269hours or days. [Locked use](https://learn.chatgpt.com/docs/computer-use#locked-use) lets Codex269hours or days. [Locked use](https://learn.chatgpt.com/docs/computer-use#locked-use) lets Codex

270continue approved computer-use work after a Mac locks, including through270continue approved computer-use work after a Mac locks, including through

271**Remote** in the ChatGPT mobile app. ChatGPT Business workspaces can also271**Remote** in the ChatGPT mobile app. ChatGPT Business workspaces can also

272[share reusable plugin bundles with workspace members](https://learn.chatgpt.com/docs/build-plugins#share-a-local-plugin-with-your-workspace).272[share reusable plugin bundles with workspace members](https://developers.openai.com/plugins/build/plugins#share-a-local-plugin-with-your-workspace).

273 273 

274[Read the May 21 launch notes](https://learn.chatgpt.com/docs/changelog#codex-2026-05-21).274[Read the May 21 launch notes](https://learn.chatgpt.com/docs/changelog#codex-2026-05-21).

275 275 

workflows.md +6 −5

Details

67 67 

68### Use plugins68### Use plugins

69 69 

70Plugins give ChatGPT reusable instructions and connections to tools such as70Plugins give ChatGPT and Codex reusable instructions and connections to tools

71Google Drive, Gmail, Slack, and GitHub. Ask for the result you need and let71such as Google Drive, Gmail, Slack, and GitHub. Both products draw public

72ChatGPT choose from the tools available to it. To choose a specific plugin, type72plugins from the same universal directory. Ask for the result you need and let

73`@` in the composer.73the active surface choose from the tools available to it. In ChatGPT, type `@`

74in the composer to choose a specific plugin.

74 75 

75[<IconItem title="Learn about plugins" className="mt-4">76[<IconItem title="Learn about plugins" className="mt-4">

76 <span slot="icon">77 <span slot="icon">

77 <Plugin />78 <Plugin />

78 </span>79 </span>

79 Find, install, and use plugins in ChatGPT.80 Find, install, and use plugins in ChatGPT and Codex.

80 </IconItem>](https://learn.chatgpt.com/docs/plugins)81 </IconItem>](https://learn.chatgpt.com/docs/plugins)

81 82 

82### Personalize ChatGPT83### Personalize ChatGPT