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 a skills/ directory for agent capabilities
  • --with-hooks – Creates a hooks/ directory for lifecycle hooks
  • --with-assets – Creates an assets/ directory for UI resources
  • --with-mcp – Generates .mcp.json with {"mcpServers": {}} stub
  • --with-apps – Generates .app.json with {"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 identifier
  • source – Object with {"source": "local", "path": "./plugins/<name>"} pointing to the plugin directory
  • policy – Object with installation and authentication settings
  • category – Display category for the Codex UI marketplace view

Policy Configuration Flags

Three additional flags control the marketplace entry:

  • --install-policy – Sets AVAILABLE, HIDDEN, or DISABLED
  • --auth-policy – Sets ON_INSTALL, ON_USE, or NONE
  • --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.py to create a standardized plugin directory with normalized naming and automatic manifest creation.
  • Manifest structure – The plugin.json at .codex-plugin/plugin.json combines metadata and UI interface definitions per the spec in references/plugin-json-spec.md.
  • Component options – Flags like --with-skills and --with-mcp generate directory stubs and configuration files for extended functionality.
  • Marketplace registration – The --with-marketplace flag automatically creates valid marketplace entries with configurable installation and authentication policies.
  • Validation – Run quick_validate.py to 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →