# How to Develop an OpenAI Plugin: A Complete Guide to Building Codex Extensions

> Learn how to develop an OpenAI plugin with this complete guide. Discover the manifest-driven architecture, scaffold skills with the Plugin-Creator tool, and register your extension.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: tutorial
- Published: 2026-06-25

---

**OpenAI plugins are built using a manifest-driven architecture where you create a [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) file in a dedicated folder, scaffold skills with the Plugin-Creator tool, and register the plugin in either a personal or team-wide marketplace.**

OpenAI plugins extend the Codex runtime with custom capabilities, allowing you to expose APIs, automate workflows, and integrate external services. This guide walks through the complete development workflow using the official `openai/plugins` repository, from initial scaffolding to marketplace publication.

## Understanding the Plugin Architecture

Every OpenAI plugin lives in its own folder under `plugins/<plugin-name>/` and follows a strict directory convention. The architecture centers on a **manifest file** that describes the plugin's metadata, capabilities, and UI presentation.

### Core Components

The required structure includes a [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) file that defines the plugin's **interface** object—containing display names, descriptions, icons, and default prompts. Optional subdirectories add functionality:

- **Skills**: `plugins/<plugin-name>/skills/` contain JSON or YAML-defined actions that expose API calls to the Codex runtime
- **Hooks**: `plugins/<plugin-name>/hooks.json` provides event-driven callbacks for lifecycle events like installation or authentication
- **MCP Servers**: `plugins/<plugin-name>/.mcp.json` defines Multi-Channel-Protocol connections for external services
- **Apps**: `plugins/<plugin-name>/.app.json` configures UI integrations for Composer UI and custom widgets
- **Assets**: `plugins/<plugin-name>/assets/` stores icons, logos, and screenshots referenced by the manifest

### Personal vs Team-Wide Distribution

Plugins can be installed in two scopes. **Personal plugins** live in `~/.agents/plugins/marketplace.json` in the user's home directory, while **team-wide plugins** are stored in the repository's [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json). The marketplace file enumerates available plugins and defines installation policies such as `AVAILABLE` or `ON_INSTALL`.

## Scaffolding a New OpenAI Plugin

OpenAI provides a **Plugin-Creator skill** that automates boilerplate generation. The scaffold script creates the folder structure, populates the manifest with placeholder values, and optionally registers the plugin in a marketplace.

### Using the Plugin-Creator Script

Run the scaffold command from the repository root:

```bash
python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin

```

The script normalizes the plugin name to kebab-case and performs the following actions:

1. Creates the plugin folder `plugins/my-plugin/` with [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) containing all required fields
2. Generates optional subfolders (`skills/`, `hooks/`, `assets/`) when specified with flags
3. Writes a marketplace entry (personal by default) linking the plugin to the Codex UI
4. Outputs **deep-link URLs** in the format `codex://plugins/<name>?marketplacePath=…` for direct sharing

Add the `--with-marketplace` flag to automatically update the marketplace file, or use specific flags like `--with-skills`, `--with-hooks`, or `--with-assets` to generate only the components you need.

### Generated File Structure

After scaffolding, your plugin contains:

```

plugins/my-plugin/
├── .codex-plugin/
│   └── plugin.json          # Manifest with interface configuration

├── skills/                  # Optional: skill definitions

├── assets/                  # Optional: icons and logos

└── hooks.json               # Optional: lifecycle callbacks

```

The generated [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) includes placeholder fields for `description`, `author`, and `interface` properties like `displayName`, `shortDescription`, and `brandColor` that you must fill in before publishing.

## Building Skills for Your Plugin

Skills are the functional units that Codex invokes. Each skill requires a schema definition and an implementation script.

### Defining the OpenAI Schema

Create a skill directory at `plugins/<plugin-name>/skills/<skill-name>/` and add an [`agents/openai.yaml`](https://github.com/openai/plugins/blob/main/agents/openai.yaml) file. This YAML defines the OpenAI-compatible JSON schema for inputs and outputs:

```yaml
name: get_current_weather
description: Retrieve the current weather for a city.
input:
  type: object
  required: [city]
  properties:
    city:
      type: string
      description: Name of the city
output:
  type: object
  properties:
    temperature:
      type: number
      description: Temperature in Celsius
    condition:
      type: string
      description: Short weather description

```

### Implementing the Skill Logic

The implementation can use any programming language. The entry point must read JSON from `stdin` and write JSON to `stdout`. For example, a Python implementation at [`skills/get_current_weather/scripts/weather.py`](https://github.com/openai/plugins/blob/main/skills/get_current_weather/scripts/weather.py):

```python
import sys, json, requests

def main():
    data = json.load(sys.stdin)
    city = data["city"]
    # Replace with actual API call

    response = requests.get(f"https://api.example.com/weather?q={city}")
    weather = response.json()
    print(json.dumps({
        "temperature": weather["temp_c"],
        "condition": weather["condition"]["text"]
    }))

if __name__ == "__main__":
    main()

```

Register the skill by adding the skills directory to your [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json):

```json
{
  "skills": "./skills/"
}

```

## Validating and Testing

Before publishing, validate your plugin against the specification to ensure the manifest and skill definitions are correct.

### Local Validation

Run the validation script from the repository root:

```bash
python3 .agents/skills/plugin-creator/scripts/quick_validate.py .agents/skills/plugin-creator

```

This checks the [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) structure and verifies that all referenced skill schemas conform to the OpenAI specification.

### Runtime Testing

Codex automatically loads any plugin under the `plugins/` directory. Start the Codex runtime to test your plugin locally:

1. Ensure your plugin folder is under `plugins/<plugin-name>/`
2. Verify the `interface` fields in [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) are populated with real values
3. Test skill invocation through the Codex UI or API

Iterate by editing the manifest and reloading the runtime.

## Publishing to the Marketplace

When ready for distribution, move your plugin to the appropriate marketplace location. Copy the plugin folder to either your personal marketplace at `~/.agents/plugins/` or the team-wide `.agents/plugins/` directory in the repository.

Update the [`marketplace.json`](https://github.com/openai/plugins/blob/main/marketplace.json) file to include your plugin with the correct installation policy. Commit these changes to make the plugin discoverable to all Codex users with access to that marketplace. The deep-link URLs generated during scaffolding allow users to install the plugin directly from the Codex app.

## Summary

- **OpenAI plugins** use a manifest-driven architecture centered on [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json)
- Use `python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py` to scaffold new plugins with proper directory structure
- Store plugins in `plugins/<plugin-name>/` with optional `skills/`, `assets/`, and [`hooks.json`](https://github.com/openai/plugins/blob/main/hooks.json) components
- Define skills using [`agents/openai.yaml`](https://github.com/openai/plugins/blob/main/agents/openai.yaml) schemas and implement them as scripts reading from `stdin` and writing to `stdout`
- Validate plugins using [`quick_validate.py`](https://github.com/openai/plugins/blob/main/quick_validate.py) before publishing
- Publish to either personal (`~/.agents/plugins/marketplace.json`) or team-wide ([`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json)) marketplaces

## Frequently Asked Questions

### What programming languages can I use to build OpenAI plugin skills?

You can use any programming language for skill implementations as long as the entry point executable reads JSON input from `stdin` and outputs valid JSON to `stdout`. The repository includes examples in Python and Node.js, but the runtime is language-agnostic. The [`agents/openai.yaml`](https://github.com/openai/plugins/blob/main/agents/openai.yaml) file defines the schema, while the actual logic resides in scripts within the `skills/<skill-name>/scripts/` directory.

### How do I share my OpenAI plugin with team members?

Share your plugin by committing it to the team-wide marketplace at [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json) in the repository. When you run the scaffold script with `--with-marketplace`, it generates a deep-link URL in the format `codex://plugins/<name>?marketplacePath=…`. Team members can click this link to install the plugin directly in their Codex app, or they can browse the marketplace if the plugin is registered in the shared repository location.

### What is the difference between personal and team-wide plugins?

**Personal plugins** are stored in `~/.agents/plugins/marketplace.json` in your home directory and are only visible to your user account. **Team-wide plugins** reside in the repository's [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json) and are accessible to all users with access to that repository. The scaffold script defaults to personal installation, but you can specify the team-wide location by adjusting the marketplace path or manually moving the plugin files after creation.

### How do I validate my plugin before publishing?

Run the validation script `python3 .agents/skills/plugin-creator/scripts/quick_validate.py` followed by the path to your plugin directory. This script checks that your [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) manifest conforms to the specification, verifies that all referenced skills have valid [`agents/openai.yaml`](https://github.com/openai/plugins/blob/main/agents/openai.yaml) schemas, and ensures all required fields are populated. Fix any validation errors before copying the plugin to a marketplace location to ensure Codex can load and execute your skills correctly.