# How to Validate Plugin Structure in the OpenAI Plugins Repository

> Learn how to validate plugin structure for the OpenAI plugins repository. Ensure correct naming and a valid plugin JSON manifest to avoid errors.

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

---

**To validate a plugin structure, ensure the plugin name contains only lowercase alphanumerics and hyphens (maximum 64 characters) and the [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) manifest includes all required fields such as name, version, description, author, and interface, optionally verifying against the official JSON Schema.**

The openai/plugins repository enforces a strict directory layout and manifest schema for all valid plugins. Validation occurs in two stages: first checking the plugin name against naming conventions, then verifying the manifest structure contains all required top-level keys and sub-objects. Understanding these validation rules ensures your plugin integrates correctly with the scaffold generator and analysis runners.

## Plugin Naming Conventions

The first validation step checks the plugin name using the `validate_plugin_name` function located in [`.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) (lines 33-40). This function enforces three strict rules:

- The name must be non-empty
- The name must not exceed 64 characters
- The name may contain only lowercase alphanumerics and hyphens

If any rule is violated, the function raises a `ValueError` immediately. The scaffold script also provides a `normalize_plugin_name` function that transforms raw input into the valid format before validation occurs.

```python

# Example: validate a plugin name before creating the scaffold

from pathlib import Path
from .agents.skills.plugin_creator.scripts.create_basic_plugin import (
    normalize_plugin_name,
    validate_plugin_name,
)

raw_name = "My Awesome Plugin"
plugin_name = normalize_plugin_name(raw_name)   # "my-awesome-plugin"

validate_plugin_name(plugin_name)               # raises if invalid

```

## Manifest Structure Requirements

Every valid plugin must contain a manifest file at [`PLUGIN_ROOT/.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/PLUGIN_ROOT/.codex-plugin/plugin.json). The `build_plugin_json` function in [`.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) (lines 43-70) defines the complete schema for valid manifests.

### Required Top-Level Fields

The manifest must include the following required keys:

- **`name`** – Must match the validated plugin name
- **`version`** – A semantic-version string
- **`description`** – Short free-form description
- **`author`** – Object containing `name`, `email`, and `url`
- **`homepage`**, **`repository`**, **`license`**, **`keywords`**
- **`skills`**, **`hooks`**, **`mcpServers`**, **`apps`** – Paths or placeholders for optional components
- **`interface`** – Complex object defining the UI surface, including display name, short/long description, developer name, category, capabilities, URLs (website, privacy policy, TOS), default prompts, branding assets, and screenshots

### Loading Existing Manifests

You can validate an existing plugin by loading its manifest and inspecting these fields. The repository demonstrates this pattern in [`plugins/ngs-analysis/scripts/ngs_run_utils.py`](https://github.com/openai/plugins/blob/main/plugins/ngs-analysis/scripts/ngs_run_utils.py) (lines 386-404), where the manifest is loaded at runtime to configure the analysis runner.

```python

# Example: load and validate an existing manifest

import json
from jsonschema import validate, ValidationError

manifest_path = Path("my-awesome-plugin/.codex-plugin/plugin.json")
manifest = json.loads(manifest_path.read_text())

# Load the official schema from the repo

schema_url = (
    "https://raw.githubusercontent.com/openai/plugins/main/.agents/schemas/plugin-manifest.schema.json"
)
schema = json.loads(Path("/tmp/plugin-manifest.schema.json").read_text())   # assumed pre‑download

try:
    validate(instance=manifest, schema=schema)
    print("Manifest is valid!")
except ValidationError as exc:
    print(f"Manifest validation error: {exc.message}")

```

## Advanced JSON Schema Validation

For rigorous validation, use the official JSON Schema definition located at [`.agents/schemas/plugin-manifest.schema.json`](https://github.com/openai/plugins/blob/main/.agents/schemas/plugin-manifest.schema.json). This schema describes the complete shape of valid manifests and can be used with standard validators like `jsonschema.validate` to catch missing fields, type mismatches, or disallowed values programmatically.

## Summary

- Plugin names must be non-empty, ≤64 characters, and contain only lowercase alphanumerics and hyphens as enforced by `validate_plugin_name` in [`create_basic_plugin.py`](https://github.com/openai/plugins/blob/main/create_basic_plugin.py)
- The manifest must reside at [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) and include all required fields defined in `build_plugin_json`
- Required manifest sections include name, version, description, author, interface, and component placeholders for skills, hooks, and MCP servers
- Advanced validation can be performed using the JSON Schema at [`.agents/schemas/plugin-manifest.schema.json`](https://github.com/openai/plugins/blob/main/.agents/schemas/plugin-manifest.schema.json)

## Frequently Asked Questions

### What are the exact character limits for plugin names?

Plugin names must be non-empty and cannot exceed 64 characters. They may contain only lowercase letters, numbers, and hyphens. The `validate_plugin_name` function in [`.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) enforces these constraints and raises a `ValueError` for any violations.

### Where must the plugin.json file be located?

The manifest file must reside at [`PLUGIN_ROOT/.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/PLUGIN_ROOT/.codex-plugin/plugin.json) relative to your plugin's root directory. This path is hardcoded in the scaffold generator and expected by analysis runners such as the one implemented in [`plugins/ngs-analysis/scripts/ngs_run_utils.py`](https://github.com/openai/plugins/blob/main/plugins/ngs-analysis/scripts/ngs_run_utils.py).

### Can I validate a plugin without using the scaffold script?

Yes. You can manually verify that your plugin name conforms to the naming rules and that your manifest contains all required fields listed in the `build_plugin_json` function. Additionally, you can validate against the JSON Schema using any standard JSON Schema validator like `jsonschema`.

### What happens if my manifest is missing required fields?

Missing required fields will cause validation failures when using JSON Schema validation, and may cause runtime errors when the plugin is loaded by analysis runners. The scaffold script ensures all required fields are present during initial creation, but manual edits must maintain this structure to remain valid.