How to Create a Codex Plugin from Scratch: A Complete Guide to Scaffolding, Manifests, and Marketplace Registration
Use the create_basic_plugin.py scaffold script in openai/plugins to generate a complete plugin directory with a plugin.json manifest, optional component folders, and automatic marketplace registration in a single command.
Creating a custom Codex plugin requires more than just writing code—you need a properly structured directory, a validated manifest file, and an entry in the marketplace registry. The openai/plugins repository provides a dedicated plugin-creator skill that automates this entire workflow. This guide walks you through generating a complete plugin skeleton, understanding the plugin.json schema, and making your plugin discoverable in the Codex UI.
What the Scaffold Script Generates
The plugin scaffolding system lives in .agents/skills/plugin-creator/ and centers on scripts/create_basic_plugin.py. This script performs three core functions: it normalizes your plugin name, creates the directory structure, and writes a placeholder manifest.
When you run the script, it executes the normalize_plugin_name() function to convert your input to lower-case kebab-case (e.g., MyPlugin becomes my-plugin). The validate_plugin_name() helper enforces a maximum length of 64 characters. These functions ensure your plugin identifier follows Codex naming conventions.
The script creates the plugin root folder and writes the manifest to .codex-plugin/plugin.json. By default, this produces a minimal structure containing only the manifest file. You can extend this with optional component directories using flags.
Optional Component Flags
The scaffold script supports five boolean flags that create empty directories or stub JSON files:
--with-skills– Creates askills/directory for agent capabilities--with-hooks– Creates ahooks/directory for lifecycle hooks--with-assets– Creates anassets/directory for UI resources--with-mcp– Generates.mcp.jsonwith{"mcpServers": {}}stub--with-apps– Generates.app.jsonwith{"apps": {}}stub
These flags give you a ready-to-extend skeleton without manual directory creation.
Understanding the plugin.json Manifest
The generated manifest at <plugin-root>/.codex-plugin/plugin.json follows the schema defined in references/plugin-json-spec.md. This file contains two critical sections: top-level metadata and an interface block.
Top-level metadata includes fields like name, version, and author. These identify your plugin in the Codex system.
The interface block drives how your plugin appears in the Codex app UI. It controls display properties, entry points, and integration hooks. The spec file documents valid values for each field, including type constraints and required vs. optional status.
When you edit the manifest, reference the specification to ensure compatibility with the Codex runtime. Invalid manifests will fail validation checks.
Registering Your Plugin in the Marketplace
The --with-marketplace flag automates marketplace registration, eliminating manual JSON editing. When enabled, the script updates a marketplace.json file with your plugin's entry.
Marketplace Entry Structure
Each marketplace entry contains:
name– The normalized plugin identifiersource– Object with{"source": "local", "path": "./plugins/<name>"}pointing to the plugin directorypolicy– Object withinstallationandauthenticationsettingscategory– Display category for the Codex UI marketplace view
Policy Configuration Flags
Three additional flags control the marketplace entry:
--install-policy– SetsAVAILABLE,HIDDEN, orDISABLED--auth-policy– SetsON_INSTALL,ON_USE, orNONE--category– Assigns a display category like "Productivity" or "Development"
The default marketplace path is ~/.agents/plugins/marketplace.json. Override this with --marketplace-path to use a repository-local file instead.
The marketplace itself has a top-level interface.displayName field that belongs to the marketplace, not individual plugins. New marketplace files are seeded with a placeholder display name and an empty plugins array as outlined in lines 13-20 of the spec.
Step-by-Step: Creating Your First Codex Plugin
1. Scaffold a Basic Plugin
Run the scaffold script with your desired plugin name:
python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin
This creates:
~/plugins/my-plugin/.codex-plugin/plugin.json– Placeholder manifest with kebab-cased name~/plugins/my-plugin/– Root directory ready for your code
2. Add Component Directories
Generate a full-featured skeleton with all optional components:
python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py \
my-plugin \
--with-skills \
--with-hooks \
--with-assets \
--with-mcp \
--with-apps
This produces the structure:
my-plugin/
├─ .codex-plugin/
│ └─ plugin.json
├─ skills/
├─ hooks/
├─ assets/
├─ .mcp.json
└─ .app.json
3. Register with Marketplace Integration
Complete the setup with marketplace registration and policy settings:
python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py \
my-plugin \
--with-marketplace \
--install-policy AVAILABLE \
--auth-policy ON_INSTALL \
--category Productivity
The script appends this entry to your marketplace file:
{
"name": "my-plugin",
"source": { "source": "local", "path": "./plugins/my-plugin" },
"policy": { "installation": "AVAILABLE", "authentication": "ON_INSTALL" },
"category": "Productivity"
}
4. Validate Your Plugin
Before deployment, verify your JSON schemas using the validation helper:
python3 .agents/skills/plugin-creator/scripts/quick_validate.py .agents/skills/plugin-creator
This script checks the validity of your manifest and marketplace entries against the specification.
Key Source Files in openai/plugins
| Path | Purpose |
|---|---|
.agents/skills/plugin-creator/scripts/create_basic_plugin.py |
Main scaffold script with normalize_plugin_name() and validate_plugin_name() functions |
.agents/skills/plugin-creator/references/plugin-json-spec.md |
Complete JSON schema for plugin.json and marketplace entries |
.agents/skills/plugin-creator/SKILL.md |
Usage documentation and flag descriptions |
.agents/skills/plugin-creator/scripts/quick_validate.py |
JSON validation helper for scaffolded files |
.agents/plugins/marketplace.json |
Example marketplace showing entry format and ordering |
Summary
- Scaffold generation – Use
create_basic_plugin.pyto create a standardized plugin directory with normalized naming and automatic manifest creation. - Manifest structure – The
plugin.jsonat.codex-plugin/plugin.jsoncombines metadata and UI interface definitions per the spec inreferences/plugin-json-spec.md. - Component options – Flags like
--with-skillsand--with-mcpgenerate directory stubs and configuration files for extended functionality. - Marketplace registration – The
--with-marketplaceflag automatically creates valid marketplace entries with configurable installation and authentication policies. - Validation – Run
quick_validate.pyto catch JSON schema errors before deployment.
Frequently Asked Questions
What is the maximum length for a Codex plugin name?
Plugin names must be 64 characters or fewer. The validate_plugin_name() function in create_basic_plugin.py enforces this limit, and normalize_plugin_name() converts your input to lower-case kebab-case to ensure compatibility.
What does the plugin.json interface block control?
The interface block in your manifest drives the UI presentation inside the Codex app. It defines how your plugin appears to users, including display properties and integration hooks. The complete schema is documented in references/plugin-json-spec.md.
Can I register a plugin in a custom marketplace location?
Yes. While the default marketplace path is ~/.agents/plugins/marketplace.json, you can specify an alternative location using the --marketplace-path flag. This is useful for repository-local development or team-shared plugin registries.
What is the difference between installation and authentication policies?
Installation policy (--install-policy) controls whether the plugin appears in the marketplace (AVAILABLE), is hidden (HIDDEN), or disabled (DISABLED). Authentication policy (--auth-policy) determines when the user must authenticate: at installation (ON_INSTALL), at first use (ON_USE), or never (NONE).
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →