# How to Structure a New Codex Plugin in the OpenAI Plugins Repository

> Learn how to structure a new Codex plugin in the openai/plugins repository. Follow our guide to create a plugin.json manifest register your plugin and organize assets.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: how-to-guide
- Published: 2026-09-10

---

**To structure a new Codex plugin in the openai/plugins repository, create a directory under `plugins/`, populate a [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) manifest conforming to the official schema, register the plugin in [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json), and organize optional assets, skills, and authentication files according to the monorepo conventions.**

The openai/plugins repository operates as a monorepo where the Codex platform automatically discovers and loads extensions. When you structure a new Codex plugin following the repository's layout conventions, the system indexes your metadata from hidden manifest files, renders your UI assets, and exposes your skills without requiring manual configuration. This guide walks through the exact file paths, JSON schemas, and directory hierarchies defined in the source code.

## Required Directory Layout

Every Codex plugin begins as a folder inside the `plugins/` directory (e.g., `plugins/my-plugin`). This container holds all resources the platform needs for discovery, display, and execution. The Codex indexing system specifically looks for files at predetermined paths to build the plugin registry.

### Core Files and Subdirectories

Place these required and optional files at specific locations within your plugin folder:

- [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) — The hidden manifest containing metadata and UI configuration
- `assets/` — Directory for PNG or SVG files (icons, logos, screenshots) referenced by the manifest
- `skills/` — Directory containing skill implementations, each with documentation and agent definitions
- [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) — Optional file at the plugin root defining the App ID for authentication flows
- [`hooks.json`](https://github.com/openai/plugins/blob/main/hooks.json) and [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) — Optional configuration files for custom HTTP hooks or Multi-Component-Package servers

## Creating the Plugin Manifest

The [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) file serves as the canonical source of truth for plugin discovery. According to the Plugin JSON spec documented in [`.agents/skills/plugin-creator/references/plugin-json-spec.md`](https://github.com/openai/plugins/blob/main/.agents/skills/plugin-creator/references/plugin-json-spec.md), this manifest must declare top-level fields including `name`, `version`, `description`, `author`, `license`, `keywords`, `skills`, `hooks`, `mcpServers`, and `apps`.

The `interface` object controls how your plugin appears in the Codex UI. It specifies the `displayName`, `shortDescription`, `longDescription`, `developerName`, `category`, `capabilities`, `brandColor`, and paths to visual assets like `composerIcon`, `logo`, and `screenshots`.

```json
{
  "name": "my-plugin",
  "version": "0.1.0",
  "description": "Brief description of what the plugin does",
  "author": {
    "name": "Your Name",
    "email": "you@example.com",
    "url": "https://github.com/your"
  },
  "license": "MIT",
  "keywords": ["my", "plugin"],
  "skills": "./skills/",
  "apps": "./.app.json",
  "interface": {
    "displayName": "My Plugin",
    "shortDescription": "One-liner shown in the plugin list",
    "longDescription": "Longer description displayed on the details page",
    "developerName": "Your Company",
    "category": "Productivity",
    "capabilities": ["Interactive", "Write"],
    "websiteURL": "https://your-site.com",
    "privacyPolicyURL": "https://your-site.com/privacy",
    "termsOfServiceURL": "https://your-site.com/terms",
    "defaultPrompt": [
      "Summarize the latest report.",
      "Create a draft email from the summary."
    ],
    "brandColor": "#3B82F6",
    "composerIcon": "./assets/composer-icon.svg",
    "logo": "./assets/logo.png",
    "screenshots": [
      "./assets/screenshot1.png",
      "./assets/screenshot2.png"
    ]
  }
}

```

Reference the Airtable plugin at [`plugins/airtable/.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/plugins/airtable/.codex-plugin/plugin.json) for a full-featured example of a production manifest.

## Registering Your Plugin with the Marketplace

To make your plugin discoverable in the Codex UI, you must add an entry to the repository-wide marketplace registry located at [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json). Each entry requires four specific components:

1. **name** — The unique plugin identifier matching the `name` field in your manifest
2. **source** — An object with `"source": "local"` and a `path` pointing to your plugin directory (e.g., `"./plugins/my-plugin"`)
3. **policy** — A configuration block defining `installation` (e.g., `"AVAILABLE"`) and `authentication` (e.g., `"ON_INSTALL"`) rules
4. **category** — A string classification (e.g., `"Productivity"`) for browsing organization

```json
{
  "name": "my-plugin",
  "source": {
    "source": "local",
    "path": "./plugins/my-plugin"
  },
  "policy": {
    "installation": "AVAILABLE",
    "authentication": "ON_INSTALL"
  },
  "category": "Productivity"
}

```

Append this object to the JSON array in [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json), ensuring the file remains valid JSON.

## Optional Configuration Files

Depending on your plugin's requirements, you may need to provide additional configuration files alongside the core manifest.

### Authentication with .app.json

If your plugin requires an App ID for OAuth flows or API authentication, create an [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) file at the plugin root. This file maps your plugin name to a unique identifier using the format `asdk_app_<unique-hash>`, as implemented in [`plugins/airtable/.app.json`](https://github.com/openai/plugins/blob/main/plugins/airtable/.app.json):

```json
{
  "apps": {
    "my-plugin": {
      "id": "asdk_app_<unique-hash>"
    }
  }
}

```

Reference this file in your [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) manifest using the `apps` field.

### Hooks and MCP Servers

For plugins requiring custom HTTP endpoints or Multi-Component-Package (MCP) server configurations, create [`hooks.json`](https://github.com/openai/plugins/blob/main/hooks.json) and [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) files. Point to these files from your manifest using the `hooks` and `mcpServers` fields to integrate them with the Codex runtime.

## Adding Skills to Your Plugin

Skills represent the functional units your plugin exposes to the Codex platform. Store these in the `skills/` directory (or the custom path defined in your manifest's `skills` field). Each skill requires a specific internal structure:

- **SKILL.md** — Markdown documentation describing the skill's purpose and behavior
- **agents/openai.yaml** — Agent definition specifying the `name`, `description`, `type`, `runtime` (e.g., `python3`), and `entrypoint`
- **Implementation files** — Python, JavaScript, or other executable code invoked when the skill runs

### Example Skill Structure

```text
plugins/my-plugin/
└── skills/
   └── hello_world/
      ├── SKILL.md
      ├── agents/
      │   └── openai.yaml
      └── hello_world.py

```

The [`agents/openai.yaml`](https://github.com/openai/plugins/blob/main/agents/openai.yaml) file defines how Codex invokes your code:

```yaml
name: hello_world
description: Returns a greeting
type: function
runtime: python3
entrypoint: hello_world.py

```

The implementation file contains the actual logic:

```python
def run(args):
    return "👋 Hello from My Plugin!"

```

## Summary

- Create a container directory under `plugins/` to hold all plugin resources
- Define core metadata and UI appearance in [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) following the schema in [`.agents/skills/plugin-creator/references/plugin-json-spec.md`](https://github.com/openai/plugins/blob/main/.agents/skills/plugin-creator/references/plugin-json-spec.md)
- Register the plugin in [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json) with a local source path and policy configuration
- Store visual assets in `assets/` using PNG or SVG formats, referencing them relative to the plugin root
- Implement functionality in `skills/` with proper [`SKILL.md`](https://github.com/openai/plugins/blob/main/SKILL.md) documentation and [`agents/openai.yaml`](https://github.com/openai/plugins/blob/main/agents/openai.yaml) definitions
- Add [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) only if your plugin requires an App ID for authentication, using the `asdk_app_<hash>` format

## Frequently Asked Questions

### What image formats are supported for plugin assets?

The Codex platform requires all UI assets—including `composerIcon`, `logo`, and `screenshots`—to use **PNG** or **SVG** formats. Store these files in the `assets/` directory and reference them using relative paths from the plugin root in your [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) manifest.

### Where do I configure the App ID for OAuth authentication?

Define the App ID in an [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) file at your plugin root (e.g., [`plugins/my-plugin/.app.json`](https://github.com/openai/plugins/blob/main/plugins/my-plugin/.app.json)). This file must contain an `apps` object mapping your plugin name to an `id` field with the format `asdk_app_<unique-hash>`, then reference this file in your manifest's `apps` field.

### How does the Codex platform discover new plugins?

The platform scans the [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json) file at the repository root to build the plugin registry. You must manually append your plugin entry to this file, specifying the local path, installation policy, and category for the indexing system to recognize your plugin.

### Can I organize skills in a directory other than `skills/`?

Yes. While `skills/` is the conventional location, you can point to any directory by modifying the `skills` field in your [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) manifest. The value accepts a relative path (e.g., `"./custom-logic/"`) that the Codex runtime will resolve when loading skill definitions.