# How to Create a Custom OpenAI Plugin for Your Service: A Complete Guide

> Create a custom OpenAI plugin for your service with our complete guide. Learn to scaffold a manifest bundle and implement API logic using the Plugin Creator tool.

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

---

**Yes, you can create a custom OpenAI plugin by scaffolding a manifest-based bundle and optional skill directories using the repository's Plugin Creator tool, then implementing your custom API logic in the provided folders.**

The `openai/plugins` repository provides a complete framework for building self-contained plugins that extend OpenAI's capabilities. By following the standardized directory structure and manifest schema, you can integrate any external service with ChatGPT and make it discoverable in the Codex UI.

## Understanding the OpenAI Plugin Architecture

OpenAI plugins are structured as self-contained bundles centered around a **manifest file** that defines metadata, capabilities, and entry points. The architecture follows a convention-based directory layout that separates configuration from implementation logic.

### The Plugin Manifest ([`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json))

Every plugin requires a manifest located at `plugins/<plugin-name>/.codex-plugin/plugin.json`. This JSON file declares the plugin's identity, interface specifications, and references to executable components. According to the source code, the manifest must include fields for `name`, `version`, `description`, `author`, and an `interface` object that defines display names, icons, and capabilities.

### Optional Components and Assets

Beyond the manifest, plugins can include several optional directories that extend functionality:

- **`skills/`** – Python functions or scripts that the LLM can invoke
- **`hooks/`** – Event-driven callbacks for lifecycle management
- **`scripts/`** – Utility automation scripts
- **`assets/`** – Static files like icons, logos, and screenshots
- **[`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json)** – Model Context Protocol server configurations
- **[`.app.json`](https://github.com/openai/plugins/blob/main/.app.json)** – Application-specific settings

## How to Create a Custom OpenAI Plugin Using the Plugin Creator

The repository includes a **Plugin Creator skill** that automates the scaffolding process. Located in `.agents/skills/plugin-creator/`, this tool generates the required directory structure, writes a placeholder manifest, and optionally registers your plugin in the marketplace.

### Step 1: Scaffold the Plugin Structure

Run the [`create_basic_plugin.py`](https://github.com/openai/plugins/blob/main/create_basic_plugin.py) script to initialize your plugin:

```bash
python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-service-plugin \
  --with-skills --with-hooks --with-assets --with-marketplace

```

This command performs four critical operations:
1. Normalizes the plugin name to lowercase hyphen-case
2. Creates the directory `plugins/my-service-plugin/`
3. Writes a placeholder manifest at [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json)
4. Updates [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json) to include your plugin in the Codex UI

### Step 2: Configure the Manifest

Edit the generated [`plugins/my-service-plugin/.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/plugins/my-service-plugin/.codex-plugin/plugin.json) to replace placeholder values with your service-specific metadata:

```json
{
  "name": "my-service-plugin",
  "version": "1.0.0",
  "description": "Integrates My Service with OpenAI’s Codex.",
  "author": {
    "name": "Your Name",
    "email": "you@example.com",
    "url": "https://github.com/yourname"
  },
  "homepage": "https://docs.myservice.com/plugin",
  "repository": "https://github.com/yourname/my-service-plugin",
  "license": "MIT",
  "keywords": ["my-service", "openai", "plugin"],
  "skills": "./skills/",
  "hooks": "./hooks.json",
  "mcpServers": "./.mcp.json",
  "apps": "./.app.json",
  "interface": {
    "displayName": "My Service Plugin",
    "shortDescription": "Connect My Service to ChatGPT.",
    "longDescription": "Allows ChatGPT to call My Service APIs for data retrieval, updates, and notifications.",
    "developerName": "Your Company",
    "category": "Productivity",
    "capabilities": ["Interactive", "Write"],
    "websiteURL": "https://myservice.com",
    "privacyPolicyURL": "https://myservice.com/privacy",
    "termsOfServiceURL": "https://myservice.com/terms",
    "defaultPrompt": [
      "Summarize recent activity in My Service.",
      "Create a new entry based on user input."
    ],
    "brandColor": "#3B82F6",
    "composerIcon": "./assets/icon.png",
    "logo": "./assets/logo.png",
    "screenshots": [
      "./assets/screenshot1.png",
      "./assets/screenshot2.png"
    ]
  }
}

```

### Step 3: Implement Custom Skills

Create executable functions in the `skills/` directory that the LLM can invoke. Each skill should accept a context parameter and return serializable data:

```python

# skills/get_status.py

def get_status(context):
    """
    Returns the current status of the user's account in My Service.
    """
    # Your HTTP request logic goes here

    return {"status": "active", "plan": "Pro"}

```

Register individual skills in a [`skills/manifest.json`](https://github.com/openai/plugins/blob/main/skills/manifest.json) file if your plugin framework requires explicit registration, or ensure they are discoverable via the main [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) reference.

### Step 4: (Optional) Add Hooks and Scripts

For lifecycle management or background processing, add Python scripts to the `hooks/` directory or shell scripts to `scripts/`. Reference these in your main manifest using relative paths to ensure the plugin loader can locate them during initialization.

## Registering Your Plugin in the Marketplace

When you use the `--with-marketplace` flag during scaffolding, the [`create_basic_plugin.py`](https://github.com/openai/plugins/blob/main/create_basic_plugin.py) script automatically appends an entry to [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json). This JSON file serves as the registry for the Codex UI, making your plugin searchable and installable by users.

If you need to manually update the marketplace entry later, edit [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json) to ensure the path points to your plugin's root directory and the metadata matches your [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) specifications.

## Key Files in the OpenAI Plugins Repository

Understanding these core files helps you navigate the codebase effectively:

- **[`.agents/skills/plugin-creator/scripts/create_basic_plugin.py`](https://github.com/openai/plugins/blob/main/.agents/skills/plugin-creator/scripts/create_basic_plugin.py)** – The CLI scaffolding tool that generates plugin directories and manifests
- **[`.agents/skills/plugin-creator/SKILL.md`](https://github.com/openai/plugins/blob/main/.agents/skills/plugin-creator/SKILL.md)** – Documentation covering the Plugin Creator's flags, workflow, and marketplace integration
- **[`README.md`](https://github.com/openai/plugins/blob/main/README.md)** – Repository overview with examples of highlighted plugins and architectural patterns
- **[`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json)** – The registry file that lists available plugins for the Codex UI

## Summary

- **OpenAI plugins** are self-contained bundles that expose a `manifest` file and optional components like skills, hooks, and assets.
- Use the **Plugin Creator skill** at [`.agents/skills/plugin-creator/scripts/create_basic_plugin.py`](https://github.com/openai/plugins/blob/main/.agents/skills/plugin-creator/scripts/create_basic_plugin.py) to scaffold the required directory structure automatically.
- The **manifest** at `plugins/<name>/.codex-plugin/plugin.json` defines your plugin's metadata, interface, and capabilities.
- Implement **custom logic** in the `skills/` directory as Python functions that the LLM can invoke.
- Register your plugin in the **Codex marketplace** by using the `--with-marketplace` flag or manually updating [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json).

## Frequently Asked Questions

### What programming language should I use to write plugin skills?

You should write plugin skills in **Python**, as the OpenAI plugins framework expects Python functions in the `skills/` directory that accept a `context` parameter and return JSON-serializable data. The scaffolding tool creates `.py` files by default, and the example implementations in the repository use Python for API wrappers and business logic.

### Do I need to manually update the marketplace file to make my plugin visible?

No, if you use the `--with-marketplace` flag when running [`create_basic_plugin.py`](https://github.com/openai/plugins/blob/main/create_basic_plugin.py), the script automatically updates [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json) with the correct path and metadata. However, if you move your plugin directory after creation or need to modify marketplace-specific display properties, you can manually edit the marketplace file to ensure the paths remain accurate.

### Can I create a plugin without using the Plugin Creator skill?

Yes, you can create a custom OpenAI plugin manually by creating the directory structure yourself and writing the [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) manifest according to the schema. However, using the Plugin Creator ensures you follow the correct naming conventions, directory layouts, and JSON structure required by the Codex loader, reducing configuration errors.

### Where do I store API keys and sensitive configuration for my plugin?

You should store sensitive configuration like API keys in environment variables or a separate configuration file (such as `.env` or a secrets manager) that your skills import at runtime. Do not commit credentials to the [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) manifest or version-controlled skill files, as these may be exposed when the plugin is distributed through the marketplace.