# How to Handle Plugin Metadata (Author, License, Keywords) in OpenAI Codex

> Learn to manage plugin metadata author license and keywords in OpenAI Codex using the plugin json manifest file for better discoverability and organization.

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

---

**Plugin metadata is defined in the [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) manifest file, where the `author` object identifies the publisher, the `license` string declares legal terms, and the `keywords` array supplies discovery tags for the marketplace.**

The openai/plugins repository powers the Codex platform's extensibility through a structured manifest system. To handle plugin metadata correctly, developers must populate specific fields in a JSON configuration file that the platform validates during discovery, indexing, and installation.

## The Plugin Manifest Location

Every Codex plugin stores its canonical metadata in a hidden folder at the repository root. The file [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) serves as the single source of truth for the platform's marketplace and runtime systems.

According to the specification 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 follows a strict schema that includes identity, legal, and discovery information. The platform reads this file when scanning the repository to build the searchable plugin catalog.

## Required Metadata Fields

Three critical fields control how your plugin appears in the marketplace and how users discover it.

### Author Information

The **author** field is an object containing `name`, optional `email`, and optional `url`. This identifies the publisher in the marketplace UI and provides attribution and contact details.

- **name**: Required string displayed as the publisher identity
- **email**: Optional contact address
- **url**: Optional link to the author's profile or organization

The platform validates that `author.name` is a non-empty string during plugin loading. Missing or empty values cause the plugin to be rejected at runtime.

### License Declaration

The **license** field is a string declaring the software license (e.g., `MIT`, `Apache-2.0`). Codex validates that a non-empty license is present and surfaces this information to users so they understand the legal terms before installation.

Use SPDX-compatible identifiers to ensure compatibility with automated license checkers. Common values include `MIT`, `Apache-2.0`, and `BSD-3-Clause`.

### Discovery Keywords

The **keywords** field is an array of strings that supply discovery tags for the marketplace search engine. These tokens are indexed to help users find your plugin when searching for specific capabilities.

The array must contain at least one string, and each keyword should be concise and relevant. These tags appear directly in the UI on the plugin card, so avoid overly long phrases.

## Creating and Validating Metadata

When scaffolding a new plugin, the creation script [`.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) generates a [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) with placeholder TODO markers for metadata fields. Developers must replace these placeholders with real values before submission.

The validation pipeline enforces these rules:

1. `author.name` must be a non-empty string
2. `license` must be a non-empty string
3. `keywords` must be a non-empty array of strings

Malformed manifests are rejected at load time, preventing broken plugins from appearing in the marketplace.

## Working with Metadata Programmatically

Because the manifest is plain JSON, you can parse and modify it using standard libraries.

### Loading Metadata from a Plugin

```python
import json
import pathlib

def load_plugin_metadata(plugin_root: pathlib.Path):
    manifest_path = plugin_root / ".codex-plugin" / "plugin.json"
    with manifest_path.open() as f:
        data = json.load(f)

    author = data.get("author", {})
    license = data.get("license", "")
    keywords = data.get("keywords", [])

    return {
        "author_name": author.get("name", ""),
        "author_email": author.get("email", ""),
        "author_url": author.get("url", ""),
        "license": license,
        "keywords": keywords,
    }

# Usage

metadata = load_plugin_metadata(pathlib.Path("/path/to/plugins/zoom"))
print(metadata)

```

### Updating License and Keywords

```python
import json
import pathlib

def update_license_and_keywords(plugin_root: pathlib.Path, new_license: str, new_keywords: list[str]):
    manifest_path = plugin_root / ".codex-plugin" / "plugin.json"
    manifest = json.loads(manifest_path.read_text())

    manifest["license"] = new_license
    manifest["keywords"] = new_keywords

    manifest_path.write_text(json.dumps(manifest, indent=2))
    print(f"Updated {manifest_path}")

# Example call

update_license_and_keywords(
    pathlib.Path("/repo/plugins/zoom"),
    "Apache-2.0",
    ["zoom", "video", "conference", "api"]
)

```

### Validating Metadata in Tests

```python
import json
import pathlib
import pytest

def test_plugin_metadata():
    manifest = json.loads(
        pathlib.Path("/repo/plugins/zoom/.codex-plugin/plugin.json").read_text()
    )
    assert isinstance(manifest["author"]["name"], str) and manifest["author"]["name"]
    assert isinstance(manifest["license"], str) and manifest["license"]
    assert isinstance(manifest["keywords"], list) and all(isinstance(k, str) for k in manifest["keywords"])

```

## Complete Manifest Example

The Zoom plugin in [`plugins/zoom/.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/plugins/zoom/.codex-plugin/plugin.json) demonstrates production-ready metadata:

```json
{
  "name": "zoom",
  "version": "1.0.0",
  "description": "Interact with Zoom meetings and recordings.",
  "author": {
    "name": "OpenAI",
    "email": "support@openai.com",
    "url": "https://openai.com"
  },
  "homepage": "https://zoom.us",
  "repository": "https://github.com/openai/plugins/tree/main/plugins/zoom",
  "license": "MIT",
  "keywords": ["zoom", "video", "conference", "meetings"],
  "skills": "./skills/",
  "interface": {
    "displayName": "Zoom",
    "shortDescription": "Manage Zoom meetings",
    "category": "Communication",
    "capabilities": ["Interactive", "Write"]
  }
}

```

## Summary

- **Store metadata** in [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) using the schema defined 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)
- **Define authorship** with the `author` object containing at minimum a `name` string
- **Declare licensing** using SPDX identifiers in the `license` field to ensure legal clarity
- **Enable discovery** by providing relevant terms in the `keywords` array for marketplace search indexing
- **Validate requirements** programmatically to ensure `author.name`, `license`, and `keywords` meet the platform's non-empty constraints

## Frequently Asked Questions

### Where is plugin metadata stored in the openai/plugins repository?

Plugin metadata lives in the [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) file within each plugin's directory. The platform discovers this manifest during repository scanning and uses it to populate the marketplace catalog and runtime configurations.

### What license format should I use for Codex plugins?

Use SPDX-compatible license identifiers such as `MIT`, `Apache-2.0`, or `BSD-3-Clause`. The platform requires a non-empty string for the `license` field and validates its presence during plugin loading.

### How does the Codex platform validate plugin metadata?

The validation pipeline checks that `author.name` is a non-empty string, `license` contains a non-empty string, and `keywords` is a non-empty array of strings. Plugins with placeholder values like `[TODO: MIT]` or missing required fields are rejected at load time and will not appear in the marketplace.

### Can I update plugin metadata after the initial creation?

Yes. The [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) file is a standard JSON document that you can edit directly or modify programmatically. After updating metadata, ensure the plugin passes validation by checking that all required fields contain proper non-empty values according to the specification.